#archived-code-advanced
1 messages ยท Page 126 of 1
of course that's going to be a problem
the reason it works when you have the identity line there is because if you reset your value to 0, then add the accumulated value, it will look qcorrect
the right way is really just to set the rotation directly based on the accumulated value, instead of using an additive approach
transform.rotation = Quaternion.AngleAxis(t.CurrentValue, axis);
so use
ahh i see
thanks friend
also what is the difference between angleAxis and Euler?
euler angles are x,y,z rotations
AngleAxis is a number of degrees and an axis around which to rotate
just two different ways of expressing a rotation
but I can use .Euler right
if you have a set of euler angles to use
based on the code right now it looks like you have an axis and an angle
Okay, tysm
Hey, general question :
How are these type of games made please ? Here I'm referring to games that have programming / logic systems in their game like here "Human Resource Machine".
How's the right side panel where the player must write his logic handled through programming in Unity ? How do you handle loop in it ? How do you jump from one part to another in C# ? etc...
Here's a 3 minutes review of the game : https://www.youtube.com/watch?v=73bwLQQHExk
Human Resource Machine review and gameplay by Tomorrow Corportation! This is a programming and logic game from the creators of World of Goo and Little Inferno that'll test your brain and your ability to do things in quick, logical fashion. In this Human Resource Machine review I'm playing a review copy provided by the developers. Human Resource ...
Pretty much the same way any programming language is implemented
Tell me more please. Because I can't think / understand how it's implemented if I had to do a game like that myself ๐
it's a turing machine
i don't know that game in particular
It's not something you will learn in 5 minutes somewhere
That doesn't help me ๐ฅฒ
Still doesn't help
wow you watched all those videos in 30 seconds
It's the same as any other language except you skip the parsing/lexing part and you go straight to the AST representation of the program
does anyone know how to play AnimationClip without animator?
I have lots of animations and mapping them in Mechanism sounds like a nightmare
The Animation component is still there but you need to change the clips to legacy to use it
You can also try something like Animancer, or implement your own system with the Playables API
I was thinking about buying the asset you mentioned, but it's almost 100 bucks. so I am wondering if I could just not use it
I've been meaning to try Animancer
its kinda not cheap though...
It's free unless you sell your game then you buy it for the license
May be some premium features? Or maybe I am misremembering
Animancer Pro Features: you can try out the following features for FREE in the Unity Editor with Animancer Lite, but you will need to purchase Animancer Pro to use them in a runtime build or access the Source Code.
free version has a limited feature
how do I mark an animation legacy
Ah, well shoot that stink. Was in a humble bundle for like 10 bucks a year or so ago ;p
On the clip exactly where you can set it to loop, ect
If you select more than one anim clip the inspector half breaks and shows the legacy option ๐ค
How to ship my Unity devtools package as DLLs, without prefabs breaking
Should you ever use coroutines for delaying anything in code?
That's their main use case, so yeah
Is there any memory concerns?
like I need to use it to disable a particle effect after a second for example
Coroutines use memory yes. Whether that's a concern or not depends
Also creating yield instructions also uses memory
profile it and see, unity has to store it somehow so its definitely in memory. This really isnt advanced though
By hooking into BeginCameraRendering and EndCameraRendering in URP, I should be able to perform a LookAt on a billboard, such that when the final frame renders it appears to be facing each camera in the scene at the same time, right?
The reason I ask, is because I've attempted that but it appears that the final frame only shows the billboard with its LookAt facing ONE camera, not EVERY camera
Here is an example:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Rendering;
using static UnityEngine.GraphicsBuffer;
public class BillboardProcesser : MonoBehaviour
{
public string billboardTag = "Billboard";
void OnEnable()
{
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
}
void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
}
void OnBeginCameraRendering(ScriptableRenderContext context, Camera cam)
{
GameObject[] billboards = GameObject.FindGameObjectsWithTag(billboardTag);
foreach (GameObject obj in billboards)
{
Transform billboardTransform = obj.transform;
// Rotate the billboard to face the camera -- ONLY ON THE Y AXIS.
Vector3 targetPostition = new Vector3(cam.transform.position.x, billboardTransform.position.y, cam.transform.position.z);
billboardTransform.LookAt(targetPostition);
}
}
}
Visual: the billboard faces the scene camera dead on, but not the orbiting camera (bottom right)
Logging each LookAt I can see that each cameras render is properly adjusting the LookAt, but I think Unity is doing something weird behind the scenes and disregarding this
Unity appears to call a new BeginFrameRendering pass for EACH camera individually for the final frame, and moving the LookAt into that pass still yielded the same issue ๐ค
ex: seperate passes for SceneCamera and MainCamera
I might be way off base but does this work instead? https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.OnWillRenderObject.html
Oh sorry I see you have one centralized processor here
rather than a MB on each billboard
so this wouldn't exactly work. At least - not unless you could guarantee this central processor is "visible" to all cameras
I actually gave that a shot, but for some reason it wouldn't fire at all on the billboard ๐ญ
Honestly I'm kindof at a loss... I think there is a weird engine optimization occurring which causes these minute changes to not actually show in the cam views
I think I'm just going to sleep on it and hope one of you brilliant folks has some insight lol
the fact that the logs show the pose is correctly updating in each pass makes me very confused as to why it's not showing in the render, because the unity docs mention that OnEndFrameRendering is called after the rendering finishes
wait are you relying on the scene view camera preview to tell if this is working?
I wonder if it's not actually just an issue with that. That little camera preview window might not trigger the full suite of render callbacks
Both scene and game view, the orbit camera showed in the scene view actually renders to a RawImage in a UI widget
Here is an example
you can see in the scene view that the billboard points the rendering camera, but in the game view the rendertexture orbit camera does not show the LookAt result
I only just now saw the billboard at all lol
yeah sorry its a little subtle
if you compare left vs right in this case you can see the left scene view is pointed at the camera, but if you zoom into the render texture on the right (driver side window) you can see it's not facing the rendering camera
is it possible to have a script where you can serialize an event to add a certain listener to?
Your events need to be serializable. Like UnityEvent.
how do you guys get over analysis paralysis for big projects... ๐
i feel like ive been debating the "best approach" for a system for weeks. albeit it is probably the most important system in the game... but still
i guess you can ask some professionals what the best approach is?
You eventually reach the point of enlightment where you accept there is no best approach to anything.
The best approach in the moment is making progress, so just make it work for what you know what you have to accomplish now and let the future iterations and features figure themselves out.
I wonder if this has to do with the fact that the object is a world canvas? ๐ค
My project uses a custom procedural terrain generation system that stores the transforms of all the objects within it (which only exist as indirectly rendered meshes). The point of this is to be able to point a raycast at the terrain and "select" whichever object is closest to the hit point, which it finds using a KDTree algorithm. It works, but the KDTree search takes about half a second to process.
I wanna add an indicator for when the raycast is started that tells the user whether the area they're pointing the raycast at is within a certain radius of one of those objects. I'm not sure how to do that without trying to use the KDTree search every single frame, though
Caching, Threading, Staggering (do you really need every frame, or every other frame is fine), Data Oriented approach, etc.
might need some elaboration on those
It's kinda hard without knowing the full context, but you can make your search multithreaded or you could simply put it in a seperate thread.
You could also not calculate every frame, but every X frames
it's for a VR game that's gonna run on the Quest 3, it's a data visualization thing primarily
How many object we are talking about
roughly 900 total at any given point, but anywhere between like 5-50 per terrain tile
the full dataset is about 700k
but it's scaled so that only 900 are loaded in at any given point
I see, and how deep is your tree
each terrain tile has it's own tree
not sure about depth
(I didn't write the kdtree code)
I mean, if your tree is really deep, then it is usually. If it is really broad, it is useless also.
If you have not written the code, you should start there.
Write your own implementation.
given my deadline, that doesn't sound like a very efficient use of time
There is nothing we can do here. This issue is advanced and you do not have the appropriate knowledge to have a discussion where we could solve your issue.
At least, I won't try to help you more given that I have no idea how to help you without doing it for you.
:\
what'd you mean by data oriented approach here?
By using array of ~unmanaged structure you can avoid cache miss which is usually what cost the more for a CPU to run.
A struct array will be all together in memory vs a class type array
In other words, instead of having class that points to your children, you would use ID to point to its children.
Then, you would obviously need to group up the data such as you reduce the amount of cache miss.
But obviously, its irrelevant if you are not ready to write your own implementation.
the amount of google searches for the terminology you're using I've having to do per message is uh.. 
you're telling me to go to beginner to figure out how to improve a real-time search algorithm?
Im telling you to learn how to code before learning how to optimize
and you're treating me like a child lmao
Optimizing something you have not written or you do not understand is extremely hard.
Im sorry it is coming out this way, but there is not a lot of way to say what I believe are the right step for what you are trying to do.
And do not worry, I also needs to take a step back to understand what I am dealing with before attempting to modify it.
Everyday.
Trust me, I get it lol. All of my development for this game been almost exclusively optimization-focused
custom procedural terrain generation, indirect mesh rendering, etc all running on phone hardware
Do you even need to do something complicated as a search?
Can you not do a sphere cast or something. Assuming your objects have colliders.
that's the thing, there are no actual objects because of the indirect mesh rendering
technically yes, though I had to make a custom transform class since normal Transforms seemingly have to be tied to a gameobject
sounds like ecs should have been used from the start
the system I'm using for indirect mesh rendering does have some stuff set up for having objects in the scene as actual gameobjects, I might see if I can have it do that for objects within a certain radius of the player
ecs?
entity component system: https://docs.unity3d.com/Packages/com.unity.entities@1.4/manual/index.html
usually combined with burst + jobs to greatly improve performance for certain tasks
oh, huh. That does sound like exactly what I was trying to implement manually lol
Yeah. That's the issue with reinventing the wheel: you can't expect other tools that unity provides to work(like physics) without some hacks.
Should've probably looked at DOTs before starting.
Just for fun, are you sure you are not bulding the tree each frame instead of simply querying it ?
would've helped to know what it was to begin with
but yeah true
I think proper profiling is in order as well. We don't even know what exactly is talking 0.5s at the moment.
trees are only made when a terrain tile is initially loaded in
can you share some code?
Because 700k element is not a lot of a KDTree
Build: O(n log n)
Query: O(log n)
Drastically different.
Are the trees generated at random position every time a chunk is loaded or something?
And on the other hand, if we're only dealing with loaded tiles, are there really 700k objects to search through at any given time?
ah, no there I meant kdtrees. the objects I'm talking about searching for are from a dataset with specified coordinates
no, which is why each tile has its own kdtree
So you do have data ahead of time. You should be able to construct the kdtree once and not touch it after that.
I think I did have it working like that at some point, it'd just freeze for a few seconds every time I did a query
Did you profile?
likely cuz this kdtree implementation my colleague gave me for this (which they wrote in like 2009 apparently) doesn't implement threading or anything
not sure if I did at the time, but sampling from a smaller dataset resulted in shorter frame drops, so conclusions were drawn lol
That's not conclusions. That's assumptions.
You're boasting about how experienced you are at optimizations by now, but it seems like you're skipping optimization rule 0 - always profile first. Optimize based on the profiling data. Make conclusions based on profiling data.
blah blah
profile it right now ๐
it's a bit time inefficient to be profiling constantly, especially when this is meant to run on a standalone VR headset
It's not that I don't use profiler, I've just yet to look through the profile searching for things in the context of what we're trying to fix now
how else do you expect to do this? wishful thinking and luck?
Not really, it is important to have appropriate data. Also, you should be able to profile directly from the editor without even needing to build given the nature of your issue.
It's not. It takes a few min to profile. And it's not like you need to do it constantly. Only when investigating performance issues.
And it would be even less efficient to optimize blindly
Sometimes I need to make a build which can take 1-4 hours depending on the project.
I still do it.
I have multiple computer to work on.
alright what do I need to be profiling specifically, then?
Or I do it at night.
Your code...
:|
Look at big ass spike in framerate graph, find what took super long in that frame, go down the stack and READ
For whatever takes most time obviously. If it's 0.5s hitch you wouldn't miss it, trust me.
And that's another reason why this question should have been in code beginner. Using the profiler is around the basics.
You'll need to use the hierarchy mode and sort it by CPU time.
build/enable "deep profiling" to get more info for calls
otherwise only unity managed stuff gets shown but yes you want to use the other view to better explore the stack of the calls.
you can also use Stopwatch to track how long things take yourself
Or use ProfileMarker to costumize the profiler
by how much does that normally affect performance?
A lot
And we do not care, we are looking at relative.
...yeah so that's making the terrain generation take several minutes
Then look at the related code and add profiler markers.
Also, if you're doing something heavy like terrain generation, it's a good idea to split it into several frames to avoid freezing your app
i dread to think how this was written but usually best for tasks like that to be jobs or threaded
I use UniTask wherever I can
Well, deep profiling would add some overhead depending on the code
async doesnt automatically mean threading
unless you are running on another thread using it + awaiting result
That looks like a lot of memory allocations.
GC memory at that too.
And the whole player loop allocates even more, so I wouldn't be surprised if GC is the bottleneck
But yeah, cloning and marshalling memory(assuming that's what it is) doesn't help either.
not sure how to check what specifically it's doing, but if I had to guess what it's from, it's likely the search that's done after the kdtree. The dataset is a list of lines from a series of transcripts, each line being a separate datapoint. After the datapoint is found with the KDTree, it goes through the whole dataset and finds all of the datapoints with the same file number and recreates the original full transcript
ah i just realised you ofc cant share this code
can you describe with more specifics, whats allocating? is there any attempts to avoid heap allocation?
use of classes or structs?
as said, many things are contributing here
I kinda can. Probably can't share the KDTree script, but all of my code is across many scripts so it's hard figuring out which parts are best to send lol
ideally you would read yourself and identify problem areas
only soo much we here can do with no extra info ๐ฆ
Here's the script in charge of getting full transcripts
https://codeshare.io/J7BzNX
why are functions async when nothing is awaited ๐
likely from when I was originally figuring out how Tasks worked and was just spamming it everywhere 
yea undo all of that
I've learned a lot since but there's remnants
its not free to produce a Task
the functions themselves are being awaited when called
an async function that does not await inside is a waste
I'more curious what the heck are these abominations?
level.parq.df.Filter(level.parq.df["file_num"].ElementwiseEquals(fileNum))
yeah dataframes suck to work with
what is it from
but it's the only thing I can get methods from parquet.net to spit out that's useful to me
which is being used because the original dataset is a .parquet file
your data needs to be in a good format to not be dog slow to read
which is a big reason why I don't like working with parquet files as well lol
but I'm stuck with it as far as I know
for such large work its clear its not gonna fly anymore ๐
You should probably cache the data in memory to avoid reading from file every time.
And also make it more readable.
that's why it's all put into a dataframe
it only reads the file once
I'll send the parquet parser script
No, what I mean is have your own data structures.
I thought I was supposed to not be reinventing the wheel
Reading about DataFrame makes me think it's really not intended for use in real time apps like games.
but also I'd need to mess with the code included with parquet.net to create the methods necessary to output anything other than a dataframe, which I would assume involves reverse engineering parquet.net
This is not reinventing the wheel. It's about how you store data in your app.
right, but you're saying instead of swapping to a better pre-existing solution, I should make a whole new one from scratch?
You can use data frame when loading the data initially. But then you should put it in your own data structures optimized for you use case.
No. I'm not telling you to reinvent something. Just not stop halfway through.
DataFrame is intended for data analysis. Not real time applications.
What would be a good thing to convert it to, then?
Your own data structure. I don't know what kind of data you're working, but a list of structs or classes with the data pulled from the data frame should do. Point is, you should not use it every frame or every query you're doing.
I should also mention, I did look into alternative means of handling the data. I got my employer to get this asset for the project, but I haven't been able to figure out how to work it https://assetstore.unity.com/packages/tools/utilities/sql-for-unity-database-115308
SQL is gonna be as slow.
You're missing the point...
DataBase access is slow. Loading, retrieving, filtering data is all slow. This is something that should be handled on the same level as your terrain generation.
Once you have the data you keep it cached in your own data structures in memory and use the cached data instead of the database.
I assume my Testimony class at the top of my parquet parser script will be useful for that, then
I think it's currently unused, though
At one point I did try storing the dataset as an IList
I think it was meant to be a workaround for not being able to use a List with the custom indirect mesh renderer the project used to use
Yes, this looks like your own data structure.
I don't know about IList and don't see a point of using it there. Is it an interface?
Anyways, that's irrelevant at the moment. The point is that you need your own data structures and logic that would be able to search through them if needed.
Well said, nothing i can add. Goodluck
I think I've also suggested a while ago that you process the data at build time and convert them to your own format that's tailored to your game, so you don't need Parquet.NET or whatever at runtime.
Yeah, unless they expect to load new files at runtime.
I think when I initially tried to do that, I couldn't figure out how to convert a parquet file into any other file type, could give it another go now. Any recommended formats?
it does need to be at least decently modular
the point of this whole project is to make a data visualization system that can be easily adapted to different datasets with visuals that can be easily modified
the more standardized, the better, in that context
I think the important thing about it was that it's an unmanaged type, since the indirect mesh rendering method I was using had to run outside of the main thread
Why does this have anything at all to do with rendering? Storing data about your scene and rendering are like on the opposite sides of the globe.
the datapoints determine where things are rendered lol
If you need some data for rendering, then create a separate data structure for rendering that is compatible with however you're doing your rendering.
You could have a fixed array or a native collection that you fill with the data from your scene data.
said and done already lol
partially due to how much easier the GPUI asset I use now makes it
Your own format, tailored to however your game will use the data.
https://assetstore.unity.com/packages/tools/utilities/gpu-instancer-pro-290293
this thing kicks ass btw
.. I might need one of y'all to explain to me what "reinventing the wheel" actually means, because I keep thinking that's what y'all are telling me to do for various things lmao
are you saying make a custom filetype?
Reinventing the wheel was mentioned once in the context of DOTs, as it would allow you to render millions of objects like that without the paid assets.
Or reinvent a way to query objects in space.
If you need custom file types, yes. But it wouldn't solve your current issue: loading data from disk is expensive, processing data with data analysis tools is expensive.
What you need is data in the memory that you can access easily. And make it easier to read the code too.
I'll use a very simple example, let's say the data you are working with is just a list of numbers, and at runtime the game needs to access the data in the form of "give me the sum of number 123 to 456." If you are just using the data given to you directly, then every time the game asks you for a sum, you have not better way than to loop from number 123 to 456 and add them up.
But now you have the knowledge of what the data is like and how the game is going to access the data, you can first process the data in a way that makes it more performant to access. For this example, you can process the data in this way: the processed data is still a list of numbers, but the first number is the sum of all original numbers up to the first, the second number is the sum up to second, etc.
Now with processed data, if the game asks for "the sum of number 123 to 456," you simple just take processedData[456] - processedData[122] and that's it, so much faster than before.
Is "a list of numbers that are sums" a new file type? I don't know and it doesn't matter. The point is that look at how your game is going to use the data, and process your data in a way that makes your game's data access faster by front loading the calculations.
Ah, gotcha. I thought you were referring to how the data is stored before runtime
not necessarily the ordering of the data
I'm not sure what kinda ordering techniques would do much good for the stuff I'm doing with it, though
I guess the way it comes by default is good for getting full transcripts
but if I were to reorder that to attempt to benefit the coordinate searching, I would assume it'd mess that up
You can process your data into two copies, one copy that's good at accessing transcripts, another copy that's good at coordinate search.
You have endless freedom and possibilities, you are not confined by whatever Parquet supports.
True, but doing that too much would defeat the point of this project
it's gotta be easily adaptable
maybe if I were to also make a tool that does that dataset reordering automatically
Universally adaptable app is a fantasy. It would require AGI to process truly arbitrary data.
Which is why you would need to put some constraints such that it is the responsibility of the data provider to provide data compatible with your apps.
If you standardize the input data such that there are always specific fields in specific order, you can then do whatever and however you want with it.
Whether it's recording or something else.
Fair enough then, I guess it's just a matter of figuring out what reordering works best for attempting to find coordinates within given 2D ranges
how would that work, then? if you were to make one dataset ordered by X coordinate and another by Z, then you'd have to figure out which datapoints match up between the two after filtering
You could generate a quad tree for example.
But I'd start with a simple brute force search. I'm sure even that is gonna be faster than 0.5s with what you're doing now.
..is that not what's already happening?
No. You're using DataFrame and what not which is the main bottleneck.
What a true brute force would look like is just looping an array/list of positions and caching the closest one to the target position. That's it.
I don't think the kdtree system does any searches with dataframes
or well nvm I think, you're right
yeah, lol
// filters DataFrame by given bounds to determine which plants are on a chunk
public async UniTask<DataFrame> GetDataFrameRange(DataFrame df, Vector2 min, Vector2 max)
{
level.debug.Log($"Creating chunk-specific DataFrame");
if (df.Rows.Count <= 0)
{
Debug.LogError("DataFrame is empty (no plants are on this chunk), returning null");
return null;
}
// TODO: There's gotta be a faster way to do this
DataFrame tileDf = df;
await UniTask.RunOnThreadPool(() =>
{ tileDf = tileDf.Filter(tileDf["umap_x"].ElementwiseGreaterThan(min.x)); });
await UniTask.RunOnThreadPool(() =>
{ tileDf = tileDf.Filter(tileDf["umap_x"].ElementwiseLessThan(max.x)); });
await UniTask.RunOnThreadPool(() =>
{ tileDf = tileDf.Filter(tileDf["umap_y"].ElementwiseGreaterThan(min.y)); });
await UniTask.RunOnThreadPool(() =>
{ tileDf = tileDf.Filter(tileDf["umap_y"].ElementwiseLessThan(max.y)); });
level.debug.Log("Chunk-specific DataFrame created");
return tileDf;
}```
// TODO: There's gotta be a faster way to do this
Smashcut to 4 months later: there was, in fact, a faster way to do this

Upon doing some googling for the custom filetype thing, I assume ScriptableObjects are my friend here
You're too stuck on "custom file type" thing. This is not even the point of our whole conversation.
You don't need a custom file type. Although it could help eventually.
Right, it was just mentioned that reordering the data before runtime would help to optimize searches
Which implies storing the data in some other file
This would only help if you have one data set and don't intend on loading new/different data at runtime.
Or if you're creating the data files yourself and have full control over it.
yeah no the modularity I mentioned is only from a development point of view
I think that's what they were getting at
If you can pre process the data into a more optimal format before hand that is most ideal (as we skip processing this at runtime)
Also if you want to run 4 things on the thread pool you should start them all then UniTask.WhenAll() to await them all at once (rn you are running 1 after another)
Ah, good to know
Do note that sometimes the work is too small for benefiting from using another thread (can turn out to be slower)
I'm back working on my game's enemies and I've run into a problem again - equipping gear.
So based on the enemy's "tier" it will randomly equip a selection of clothes, helmets, armor, weapon, yada yada yada
I watched this tutorial and opted for the most complex option, which was to spawn the gear in from prefab and map the skinned mesh renderer of it to the new bones
https://www.youtube.com/watch?v=nSmEirb8JGM
It was kind of a nightmare but I have it working. It really is a nightmare to manage, though, because I need to actually duplicate the base fbx out to its own separate thing and keep all of it updated.
My question is, how expensive would it really be if I just had all of the equipment spawned in, and selectively enabled/disabled stuff when needed? The enemy with everything spawned in is about 70 gameobjects,
On another hand, spawning in the prefabs separately basically copies the skeleton for every piece of gear, that's like 300 gameobjects
But they're just empties. I really don't know the internal workings of this and what is actually expensive so I would really appreciate some insight.
It would make difference during it's instantiation and some influence on memory footprint, but otherwise there shouldn't be any CPU overhead if the objects are disabled.
I don't want there to be lag spikes when spawning in enemies
My question was more really what has a bigger performance impact
Well, there would be. It's just a matter of how big they are.
If you want to avoid them, you shouldn't be spawning them at runtime anyway. Use an object pool or something.
And I explained it in detail in my reply, did I not?
If you're really worried you should test both scenarios and profile them.
I asked about two different methods for equipping gear on my enemies, I'm not sure which one you're referring to
Oh the latter
mb
Wait so it is better or worse?
It would be a little bit worse. In theory.
Because there are more empties? What actually affects the footprint?
On practice, it might not be noticible
The more objects and components you have loaded, the more memory is consumed. Even if they are deacrivated.
And roughly speaking the more memory you need to instantiate/initialize, the more expensive it would be to instantiate the GameObject.
However, once it's loaded, it's just there. If the total amount of updated object during the frame is the same in both scenarios, there wouldn't be a difference during normal frames.
If you're really worried, you should test and profile both to see for yourself .
Is there an event that can be subscribed to whenever objects are instantiated? (similar to sceneLoaded, sceneUnloaded, etc.)
not that im aware of, it sounds like a bad idea to need something like this. if you instantiate an object, Instantiate returns the spawned object. You can either invoke your own event or directly pass it to whichever objects need it
I have shared a relatively complex coding issue in coding general. Any advice is greatly appreciated.
Well, I didn't want to resort to modifying all the codes that use Instantiate. I wanted to translate texts and leave the project intact, without needing to modify the script or add extra components. I only wanted to modify fields that contain text or text-type components using search. I can check this when a scene starts, but I can't check the objects that are instantiated. It would be a worse idea to constantly check for new objects, so only using Instantiate is sufficient.
But I can't find an event in Unity that I can sign up for to check out just this part.
its not like every object would be displaying text, this is unfortunately just poor planning from the start. i assume you'd be doing this for localization?
Yes, that's all. The Unity localization plugin must add localization components to each text component that requires translation, and handle inserted variables. It seems very complex to have so many scripts of this type running.
๐คทโโ๏ธ its not complex at all, how you're trying to do it is way worse and basically a bandaid solution. if you dont want to do it per object OR have an event for your components, your only option is searching for every single component that has text.
That's easy, I just get the path of the component I want to translate
"path of the component"? i never said its hard. it's just a bandaid solution to poor planning from the beginning
Where I work our localisation system is to just use an id to get the translation string (depending on the current lang ofc) and set on text object/do something else.
Either way it needs manual effort to set up ๐คทโโ๏ธ
fixed4 frag (v2f i) : SV_Target {
return float4(1, 0, i.uv.x, 1);
}```Can someone please explain why in my hlsl shader the color is only being outputed as red and not a gradient as it should be?
#archived-shaders but uv is not what you think it is?
Can someone help me with a problem of my dll not working in my build?
I created a simple dll file that creates an overlay border for my unity app.
In the editor the dll is working perfect, only when I make a build, my dll does nothing, no crash, no log file being created, and nothing mentioned in my player.log.
I tried attaching visual studio debugger, I tried using DebugView, and even have my dll output to a logfile.
Everything works in editor, but not in my build. I have run out of options to try, and am at a loss
I have put my code on pastemyst for if someone wants to take a look, this is the link : https://paste.myst.rs/1wc2bwz3
a powerful website for storing and sharing text and code snippets. completely free and open source.
what happened when you attached to debug this native code (was it attached for native and not managed?) Never broke in your exported functions?
It was attached for native, but never broke in my exported functions, not even in DLLMain
is it ticked to be included for windows on the dll in editor?
Yes, doublechecked all import settings, and the right file gets exported to my build
what exactly do you see if you step through a call to one of these methods in the unity debugger? does it look like it's trying to call the native method?
If I run it in the editor, it does work, it calls the correct native method, no errors
right, but what about if you debug the build?
If I create a debug build, with script debugging, using Debug.LogError I get no messages at all
what happens if you debug it?
managed debugging works differently to native code debugging with unity which is why its important to make sure its attached correctly for native code
i'm not talking about debugging the native code, i'm just saying use the unity debugger to debug your C# code
it sounds like it's not being called in the first place, so the problem is probably on the C# end?
Im not sure because they claim DllMain was not called either but this was probably confirmed via debugger too
I agree that it should be checked both ends though
i think unity wouldn't load the DLL until you call one of its exported functions so that tracks
ie, it isn't calling them!
ah i presumed it would be loaded on launch but makes sense ๐ค
i've never needed it but i guess that's what this box does
I never needed that one before, but will try it out, also just saw that visual studio could not find the correct symbols, maybe wrong pdb file got attached
Hmm could be. My experience is only with android/ios with unity compiling the cpp for me.
to debug the unity code don't attach natively with visual studio, attach with the unity debugger
c# -> unity attach
cpp -> normal process attach
I will first go back to unity, and attach my build to check the c# part, and afterwards check my cpp with visual studio debugger with the correct pdb file
should be able to attach both (presuming you have a sln for your dll too)
if it's true that your methods aren't being called, part of the problem in VS may be that the module is never being loaded so it won't even try to load that pdb
It seems that for me, when building for x64 on a windows 64 bit platform -
#if UNITY_STANDALONE_WIN && UNITY_STANDALONE_WIN64 returns false ๐ค
Changing it to #if UNITY_STANDALONE_WIN && UNITY_64 fixed the problem, now my dll is being recognized again
where does that second one come from as its not in this list? https://docs.unity3d.com/6000.0/Documentation/Manual/scripting-symbol-reference.html
anyway its 2025 you can probably forget about win 32
The second one was accidently taken from an older project where that error never gave any problems ๐
I probably can forget about win32 but do have a dll for it, in case someone with old computer runs my app.
Thanks for the help though, by attaching both c# and cpp I found the issue.
Can the DOTS system lower performance of my voxel engine? I wasn't using it before and now that I am it is struggling to work like it used to. I am running using job system and burst, rendering my voxels at a much slower rate and with way more constant lag.
You need to use the profiler
Don't deal in vagueries
What do you mean?
I mean "Can the DOTS system lower performance of my voxel engine?" Is an extremely vague question
nobody knows anything about your voxel engine or how you are using DOTS.
You need to use the profiler to get real insight about why you're having framerate issues.
oh okay
I was more along the lines asking if I was wasting time on the DOTS system
since it has given me zero benefits
DOTS itself is good but nobody has enough information except you to make that call. We don't know what we're comparing to or in what way you've utilized it it.
Also #1062393052863414313 is a thing if you have DOTS specific questions
Hey all, just wanted to ressurect this thread and see if anyone has any insight ๐
Anyone know if there are any Unity Devs or URP maintainers in this server who I should reach out to?
I'd say I understand rendering to a decent degree but im no expert. I'm going to presume at some point during the update cycle that transforms changes no longer take effect on the meshes and triangles rendered. So what you are seeing is when the transform data was last synced to the transformation matrix used with the draw calls.
the frame debugger should show the transformation for the draw call
good lead, will investigate thanks
is there a feedback email for Unity and its upcoming changes? I have an extreme opinion that should be shared with the top brass for hiring a Java developer to "fix" basic default coding such as FindObjectsOfType/FindObjectsByType - and making it a disgusting mess of nonsensical trash.
The best place for that kind of feedback is discussions: https://discussions.unity.com/
ty!
There is no off topic here, thanks.
How do people render small text without suffering from anti alliasing ? We're using textmeshpro and it's really bad especially on platforms that have a low render resolution
FWIW, I switched the object I am attempting to modify during the render pass from a world canvas into a plane, and the LookAt appears to update per-camera now
looks like the mesh update works too, I guess mixing world canvas rendering and the URP rendering callbacks is dubious
makes sense
Great news. Perhaps canvas mesh rebuilds only happen at one point hence the previous issues
Yeah, thanks for the lead!
I've got it working pretty well now, hooking into those render callbacks provides a waaaaay cleaner way to achieve what I'm looking for
glad that it worked out
Hey all,
Have anyone used Mesh Baker for models with LOD Group ? Does it support that ?
Hi
I want to make a system where I can put script (MonoBehaviour) as a reference in a var (List) in my script. I want to create a tool to make Bosses easily without any more code (except patterns).
But I can't assign this in my inspector (screenshot). How I can do this? Or should I do something else?
Ty
you need to drag an instance of the object in, not the script itself. and if the script is something that shouldn't be attached to a gameobject in order to reference it then it should be either a scriptable object or a plain c# class (which you would use something like SerializeReference plus an asset that draws an inspector for SerializeReference)
!code
๐ Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
๐ Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
https://paste.ofcode.org/6fp7ZVD2ijHnPecyGHpcKu does anybody know why im getting an error at scenemanager.loadscene i put what error im getting in the comments
you've probably got your own class called SceneManager and it's trying to use that instead
also not an advanced issue
i think that was it thank you
why was fragmentation tab being removed from mem profiler ? i find it quite useful locating fragmentation issue
Hello ! I am looking for a solution to display this correctly in the inspector.
I am using Unity 6 HDRP.
like that
Where did RenderingLayerMask come from? I don't see that as a type anywhere in the docs.
Are you sure it's not just a LayerMask?
it's just a uint. Nothing here ever says RenderingLayerMask is a type
use LayerMask as the type
if i use LayerMask , the unity layer mask are display in my inspector , but i want to display RenderingLayerMask
not the LayerMask of unity
Ah ok I see it does exist here: https://docs.unity3d.com/6000.0/Documentation/ScriptReference/RenderingLayerMask.html
Does this not work?
The only thing that doesn't work is the display of the RenderLayerMask in the inspector.
when i expose it from a monobehaviour
On the other hand, it works with Unity's default components.
I found this solution, but it's quite strange that it isn't implemented by default like it is for LayerMask.
It... is supposed to be... and seemingly is here^
mhmmm weird ^^
is this a custom inspector or the default on your mono rn? I guess check to make sure this file exists in your package ver?
Is your code in an asmdef?
nop default assembly
Hi everyone, I'm trying to use Transforms within the unity jobs and understand that to do so I need to use TransfromAccess structs.
Currently the only way I can see how to use this is with TransformAccessArrays, however, the container that will hold the transforms is going to be resizing almost every frame, so this would mean I would have to do the resize, convert to an array and then convert to a transformAccessArray.
I also want to bundle a bit more data for each element too, so I was hoping I could create a struct that holds said data and a single instance of TransformAccess, created on Awake and disposed of on OnDestroy of a monobehaviour, then just use this struct in a NativeHashMap.
However I cannot seem to create a single instance of the TransformAccess, how can I do this, if this is possible?
My current approaches are either do the above, deal with the slowdown of creating the arrays and transformAccessArrays every frame or just sample the transforms as I only need to get the read the positions not set them.
the container that will hold the transforms is going to be resizing almost every frame
Ideally you would preallocate some maximum capacity ahead of time so no resizing is required.
How would the transformAccessArray deal with non full arrays then?
Right now the only things it takes in are a standard array and a jobCount.
If I have an array of 100 elements but I am only using 20, then even if I manage that memory correctly since we can't set the copy capacity of the transformAccessArray would it not load junk memory and cause issues?
it has different properties for length and capacity
Or do you mean to predefine the capacity and then copy the elements over
It acts like a list with a max capacity. Check the docs https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Jobs.TransformAccessArray.html
Does it have an overload then for the indexer to autoconver the transforms to TransformAccess's?
Just looked and it says Transform so yeah
Final question then sorry, does this kind of approach scale for running every frame? As I would still need to create the TransformAccessArray each frame, even if I didn't have to create the Array?
Or can you dynamically change the size, but not capacity of a transform access array
dw
I just realised it has a length property
All is good xD
Thank you
You don't need to create the TAA each frame, you create it once and reuse it
You can also use the Add and RemoveAtSwapBack methods to add and remove elements
Oh, intresting! Does this work as dynamic memory like Lists then? Can I just add and remove and have the TAA deal with the capacity changing?
Or will that still be something I will have to manage, (fine either way just wanting to make sure xD)
Yes, it behaves like a list.
Excellent! Thank you,
I realised I'm going to have to carry some extra data that needs to couple with the index of the TAA, I'm going to be manually dealing with the capacity of this other array to match the TAA. However on resize with it being automatic, how much does it resize itself by? I can't find anything online about this, and secondly if I manually set the capacity to a given number doing collisionEntityTransforms.capacity = 10 does this empty the list / if not does it keep the ordering?
Why is it important that the capacity is the same?
Its not necisarilly, it just means I wont have to have an extra in variable to manage the capacity of the Malloc array. I was going to see if since these two arrays need to be directly coupled (in terms of order and size) I could just make sure the manually allocated array uses the same capactity variable as the TAA. So instead of manually dealing with 1 with 2 capacity variables, I could just use the already existing varriable built into the TAA and manually deal with both
You should avoid ever resizing/reallocating the arrays. I would just manage reallocations myself. Like if you're trying to add something and the capacity is full, manually reallocate both arrays and copy
I'm not even sure that TransformAccessArray automatically resizes
I don't see any indication it does, the Add method's documenation is sparse.
The docs certainly don't answer that question.
indeed
But I'm pretty certain it does. I don't remember having to check capacity before calling Add, but it's a while since I've used it.
This is the main thing I need to do, but once they are added since the collisionEntity is a struct it becomes a copy and looses the ability for me to change it. So when I then go to remove it I cannot know what the position of where to remove,
My thoughts where to store an index in the collisionEntityData itself on being added, so then I can remove it from that location and update the other elements in the list. However for that to work it then needs to be a pointer.
public void AddCollisionEntity(in Transform transform, CollisionEntityData collisionEntityData)
{
collisionEntityTransforms.Add(transform);
collisionEntityDataList.Add(collisionEntityData);
}
public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
collisionEntityDataList.RemoveAtSwapBack(collisionEntityData->listLocation);
}
You could always just check the capacity after you add, and if it's bigger than your other array, reallocate the other array to match
Or just use a NativeList for the other array and don't worry about it
You should be able to use ref instead of a pointer.
I was under the impression that NativeContainers alwasys copied data and didnt' work with references?
But if you use NativeList, you don't have to do this. It stores a pointer to the list and count, so it can be passed around as a value.
native containers are a struct but they should point to only 1 block of native memory
so I presume it will always share this memory till its released manually
Only inside the list though, the data is originally coming from gameObjects being added and removed from the list on OnEnable nad OnDisable, if I was to do that, then I would hten need to update all gameojbects to have int indexes for the list in the array which complicates things further
All the unsafe collections are pointers to data, so the data never gets copied. Structs like UnsafeList have a pointer to the data and a field for the count, so you have to pass that as a reference if you want to update the count. But NativeList wraps the count in a pointer too, so you don't have to pass it around as reference.
This should explain a bit for what I mean by this:
public unsafe class WorldCollisionEntity : MonoBehaviour
{
#region [ Serialised Fields ]
[SerializeField] private float _collisionInfluenceDistance;
#endregion
#region [ Unserialised Fields ]
private Transform _transform;
private CollisionEntityData* _collisionEntityData;
#endregion
private void Awake()
{
_transform = transform;
_collisionEntityData = (CollisionEntityData*) UnsafeUtility.Malloc(sizeof(CollisionEntityData), 4, Allocator.Persistent);
*_collisionEntityData = new CollisionEntityData(_collisionInfluenceDistance);
}
private void OnDestroy() => UnsafeUtility.Free(_collisionEntityData, Allocator.Persistent);
private void OnEnable() => WorldCollisionPoolManager.Instance.AddCollisionEntity(_transform, _collisionEntityData);
private void OnDisable() => WorldCollisionPoolManager.Instance.RemoveCollisionEntity(_transform, _collisionEntityData);
}
[BurstCompile]
public struct CollisionEntityData
{
#region [ Properties ]
public int listLocation;
public float collisionInfluenceDistance;
#endregion
public CollisionEntityData (float collisionInfluenceDistance)
{
this.collisionInfluenceDistance = collisionInfluenceDistance;
listLocation = -1;
}
}
Any particular reason why you are using Malloc instead of NativeArray or NativeList?
Because this is only a single instance of the data, this all then gets passed into the manager class for collisions
The idea is that the game objects control their own behavior, this component just updates the collision manager on Enable or Disable to remove them from the lists.
The collision manager then handles the Jobs for loading which cells (cell based procedural system) have colliders
And this is not possible with NativeArray?
Do you mean to have a nativeArray of length 1? If so then you can't nest native arrays inside other native arrays.
If you mean to have a single native array on the manager, then yes that would work, however then we run into the problem again of ordering and knowing which item to remove on disabling the gameobject, as the order may have changed so caching a value on start woulnd't work.
Instead you would need to update every object each time that one changes with their new index, so rather then a single object interacting with the manager, you would instead have a single object interact with the manager that then calls every other connected object to update their indexes
I want to avoid event calls like this as it makes following the flow of things a nightmare.
Im confused why you are storing pointers to structs tbh
And it's crucial that WorldCollisionEntity has direct access to its data as a pointer? It's not just the manager that needs it?
Mainly its to have a single source of truth for updating the index of where it sits in the array.
Does it have access to the array? Why does it need its index?
I assume you've omitted the code that uses it in the code you pasted.
Its not fully written yet so I can't really post it. But I can post what I have atm if that helps.
For when its removed.
For example:
Say I have for game objects, that
When I add these I need to know where in the list they are for later, so I store their positions as their indexs
A, B, C, D
A = 0
B = 1
C = 2
D = 3
if I remove B I check what index it had which in this case is 1, and remove that
A, C, D
I then want to remove C,
The problem is that since I havn't updated the indexes C still have the index of 2 so I would actually be removind D.
If instead I updated C and D's indexes to update the change then this would solve this.
Given however I cannot use a single source of truth from the gameobject side when I then call the remove function from the game object it can't know without having its own version of the index.
Either by keeping the original object itself, which handles its own position changes, or by having a callback event that updates all gameobjects with their new indexes (which is unneccary)
public void AddCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
collisionEntityTransforms.Add(transform);
collisionEntityDataListPtr.Add(collisionEntityData);
}
public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
collisionEntityDataListPtr.RemoveAtSwapBack(collisionEntityData->listLocation);
}
private void FixedUpdate()
{
CheckCurrentCollisionStatus();
ProcessCollisionUpdates();
}
private void CheckCurrentCollisionStatus()
{
int size = worldCollisionEntityTransforms.Count;
(_previousActiveColliders, _currentActiveColliders) = (_currentActiveColliders, _previousActiveColliders);
if (_currentActiveColliders.Capacity < size) _currentActiveColliders.Capacity = size;
_currentActiveColliders.Clear();
CheckCurrentCollisionStatusJob job = new ()
{
};
TransformAccessArray transformAccessArray = new (worldCollisionEntityTransforms.ToArray(), 16);
JobHandle jobHandle = job.Schedule(transformAccessArray);
jobHandle.Complete();
}
private void ProcessCollisionUpdates()
{
}
The idea for the code above is that In CheckCurrentCollisionStatus, I iterate over all gameobjects and return the cells around them that need to be active for collision. ProcessCollision then checks which need to be turned on / off from a objectPool of Collision components on the manager.
As I mentioned the codes not really written, the main points of intrest are the Add and remove functions.
My current plan is to update them to this:
public void AddCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
collisionEntityTransforms.Add(transform);
collisionEntityDataListPtr.Add(collisionEntityData);
collisionEntityData->listLocation = collisionEntityTransforms.length - 1;
}
public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
collisionEntityDataListPtr.RemoveAtSwapBack(collisionEntityData->listLocation);
collisionEntityDataListPtr[collisionEntityData->listLocation]->listLocation = collisionEntityData->listLocation;
}
This would work, given I also add some code on Add for managing both the containers capacity. Though I do understand that this isn't a very pleasant way for doing this.
Though it would mean only the swapped item would get updated on remove instead of everything. And the memory would be accessed via pointer to do so rather event listeners.
Tbh, a better solution to all of this would be to have a way of coupling persistent data directly with the transformAccess, though I looked into this early and that doesn't seem possible
Is the main issue here how you keep these indexes valid? Why can you loop and remove the first ptr match?
Its to keep the different gameobjects able to call and remove themselves from the collision manager. Basically I just need to know where in the list a gameobjects data is. (both for the WorldCollisionData struct and the transform).
But if you use a native list for example and the monobehaviour has the ptr to its object, it can be removed with just this.
That is what List.Remove() can do anyway, loop and remove when a comparison is true
Quick question: When exactly do I know I should use a ScriptableObject?
I know itโs used to store and share data, but how do I know when I should use it instead of MonoBehaviour?
Another option is to use a Dictionary to map the game objects to an index, and updating the index when performing the swap back remove. It's more work to retrieve the index than the solution you're trying to implement, but if you don't need to retrieve it often, it's fine.
Another option is to create a sparse array of indices. Assign a permanent index for each object and save the internal, moving index in the sparse array. That's quicker to fetch than a dictionary, but uses more memory, depending on how sparse it becomes.
Ahh, so what you saying is when I add it to the NativeContainer I return the pointer. That would work, I might try that. I've implemented my kinda janky approach with the pointers now but I want this code to be as fast as possible so I'll do a commit and test with this approach too.
well atm you have a list of pointers right?
you cannot safely have a pointer to an array item as ofc these will change any time
I have an array of pointers atm, so CollisionEntityData** _collisionEntityDataListPtr
I meant that if you have a list/array of pointers you can loop over and compare the ptr address to the one you wish to remove and remove this way.
a ptr is just a number
At the very least, if you want to store a pointer to the index on the object itself, make it private, wrap it in a regular struct. There's no need for the script to know the index or even that it is storing one. It just needs to pass it back to the manager when it wants to remove itself.
Oh like a pointer to an int inside the struct? That would work too, I would still need to Malloc that int though.
Given unity will be doing stuff below the hood, would it be faster to try and use Native containers as much as possible? Given their is some overhead with copying the data to the native array does the format of native containers outway that compared to just passing raw pointers?
I say the best example is let's say you have a single Card prefab. Instead of making multiple cards, you can instead insert data into this one Monobehaviour template that constructs it depending on the values that are set in the scriptable object.
Still, there's nothing stopping you from making a bunch of different Card prefabs with different SeralizeField properties which you can just modify.
The native containers should be your starting point, and only move to malloc and pointers if you run into limitations or performance problems.
What I would have is a Native list of CollisionEntityData and give each some unique id when its added so they can get removed later.
Then we have them all allocated all together and avoid using unsafe in managed land.
I think doing a malloc for each one is not doing you any favours when you are trying to benefit from burst jobs
It's more comparable to serialize classes but it's much more decoupled in a sense that you can insert lesser derived scriptable objects into these Monos, as well as reusing them in other parts of the editor
So basically, when a prefab is heavily reused, is it preferable to use a ScriptableObject instead of a MonoBehaviour? Did I get that right? (Sorry if this isnโt considered an advanced-level question to ask here.)
So the best way I describe them is data that can be easily swapped around on the editor and can easily be referenced by multiple different objects (unlike serializing classes)
Does malloc not work well with burst then?
That's usually what people recommend, but there's benefits to just sticking to prefabs and learning how to use prefab variance as for one you have scene presence at editor time while with those prefabs, while the SO constructor idea requires runtime instantiation
The way I think about it is this:
MonoBehaviour is how you create your own custom component type.
ScriptableObject is how you create your own custom asset type.
Examples of built-in components: AudioSource, Rigidbody, MeshRenderer
Examples of built-in assets: AudioClip, Mesh, Material
Which category fits better for your need?
This gets a little fuzzy since GameObjects themselves can also be assets in the form of a prefab. But generally, prefabs exist to be instantiated. It's possible to use a prefab like an asset that you don't ever instantiate, but it's not often done.
nothing to do with burst. its more ideal to have objects allocated all together as this is faster.
So if you have a native array/list/whatever that holds structs not pointers it will be better and basically the same as what you have now but without the initial malloc of each element.
I'm not sure if i'm just not getting it with the native containers but I'm finding its actually harder to work with then predefining the memory myself. Stuff like capacity changes, parallel writing and accessing the structs outside of the single job (keeping them around for the lifetime of the program without copying them) causes more headaches then just having manually made memory given I know I have to deal with it all.
Its weird I know but I've been playing with the Arrays, HashSets and Queues a fair bit now and each time i feel like I run into more problems with the containers then without.
I think I will just need to do some more reading on everything and see some examples, I'm coming in "blind" with jobs and native containers so I'm almost definatly picking up bad habbits.
I do appreaciate the help though!
Thank you everyone ^-^
Thanks a ton, @regal lava and @sage radish ! I finally get it. I really appreciate your guys' help. You guys are the best! ๐ฅ And it wasnโt confusing at all, actually, it was explained really well in just a few words. Thank you so much!
Gotcha!
Remember in this case you cannot safely keep a pointer to a struct in the list/array as it could become another (due to removals) or the list could be reallocated and moved to elsewhere.
An index works but you are back to your original issue of making sure your stored indexes are correct later.
Hey, I'm trying to create a texture during runtime and use it as an asset sprite but I am getting blocked in any direction I want to go in:
- I tried creating a new texture and assigning it to the sprite asset, for some reason it fails and editor shows "Type mismatch"
- I tried creating a texture in editor and manipulating it in runtime, but setting pixels are not allowed for its graphic format, so that fails too
Asset sprite? You can create a sprite instance at runtime no problem, just need the texture + rect.
Sorry I meant TMP_AssetSprite
anybody got any resources I can look at for some design idealogies for setting up a character stat skill system?
Might want to provide a better explanation of what you're trying to do with code and screenshots of necessary.
Not sure what you mean by "idealogies", but there should be plenty of tutorials on that online. Other than that, maybe write down on paper what features you want your system to have and how you want it to work. Basically, provide us with something to work with.
Also, this is hardly an advanced ques.
hello, I upgraded my project from Unity 2023.2 to Unity 6 (43f1) and while I can successfully build locally both Android and iOS (with Xcode 16.0) , the iOS Unity Cloud Build is failing in the XCode build phase (I tried both Xcode 16.0 and 16.1). I think it has something to do with the shift to SPM (Swift Package Manager) target signing because the log shows it's failing with multiple "Signing for 'something' requires a development team. Select a development team in the Signing & Capabilities editor. (in target 'something' from project 'something')". But I don't know how to fix those errors. Can anyone provide any hint please? I'm attaching the whole Xcode log
Don't think this is SPM - it's likely your distribution certificate ("Apple Distribution: Drest Limited"). Are you familiar with how to sign, create and specify the certificate, and use a provisioning profile?
I've just gone through this pain implementing a CICD pipeline (codemagic) and it's.. kind of a pain.
That being said, there's nothing in your logfiles that indicate a failure.. whatever's failing is either later in the log or in another process..
I'm often needing to have my works Jenkins xcode Auth fixed so I know the pain
we migrated from Jenkins to CodeMagic and .. despite some of the pain points, I have to say I'm loving life on the new CICD pipeline
So, i am working with a script of quake movement made in unity with Character Controller. It would be so much better for all the things i want to do to be RigidBody based. Is this possible to do? I dont know, and still i am kind of new to this. If i understand it right, for the quake movement to be working right you have to tweak the physics laws and concepts so that it works how it should. With RigidBody you have default values that are behaving like real-life objects and cannot really change that. They can, but it is not as customizable as CC. Thanks for all the help. :)) https://paste.mod.gg/yucyzjfysneu/0
A tool for sharing your source code with the world!
you would have to rewrite the entire thing to make it work with Rigidbody.
This isn't really an advanced question btw
You would do the same logic, but use Rigidbody instead and rely on Rigidbody's built-in momentum and forces and such to do everything
The actual answer to your question is the code itself, which I'm not going to write for you
It's going to require you to understand three things:
- How to code
- How Rigidbodies work
- How the physics expressed in this code works'
Source engine which we know is based on gold src which is based on the quake engine moves the player without physics but syncs a physics collider to move alongside. You can read the src or other things to learn more.
After 15 mins of searching I have concluded tf2/source engine movement is VERY complex
Best part to read i could find: https://github.com/ValveSoftware/source-sdk-2013/blob/master/src/game/shared/gamemovement.cpp#L4562
Realistic human speed and physics isn't ideal for that sort of game, usually.
Does Unity have any way to visualize Spline Data on a spline (just the position) or would I need to make a gizmo for it?
The spline package has gizmos for erverything already
make sure you turned gizmos on
I recommend this^
Yeah I'm already in that mode
by spline data I mean the drawers I have open (int data and object data), not the knots or the spline itself
just a dot on the spline
!collab
:loudspeaker: Collaborating and Job Posting
We do not accept job or collab posts on Discord.
Please, use Discussions to promote yourself as job-seeking, advertise commercial job offers, or look for non-commercial projects to participate in:
โข Collaboration & Jobs
Removed ty
Can I ask shader help here since they are code related?
#archived-shaders exists though!
I won't get any help any time soon
Hi all, any Unity devs using Vim or similar editors that may want to chat about their favorite motions? It's for a little project I'm working on
Thanks for help @echo coral @sly grove
does it make sense to do a cullinggroup pass on DrawInstancedMesh? I read in the doc that it splits batch per groups then does a culling pass per group, I just don't know what groups are..
Instanced meshes usually have some (singular) bounding boxes instead of selectively culling each and every render, and usually those instanced methods do have some automation to that, but I guess if you need more control on how grouped your meshes are I guess you can add your own cull groups
Unity culls and sorts instanced Meshes as a group. It creates an axis-aligned bounding box that contains all the Meshes, calculates the center point, then uses this information to cull and sort the Mesh instances. Note that after culling and sorting the combined instances, Unity does not further cull individual instances by the view frustum or baked occluders. It also does not sort individual instances for transparency or depth efficiency.
Yeah I had cullinggroup running alongside, before I read the documentation ๐
I think that worst case scenario is so bad anyway that culling wouldn't help unless meshes themselves provide cover to each other. And experience on Unreal wasn't too favorable to deploying GPU culling to solve that.
I'll have to get more clever I think.
Do you understand the docu as: it makes one big bbox for a drawmeshinstacned and then cullt hat bbox? or do you think it splits a call into subgroups?
Unity 6 has additional GPU culling via the resident drawer feature which uses depth map to further cull instanced meshes
this would have me jump on 6 and switch to URP, I guess it's doable after I pre-release, have you used u6 gpu culling on quest 2?
Oh, no. I've not touched any of the VR stuff but I should jump onto it ;p
what's the lowest spec + high pixel count device you've built for?
Probably androids I guess unless you consider WebGL/GPU builds running on my decade old laptops
mobile android will do, even decade old edsktop have more ompf in some areas
u6 gives you faster perfs with that new gpudrawer thing?
It's buggy with web builds, but it's great at culling stuff like grass when occluded by trees and stuff like that
There's a bit more to the whole resident drawer feature, and they are still working on it, but it does kinda break some of my shaders too. It's still relatively new so I expect it to improved upon with 7
Similarly with the render graph
I'm using splines, is this normal? Getting a lot of NREs here whenever domain gets reloaded or I enter Play mode I have absolutely zero stacktrace to work with so I assume it's editor stuff?
I get no warnings or errors about it in the console and it just runs fine regardless
Maybe splines just don't like being in subscenes because I disabled the subscene it was in and now its silent
lol usual unity, i'll wait a year
thanks for the info. Yes, I am familiar with how to sign, at least with the basics. The strange thing here is that we signed and still can sign successfully this app with Unity 2022 and 2023 without any issue, so if there's an issue with the distribution certificate, for some reason the issue only exists with Unity 6. Can you provide some more detailed help please? This is a huge porblem for me because it's blocking the whole engien upgrade initiative.
hey, does anyone know definitive info about using bluetooth game controllers on macOS apps for distribution on the Mac App Store?
We're using Rewired for game controller support and our builds were using the bluetooth and usb entitlements when codesigning. Previously this was ok but App Store review has started rejecting our submissions because we don't explicitly request bluetooth access from the user with a native OS popup. There's no way to request this from the user in the Unity c# api and will need to be done with a native plugin I think. It's hard to get useful info on if Unity would actually pop this request itself using the info in the player project settings for 'bluetooth usage info'. I've not seen Unity do this before.
The Rewired docs wipe their hands of real info, instead just listing some troubleshooting stuff around it all but ultimately saying they don't have solid info.
what's the best i18n solution currently? Should I use I2 Localization or Unity's built-in solution? or is there any other recommended solution? (for Unity 2022)
Does [InitializeOnLoad] not run in batch mode ? I'm experiencing a wierd discrepancy between our automated CI and local building.
does anyone know how to get the actual bone that a skinnedmeshrenderer is linked to?
like if i add a sphere collider to the mesh when it animates the sphere stays in the same place, but if i find the right bone and put it in there it moves as expected,
but i dont know how to find the right bone without manually doing it
i know its the problem of the model but ive had the guy modelling it out for 6 months now and he has never once got it right
It can have many bones and all of those transforms are the bones so yea you need to add the collider in the correct place to follow a certain bone.
Not really code related so ask in #๐โanimation in future
yeh but how do i know which one relates to the right mesh, and i think its more coding than animation surely, i need to write a script to do it
a bone is a transform so yea you can find the closest to some position. many verts of the mesh can be weighted to the bone however.
So yea you can do a distance check and pick the smallest dist
but if its a humanoid you can just learn the hierachy that you will basically always see for bones
ah, yeh this is just a one off model, i love it but its never been right,
dont suppose u have a script showing how to do what you said there ๐ seems like it would be difficult, ill ask copilot see what it can do ๐
Finding the closest thing out of a set is easy:
Transform closest = null;
float closestDist;
Vector3 ourPos = transform.position;
foreach(var otherTransform in transformList)
{
float distance = Vector3.Distance(ourPos, otherTransform.position);
if(closest == null || distance < closestDist)
{
closest = otherTransform;
closestDist = distance;
}
}
Debug.Log($"Closest transform is {closest} with distance of {closestDist}");
solutions that get all the distances in a list then sort the list are bad
thanks i will give that a try i actually got somehting similar from copilot earlier but iassumed it was wrong when i saw the distance checks etc
cheers!!!
we can make it faster if we use squared distance instead (as square root is a tad costly) but for editor stuff its not really a problem
yeh, have u tried it before, actually works?
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/SkinnedMeshRenderer-bones.html from here you can check if the names match a certain convention
thanks yeh i found that but it just gave me an array on tons of bones couldnt make sense of it
thats the point
yeh but i expected one bone to lin kto one mesh
not many
i guess my modeller just needs to export it properly, never had this issue
it can be 1 mesh or many sub meshes but there is not a 1 to 1 match of a bone to a sub mesh. go research how skinning with bones works.
ok thanks
Hi im trying to build for UWP ut i don't get why i get an error something about failed to run refrernce rewriter with command and something about the System.Memory version
https://pastebin.com/3KqpYNv3 this is the full error i dont get the problem
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Thats why we add _c_colliderType to the name of the relevant bones
Hey all,
I have a scene with so many cliffs (With 3 LODs), I want to optimize the scene with Mesh Baker.
Mesh Baker can bake LODs togther but can't add them to LOD Group automatically. So I have to make a system to do that.
Now before starting, I want to know if it makes sense to bake cliff (And other props) which are next to each other or near enough, to gain more FPS and performance in my game ?
In the example you circled it doesn't seem like combining them would reduce a lot of polygons to me. So seems like a lot of effort for very minimal returns to me
If you have good lods it may be better still to keep them separate somewhat. Then you benefit more from culling. It's always a careful balancing act!
What is the code "theory" or logic to updating server builds and client builds
For example updating a rust server that has builds and player inventories on etc to a new update that adds new items etc
how does that work? because you can update the game via steam but dedicated servers running a server build i dont understand how they recieve updates
Ideally through a CI/CD pipeline
can you run c++ plugins in Unity Job?
I don't see why not
๐
There is many way to update a server, but the simplest would simply be to prevent user to connect to a server if their client does not have the appropriate version.
Minecraft does kinda work like that.
You should do proper profiling to identify the bottleneck first.
Ah
But to actually update the servers automatically
Like on next launch do i just make then check an external database fkr changes in files then download thosebchanges or what
That could work. You might also have a separate application managing the whole process, especially if you want to do this without downtime.
Wdym by that?
Separate program can do large changes to the server setup regardless of state of the server(s) being changed.
Have you set up a server yet?
Note down the steps required to spin up a new server and getting clients to start connecting to them.
Yep ive got server logic setup dedicated servers server browser etc you can connect everything like that
i havnt actually tested on a cloud server but currently im just using dedicated server builds and running them on my pc
or my other pc
Hey, so I've made a project to generate a world procedurally but I see like land is not really big and often cut by the water. I've lowered the water level and the Noise but not really know how to make it more real, does someone know what values should I change?
World generation (sometimes abbreviated as worldgen) is the procedural generation process Minecraft uses to algorithmically generate terrain, biomes, features, and thus ultimately decides which blocks are placed where. Minecraft worlds are made of 16ร16 blocks wide chunks stretching the full height of the dimension. Because there are more than ...
minecraft uses a lot of noise maps for climate and stuff to get more realistic terrain
Let me check
You should use multiple layers of noise for terrain generation if you want more control imo. Here's an example of it: https://www.youtube.com/watch?app=desktop&v=uY9PAcNMu8s
In this episode we'll create a noise filter to process noise, and layer it for more interesting terrain. Episode 04 is out for early access viewers here: https://www.patreon.com/posts/21079771
Noise script:
https://github.com/SebLague/Procedural-Planets/blob/master/Procedural Planet Noise/Noise.cs
Get the project files for this episode:
ht...
I already do that, the problem is that my noise settings generate too much land and oceans are rare too. I'm thinking in putting things higher, like sea level at 39 and leveling the land. However I don't know if it would be better to put an offset on y or changing how the perlin noise system is working.
I think the way to go is by putting an offset? However that wont change much of how it is looking
Is there any way to have multiple conflicting packages in one project?
What I mean is that many packages dump their settings into the Assets, and you cannot exclude or ignore those packages or settings for a specific build, unless you manually make the folder "invisible" by using ~.
Let's say I have two headset I am trying to develop XR for. One XReal, one AR for Meta. Their packages are conflicting, and can't live well together in the same project
The solution is to have multiple projects, each one for every setup?
how do they conflict exactly? I would personally prefer one project with feature-enabling scripting defines if needed than multiple projects or doing weird things abusing Unity's special folder handling
Well for instance try to support XReal together with Meta Passthrough VR. Or... the OpenXR don't like Oculus VR installed and etc.
And they also dump files on Assets, like config files, or manifest files. Both packages try to edit a manifest file
And that cause issues
In visual studio you can have multiple projects in one scene. Each project referst to files, it doesn't not replicate the folder structure
So you can have different projects have different files includes or excluded. All in the same solution
You could use another noise layer to determine what can be land/lakes and what is ocean
Or just sqrt everything and scale it up
But thatโs unreliable
Is there a steamworks documentation?
there is a steamworks SDK documentation but is there the steamworks unity wrapper documentation i cannot find it anywhere
If the source code is available, there might be no documentation for the wrapper.
Doesn't seem like there's an official solution, so anything you'd find is an open source solution by third party devs.
๐ ty
Thankfully, wrappers are usually straightforward, so it should be pretty easy to read the source code.
There are multiple strategies to bring sanity to this type of project. The first is what @long ivy mentioned, scripting defines to include/exclude platform specific code. But this will not solve the platform specific assets added by SDKs, and as you highlighted the overrides to the manifest files, etc.
One strategy would be to use version control and branches to segment incompatible platforms. One branch for Quest, one for XReal and a main branch where the common elements are tracked.
Like this you can avoid incompatibility errors due to SDKs not coexisting.
There is a great ebook on version control with Unity.
You can run the values through AnimationCurves for more control over the shapes
Could be, but i'm thinking on having different parametres as minecraft do, like continentValue, seaValue etc idk, the thing is I don't know how to adapt values to make perlin noise give more flat values or spiker
I'll have to test
You can scale a perlin value by simply multiplying it
Yeah could be
That's kind of like separate projects in a way. If you adjust the files with a repository. I think the best way is to make the "logic code" into a separate module, like just a library. Then every project for every different device use the same module. (Like a dll for instance)
Unity's ebooks are so underrated, love them
I just wish they had more
They are a gold mine, and also a monumental effort for the teams involved. In case people here need reading materials over Easter... 100+ ebooks can be found here:
https://unity.com/resources?filters=e-book
Yes. That can work for components you control. But with external SDKs like Meta, XReal, etc. it's harder to manage. So platform branches, off of a main common one, can help solve these issues. That's something we use internally with Unity Version Control and Build Automation forAndroid, iOs, Quest, AVP builds, etc...
my personal favorite https://unity.com/resources/mobile-xr-web-game-performance-optimization-unity-6
Does anyone here have example code for how you can integrate with steams master server list using facepunch steamworks
Yes i have read the entire documentation but whatever way i attempt to do it i can never manage to get it to work
alright let me refrain ๐ญ
Hi guys I wanna ask is it difficult to put a circular indicator right? Like in the MachiaVillain game where you see a color circle underneath the characters but combine it with an arrow to lock-on something (enemy, object, etc.).
Got a vid or image to illustrate? You can do world pos to screen POS to make UI elements follow something
Like this the green circle but imagine that circle with an arrow as like a direction to lock-on
Ah well you can do (targetPos - myPos).normalized to get a direction to something and this can be used to set rotation.
Atan2 can be used for a 2d "lookat" using this
So basically use Atan2, even if it is in an 3D environment?
If 3d you can use transform.LookAt() but atan2 can be useful if you wanted to keep it on a 2d plane (e.g. x and z only)
Ahh I see, I get it now, but the circle is just an insert sprite thing right?
Insert? I'm gonna presume it's a quad or sprite renderer
Yes insert like you drag the image to the inspector thing. So yeah at least now I get it. Thanks @echo coral
so uh, about that...
2 GB worth of 125 million allocations
My attempt at making a custom datatype optimized for searches has resulted in performance worse by orders of magnitude

