Hey everyone! Im new to unity and im looking for someone very exeprienced with unity that can CR my project on github https://github.com/kuskus110/create-with-code-unit3
I am looking to learn and improve 🙂
Thank you!
1 messages · Page 186 of 1
Hey everyone! Im new to unity and im looking for someone very exeprienced with unity that can CR my project on github https://github.com/kuskus110/create-with-code-unit3
I am looking to learn and improve 🙂
Thank you!
Hello people. What should I do for exception handing in my API?
When I encounter an error (for example in the validation) should I throw an exception or return an error object to the user having the details of the error with the boolean 0
Is it possible to detect when your camera is NOT rendering anything? just the skyview?
i would like to detect when the player has moded the camera away from the map
to bring him back
but how can I know this?
ideally you'd need to implement some sort of a Dead zones in your game
so certain areas can only accessible to certain objects in your game
Does anyone happen to know with which version Unity went from caching builds in Temp to Library?
Hello. I am trying to make a serializable class in Unity to read from a JSON. However, it's a class whose members will be arbitrary. In essence, I want to be able to read from a JSON into a <string, object> Dictionary.
I am having some trouble using the JsonUtility.fromJSON method, which seems to not like my serializable class, as it never calls the constructor that takes the SerializationInfo.
I do not wish to import a package such as Newtonson's JSON.Net package, because I only need this one functionality...
Any recommendations?
It never enters here.
if I add a default constructor, it calls that one.
Which is what I assume is happening.
Unity's serializer doesn't support that
You should use json.net or something similar
There's also some other small json libraries that might do what you want like minijson
@novel plinth im afraid for this case would be hard because the cam tilt rotation... take a look:
this one is sttill valid
this one it sttill shouild be valid since player still sees a little part of the map
you can just restrict the movement of the camera then
this is the onne that should trigger the actio
yeah, restricting the movement leads to otther problems buttthanks
i guess there is no way to know when the cam is not rerndering any object right?
maybe raycasting
making a boxraycast
Sure, there are ways of course
Either via the object's renderer itself https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html
OR
Via CullingGroup
https://docs.unity3d.com/ScriptReference/CullingGroup.html
Even tho you don't have to tbfh...
the latter is a bit too much for your simple use case tbh
ttheres a botttom object in the map
why not OnBecameVisible?
and i assigened a script with the OnBecameVisible
and OnBecameInvisible
but sometimes i dont see the map and itt doesnt trigger, i think is not accurate
I guess the render isvisible, is ddirectly connected to OnBecameVisible
ill try
I'm not quite sure with this claim, I've been using it with no problems even in a very fast-paced games
I will take a look at minijson, even if I don't like the idea of having to take code from some other source, it does seem relatively small. Thank you.
what kind of camera
this is a perspective camera with autotilt and i think sometimes is not 100% accurate whatt the script says itts on cam andwhat it is
Ill try with the simulator instetad of editor just in case
yeah but imo scriptable objects really would suck for this, imagine having a folder full of objects with numbers
i have an editor script to control whether a variable appears or not on the editor depending on the type of my item. But this line is breaking my code? Does anyone know how i should proceed to do this with a variable of type Color?
all the others are ints floats or bools, i guess that's the problem
wdym, colors work fine in PropertyFields?
well when I add that specific line this happens
i get an error and a ton of my properties disappear from the editor script
What's the stack trace of that error
That sounds more like hiddenResourceColor doesn't exist
Send the stacktrace here
private static bool IsChildrenIncluded(SerializedProperty prop)
{
switch (prop.propertyType)
{
case SerializedPropertyType.Generic:
case SerializedPropertyType.Vector4:
return true;
default:
return false;
}
}```
Is the source of the method throwing the NRE
So it can't find that field somehow
You sure that's a Unity Color?
hmmm okay maybe that's the problem
got a lot of colors on my project
do i need any include?
might be a color from another namespace or class i'm guessing
Right, so double check that and make sure it's Unity's COlor
is there another way i don't have to do this?
just writing color seems to no work it doesn't let mne select the proper Color type
Don't import the other Color into that class
Could someonne help me how to make some sort of raycast, boxcast, or planecast with the camera borders there ?
@stuck onyx You can translate camera space to world space and align a box cast but it really depents on what you want to achieve
Show your "using"s. Also did you make your own class called "Color"?
first im tryinng with 4 raycasttts
var raytopRight = Cam.ScreenPointToRay(new Vector3(Screen.width, Screen.height, 0));
Physics.Raycast(raytopRight, out topRightHit, 1000,````
what I want to achieve is to be sure nothinng is being rendered
to rotate the camera 180 degrees
What would be a good way to add grass to procedurally generated mesh terrain?
Guys
anyone can help me out
internal static void SaveCubemapToFile(Cubemap cubemap, string path)
{
CubemapFace[] faces = new CubemapFace[] {
CubemapFace.PositiveX, CubemapFace.NegativeX,
CubemapFace.PositiveY, CubemapFace.NegativeY,
CubemapFace.PositiveZ, CubemapFace.NegativeZ };
Texture2D Text = new Texture2D(cubemap.width, cubemap.height);
foreach (CubemapFace face in faces)
{
try
{
Log.Debug($"Generating Texture of {face}");
Text.SetPixels(cubemap.GetPixels(face));
Log.Debug("Saving Texture...");
Text.SaveTextureAsPNG(path, face.ToString() + ".png");
Log.Debug($"Saved {cubemap.name} {face.ToString()}");
}
catch (Exception e)
{
Log.Exception(e);
}
}
}
tryin to copy the cubemaps
and save them
Graphics.CopyTexture(Text, 0, 0, cubemap, (int)face, 0);
i tried with this, all i get is a blank grey png file
this is what it comes out in all cubemaps faces
Try calling Apply on the texture after setting pixels
shouldn't Graphics do it?
why would it?
givin a try again
i thought so?
nope, again
** internal static void SaveCubemapToFile(Cubemap cubemap, string path)
{
CubemapFace[] faces = new CubemapFace[] {
CubemapFace.PositiveX, CubemapFace.NegativeX,
CubemapFace.PositiveY, CubemapFace.NegativeY,
CubemapFace.PositiveZ, CubemapFace.NegativeZ };
foreach (CubemapFace face in faces)
{
try
{
Texture2D Text = new Texture2D(cubemap.width, cubemap.height);
Log.Debug($"Generating Texture of {face}");
Graphics.CopyTexture(Text, 0, 0, cubemap, (int)face, 0);
Text.Apply();
Log.Debug("Saving Texture...");
Text.SaveTextureAsPNG(path, face.ToString());
Log.Debug($"Saved {cubemap.name} {face.ToString()}");
}
catch (Exception e)
{
Log.Exception(e);
}
}
}
For context: I am trying to create a simple mechanic, which is regeneration for the player. However, I wanted it to change depending on the environment the player is in, so I was thinking of having the rate in which the regeneration happens change depending on how green the environment is. To do that, I was thinking of taking the camera's display and checking the average RGB value from that, and see how closely it would resemble pure green.
Then I encountered the problem of how I would do so. So, I am currently asking how I would program that in.
I don't know if it would fit in this channel, but the question wasn't being answered in either beginner nor general code, so I decided to post it here. I've been searching everywhere to figure it out, but I simply couldn't find a good answer.
Thank you for reading, and maybe even answering.
I don't understand, now you're creating an undefined texture, copying that into a cubemap face, and then applying the texture and saving it? Where did the Get/Set pixels go?
the cubemap texture IsReadable is not set to true
im trying to figure a workaround to sort of "futureproof" it and ignore the isReadable flag
Maybe you ought to flip the arguments in the CopyTexture call around
because you're copying the texture into the cubemap face right now, which doesn't seem right
im trying to save the cubemap faces back to .png
not copy the texture into the cubemap
you are currently doing this
Graphics.CopyTexture(Text, 0, 0, cubemap, (int)face, 0);
src : Source texture. : Text
dst: Destination texture. : cubemap
oh
givin a try again
nope, just flipped em and still same results
internal static void SaveCubemapToFile(Cubemap cubemap, string path)
{
CubemapFace[] faces = new CubemapFace[] {
CubemapFace.PositiveX, CubemapFace.NegativeX,
CubemapFace.PositiveY, CubemapFace.NegativeY,
CubemapFace.PositiveZ, CubemapFace.NegativeZ };
foreach (CubemapFace face in faces)
{
try
{
Texture2D Text = new Texture2D(cubemap.width, cubemap.height);
Log.Debug($"Generating Texture of {face}");
Graphics.CopyTexture(cubemap, 0, 0, Text, (int)face, 0);
Text.Apply();
Log.Debug("Saving Texture...");
Text.SaveTextureAsPNG(path, face.ToString());
Log.Debug($"Saved {cubemap.name} {face.ToString()}");
}
catch (Exception e)
{
Log.Exception(e);
}
}
}
@austere jewel
You have (int)face in the wrong place.
Also, now you're no longer doing SetPixels, calling Apply is wrong and will just yield undefined results
because the CopyTexture only occurs on the GPU, so Apply is just overwriting it
I don't know how SaveTextureAsPNG works though so I can't say whether it'd do what you want it to
save texture just processes it back to png if not readable
where i should put (int) face?
Graphics.CopyTexture(cubemap, (int)face, 0, Text, 0, 0); associated with the element of the cubemap
What would be the best way to approach IK in 2022, should I use the new rigging system or the old animation IK pass?
Still need help!
sample the mesh in UV space
you can render the camera to a texture and analyze it
are you sure the cubemap has something in it?
gray is unusual
why would it be gray, and not all black, if it were an empty texture?
Grey is one of the common outputs to undefined textures
i fixed it, but now is just rotated in the wrong way lol
Guys Im having an issue, Im working with toggles I instantiate a bunch of toggles that are ment to be clicked when a user wants that question to be added. After I change scene and create the question doc, if the user chooses to go back and sellect different questions this error pops up
(MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.)
Google says something about singletons but Im not sure where that would help
you're trying to access an object you've destroyed
when you switch scenes everything in that scene gets destroyed
so for some reason you're still referencing something from the old scene
Yeah I understand that, but Im essntially re-instantiating the objects right ? When I go back at the scene
Im calling a static method that I used in the first place to instantiate those objects
Yeah but still I assign them in the start function when I switch scenes
How should I fix this cause Ive been struggling to be honest :/
let me see the code
just the relevant portions
alright
use triple backticks to make a code block -> ```
Im trying to paste the code
oh
//
public void FromMenuToSellectionView(int SceneID)
{
LocateCategory(); // this just gets and filters the input from a field
SceneManager.LoadScene(SceneID);
}
public void nextPage(int SceneID)// this is what I use to go to the final scene
{
int numOfQuestions = questionsFormat.Count;
using (var connection = new SqliteConnection(dbName))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "DELETE FROM SellectedQuestions";
command.ExecuteNonQuery();
for (int i = 0; i < numOfQuestions; i++)
{
if (checkToogles[i].GetComponent<Toggle>().isOn)
{
command.CommandText =
"INSERT INTO SellectedQuestions(Τύπος,Αντικείμενο,Ερώτηση,ΕπιλογήΑ,ΕπιλογήΒ,ΕπιλογήΓ,ΕπιλογήΔ,Απάντηση) VALUES ('" +
questionsFormat[i].questionCategory + "','" + questionsFormat[i].type + "','" +
questionsFormat[i].question + "','" + questionsFormat[i].answer1 + "','" +
questionsFormat[i].answer2 + "','" + questionsFormat[i].answer3 + "','" +
questionsFormat[i].answer4 + "','" + questionsFormat[i].correctIndex + "');";
command.ExecuteNonQuery(); // It executes the command the number of questions maybe ?
}
}
connection.Close();
}
}
storeSellectedQuestions();
SceneManager.LoadScene(SceneID);
}
public void fromFinalToPreview(int SceneID) // this is what I use to to go back to the previous scene
{
if (!initialized)
{
initialized = true;
SceneManager.LoadScene(SceneID);
}
}```
And Im doing this ugly for loop to assign each toggle to each question
which line is causing the nullref?
This is in Sellection/Preview
As soon as I use the function fromFinalToPreview
And gimme 1 sec to tell you exactly
It points to the if statement int nextPage() method
if (checkToogles[i].GetComponent<Toggle>().isOn) // this is in the sellection/Preview scene
I have a button assigned to nextPage(), and as soon as I click is that error pops up. saying checkToogles[i].GetComponent<Toggle>().isOn is destroyed
are both of those scripts inside the Preview/Sellection scene?
are you changing scenes in between the second code block and the first getting called?
yes the for loop as well as the nextpage script are in the preview/sellection scene
the very last script esentially creates a pdf document with all sellected quetions in preview/sellection scene
I gave the option to the user to go back and choose different questions, with is the fromFinalToPreview method
something is destroying your toggle buttons looks like
Hey, i want my square to go from one yellow point to the next one by passing through red points. Currently i can go by a system of pathfinding from one point yellow to another. I would like to add some points between two yellow point
I suppose change the scene would destroy them but after that I still call the script when I go back at that scene right ?
presumably
I don't see anything that would cause the behaviour you're experiencing in the code you posted
are you destroying things elsewhere
well no :/
do you have multiple scripts in the scene perhaps
No, for this scene thats the only scripts, I have to scripts in a scene unrealatable
you're definitely doing something funky, but it's not obvious from what you've posted
I do create a list of objects which I dont clear after I move to the next scene
ohh, I think I got it.
that would do it
yw
how can she slap???
how so?
for reasons like that
and I recall it created quite a headache for a friend's editor project because it's very magical and hard to script around
when you're dynamically creating objects
did you try running the game? I remember getting some warnings/errors about dangling dependencies when in this situation
i didnt but i should have
IEnumerable<Vector3> goals;
IEnumerable<Vector3> Goals => goals ??= from GameObject go in GameObject.FindGameObjectsWithTag("NavPoint") select go.transform.position;
Is there a way to rewrite this as an autoproperty? I tried this, but here goals is read-only
IEnumerable goals => goals ??= from GameObject go in GameObject.FindGameObjectsWithTag("NavPoint") select go.transform.position;
IEnumerable<Vector3> goals { get; } = from GameObject go in GameObject.FindGameObjectsWithTag("NavPoint") select go.transform.position;
seems to be valid but I'm not sure if the FindGameObjectsWithTag() will work properly given the context.
yep lol
So, if I await a Task.Run(), does Unity guarantee that the thread to complete the Task.Run() will be the game thread?
That seems to be the case.
I'm not sure but look into UniTask if you haven't already
Are you asking because the following code needs to be run on the main thread?
If so, I think you can configure that using ConfigureAwait(true)
Otherwise, if the code inside of of the Run() needs to run on the game thread, then that's a job for a Coroutine
or a UniTask
Never seen AutoGetComponent before :o
hmm, i suppose just add them to your graph of points right?
@undone coral he's being helped in #archived-code-general
I can give you the code for it if you want. It works beautifully, and the field can even be readonly because it uses reflections. However, the performance of the code in the attribute could be improved, but I haven't looked into it.
no. use unitask if you want to run tasks on the main thread
I didn't say that I wanted to run tasks on the main thread.
Please do
a task can run on multiple threads throughout its execution. they are separate things
Tysm
within an async method you can control which thread gets control when the task you're awaiting completes
it's very tricky
I'm aware. I know how to manually use TaskCompletionSources in general. I'm asking what Unity does.
you can use UniTask to easily express which Thread you want to "Return to"
unity out of the box is undefined behavior
so you have to use unitask to do this stuff
Or I could just do the task completion sources myself, but it seems like Unity guarantees more than that. One second while I write up an example.
you can reinvent unitask yes
reinventing unitask is a bad idea
one of the worst ideas out there
all the downsides of rediscovering unity idiosyncracies with none of the upsides of working code
private Update()
{
TestFunction();
}
private async void TestFunction()
{
//I'm on game thread
await Task.Run(() => {
// I'm likely on a worker thread.
});
// In my testing, I am back on the game thread, likely because Unity specifies a SynchronizationContext, but that's not documented that I've found.
}
yeah
you should definitely use unitask
it documents its answers to these questions
Every time I add a dependency it causes crashes right before deadlines...
i don't know either and i think the value of finding out, since it's not in the unity docs, is low - what they're saying is it might change
hmm
i don't think this is going to do that
... If I can't trust Unity, then I'm just going to use blocking calls, because that's safer for the deadlines that I have.
But it looks like Unity resumes Task.Run()s on the game thread... that's been the case in my testing. Curious if that was just coincidence.
@red osprey
private Update()
{
// "Forget" is dealing with a critical gotcha. your IDE is warning
// you about this
TestFunction().Forget();
}
// void is another gotcha with async methods. ide is also warning
// you about this
private async UniTaskVoid TestFunction()
{
await UniTask.SwitchToMainThread();
//I'm on game thread
await UniTask.SwitchToThreadPool();
// now you're on the thread pool
DoCostlyWork();
await UniTask.SwitchToMainThread();
// I'm on game thread
}
unitask is a low risk depndency
No thank you.
i can see if you added dependencies in another life, like in javascript life
well, you don't pay for javascript libraries now do you? of course they're awful
unitask ships in all my games
anyway i'm trying to make it way easier for you to do what you need
that example is very cute and good
unitask forces you to deal with all the gotchas too.
in a good way
I mean the easiest is if Unity already guarantees what my use case would be.
And one example is a voice chat library that I used that had two separate crashes, one on ARM64, and one on TCP.
was it a FREE voice chat library?
That forced me to ship my demo 32-bit only, which isn't allowed by Oculus.
Nope. Asset Store.
I talked to the author. He didn't have a Quest.
jk
it's okay dude
i don't want you to stress
i don't know if the body of Task.Run is on a worker thread
i know in unitask you can control it explicitly
I'm asking as you LEAVE task.run
There we go. That was the question.
however
with regular csharp tasks, you can put yourself in jeopardy easily
and that will not be the case
for example, if you are using RestEasy
@undone coral isn't this exactly what ConfigureAwait is for?
you can easily wind up on the resteasy http client implementation's thread pool
or something weird like that
because resteasy is weird and radioactive
If the worker can be whatever thread but the continuing context needs to be the game thread...
Yeah ConfigureAwait will determine whether to resume the task on the thread that initially started it
So he doesn't need a unitask here
Nope
You disagree?
it's up to you. you can try to interact with all this radioactive stuff
that requires a degree in taskology
Sorry I totally agree with you here
or you can use the thing that this cygames guy, maybe the greatest contributor to open source unity code, has made and ships in his huge games
Lol just English things
Yep
The problem is that unitask isn't multiprogramming
so i guess really my point is, i have never wound up in jeopardy using unitask
whereas in the past, when i use async or blocking code from libraries like grpc or resteasy, out of the box unity async can put me in surprising kinds of jeopardy due to all the gotchas of nude C# async
My understanding is that unitask doesn't have the parallelism performance increase that tasks are great for
i guess the most common place you'll run into "being int he wrong thread pool" is if you are configuring listeners, like for a websocket or tcp listening library
if you are using these things to await network messages, you might be better off using unirx
since nude C# async is challenging to use for channels / signaling this way
nude async challenge
lol
i haven't even gotten into cancellation
if you don't Java you don't know why all this stuff exists
the .net docs certainly don't tell you
because those people don't even know
like, does X throw operation cancelled exception or not?
why does the token have iscancelled?
do i have to check this after every await? (basically, yes)
so many gotchas!
Does it throw? You look at the docs or what intellisense tells you to check
The token has to track state whether the Cancel was called on the CTS so of course it has a flag, for methods to bail out if they don't throw an exception via ThrowIfCancellationRequested()
i think you agree then that it's really arcane
No
hmm
Talking about plain old C# TAP here, no Unity, no random assets
the answers you gave to those questions sound arcane
arcane is a qualitative thing
it's arcane
To you probably
cancellation token linking, and whether or not you have to pass down a token, and how to do that, are also pretty arcane
i think it's arcane
How would you do it then
there is a ton of arcane stuff
well, it seems wrong to pass a cancellation token deep down into everything, and then having to declare every method (eventually) with CancellationTokenSource cancellationToken=default (or whatever)
Let's say you implement a library that does async... stuff, and you want to implement something that would replace the TCS while still being compatible with the C# ecosystem
How would you do it
i'm saying that because you start and stop the editor all the time, in practice you will need to cancel in the middle of unity async tasks all the time
so you have to deal with it up front, everywhere
and it's cantankerous and bad
and UniTask does some stuff to make life easier for you
So yeah, you're just ignoring my question
no no
UniTask has WithCancellation extensions for common stuff, it has an OnDestroyToken, etc. etc.
it has good stuff for this
No Unity, no external package
If you were in charge of developing the async cancellation system how would you do it
i'm not sure. i don't write C# backend code. i don't use visual studio
i would probably do what Golang does, and back in java world, i would stick to what ron pressler did in quasar, which is now becoming java virtual threads i.e. fibers
in video games a lot more cancellation happens
than in stateless http backends. but anyway, who's writing those anymore
there isn't much value in the 10,000th stateless thing.
all the value of stateless crap has been mined, and only stateless stuff doesn't have to deal with cancellation
in java world, exhibit A is Vertx
you're talking about intellisense, and i use rider 🙂
video games are very stateful. i actualyl really liked experimenting with defining my whole game loop in one big async method
i think it's a viable way to make minigames / constrained experiences
you gain a lot from being forced to deal with something like cancellation, because it reflects real potential bugs
in my experience, backend C# code nowadays has a lot of clunky dependency injection. when people really just want a Kestrel and to add routes to it (i.e., they want Vertx in their C#)
in that context, yeah, i think the way C# does async makes sense. because it already coexists with this crummy, arcane thing that nobody wants
go doesn't have the concept of cancellation, but in its opinion it doesn't want you to model that using its stack at all
they don't do function coloring (i.e. marking a method as async), they don't have function polymorphism (i.e. throwing exceptions)
then again if i was more familiar with rust i'd probably say "whatever rust does" because they have spent the longest time thinking about this for all possible end user applications
rust has function coloring
i kinda second this.
heavy reliance on some third party asset might work for indie projects, but you cannot always use a third party plugin everytime for every program you make in c#
i feel unirx is kind of bloated. also generally speaking (not just unirx) it becomes a very tedious process to migrate away your programming pattern from Unirx to vanilla c# style incase unirx gets abandoned
C++20 coroutines are quite cute. (They don't have any consideration for threads... just the state machine to know where you're starting from each time you enter the "function".) So efficient that some people are actually using them to "await" RAM fetches. (Basically, write their code as if they're processing fetching processing fetching processing, etc.... but, in terms of what the CPU sees, it's everything up to and including the load, but before ever using any of the loads.)
So I have been looking in to how to handle larger open worlds and it seems a common method is to split it up in to scenes which are additively loaded.
However unloading a scene will clear/reset any changes that were made in that scene. So if I understand correctly, when unloading a scene during play you need to save any changes the way you would when saving the whole game, and then load those changes when the scene is loaded.
Does that all sound correct, or am I missing something?
Sounds sound
sounds correct but wont work in unity without stop-the-world-freezes
there is no way in unity to prevent the engine from initializing all gameobjects in an additive load (even when its an async one) at least once
Cool, glad I understand it correctly.
How do I reinvent csharp so that I can create a new operator called "backwards equal" ≈ to allow for newValue = shouldUseFirstVariable ? defaultVariable : fallbackVariable which assigns the left side to the variable that the right side evaluates to
1 ≈ myInt;
From what I understand a way to get around this to to have everything disabled by default and then enable it async after the scene has loaded.
Unless you know a better way to handle loading stuff in large open worlds?
this does not help, because its not the awake that causes the lag but some sort of engine internal init
if you keep the scenes small enough it is manageable, or do it with very fine grained addressable loading
Oh really? So... what do people do for streaming open worlds then...?
they dont build them in unity or preload or hide the loads
Well... there are a good number that do it in Unity so...
some also have a source license and modify the engine
do you have an example?
curious myself
Subnautica is the first that comes to mind
how do you "hide" the loads?
Multi-scene management is a bit complicated (ex: baking lighting with multiple scenes loaded writes IIRC the lightmap to the active scene based on lighting from all the loaded scenes).
In the handful of demos that I have, I have a scene that has most of my typical objects, and I additively load/unload scenes accordingly.
i'd say if you are standing in an elevator the freeze is less annoying as it is expected
ah, portal types. Gotcha
I also know Pine was made in Unity and Genshin Impact (but they for sure have a engine license)
overall unity and unreal are (have been) "terrible" engines for open world games
they can do it with workarounds but they have nothing in them that makes it easy
The main issue seems to be the lag when loading a scene caused by in-engine stuff
open world = requiring lots of asset streaming
the other issue is scene management
You'd need to profile that.
thats just atrocious
Asset streaming, that is done with addressables right?
Or just asset bundles in general.
either with addressables or scenes
I need to look in to that more
raw bundles will melt your brain
hey guys, im trying to multiply a bunch of matrixes(4x4) tho the last row is always the same as the identity matrix. how can i multiply these faster by eliminating the need for accounting the last row?
I'll just use this for now
public static int BackwardsEquals(this int a, out int b) => b = a;
1.BackwardsEquals(out int myInt);
Debug.Log(myInt);
// in method
1.BackwardsEquals(out int myInt);
Debug.Log(myInt);
but this only works in a method, so I can't create a field with that
It's a bit messy unless (like my current project) the use case is VERY simple.
"A bit".
In the cases that I've done additive loading/unloading, it's mostly just to transition between scenes while the user can do stuff in the load time.
Alrighty, thanks all for the insight! Glad to know I am on the right track. I will carry on as is and I guess just figure out how to work around stuff it becomes a problem.
On a related note, would you use the same method (scenes) for loading and unloading distant objects?
Like unloading small objects, then bigger and bigger ones.
Or would you not really do that and just unload the whole section at once in a single scene?
Well "load time". One of them was a VR demo that had basically zero load time, but transitioning from scene to scene involved matchmaking, which <shrug emoji> when we can find a partner.
So they'd stand in an empty room while the matchmaking ran.
But they could still walk around, move their hands, etc.
hmmm.. well for most of its history many C# developers were adding Newtonsoft JSON to their project, which is probably "10x" as "bloated" as unirx
and nothing bad happened
i can never really pin down what people mean by bloated. it is usually a tautology for "i don't like this"
if you ban "bloated" as a reason not to use something, there's nothing to what you're saying
Nothing bad happened? Not even when Unity added it too and broke people's builds?
a library duplicate is not "breaking a build"
anyone could fix that, does not require special project specific knowledge of the codebase
Breaking the build process.
i meant day to day, c# developers and the unity ecosystem uses external libraries and plugins routinely
And not anyone could fix that. It was an ongoing struggle that lasted years.
some are bad. but why would i recommend a bad library to my bros on the internet
anyone with a chance to actually finish a project must be able to deal with library conflicts
But the point is why did you waste time dealing with library conflicts if there was a simpler solution?
unity probably helped the average developer by forcing them to vendor source code
isn't that crazy? that's the opposite of what the yavascript developer would do
unity is good at making people believe its easy to make stuff with it
i really think the json library conflict thing was not that big of a deal
the error message is a little arcane
but if you punch it into google the solution is there
Correct. I use Newtonsoft right now. But that's because I need polymorphism for this specific project. Until that point, Unity's built-in library worked just as good, and it was built in.
the builtin one is a joke
well if you're doing some kind of networked RPC HTTP thing
If it handles your need, then why would you waste your time managing build dependencies?
you know, you better start believing in external libraries and codebases, because you're using one
something something, the pirates of the caribbean meme
Lol
i agree. but nude async is really painful
Lol
lol
"computer, can i get a Nude Async?"
"hi, i'm async, i'm one of your new dancers. and you're gonna love me"
you shouldn't compare Newtonsoft json with unirx because
i) Newtonsoft works with both Unity and non unity applications. Unirx doesnt.
ii) What newtonsoft does, did not exist in c# before. there was no way you can implement it individually and as nicely as them.
iii) Newtonsoft json is a utility. It doesn't determine the programmer patterns you pick. Newtonsoft is abandoned and deprecated? fine. just simply replace the calls to Newtonsoft with another package or your own version of serialization.
its like comparing apple to oranges. totally irrelevant in this conversation
The point is that, if you're importing a library that can do 20 things, and you need 2, then you are importing 18 things that you need to support but don't need to use. If those 2 things are already handled by something you already have, then you're importing 20 things that you need to support but don't need.
That's okay, but it's quicker and simpler to not do that, unless you have a specific reason.
libraries dont do 20 things, they do one thing, and if you pick one where you feel it does 20 you are not using the right one
That's... not even true at all?
if you hate the async/await pattern, there is always IAsyncResult/callback pattern which you can implement, probably what most C# programmers were using before TPL was introduced in .net4
you can easily control the thread from which the callback is being fired.
you can implement error callbacks incase theres an exception/cancellation.
its like you fire a function and forget. when you get the callback, deal with it
if you want your code to just do exactly what you need, write it from scratch in C
That's... also not even true at all?
If you're being completely purist, it would be machine bytecode.
But, even then, that still doesn't even make sense?
maybe you don't want it to make sense to you
newtonsoft definitely determines a ton of patterns. describing the rules as annotations is a big one. jsonfx borrows its whole design from jackson.
they're useful patterns though
it's a big part of its value*
but its not as invasive as adding unirx
anyway, i think this is trying to arrive at a definition of bloat, which is uninteresting
not as much as unirx.
adapting unirx basically the reactive programming and the context switch is what you're after.
switching from that to vanilla is basically rewriting your code
well a lot of people reinvent reactive programming
exhibit a: DOTS
that's why i advocate it so much. it's a good way to make games
DOTS is a lot clunkier than UniRx
But yeah I mean if you want to use external libraries, then that's cool. If you spend more time doing that then actually solving your problems, initially and over time as you need to support it, especially when multiple people are involved, then you literally wasted time.
reinventing this stuff is a bad idea
However, if you saved time, then you saved time, and that's good.
If you spend more time doing that
you are definitely going to spend more time reinventing valuable stuff from unirx
You need to make the value judgement whether you're being foolish... and you'll be wrong at times, and that's okay.
than from like, adding a line to your manifest.json
you mean entities? if its jobs you're talkinh about, probably it will stay like that for a long time.
incase of entities, well they are warning beforehand for massive api changes. who knows they might improve
it's interesting. it sounds like you got it backwards basically. it sounds like there's a belief using the external library is slower than figuring out GetAwaiter, ThrowIfCancellationRequested, SynchronizationContext, the whole async task api just to figure out like, how do make sure it's on the right thread
UniTask has a way to guarantee you're on the right thread
that's better than the built in ways
It might be, especially if you already know that stuff from other work, and especially if the alternative is significantly different from what you know.
yeah. ig uess it's apples to oranges. but a lot of the intellectual value of DOTS is tied up in forcing you to make reactive code
yeah, i suppose "a more knowledgeable person" is going to be better at everything
you started with a question
I didn't say that???
knowing stuff from other work
this is what i mean by a more knowledgeable person
anyway
it's your dime
something something, the SCV meme
I mean it's reasonable to gutcheck whether my experience matches anything weird that Unity does.
yeah. unity is weird
why is it weird?
it's Flash, written in C#. it predates the stuff aspnetcore developers know and love
can you elaborate, i don't really follow
To be clear I wasn't crapping on your suggestion for UniTask. It was a good suggestion for someone that didn't know it exists. But I was asking a specific question, and I wanted to make sure that other people in the channel who did know the answer to the actual question that I asked didn't think that I was satisfied with your answer and not say anything. @undone coral
like i don't think aspnetcore experience translates well to unity's architecture. it looks more like macromedia flash than something in the .net ecosystem
Like -- if people think you answered it, then I would never get the answer that I needed.
my 🅱️
it's answered
although i'm not 100% sure 😦
it's such a tricky question
Nah it's not a bad or whatever. It just kinda blew up.
It was definitely a valid suggestion for the assumed root problem.
alright, but thats just the nature of using an opinionated, complex tool
maybe people think too much in terms of what c# can do and can't and too little about what they want to make happen and what principles get them there independent of whether or not c# can express them cleanly
@urban warren Oh I forgot to mention... if you do additive loading and unloading, then you need to remember to garbage collect the assets after you unload a level. Unity does this by default with a full level open, but skips it for additive, forcing the user to write Resources.UnloadUnusedAssets() otherwise old scenes will pile up in memory.
It's a TINY mention at the bottom of some of the documentation pages, like the second-last line of here https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.UnloadSceneAsync.html, but it's very important.
(I don't know why they didn't just make it a required parameter... do you want to run a garbage collection to find assets to clean up too? true, false?)
I mean cleaner API but I'm wondering how many people's games are leaking gigabytes of RAM because of this.
most people's games fit entirely into memory, and its only assets, which get reused and not duplicated on each scene load
To be clear I am aware why it's not done automatically for additive loading. I'm asking why it's left as arcane knowledge rather than, like, a compiler error -- unless you're saying that it's rare enough that it's more harm than good.
Ooh, thank you! I doubt I would have noticed or been able to figure it out in a timely manner.
I think I will be reusing most assets over the whole thing so idk how much would actually be unloaded. But it is good to know and keep in mind
its not really hidden information
Yup. No problem.
public void OnScoreboard(InputAction.CallbackContext context)
{
switch(context.action.phase)
{
case InputActionPhase.Started when IsLocalPlayer:
scoreboard.SetActive(true);
break;
case InputActionPhase.Canceled when IsLocalPlayer:
scoreboard.SetActive(false);
break;
}
}
vs
public void OnScoreboard(InputAction.CallbackContext context)
{
if(IsLocalPlayer && context.action.phase is InputActionPhase.Started)
scoreboard.SetActive(true);
else if(IsLocalPlayer && context.action.phase is InputActionPhase.Canceled)
scoreboard.SetActive(false);
}
which one do you hate less
if(IsLocalPlayer)
{
switch(...)
{
// ...
}
}
or
if(!IsLocalPlayer)
{
return;
}
switch(...)
{
// ...
}
but from your examples, it's the first one
Another option
if (!IsLocalPlayer || context.action.phase is InputActionPhase.Performed)
return;
scoreboard.SetActive(context.action.phase is InputActionPhase.Started);
point is, the IsLocalPlayer is an extremely important condition and should be treated as such, not buried and repeated in each statement
Yeah. Early exit for IsLocalPlayer looks good. Another alternative is get-only properties depending on how else it's used in code, but I think I prefer wtch28's example over the others.
It also probably doesn't matter toooo much. I can understand what every one of these examples does at a glance (without having background knowledge of your codebase).
That's kind-of the hierarchy of code structure choices:
Could also get fancy and have a thing that's listening to the input, check if it's LocalPlayer, and only if so, forwards it to some kind of processor, so the part where you're processing the input doesn't even know about Local or NonLocal Players and could be used by either, if ever necessary
Just4fun 😂
Yeah, defer the problem entirely. That works, too.
Have some form of finite state machine setup such that it's impossible to hit that code path unless you're a local player. That said, it's easy to over-engineer that (granted it was said "just4fun").
simplistically, random naming
class InputReceiver
{
InputProcessor inputProcessor;
// subscribe / unsubscribe somewhere
void OnInputReceived(...)
{
if(!IsLocalPlayer) return;
inputProcessor.ProcessInput(...);
}
}
class InputProcessor
{
void ProcessInput(...)
{
switch(...)
{
// ...
}
}
}
in it's barest form, it wouldn't even need a FSM
ah yes, implementing an InputProcessor for the new unity InputSystem for input, replacing the old Input system (two words)
Is there a way to map raycasts to a 3d object, like say I want to have them shoot out of the object at regular intervals, but change their angle based on the terrain
Like every 20 pixels or so a raycast is generated
If you abandon the measurements in pixels, sure (pixels are meaningless in 3d space without referencing a camera and screen to render to)
pixels was the first measurement that came to mind, its not my actual intent on aproaching this
Okay, I'm throwing my hands up in defeat here. I simply can't figure out how to use Animation Events' Object Reference parameters at all. I've never seen so many NullReferenceExceptions in my life. It's like it's just refusing to read the data. This is poorly documented, how does this work? 😦
Hi again, everyone. I have a simple issue that I can't seem to solve. I have a large number of gameObjects in a scene that are supposed to have a reference to the next gameObject in sequence. To automate this process of populating all of them, I wrote an editor script. The script works great! When I run it and check all the objects, the references are present. However, if I close unity, switch to another scene and back, or press play, all of the references disappear. Am I missing a SaveScene function or something? I can't find anything like this on the forums or Scripting API!
Here is the script: Thanks!
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class SetupCheckpoints : MonoBehaviour
{
[MenuItem("Extreme/Fill Checkpoint Data")]
static void FillCheckpointData()
{
Checkpoint[] cps;
EventManager em = GameObject.Find("ManagerContainer").GetComponent<EventManager>();
cps = em.checkpoints;
string message = cps.Length.ToString() + " checkpoints are listed in EventManager. Is this correct?";
if (EditorUtility.DisplayDialog("Fill Checkpoint Data",message,"Yes, fill data","Cancel"))
{
for (int i = 0; i < cps.Length; i++)
{
if (i!=cps.Length-1) cps[i].nextCheckpoint = cps[i+1];
else if (i==cps.Length-1) cps[i].nextCheckpoint = cps[0];
}
Debug.Log("Done");
}
}
}
It requires an object as a reference. What do I call it on? Would that be every single object I modify (i in the loop)?
I would assume so
The docs aren't very good on this function. SetDirty isn't defined. What using reference am I missing?
EditorUtility.SetDirty()
Okay, thanks. This seems to work!
Is there a straightforward way to tell if a type deriving from Unity.Object is defined by Unity? (I'm guessing checking the type's namespace against Unity's namespaces)
Extra credit: is there a way to tell if it was defined a script that was written by the developer of the project (aka not an asset)?
use refelction
Is it possible to decompress an asset bundle just by using the reference LZ4 decompressor library?
Can anybody help with why I'm getting this error... from the following code snippet.
var Copy = UnitsOutOfLockOnRange;
//Check the time stamp of each unit in this out of range dictionary.
foreach (KeyValuePair<BaseUnit, float> kvp in UnitsOutOfLockOnRange)
{
//If X amount of time has passed, remove their lock on status.
if (Time.time - kvp.Value > lockOnHoldDuration)
{
UnitsLockedOnto[kvp.Key].Disable();
UnitsLockedOnto.Remove(kvp.Key);
Copy.Remove(kvp.Key);
}
}
UnitsOutOfLockOnRange = Copy;```
The error obviously occurs on the foreach line.
something.GetType().Namespace
You are shallow copying a list, you might want to deep copy it instead
It's a Dictionary; but what do you mean?
you can make a shallowCopy of it via .ToList()
foreach (KeyValuePair<BaseUnit, float> kvp in UnitsOutOfLockOnRange.ToList()) this is considered a bad workaround, use reverse for-loop instead
That's funny, because I just typed that up while waiting for a reply...
for(int i = UnitsOutOfLockOnRange.Count - 1; i > -1; i--)
{
//If X amount of time has passed, remove their lock on status.
if (Time.time - UnitsOutOfLockOnRange.ElementAt(i).Value > lockOnHoldDuration)
{
UnitsLockedOnto[UnitsOutOfLockOnRange.ElementAt(i).Key].Disable();
UnitsLockedOnto.Remove(UnitsOutOfLockOnRange.ElementAt(i).Key);
UnitsOutOfLockOnRange.Remove(UnitsOutOfLockOnRange.ElementAt(i).Key);
}
}
Should work?
try it
Your dictionary sorta useless if you decided to iterate it, tbh
shallow copy only copies the reference, what you do to the copy will reflected into the original dictionary/list, that's why the compiler complains about modified collection
Well the thing was I needed to hold a reference to the Unit as well as its time stamp.
But I suppose I could do a List of KeyValuePairs instead.
Ah... Okay. I wasn't aware of that.
But reverse looping it worked.
Thanks.
thanks, the guy above you answered that already
thanks. I had to use .Split('.')[0] to get just the top level of the namespace so I could compare that against the list of known namespaces i want to ignore
why
If you want to raycast at regular intervals of movement you can track the last raycast position and test how far the object has moved.
[SerializeField] float _raycastMoveDistance = 1f;
Vector3 _lastRaycastPosition;
void FixedUpdate() {
Move();
if (Vector3.Distance(transform.position, _lastRaycastPosition) > _raycastMoveDistance) {
DoRaycast();
_lastRaycastPosition = transform.position;
}
}
Hi guys, I have a question about FBX importing. Can I do it and instantiate the FBX as GameObject in runtime?
Yeah, just not directly
Could you explain more, please?
You can't just instantiate models, they have to be part of a prefab. So make a prefab with the model in it, using a mesh renderer
Then you can instantiate it at runtime
Thanks for replying 😄 But that's the problem, I just want our 3D artists uploading their stuffs directly on the server and instantiating models on client.
It seems technically impossible then...
I'm sure it possible, just harder
I'm sure you can get some library to import FBXs at runtime and then convert them to a Mesh and generate a gameobject that renders it
Is it easy? Probably not. Is it worth it over other workflows? Probably not either
I wouldn't do it unless you have no choice
Also look into things like Addressables, which do let you update content at runtime easily but your artsts will still have to do some work in Unity
Yeah, you're right.
Silly thing is our artists favor Unreal Engine and... you may know the rest
having a server makes things easier. you can write unity editor scripts in server to convert the fbx to asset bundle. and load the asset bundle on client if performance matters to you.
if you dont want all that hassle and are dealing with multiple platform, your best bet is to find some runtime FBX importer from asset store. runtime fbx importing will be hassle free, but loading performance and memory footprint will never be as an asset bundle
Thanks, malloc. Your advice's very helpful. But can Unity execute Editor's scripts in command line? Or I need an opened Unity Editor on the server?
yes, command line is possible
https://docs.unity3d.com/Manual/EditorCommandLineArguments.html
its usually weird mapping fbx textures and materials correctly and automatically and also use the correct shader for each material (like transparent ones)
you need to handle it yourself if you're going with editor approach.
you can also try GLB format if you artists are making the models . its not standard yet, but you wont have issue mapping the texture and materials and shaders. most unity glb importers have their own shader, you can try Gltfast to import GLB both in runtime and in editor
If your artists are so stubborn that they can't switch engines because it is better for the project then you might want to look for new artists
@queen sparrow Not gifs or memes, please.
public List<RoleDto> GetOrgAdminUserDtos(string userId, string orgId)
{
using (var context = new EfVrCloudContext())
{
var result = from userOperationClaim in context.UserOperationClaims
join operationClaim in context.OperationClaims on userOperationClaim.OperationClaimId equals operationClaim.Id
join orgAdmin in context.OrganizationAdminUsers on userOperationClaim.UserId equals orgAdmin.AdminId
where orgAdmin.OrganizationId == orgId
select new RoleDto()
{
Id = operationClaim.Id,
RoleName = operationClaim.Name
};
return result.ToList();
}
}```
Hello folk
this query returns an incorrect value.
I could not figure it out why
We did the same, but with GLtf.. https://github.com/KhronosGroup/UnityGLTF
It's a time investment to review entire project. Much better approach would be to ask something specific you have questions about. Also going through #archived-unitytips could be helpful.
Anyone know what could be causing this?
Ah I just realized that I forgot structures are value types and need to be passed by reference if edits to them should be done correctly.
Hey guys, I am looking for materials on advanced AI, can someone recommend anything?
There's lots of stuff on YouTube that's called "advanced AI" that is quite basic, I want to go down that rabbit hole
This popped up a couple of times, would you say that I should research this, it could be good for a 2D Pvp shooter?
Well, if you intend to add AI, sure. It was used in FEAR, for its AI and it was a good AI
Incredible AI
GOAP is Goal Oriented Action Planning, it uses pathfinding to find a series of tasks to achieve a goal
So their AI would literally lay traps for you. One enemy would run away, to lead you into an ambush, etc. Not scripted, just generated by the planner
Thanks. I remember FEAR. Yeah something tells me that I'll have to stick to behaviour trees though
Depends what you wanna do
basically, I need to make a good AI for enemies in a PVP game, it's a 2D shooter. Think Quake Arena but in 2D
Yeah, don't need any sort of advanced AI at all for that
Trees or a FSM should be fine
That's what I thuoght, thanks for setting my mind straight!
Just having GOAP doesn't mean your AI is good 😛
Most techniques can end up with good AI but it's more of a design question than an algorithm question
its also been long known in AI research that very simple, reflex actions on agents can create very interesting complex group behaviour, think bees, ants and soccer robots (reflex action = complexity of the type move forward if environment smells nice)
Hello, does anyone know if primitive types on GPUs are deterministic across all GPUs? Meaning, given the same code used on different GPUs, it would produce the same data with no deviation to values. If not, is it in some way possible to produce a custom struct which would have this quality?
E.G double, float, half, int.
One fun AI technique is creating a list of "event" structs (ex: for stealth action games). They can sift through literally everything they remember and make appropriate choices. Really simplifies bug-crushing (ex: if the user tries to abuse AI by forcing two known, conflicting states), sharing information (if two NPCs get close together, and one has an event that they want to share, then they can do a conversation animation and the listeners now have that struct), or forgetting things (just delete the event).
But, yeah, completely not relevant for an arena shooter.
I will say no, without a source to back it up. But I know desktop GPUs upgrade half to float and not all platforms support int fully, so I don't think there are any guarantees made by the graphics API. Something custom would definitely be significantly slower.
Some keep half, but at reduced performance. Some keep half and have a performance increase.
GeForce 10 series does 16-bit floats at 1/64th the throughput of 32-bit floats.
Turing and later should all be 2x faster than 32-bit though. Ah... no... GeForce 30 are 1 to 1 for some reason??? Turing is 2x, though.
This seems to suggest that half is automatically converted to float in DX10+ by the HLSL compiler and the only possibility to use 16-bit floats is with min16float, which is still not guaranteed 16-bits.
https://therealmjp.github.io/posts/shader-fp16/
Those of you who have been working on desktop and console graphics long enough will remember working with fp16 math in shaders during the D3D9 era. Back then HLSL supported the half scalar type, which corresponded to a floating-point value using 16-bits of precision. Using it was crucial for extracting the best performance from Nvidia's FX serie...
And Unity says this:
One complication of
float/half/fixeddata type usage is that PC GPUs are always high precision.
https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html
(they boldened it, not me)
I should also mention that, to some extent, no-one has any control over what the GPU executes. The driver can single out your application and replace your shaders out from under you.
Can anyone recommend me a really good advanced tutorial on YT to create complex AI with a finite state machine?
I've watched countless but they all 'feel' wrong, clunky, convoluted or just plain too simple.
complex AI and finite state machine are incompatible
you would need a different model to implement it, like a BT, utility functions, planners, ML, ..., FSMs can be part of it, but they have a tendency to get unwieldy/complex rather quickly
interesting, yeah feels like that's what I'm struggling with
let's say my needs are not that complex though, I just suck at keeping my sight on the big picture
do you have any FSM implementation that you can whole heartedly recommend a video for on YT ?
i dont, sorry
if you need a nice FSM library, i recommend https://github.com/dotnet-state-machine/stateless
Thank you! I'll check that out!
what exactly are you struggling with in regard to FSMs that you hope a YT course could solve?
I just need handholding by yt video, I'm not experienced enough yet to fully juggle things like abstract classes, dictionaries etc
I can write a reasonably good state machine for a single enemy/npc but I'm trying to figure out an implementation that allows me to use the same code for a multitude of monsters
while still giving some of them unique behaviors that blend in neatly
basically a really solid scaleable implementation is what I'm after
sounds like you need to work on your c# and overall programming fundamentals
yeah I probably do
wish there was a single thing that could be recommended to everyone to get them to a point where they don't feel limited by their lack of knowledge about programming in general and c# in particular
Microsoft docs
"the world"
tbh, if you don’t know how to do something, just read the documentation on it or look up a yt video on it
that doesn't work for complex, custom systems and your own ideas
you said fundamentals
Hello all,
Not sure if this is #archived-code-advanced worthy or not but here we go. Anyone know how I would go about getting access to an fbx's animation clips in an editor script not during run time? I've tried using AnimationUtility.GetAnimationClips(Object) which only works at runtime. I'm on 2019.2.19f1.
of course if you’re trying to make your own thing, you have to make it
maybe we have a different definition of what fundamentals are
the person above was talking about dictionaries and abstraction
one is a fundamental data structure, the other is fundamental to OOP in general
hi guys, im currently working on an Optimized Center of Rotation skinning solution for unity, and right now my bottleneck is this loop:
for (int j = 0; j < bones.Length; j++)
{
boneMatrices[j] = bones[j].localToWorldMatrix;
q[j] = bones[j].rotation;
}
with 144 animated characters, i get about 100 fps. using standard skinning, i get about 130 fps. about 39% of the frame time is used just in that loop. does anyone have any ideas for what could be done to improve this?
the loop is setting up arrays to set the data on a compute buffer for use with the compute shader
You can use Jobs and Burst for this most likely. C# jobs can write directly into compute buffers with ComputeBuffer.BeginWrite.
You can use TransformAccessArray and IJobParallelForTransform to iterate over the bone transforms while still being Burst compatible.
I think you could easily get 100% better performance with Burst in this scenario.
i didnt know you could access transforms in jobs since it was on a different thread. this is huge information, thank you
i dont have much burst compiler experience, what kind of performance boost do you think i could get with this?
well it obv depends on core count but you get what i mean
Like I said, I don't think 100% improvement is unreasonable.
So, double the performance
oh wow with that i could outperform the unity skinned mesh renderer
i have no idea why my brain skipped right over where you said 100% the first time, sorry about that
thank you for your suggestion sir
i just read on the unity forums that IJobParallelForTransform will operate on the same thread if they have the same parent : https://forum.unity.com/threads/ijobparallelfortransform-15000-transforms-executed-on-single-job-thread-any-hints.537723/
since im using this in the context of writing a new skinned mesh renderer, and the bone hierarchy is well, a humanoid skeleton, are there still performance improvements to be seen?
It should still a thread per renderer, plus Burst, plus potentially writing directly to GPU memory with ComputeBuffer.BeginWrite.
No, I'm wrong. It's using the root parent.
the compute buffer writing is ~5% of the cpu time, while it would be nice to get down the main thing is the loop where i get the bone matrices
ill give it a shot and see how much it helps, thanks again
do you have a video or something of the animation?
no video yet, but heres the results so far
both dummys have the same pose, you can see the volume preservation in action
most of the logic isnt my work, but further developing and optimizing the project with permission from the original author
cool i get it, so it's like for muscles?
im uploading to github when its done under mit
what maya calls muscles
yea its to preserve skinned characters volume when rotating twist bones and such
areas around wrists and elbows in FPS games get a big benefit
does Maya pull out of the same literature?
this is obviously an extreme example
no it looks really good
most likely, the skinning algorithm unity uses (LBS) is a standard used by most programs
there are other alternatives, such as the popular DQS algorithm, which already has a public project on github
that however comes with its own issues, such as bulging artifacts
most of the 3d humanoid models i work with that aren't pre-made for games come from 3d scans
for very narrow cinema effects. so they look good but they are not rigged for animation in a meaningful way
ah yea this system still uses standard setup for rigged characters
characters need to be weight painted and rigged
yeah my memory is in maya you have to do things like painting the muscle groups
right you still have to do that here
animations do work btw i just dont have a video yet
i wonder if in photogrammetry workflows they'll figure out how to shoot people in different poses
and infer the muscles that way
there are methods that do what you desire
"voxel heat diffuse skinning"
it provides pretty good skinned results out of the box, which can then be tweaked
this stuff doesn't translate to unity right?
i learned about it when researching for this project
maya has a similar builtin but it's worse than this
well it does, pretty much all programs use the same (more or less) skinned character setup
anyway this is very cool keep everyone updated 🙂
absolutely, heres the link to the github
https://github.com/Milk-Drinker01/CoR-Skinning
if you find it interesting id appreciate a star on it. while ur there u may as well check out my normal map inverter or the gpu instancing tool
can i suggest a mnemonic for the normals issue?
"Sky in your Eye? Flip your Y"
needs some work...
very close though
you know it's wrong when there's sky reflecting inside the edges of a flat surface
lol
haha thats pretty good, ill include that
sorry for the extra ping. do you know a good resource on computebuffer.beginwrite working within a job?
You have to call it before. It gives you a NativeArray which you can then pass to the job.
#📖┃code-of-conduct this is against the rules here
My bad, didnt see it in the rule section I was reading but it was the wrong one. Just difficult to find someone for a 1:1
ah, ive got it all working. i definitely got a small bump in performance, and the job itself is way faster than doing it all on the main thread. now i get to clean up all the other arrays i set on the gpu. thank you so much for the suggestion!
I have a code optimization question. When iterating over many elements in a List with a for loop, where you have to check a condition against certain properties of the element, is it faster to cache the element in a local variable or index into the List every time?
Example:
using System.Collections.Generic;
public class Example
{
// Assume this is populated with many elements.
private List<SomeObject> listOfObjects;
// Method 1
// Index into the List once and create a local variable (someObject).
public SomeObject GetObject1(float someValue)
{
for (int i = 0, count = listOfObjects.Count; i < count; i++)
{
var someObject = listOfObjects[i];
if (someValue >= someObject.Min && someValue <= someObject.Max)
return someObject;
}
return null;
}
// Method 2
// Index into the List every time.
public SomeObject GetObject2(float someValue)
{
for (int i = 0, count = listOfObjects.Count; i < count; i++)
{
if (someValue >= listOfObjects[i].Min && someValue <= listOfObjects[i].Max)
return listOfObjects[i];
}
return null;
}
}
public class SomeObject
{
public float Min;
public float Max;
}
For the sake of the question, assume that this code is running every frame.
As a general rule, caching it in a variable always has the potential to be faster, and will almost never be slower.
also not caching it is uglier
it's hard to say exactly because there are variables at play here like compiler optimizations
to read, I mean
I agree with that - but that part is reasonably subjective.
When you take this code at face value - the indexer being called fewer times naturally will be faster, since the indexer of a list is a method.
It's possible that Roslyn optimizes that out though so who knows for real without doing some ILSpy
btw the reason this is actually important and not a pithy answer is because you spend way more time reading code than writing it, so it is good to make sure your code is as easily readable as possible
I thought unity used the mono compiler
or am I being dense
To be fair it used to use Mono for some time
ok
glad I'm not totally hopeless
really makes MonoBehaviour look even dumber of a name doesn't it
lol
yes
Given that Mono is now merely one possible scripting backend option, and not the "flagship" one.
does anyone know how to create a grappling hook in VR?
good thing it's not stuck as one of the most fundamental concepts in Unity or anything
thank you both for the insights!
For the second time, do not cross-post
sorry but no one helps me
Your question is way too broad
it's not a great question, which is why no one is helping you
Anyone able to give some insight into this?
@sour marlin I haven't worked with the ModelImporter, but try this https://docs.unity3d.com/ScriptReference/ModelImporter-clipAnimations.html
Awesome, thanks! I'll give it a shot.
gl
@sour marlin if you need to get the Importer of your asset, use AssetImporter.GetAtPath
Repeated the indexer 7 times, it still calls the method 7 times. So for at least less than 7 times it's not optimized
gtk, though with fancy schmancy compilers you never know if it just didn't do it that time
but for indexers I wouldn't be surprised if it doesn't optimize it out since there can be side effects of accessing an indexer in C#
Lol true
private int _counter;
public T this[int index]
{
get {
_counter++;
if (_counter > 3)
throw new InvalidOperationException("This collection is now tired. Please use another one, thank you.");
return ...
}
}
Oh that language
It's the one you have to say "please" the right amount of times otherwise it doesn't compile right
yeah
lmao even the user manual for the language is a complete joke
3.4.3 Precedence
Precedence of operators is as follows:¹
(literally nothing on the page)(at bottom of page)
¹ Keep in mind that the aim in designing INTERCAL was to have no precedence
This precedence (or lack thereof) may be overruled by grouping expressions between pairs of sparks (’)
or rabbit-ears (")
So the issue now is that the AnimatorState.Motion cannot be assigned to the ModelImporterClipAnimations. If only I could get AnimationUtility.GetAnimationClips to work not at runtime. That would fix all of my issues.
if the list is a List<T> i think it would be the same
if it's a struct you will get copies of it, which is probably not what you want
Found a work around. Here's what I ended up doing:
UnityEngine.Object[] clips = AssetDatabase.LoadAllAssetsAtPath(path);
AnimationClip animClip = null;
if(clips == null || clips.Length == 0) {
Debug.LogError("No clips found");
} else {
foreach(var clip in clips) {
if(clip.GetType() == typeof(AnimationClip)) {
animClip = clip as AnimationClip;
}
}
}
So... there's a lot to unpack here.
First, caching the value is just caching the memory address where to get the value, because SomeObject is a reference type. The memory addresses are stored in order once you get into listOfObjects' backing array, which should be in cache, especially for two consecutive accesses of the same value, which the compiler might eliminate anyway. Actually going into someObject to get Min and Max (which are value types) is the expensive part, because that's at some random place in memory (again, SomeObject is a reference type).
That fetch to get Min and/or Max will be ~200 cycles every iteration.
That said, chances are, fetching listOfObject[i].Min has also fetched listOfObject[i].Max, because they're probably on the same cache line (value types). An Intel or AMD CPU cannot physically request less than 64 bytes of memory, so any request gets all the 64-byte aligned memory before and after your value. (Apple M1 is 128 bytes for cache line size.) So even though you paid 200 cycles to get Min and or Max, you will probably have got them both, so you should only pay that 200 cycles once.
In other words, the thing that's cached is likely a tiny percentage of the overall work being done per iteration.
Also, "every frame" isn't the important thing at this level. Computers do about 4 billion cycles per second per core these days. If you're just talking a hot loop that only happens one time per frame (if that script is on hundreds of objects, then no, but if it's just one object...) then it's not going to be a big issue until we're talking about, like, tens of thousands of elements (or we're talking about a SomeOtherObject that has a bunch of reference types on it, because you're then hopping multiple times every element, which is ~200 cycles each hop).
And even if it was a big issue, you'd probably run into accessing the values of SomeObject before you run into problems finding out where SomeObject is. In which case, you'd make SomeObject a struct (which is a bit of a pain in the butt to work with).
Long story short -- these sorts of issues are highly unlikely to be your bottleneck. You're almost definitely going to hit an issue somewhere else. Use the profiler.
Btw: These sorts of questions are great. Optimization is very arcane, so ask ask ask.
so im still on this, this is where im at:
[BurstCompile(CompileSynchronously = true)]
private struct SetBuffersJob : IJobParallelForTransform
{
[WriteOnly]
public NativeArray<float4x4> BoneArray;
[WriteOnly]
public NativeArray<Quaternion> RotationArray;
public void Execute(int index, TransformAccess transform)
{
BoneArray[index] = transform.localToWorldMatrix;
RotationArray[index] = transform.rotation;
}
}
boneBuffer.EndWrite<Matrix4x4>(bones.Length);
_boneArray = boneBuffer.BeginWrite<float4x4>(0, bones.Length);
//var nativeArrayMatrix = UnsafeUtility.As<NativeArray<Matrix4x4>, NativeArray<float4x4>>(ref _boneArray);
qBuffer.EndWrite<Quaternion>(bones.Length);
_rotationArray = qBuffer.BeginWrite<Quaternion>(0, bones.Length);
//var nativeArrayQuaternion = UnsafeUtility.As<NativeArray<Quaternion>, NativeArray<float4>>(ref _rotationArray);
//Profiler.EndSample();
gatherMatrixJob = new SetBuffersJob()
{
BoneArray = _boneArray,
RotationArray = _rotationArray
};
gatherMatrixJobHandle = gatherMatrixJob.ScheduleReadOnly(transforms, 128);
it seems what its doing now is making copys of the buffers rather than sharing. trying to do it with pointers gains 20 fps but crashes unity
is there a way to do the setting of the compute buffer from directly within the job so i dont have to make so many duplicate buffers?
i think there's something with "fences" and stuff you're supposed to do
oh god that sounds painful
is this what ur referring to?
my understanding of this stuff is super fuzzy
ah
ok this is really annoying
i have a vector named X
its value is here
but when i debug it or compare it to something else, it turns into this
and its completely messing up my code
how can i get the script to use the actual value of x, not this rounded one
the script doesnt use the rounded one, it just does that for debugging
u can try debugging like this
Debug.Log($"{someVector.x} {someVector.y} {someVector.z}");
So I'm trying to find tiles in a grid within range of a given position. I'm doing this recursively, by starting with a point, getting its neighbors, and recursing into them, subtracting from range until range ==0, then adding to a returnValue list.
This is getting all of the nodes, but I was trying to get only the outer tiles. i.e. the tiles at max range, not in between. I figure there's a way to do this via the recursion, and I thought checking range = 0 would do this for me, but it doesn't. Makes sense why, because it's finding all possible paths, but I don't want them.
Ideas?
public static List<GraphNode> GetNodesWithinRange(Pawn pawn) {
List<GraphNode> returnValue = new List<GraphNode>();
Recursion(pawn.CurrentTarget.transform.position, pawn.AttackRange);
void Recursion(Vector3 nodePosition, int range) {
Debug.LogFormat("Recursion, range: {0}", range);
var neighbors = GetNeighborsFromPosition(nodePosition);
foreach (var neighbor in neighbors) {
if (range == 0) {
if (!returnValue.Contains(neighbor)) {
returnValue.Add(neighbor);
}
}
else {
Recursion((Vector3)neighbor.position, range - 1);
}
}
}
return returnValue;
}
your code looks like it will just return all of the tiles in the grid regardless of distance to me
i recall from your game these grids are small, so BFS up until a certain depth is fine
however, if the grids were huge, you would connect them with weighted paths corresponding to the distance they are from the tile
or... you could read them directly, since the shape of the circle known ahead of time
all of these are good solutions
This is different. There are just nodes, with neighbors
But yeah, distance does make sense. Need to check if current distance = range. Thanks
Cool, just made it not recurse to neighbors that weren't further away from target than current node
take a look at breadth first search 🙂
you are reinventing it
it's nbd
you're actually doing a mix of BFS and DFS
it's all the same though
how's the game?
Yeah, I know what it is, that's why I'm thinking I can just have the recursion handle this for me
Still not working quite right, but close
public static List<GraphNode> GetNodesWithinRange(Pawn pawn) {
List<GraphNode> returnValue = new List<GraphNode>();
Recursion(pawn.CurrentTarget.transform.position, pawn.AttackRange);
void Recursion(Vector3 nodePosition, int range) {
Debug.LogFormat("Recursion, range: {0}", range);
var neighbors = GetNeighborsFromPosition(nodePosition);
foreach (var neighbor in neighbors) {
float thisDistance = Vector3.Distance(nodePosition, pawn.CurrentTarget.transform.position);
float neighborDistance = Vector3.Distance((Vector3)neighbor.position, pawn.CurrentTarget.transform.position);
if (neighborDistance <= thisDistance) continue;
if (range == 0) {
if ( !returnValue.Contains(neighbor)) {
returnValue.Add(neighbor);
}
}
else {
if (neighborDistance > thisDistance) {
Recursion((Vector3)neighbor.position, range - 1);
}
}
}
}
return returnValue;
}
you have to do bfs directly
Thought that's what this was because I'm only doing something if range is 0
when i need to do BFS i truthfully go directly to
the textbook
CLRS
there is also a linq BFS
guava has it
Hello,
I'm trying to use mapbox and photon to spawn GPS player location in a level. I'm trying to find a way to do this with mapbox and heard that I may have to use mapbox conversions, but I don't think I understand how to go about doing this correctly. Any help would be appreciated.
i think you might be better served by niantic lightship / "ardk"
I’ll look this up, thank you
anyone know at all if it's possible to return a uint8_t* from unmanaged code and marshal it into a byte[] in c#?
i've tried [return: MarshalAs(UnmanagedType.LPArray)] but that doesn't seem to work
(complains about invalid managed/unmanaged type combination)
Hello Folk
Is it possible to turn off some of the properties coming from derived classes?
For example I have
ClassA:Base
ClassB:Base
Base
My base class has a property of string "Name"
both my classess will inherit Base but I do not want to see that property in the ClassA
Is it possible?
looks like a code smell to me
if the properties are virtuals I guess you can do it like this
public override string someStringProps
{
get
{throw new NotImplementedException();}
set
{throw new NotImplementedException();}
}
and if they aren't virtuals you can use the new keyword public new someStringProps, then trow the NotImplementedException
I don't recall I've ever used this in such scenario, but ..ugh
If you are wanting this then A shouldn't be a Base in the first place.
You need to refactor a bit.
Perhaps with another level of inheritance, or perhaps by ditching inheritance entirely.
pass a byte[] to unmanaged land, and fill it there
Anyone here experienced in using Photon for making multiplayer FPS games?
#archived-networking and don't ask to ask
The programming is giving me an aneurysm
You might have bitten off more than you can chew if that's the case and you're trying to make a networked multiplayer game
hey can someine help me with a grappling hook vr script?
@hazy gazelle literally
Anyone has used source generator in Unity?
The manual (https://docs.unity3d.com/Manual/roslyn-analyzers.html) says:
- Go to Select platforms for plugin and disable Any Platform.
- Go to Include Platforms and disable Editor and Standalone.
Do they mean to disable everything? If my project is for mobile (Android/iOS) shouldn't I disable those two as well?
Cool, that's what I thought as well.
Can I access things like AssetDatabase in the SG?
No, its a DLL you compile outside of Unity itself.
I havent used it that much, i guess you could reference the relevant UnityEditor DLL's in your source generator.
But i dont know if that will work, i kind of doubt it.
Apparently someone said they were able to reference and debug log stuffs, so I assume it works.
I'm just wondering if there's a better way to reference Unity dlls besides copying and pasting from the main Unity project it generates, and those paths seem hardcoded and not suitable for version control.
How ive used source generators is by making some C# code in Unity itself, in an custom editor. And then start the source gen, read out that code and compile it
That way i can use assetdatabase or anything else from the Editor
Similar, currently I have it as an editor script that generates the C# code and write directly to file, but it's a bit ugly (and I have to remember to run it manually every time)
Another question, the SG dll I built is just IL and platform agnostic right?
I need to build my game on Mac (not my dev OS) for iOS, don't want to run into trouble later on.
I think so yes, its compiled in editor time. Just like how your own code is compiled
best check it though
Welp I gave it a try and couldn't get it (access to Unity editor stuffs) to work.
Maybe there's a way to but I think I'll just stay with an editor script.
Since I'm only reading stuffs, I guess if I really want to, I technically could read and parse all the relevant Unity files myself and do processing from there.
But that just doesn't seem worth it, plus SG is such a pain to debug.
I guess I'll just remind myself to manually run the editor script every time instead.
Create a byte[] array in C# that's the correct size. It appears as a raw pointer in C code, and C# guarantees that it will not move the backing memory while the C function call is occurring, so you don't need to do any GCHandle pinning bullcrap.
Note: The type must be blittable. uint8_t is. see: https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types
byte[] myBuffer;
//...
[DllImport("libWhatever")]
internal static extern int GetSizeOfThing();
[DllImport("libWhatever")]
internal static extern void WriteToByteBuffer(byte[] argBytes);
//...
void myFunction()
{
// This is a slightly more complicated example where you don't know
// The size of myBuffer until it's too late. In this case, you need
// to make two calls, one to let C# allocate an appropriate buffer,
// and one to fill it.
// If you already have an unmanaged buffer of uint8_ts, then memcpy
// on the native side within the implementation of WriteToByteBuffer.
myBuffer = new byte[GetSizeOfThing()];
WriteToByteBuffer(myBuffer);
}
Ah I missed malloc's message sorry.
I was already aware of it beforehand, just wished I could do it all in one call without passing a size
Nah, the GC needs to own the memory.
Well I mean one trick that we did in a project @raw schooner was preallocate a byte[] array, and passed the pointer and the size of byte[] into the C function call. If the buffer was big enough, then it would return true and write to byte[]. If it was too small, it would return false. We reallocated and tried again. It helped us because we were looking for messages over and over again.
(In our case, the message knew its own size, and we always had enough buffer to get at least that much of the message, so we didn't need to say how many bytes there were in the return value... in most cases you'd probably want to return an int with size to know what to resize to, or negative for failure... or pass an int[] with a single element for size in another parameter lol)
Yes, very. Why would you tag me?
I mean I'd also ping the people I know I can get the most competent information from
And who said i was smart 😎
my aipath is screwing up my addForce script
i have to remove and re-add my aipath component
everytime i change something
else it wont do the addForce
Is your aipath script moving the object in a physics friendly way?
im just using the built in aipath script
Like nav mesh angents?
I've never heard of that and didn't see obvious docs in a Google search. Are you sure it's built in? Can you link docs?
But if it moves your character's, I'd bet that it's incompatible with the physics system (just like nav mesh agents) and you can only have one active at a time
Physics only works if everything moving your objects are doing it via physics. Can't say for sure without seeing the package, but 90% chance it's not moving objects via physics and that's your problem.
If you deactivate the ai, apply a force (change velocity via physics), then reactivate it, you only have one system controlling it at a time so it should be okay. But I wouldn't expect collisions to work, for example.
i have this in my ontriggerenter
other.GetComponent<Pathfinding.AIPath>().isStopped = true;
public void ManageSprites()
{
if (Grid.GetLastEntity<EntityBase>(new Vector2Int(Position.x, Position.y + 1)) is EntityWallBrick
&&
Grid.GetLastEntity<EntityBase>(new Vector2Int(Position.x, Position.y - 1)) is EntityWallBrick
)
{
SetEntitySprite(Resources.Load<Sprite>("Sprites/Tiles/Building/wall extension"));
}
}```
So I have this method here. ``Grid`` is a custom class that controls the games grid and manages tiles (2D unity game). GetLastEntity returns the last entity on that tile determined by their Z-priority. Here, I'm trying to automatically update the texture of a tile (UI image) by detecting the north and south sides. At the moment I am running this in Update, but it's expensive for performance.
Any recommendations for how I can improve performance?
Is there any reason you need to do it every frame?
I need to check whenever there's a new neighbor or if one was deleted by the player
And is this being done on every tile in the game every frame?
not every tile, only 4 different types
You should just do it when the player adds or deletes something, not every frame
and only on the tiles that were added/deleted and their neighbors
yeah I tried doing it whenever the player adds, but they're added at the same time
what's added at the same time
like if the player selected multiple tiles to place down this tile, those tiles are replaced by this tile at the same time
in a for-loop though
ill show
// Multi-Tile Building
if (Input.GetKeyUp(KeyCode.Mouse0))
{
if (!isOverUI)
{
for (int i = 0; i < SelectedEntities.Length; i++)
{
if (SelectedEntities[i].Name != "GhostEntity")
{
SelectedEntities[i].GetComponent<Image>().material = null;
BuildTileAt(SelectedEntities[i].Position);
}
}
...
so for every tile the player affected, you run the code on them
BuildTileAt handles the creation of new tiles in a case-swotch
oh okay
yeah
its just a matter when
basically the last line(s) of BuildTileAt should be running those checks or calling another function that does
or firing an event that triggers those checks
yes that's where I had it
but for-loops are done in 1 frame right
or is it a new frame after each iteration
everything is done within one frame
right
unless there's a coroutine with a yield statement
oh I think I see what you're saying - you want to do the checks only after all the changes are made?
then you would track all the tiles that changed in this loop, and do another loop afterwards over the changed tiles that does the checks for each changed tile
case CurrentTileState.S_Wall1:
if (Grid.GetLastEntity<EntityBase>(position) is EntityWallBrick)
{
return;
}
else
{
EntityWallBrick S_Wall1 = Grid.Create<EntityWallBrick>(position);
GetEconomy.CurrentExpenses += WallCost;
AllWalls.Add(S_Wall1);
S_Wall1.ManageSprites();
return;
break;
}```
So I have this for the BuildTileAt method, it's a case switch on whatever the player selected
and this is the building process for it
you can see the texture doesnt change if there are north and south neighbors
Is there a good reason you're building this from scratch? Unity's Tilemap system has a thing built in for this
More flexibility mostly
it's already fully integrated, I'm just implementing some new features
i figured out an inexpensive way
ill just check if it has that texture in the first place, if it doesnt and it has a north/south neighbor, i set the texture
so that way its only if there's no north and south neighbors, which should only be for like, 20 or so tiles
you wanna do the thing where you drag and you draw tiles
and the tiles have rules
?
like if i'm the top of the brick it's this texture, and if i'm a line segment brick it's this other texture?
there isn't anything wrong with this. change managesprites to take a list of sprites as an argument, and only call it with the neighbors of the last changed sprite
then it's Solved
use a build tool to achieve this. unity has bad support for codeweaving / source generators / other Visual studio like approaches to code generation
yeah, some of the rules are handled already
I could do that yeah, I'll see
void OnDidDrawTile(Tile tile) {
var tiles = GetNeighbors(tile);
tiles.Add(tile);
tiles.ForEach(t => {
UpdateAdjacencyBasedSprites(t);
});
}
does this make sense?
up until prepend
okay
i changed it
if you have adjacency based rules put them all in one method
or call the appropriate method on the tile itself
it's upt o you how to organize it
but keep adjacency versus other kinds of rules distinct
so that you can reason about how to update the tilemap while it's being painted
you probably want to use event system
yeah that makes sense
I use event system a decent bit for detecting UI
do they plan on deprecating Input?
you can use event system on sprites
use Physics2DRaycaster
boom that's it
i'm nto sure why they don't explain that better
they dont have any colliders
well they do, you're just setting up their colliders metaphorically in your own code 🙂
UI images have colliders?
right
well, you are doing colliders. not Colliders but colliders
you don't need to do that period though
if your tilemap is UGUI it would just work
it doesn't need a collider
I ended up detecting when the asset changes and rerunning the editor script automatically.
Debugging SG really sucks tbh.
SG?
Anyone have feedback on best practices for laying out a prefab and locating child objects for use in the script?
In the past, I've exposed the game objects but put them under a header called "internal" but I don't like this since .. if anyone removes a reference while using the prefab, it'll break (potentially at runtime, in non-obvious ways).
I could use Find by name (too slow, if I'm creating lots of the items, which I am) or GetChild by index (which also depends on the user not accidentally drag/drop/reordering the children).
Any feedback? Example progress bar in image.
Also, followup - this particular prefab has 4 images - a left and right "cap" and a middle foreground/background. I'd love to have a public Image field in the parent (and then programmatically set the image of the appropriate child object). Any downsides to that? I'm wondering if my prefabs are going to "do anything funny" by having multiple references to one Image.
I have 5 properties of the same type with very similar purpose (i.e. 5 inventory slots). I have an operation that is performed when one of these properties is set. It's the same operation each time, the only variation being which of the properties is changed.
I cannot extract this operation to a function without using pointers. Pointers are gross and apparently not reccomended in Unity. I know I can make an "inventory slot" object with the logic in there to wrap the property's current type, but I'd like to avoid extra objects for a strictly cosmetic code change. Are there other options? 🤔
private ItemState _slotFeet;
public ItemState SlotFeet
{
get => _slotFeet;
set
{
var old = _slotFeet;
_slotFeet = value;
if (old != null)
{
_inventory.GiveItem(old);
OnUnequip.Invoke(EquipSlotType.Feet, old);
}
if (_slotFeet != null) OnEquip.Invoke(EquipSlotType.Feet, _slotFeet);
}
}
Here's the feet slot, for instance. This code is identical in the other slots, but for _slotFeet being a different backing field
Without pointers, I cannot make a method that takes the backing field as a parameter
This is a bit of a blind spot for me with C# and without pointers I'm not sure what you're supposed to do 🤔
What's wrong with using a collection to access them?
A wrapper object seems like a really lame answer 😛
Take a read on ref.
public Dictionary<SlotType, ItemState> Inventory;
Dictionaries for state in unity? 
I'd rather not dance with custom serialization for this, that's far worse
I mean, it doesn't seem like you're tracking state here, but instead placing items in slots..?
I mean, not really? You have a relationship between a slot and an item.. state would be a slot being "equipped/unequipped/injured/amputated"
states are typically finite and don't really change over time.. or only marginally so... whereas I see inventory and items as something that will continuously grow
The only way the game knows you have something equipped is by it being in that backing field
That's a state
The item isn't marked on its own object in any way when equipped
The item isn't concerned with being equipped or not, rather
I will look at this 🤔
Oh this is exactly what I need 😛
Pointers that aren't gross 😛
Wait ...
There’s a package that adds an editor script which checks all serialized data for missing references, it kind of solves your issue.
But if you really ask me, I’ve transitioned my project from scene based workflow, to prefab based, to now code only. Editor is nice but the downsides are equally terrible.