Gotta do some optimizing.
...that's exactly what I was trying to do
gotta optimize my optimizations lmao
Just don't allocate that much
gotta figure out how to do that
though, on closer inspection, it might actually be the search algorithm for my datatype tanking the performance
makes sense given how chunky it is but idk a better way to do it
It's the memory allocations. As for where they originate, it's hard to say without seeing the code.(Or making more pinpoint profiling with markers/memory profiling).
I don't know if it was you, but some time ago there was a person dealing with a huge amount of data, and they were suggested to use native collections to avoid GC allocations.
okay I think it's several things together causing the issue
but most notably, it's probably the async function I'm using for the loading loop for my generative terrain, which is being called directly from update
I assume that's the problem but I also don't know what the alternative to that is in my case
guys my game doesn't build stuff properly what do i do
in editor everything is fine , but when i build the game it screws up some prefabs materials, and layers, is there a way to make a proper build same as playmode
Well, the most obvious solution that would be to not call it every frame. Make a flag/bool that you flip when that method is called and check it before calling the function again.
The next step would be to go over all the new use cases and eliminate them if possible. Use preallocated/cached objects instead of allocating new every update.
I wanna figure out how to make sure it's not trying to calculate literally everything in a single frame first
Well, normally it would do that by default. If it doesn't it's an issue in your project.
that way I can chip away at figuring this out and only worry about load times instead of the app entirely freezing or crashing
Print the frame number in update, then print when you start and end your calculation. Then see if both start and end print on the same frame.๐คทโโ๏ธ
...does the 125 million alloc calls in a single frame not indicate that?
Though, honestly you should know how it works, since you wrote the code.
Donno. Maybe you have that on many frames. You only shared data for one.
it's only on the one frame
Then it calculated all on one frame.
...so, we should try this first then, no?
Probably.
I'd assume that the issue is in loadUtil.YieldForFrameBudget();
It probably doesn't yield properly.
public async Task YieldForFrameBudget()
{
TimeSpan timeElapsed = DateTime.Now - startTime;
if (timeElapsed.TotalSeconds > frameBudget)
{
// reset the start time and wait a frame
startTime = DateTime.Now;
await UniTask.Yield();
}
}
Mm... Probably don't want to operate on seconds scale.
If it's less than a second, you're never gonna yield
Ah. What do you recommend, then?
I have never seen soo many allocations at once good grief ๐
perhaps loading this on another thread is wise
Though, it seems to be a double, so I guess it can represent time smaller than a second
that's kinda what I intended for it to do
Correct the return type to be UniTask
Anyways, start from debugging this piece of code and see if it ever enters that if statement.
you should only be using UniTask and UniTaskVoid
when would I want to use one vs the other?
UniTask can be awaited, UniTaskVoid cannot so should be used when you do not intend to await it.
UniTaskVoid is a replacement for async void so it still uses UniTask and not Task.
You can also consider pre allocating the list capacities to avoid reallocations when it resizes
Another part where I'm a bit lost on what the correct implementation should look like with UniTask is in the sort functions for my custom datatype
https://codeshare.io/G76Dra
which is likely responsible for the majority of the allocs
There's so much weirdness in that code.
For example, you have array fields in a class, but then you allocate new lists to put some data in them to create a new array from them to assign to the fields. The lists are obviously a lot of immediate GC allocations.
code architecture is definitely not my specialty ^^;
kinda just learning as I go with this stuff
This is not code architecture though. You could just create arrays of your defined size (or max estimated size) and just assign the elements to the arrays directly.
This is kinda like basic programming thing.
Yea you should sort the list
You should not use Linq to do it and produce a whole new array... Bad idea
I forget if array can be sorted in place.
Is there an easy way to do that without Linq or am I gonna have to implement sort algorithms manually?
I wanted to use System.Linq.Async at one point but it apparently relies on .Net 9 or something unity doesn't support
List has a sort function and you can do it easily using CompareTo
wait so am I using lists or not .-.
E.g.
list.Sort((a, b) => a.CompareTo(b));
You want to avoid using linq to sort as you need to allocate a whole new collection for the result which as we saw, is an issue for you
so it won't be a problem to use lists instead of arrays?
https://learn.microsoft.com/en-us/dotnet/api/system.array.sort?view=net-9.0
Looks like there are functions to do it on an array
Btw it may be more performant to just sort everything together on another thread, perhaps you can profile it a bit
I only have 30 more work hours to get this thing ready, I think I literally don't have time to try to do that lol
the profiling, that is
I'm having trouble making sense of this ngl
I guess I'm not super familiar with IComparer
while I'm rewriting these, there's another part I think is probably problematic https://codeshare.io/ax16kG
I think first off that the search algorithm just doesn't work, but also it's one of the things likely tanking performance
since it's ran for every tile of generated terrain
so 49 times at startup
since the coordinate arrays for x and y are sorted separately, the intent is to use the minimum xy coordinate of the search range to find the lowest value x and y coordinates via binary search and then just move up the array and grab every value until they exceed the max xy coordinate.
then, since the separate x and y coordinates have an index assigned to each point, it takes the x list and y list created by the binary searches and compares them to see which index values are shared between the two lists
So I took a look at it, I think you would really benefit from changing some of those classes to structs. It'll allow you to store your data on the stack instead of the heap because they're a value type, which doesn't generate garbage for the garbage collector. Id also recommend using readonly on any fields that don't get modified outside of their constructor
And also because you're generating so often, it'd be ideal if you check your integer types and make sure you only use what you need to reduce what the CPU is using
Float, int, byte, short, etc
For this case, they are all in arrays already, so changing them to structs wouldn't move them from heap to stack.
Long term data that size would not be in the stack anyway
Yup, they're on the heap because the array is, but structs still help because theyre inline inside the array, not separately allocated. So we avoid GC and get better cache performance compared to classes
I'm thinking speaker, saha, date, umapx, umapy, hdbscan_label, could all be turned into readonly structs and be beneficial compared to them being classes
File, maybe, but it's more complex so it's not as valuable but could be. The testimony stuff would remain classes
It's still beneficial to convert them to readonly structs even in arrays
Oh my bad yes structs for the array elements would be useful depending on how the data is used
Though rn the issue was a lot of allocation at once
hey! I was wondering if any extra memory is allocated whenever an animation controller is given to an animator object
im trying to implement a pooling system and if Unity's animation system requires memory to be allocated when swapping the controller on something, that kind of defeats the purpose of the pooling system in the first place
Has Unity support of GLTF been getting better as of these past years? I remember how about pretty much every single game developer, or at least the ones I know of, has been using FBX for all projects
I've found about https://docs.unity3d.com/Packages/com.unity.cloud.gltfast@6.12 and I'm pretty interested on it. I can't think of a single game that imports models at runtime other than VRChat, and I don't know how exactly they work so I have no idea how to go around this
It's pretty solid. My issue with GLTF in the very limited amount of times that I've used it is that by default, there's no easy way to set specific compression methods on the textures of a GLTF model once it's in Unity, which often means you're stuck with bad (or no) compression formats.
Hi all,
i have a prefab with two components (A and B) that both use the same ScriptableObject for shared data/events. I want each instance of the prefab to have its own unique copy of the ScriptableObject, so A and B still share it within the prefab, but not across multiple prefab instances.
I saw a community-driven Unity project where they used ScriptableObjects as event channels โ and Iโd love to adapt that approach. But Iโm running into the problem where multiple prefab instances all share the same ScriptableObject asset, which causes cross-instance interference.
Since Iโm building a larger project, the prefab might contain many components โ not just A and B โ so Iโm looking for a clean and scalable solution that keeps shared data per prefab instance but avoids global SOs.
Whatโs the best way to handle this at runtime?
Your design seems very weird to me. Are you using this SO to communicate only between components on a particular prefab instance, and never outside it? SO as an event channel sounds like the wrong approach in that case
I want to achieve both with this one solution.
For example, I want that every enemy on hit invoke an onHit event to update their own lifeGui. But if they all uses the same SO (pre configured with serializefields), then all enemies listen on that event in the SO and will update their life.
When i make an instance or lets say a clone of that SO event in script A, then the B script doenst know about it because i couldnt pre configure it and i would need to call it from script A to know each other.
if enemy life gui is one of the components they have, why wouldn't you just configure an event (UnityEvent) on the prefab instead? And if it's not, it probably makes sense for your script that wants to invoke onHit to expose an event anyway, and have whatever script spawns enemies hook the event up to the right gui at runtime. That way everything is decoupled
yes the gui is a component on the enemy too. how would you subscribe as gui to the lifecontroller event then? just have a normal reference in the gui of the lifecontroller and have onenable method something like this: lifecontroller.onHit += UpdateLife? simple as that?
i wanted to avoid having a reference of other classes, not only for different GOs, but also for all the scripts within one GO.
Right now im doin that with something like enemyEventManager, that knows all scripts alone and connects all events to another scripts. but its too much work on the long run for me.
as a simple example: suppose onHit from LifeController have one arg, a float which is % of health remaining. Then LifeController has UnityEvent<float> onHit. HealthGui has a public LifeChanged(float percent). You then set up, in the prefab, onHit to call LifeChanged. Neither script references each other directly
Just personal two cents but I think using scriptableobjects and unityevents in general to handle this kinda essential logic thats contained within a single prefab is abit overengineered
Oh sorry misread, lifegui is seperate
It definitely can be. Depending on how complicated your setup becomes, it can get very hard to debug if you have events triggering events which trigger more events
In this case is the scriptableobject usage here strictly to just limit what kind of events off the enemy outside code can see?
proto's use case seems like a bad case for SO usage. It can't be both global and local, and it sounds like they want a strictly local solution to update same-instance components. That means direct reference, UnityEvents, C# events, or a mediating class either in the instance itself or code that sets those events up between components at runtime when spawning enemies
Sorry i dont know exactly what u mean by that: You then set up, in the prefab, onHit to call LifeChanged.
You have two options to call the method in the gui. whether with an event and being subscribed to the event of the controller where the gui needs a reference for it, or the controller has a reference of the gui and call the public method of the gui lifechanged.
yes, you fully understood my problem.
So without SO event for help, there will always be a class that has a reference of another class in order to subscribe to events, am i right?
no
" You then set up, in the prefab, onHit to call LifeChanged. "
How can u do that without having a reference?
You mean in the unity inspector?
yes
here's an example of what it would look like. Neither script knows anything about the other
That is just a prettier solution for game designer isnt it? You have a reference in the life controller of the gui...
not to be pendantic but you can get the ref off the unityevent
i want just normal best practices solution here.
so its common that the gui knows the controller to subscribe to a public event? or should the controler know a gui and just call the method updatelife?
sorry i should have sent that message as a reply, I meant that message to evilreaper to point out that via that they can know about the other
The scripts don't have any direct references. I don't understand the point of your comment. If you want to communicate with a specific component, that relationship has to be known somewhere
the gui knows nothing, it just has a method to update life
the life controller knows only that it has an event to publish, with no idea what (if anything) is listening
The gui has the direct reference of the controller with your solution. Dont get fooled, just because unity gives you the oppurtunity to listen on events in the inspector.
But its still maybe the best possible solution here for my case.
the event does, the script has no references itself
that's where the "let's communicate with something specific" knowledge goes
this isn't true you can get all current targets off the unityevent reference
im not saying it matters or not but there is a connection
You could write your solution in the inspector also in code. And you would need the reference of course like you did with draging the script into the other.
yes, but the idea is to prevent these two classes from being coupled together. That is one of the solutions I suggested earlier. This one is more flexible and better design-wise, if your events aren't too complicated
Alright, thank you so much to discuss with me.
I write an action rpg for over a year and with over 100 classes it starts to get messy. so i need a good architecture. just FYI why i ask.
the wander around code isnt working for me
i just copy and pasted
i think the wanderTimer being 0 has something to do with it
I don't think anyone acknowledged this when I mentioned it
I took a quite look, and the last bit of code already has so many problems:
var xyRange = from x in xRange
join y in yRange
on x.value equals y.value
into matches
where matches.Any()
select x;
xyRange.ToList();
List<Testimony> xyList = new List<Testimony>();
for (int i = 0; i < xyRange.Count(); i++)
{
xyList.Add(testimonies.testimonyArray[xyRange.ElementAt(i).index]);
}
xyRange.ToList() materializes a list and returns it, but you are not using the return value so that line of code does nothing but allocates garbage.
The loop using xyRange.Count() and xyRange.ElementAt(i) enumerates the sequence over and over.
The entire loop to create a list could just be removed and turn into one single select on xyRange. Not that I would recommend LINQ either if this is performance critical code.
I'm not too sure what advice to give since this piece seems like quite a big mess in many ways.
I'm guessing one problem you are having is that there are too many technologies at your disposal and you don't fully understand what they are abstracting over to know if and how they should be used. LINQ ToList() doesn't turn it into a list in place, Count()/ElementAt(i) are not the same things as List.Count/List[i], and a lot of these misuses compound into all the performance issues you are having.
really anything more complicated then a single select or where just use a loop it will be easier to read and expand upon it
Its like sorting a collection just to grab the first element
The point of this is just to grab every coordinate that lies within a specific XY range. Is there any better way to do that in a way that takes advantage of the coordinate arrays being ordered?
if the array is rows/columns in order and you want a rectangular range then you can calculate the start + end index and bam you have your range to grab.
they're not, they're kind of arbitrary float values
which is why there's separate arrays for x and y
I'm baking a scene into an SDF to drive boid flow simulation, it's 19MB total, 300k cells. Anyone did that and saw big improvement by using some compression on the SDF?
19MB won't fit in cache so I was wondering if it matters a lot in a job+burstified thing
Then the way to do this is to allocate a list with a sane initial size, loop over everything with for and add items that fit the requirements to the list.
I thought you meant that your array was say a 5x5 grid defined as Thing[25] or Thing[5,5]
there isn't a way to do that without iterating over every point?
because there's 670k points
how did you think linq does this ๐
Unless you know before hand that a range will fit your criteria and can skip checking each element then yea you need to check them all
I think i need an example of the data to comment any more
ahh right the positions are floats.
You would need to pre sort them into fixed size areas (e.g. 5x5x5) to be able to cut down the data to search, this would let you narrow the search
https://en.wikipedia.org/wiki/K-d_tree
In computer science, a k-d tree (short for k-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. K-dimensional is that which concerns exactly k orthogonal axes or a space of any number of dimensions. k-d trees are a useful data structure for several applications, such as:
Searches involving a...
you can then use the input range to quickly pick the sets of data to actually search in detail
so should the first step of the data processing be to assign indexes to the XY coordinates based on which fixed size area they lie in? or should separate arrays be made for each area?
FWIW, the problems I pointed out above have nothing to do with algorithm, it's all just misusing LINQ.
what would be a better alternative? I noticed also that UniTask has an implementation for async LINQ
This suggestion is to speed up a "loop over 600k elements and do a vector2 >min && <max comparison" check
i didnt try to fully understand the existing code so want to be clear about what I mean
the gist of it is just doing a binary search for the minimum X value that lies in range, going up the array until you hit the maximum X value, doing the same for Y, then comparing the resulting X and Y lists to see which ones have matching index values
I have no idea if that's better than doing a K-D tree
because I do have a K-D tree implementation provided by a colleague, but it's just C# code without anything related to Unity in it
so none of it runs async or anything
should I try to use this instead? https://github.com/ArthurBrussee/KNN
all of the K-D Tree implementations I'm finding are at least 4 years old
It's not alternatives, that piece of code could just be cleaned up a bit and be a lot better.
All the problems I've mentioned, like xyRange.ToList() doing nothing, is something you should know when you write the code.
(This is not saying there isn't a better algorithm for the problem you are solving, but a better blueprint doesn't help if you are not laying out the bricks and pouring the concrete correctly)
Fair, I just need to know up-front if this is the route I should be trying to go in the first place
I don't think anything about k-d trees changed in the last like 30-50 years, so 4 year old implementation should work.
because this is what feels like my 8th attempt at solving the same problem by rewriting the same massive chunk of code and whether or not I finish this by the 24th is the difference between me having a job or not
Then maybe start simpler. Focus on optimizining your current implementation instead of rewriting it.
that's what I was originally doing, until I realized that the stuff I was using to do it couldn't be done async
then I was told that the best route would be to make an entire custom datatype
I don't know how far you progressed since the last time, but you had huge GC issues irc
Why not?
because I was using DataFrames, and all of the query stuff that comes with tries to do every computation in a single frame as far as I can tell
and every attempt I did at making it not do that failed
at this point I'm losing track of everything I've tried
Yeah, I remember you using data frames and that it was a very bad idea. But didn't you move from that already?
that's what I'm trying to do with making a custom datatype
Okay, but that's all pretty old news, is it not? I think yesterday you had mainly GC issues.
Or was it the day before?๐ค
So do you have a working solution ATM or not?
Without dataframes, right?
kinda yeah
though my current coordinate search doesn't work
everything else functions at least
Okay, so, now to optimizing it. Did you work on the crazy amount of memory allocations?
I think you were given several pointers yesterday. Did you fix them?
I can't remember if I did all of them, but yes
The testimonies constructor looks like this now
testimonyArray = testimonyList.ToArray();
speakerArray = new Speaker[testimonyList.Count];
fileArray = new File[testimonyList.Count];
sahaArray = new Saha[testimonyList.Count];
hearing_typeArray = new Hearing_type[testimonyList.Count];
locationArray = new Location[testimonyList.Count];
dateArray = new Date[testimonyList.Count];
umap_xArray = new Umap_x[testimonyList.Count];
umap_yArray = new Umap_y[testimonyList.Count];
hdbscan_labelArray = new Hdbscan_label[testimonyList.Count];
for (int i = 0; i < testimonyArray.Length; i++)
{
int index = (int)testimonyArray[i].index;
speakerArray[i] = new Speaker(index, testimonyArray[i].speaker);
fileArray[i] = new File(index, testimonyArray[i].file, (int)testimonyArray[i].file_num, (int)testimonyArray[i].file_index);
sahaArray[i] = new Saha(index, testimonyArray[i].saha_page, (int)testimonyArray[i].saha_loc);
hearing_typeArray[i] = new Hearing_type(index, testimonyArray[i].hearing_type);
locationArray[i] = new Location(index, testimonyArray[i].location);
dateArray[i] = new Date(index, testimonyArray[i].date);
umap_xArray[i] = new Umap_x(index, (float)testimonyArray[i].umap_x);
umap_yArray[i] = new Umap_y(index, (float)testimonyArray[i].umap_y);
hdbscan_labelArray[i] = new Hdbscan_label(index, (int)testimonyArray[i].hdbscan_label);
}
}```
sorts look like this
public async UniTask SortFile()
{
await UniTask.RunOnThreadPool(() =>
{
//fileArray = fileArray.OrderBy(row => row.file_num).ThenBy(row => row.file_index).ThenBy(row => row.index).ToArray();
Array.Sort(fileArray, Comparer<File>.Create((x, y) =>
{
if (x.file_num != y.file_num)
{
return x.file_num.CompareTo(y.file_num);
}
else if (x.file_index != y.file_index)
{
return x.file_index.CompareTo(y.file_index);
}
return x.index.CompareTo(y.index);
}));
});
}```
Did you profile after the changes?
sorting seems to run fine, but I think the performance tank happens when filtering by coordinate
The basics of optimizations:
- Test and profile
- Identify bottlenecks in the profiling data
- Fix
- Repeat
Which part is that?
Share the profiling data
I haven't done deep profiles because they've been taking way too long
I'm currently going by debug logs
You don't need deep profiles. You can understand enough with regular profiling and custom markers
You're gonna get the same and more info with a profiler, rather than logging.
I'll need to figure out how to use custom markers properly then
Start without markers to see the whole picture.
Then you can make some assumptions on your code and place the markers accordingly.
nothing's changed since here, in that case
Ok, so it's still an issue of GC allocations.
And looking at your code it doesn't seem like you've done anything about it.
Avoid creating new objects.
As well as things like ToArray
If you want to use lists, preallocate them with setting the capacity to the max expected count.
Prefer structs over classes where possible
You were told all of that before and it doesn't seem like you implemented any of this.
A lot of that comes from not knowing good alternatives
like here for example,
List<Testimonies.Umap_x> xRange = new List<Testimonies.Umap_x>(testimonies.testimonyArray.Length);
for (int i = mid; i < testimonies.umap_xArray.Length; i++)
{
await loadUtil.YieldForFrameBudget();
xRange.Add(testimonies.umap_xArray[i]);
if (testimonies.umap_xArray[i].value >= max.x)
break;
}```
I need to grab all of the Umap_x elements out of testimonies.umap_xArray (which is sorted beforehand) whose x property lies within a specific range
what would I output the results of that to if not a new list?
because the expected amount is basically random
You can use a list. Just preallocate it. Don't use new in here.
Make it a class field and init it with the max assumed capacity
I guess 680k then
Well, optimization is often a trade off. Often a trade of between memory consumption and processing resources.
Also, if the testimonyAssay is already sorted, you can just find the last index of the element that you need and use AddRange
I don't know the length of that range in the array itself
I just use a binary search to find the first index in that range
and go up the array until I find the last
Well, start with allocation optimizations first. You can think about algorithmical optimizations later.
Something like this at the start of the class, then?
private List<Testimonies.Umap_x> xRange = new List<Testimonies.Umap_x>(680000);
private List<Testimonies.Umap_y> yRange = new List<Testimonies.Umap_y>(680000);```
Yes. Though, do you really expect it to contain 680000 elementes at some point?
Then yeah
Software often would have hard limitations on ranges for performance reasons. Maybe you should consider such a limitation yourself. I.e. not allowing more than X amount of elements in this list at the same time
Or if you split the processing over several frames, you can split the range as well, so that you use less of the elements at the same time
I'd likely have to make multiple versions of this function that support different sizes, then
given how many different things use it
here's what I have now, then
https://codeshare.io/5Q1RJ5
that's what I've been trying to do the whole time lol
that's why I keep bringing up async stuff
literally anything to get a Quest 3 to not try and do everything all at once so the user doesn't throw up whenever frames drop
So does it happen in 1 frame atm?
This also allocates:
xyRange = (from x in xRange
join y in yRange
on x.value equals y.value
into matches
where matches.Any()
select x).ToList();
Not sure about the linq itself(it probably does to), but ToList is definitely allocating. Might want to avoid doing linq here.
Share the profiling data
making those lists class variables did help a lot it seems
what's the alternative to linq here?
Write the sorting/filtering logic manually.
The allocations seem to be in MySystem.Prepate. Not the method you shared.
I just grabbed the code from the unity docs example
haven't changed that name yet
What code?
Oh, is it from a marker?
yes
Then add more markers to split the method
For starters add markers around loops
And the linq part
I'll try, but I have a feeling this will take a while to figure out and at this point I also don't trust myself enough to do another thing custom lmao
Let's do the markers first
Expand the markers and share the new code
Yeah, that linq part seems to be allocating a lot.
It's weird that the other loops are allocating too.
Can you share the updated code?
Since the async doesn't seem to work for you, can you comment out the await loadUtil.YieldForFrameBudget(); lines as well as a make the method non async?
Then profile again.
I'll have to also make the return type List<Testimony> instead of Task<List<Testimony>>
Yeah