Unity Optimization - c#

I'm creating an infinite runner game in Unity and to avoid floating point precision the player stays in one place while all of the other environmental objects move when the player inputs something. It works amazing, but it's meant to be a mobile game and I want to save performance everywhere I can.
Currently, I have a script that takes the players input and translates it into force vectors that are then applied to the game objects. But since I can have a lot of visual elements that are doing this, would it be better to remove the script from each game object, have one copy of it in the scene, and then have the script apply the force vectors to all the visual game objects? This is how I see it.
(Calculate physics once -> apply to objects) > (Calculate physics 40 times)
I'm new to unity, so I don't really know if this would make a difference in performance, but it makes sense in my head that calculating physics once is better than 100 times.
Thanks in advance!

would it be better to remove the script from each game object, have one copy of it in the scene, and then have the script apply the force vectors to all the visual game objects?
That's usually better, but when it comes to optimization, it's all about testing.
I'd suggest you learn about Unity's built-in profiler, and actually see how much of an impact the physics has on the performance, and then compare those results with other methods of achieving the same thing, and then choose whichever method you think it's better.
Just remember that every device will have different performances, even on the same device.

would it be better to remove the script from each game object, have
one copy of it in the scene, and then have the script apply the force
vectors to all the visual game objects?
Yes it would be better in most cases.
From 10000 Update() calls Unity article:
Unity goes over all Behaviours (Scripts) to update them. Special
iterator class, SafeIterator, ensures that nothing breaks if someone
decides to delete the next item on the list. Just iterating over all
registered Behaviours (Scripts) takes 15%.

Related

How does the game Rust place Millions of Grass, Rocks, and Trees

Rust has millions and millions of grass, rocks, and trees instances across its maps, which get as big as 8km.
Is that grass placed dynamically around the player at runtime? If so, is that done on the GPU somehow or using a shader?
In my game, we use vertex colors and raycasting to place vegetation, and we store transform data which gets initialized with indirect GPU instancing at runtime.
However, I can't imagine this would scale well with something like trees. Are there really thousands of mesh colliders active in the scene at all times?
I thought perhaps they might store all those meshcolliders in the scene, and the gameobject could be tagged, and if you hit it with a tool, it adds a "Tree" component to it.
Am I headed in the right direction with a "spawn everything before hand, instance it at runtime" approach?
I've tested this and it actually worked, spawning 24 million instances (took 20 minutes to raycast), and then initializing the GPU with the instances.
This is cool and all, even though it lead my Unity editor to crash after a little while (memory leak?).
Maybe you store the instances before runtime, and then when you start the decicated server you do all the raycasting and place all the trees, rocks, and other interactive objects.
But I am worried that if I tried to store even 10000 gameobjects (for interaction, stuff like choppable trees, mineable rocks) that performance would tank.
You can actually see this for yourself in the code: https://github.com/Facepunch/Rust.World/blob/master/Assets/Scripts/WorldExample.cs
The game loads the instances in memory or can stream the instances as well, but you wouldn't ever have the prefabs all instanced at the same time in GO's as culling / chunks are needed to keep performance (and not crashing your program).
There's many tricks, lowering your draw calls, billboarding, culling, object pooling, chunking, just to name a few.
A suggestion if you're interested in systems like this is to look into ECS for unity as it offers a lighter way of instancing data: https://docs.unity3d.com/Packages/com.unity.entities#0.17/manual/index.html
That way you can have thousands of instanced objects for a fraction of what Game Objects would offer in size and performance.
I also don't want to get too deep into generating objects as that's not the main question, but to generate a map using raycasts is extremely slow as you now know, you should look into noise generation to create biomes and quickly spawn your instance, also maps really need a set place for objects you're just adding data that a user needs to load in. Another option is to place objects that serve as visual objects arbitrarily around a viewing distance so they only exist in memory, if someone runs past a generic grass pile, they will never care if it's moved the next time the run past it.

How to make objects in Unity2D interract smoothly?

Hello I am making a 2D game in c#, using Unity2D.
Game is basically tower stacking game where player is given random objects from array which they need to stack on top of each other. Objects spawns at the top of the screen with Body Type Kinematic and player can move it only on the x axis and when player lets go object, its Body Type changes to Dynamic and it starts to fall and lands on start platform or tower.
My problem is that when this new object lands on existing tower or start platform it does not land smoothly, it goes in the other object and sometimes bounces and that often tips over the tower.
And when these objects stay on top of each other, they are vibrating and causing the tower to tip over.
Is there any way of making objects be stable and not go in each other when landing?
Thanks in advance.
What you're describing is a well-known problem and limitation with all physics engines.
It's called stacking stability, and it always becomes a problem, if you have large enough amount of physics objects.
There isn't really a single simple solution, it's a combination of choosing the right physics engine, setting your object's properties correctly, and even putting in some custom code of your own that tries to circumvent some of the issues when possible (for example by disabling physics on elements that are too deep down on the stack, so we consider them "stable", until some point when the situation changes).
I recommend reading (and watching) this, and from there, exploring wherever the links will take you.
And as I said, keep in mind that this is ...a common problem, and sometimes hard to solve. In some complex cases (yours shouldn't be one of them, though), even impossible to solve.
(EDIT two days after the answer has been accepted, I should have written this right away, sorry) :
Oh, and I forgot (sorry about that, but hopefully you've already found out from some of the resources you read) the problem of the objects going into each other can also be influenced by some settings (max depenetration depth i think it's called in unity). Another thing that might help is outright custom code which will raycast from the object that's falling downwards, and when it detects a block at a certain distance (you'll probably want to check for distance about the size that the object can travel in 1 to 10 frames or so), it would momentarily disable the physics on the falling one, position it exactly on top of the block below, zero out the velocity, and then re-enable the physics on it. This would avoid the penetration problems, as well as the instability and vibrations that happen when the new block impacts the tower. If you, however, want the effect of that impact instability to be present in some way, you can then still manually add a physics force on the impacted block(s), and it will have the upside that you can set the size of that force yourself (instead of it being calculated from the block), meaning you'll have much more control about how significant that impact effect is, which could be very useful for game balance, since that effect is quite important for the difficulty of the game, and in general, you'll want to have this level of control over things that affect gameplay difficulty ;)

Ways to optimize conditional?

I'm making a game in Unity3D and am currently creating an AI for the enemy. The enemy needs to walk around and search for the player without running into walls.
The enemy always moves forward on it's local z-axis until it encounters an obstacle or the ray made by Raycast hits an object. When the Raycast hits an object that is part of the environment it then Raycast in all 7 directions diagonally, side-to-side and front-to-back to check for more obstacles near it as shown in this image.
The path it takes is then determined by whether or not these rays hit another object and go in the direction in which a ray didn't hit anything and that is the most optimal direction.
By most optimal I mean in the order:
fl OR fr
l OR r
bl OR br
b
I need to decide based on this data which direction to turn. If in a case where say fl and fr are both true then I would randomly decide between the two directions.
I want to optimize this process so I don't have to use multiple if-statements. I had thought of using bitmasking techniques since there are 8 directions, if you include forward, and each bit could represent a direction.
Any ideas, constructive criticism, etc is welcome. Thanks for your time.
Do not optimize pre-maturely, it is the root of all evil, as some say. This would be a perfect example.
The reason we code in C# and not in assembly (or even C) is not performance, it's readability. While it may be possible to make your code run a tiny bit faster, the results may not even be measurable. an IF branch here is still pretty tiny, and I would strongly advice against replacing it with anything else - you will loose a lot of readability, while not gaining much, if any at all performance. Bitmasking techniques start to become effective when you deal with thousands of objects (i.e. Entity), but if your if branch fits on a couple of pages, I would not touch it unless I'd find it to be a major drag by measuring it in the profiler. If you are not sure what you are doing its not that hard to make your code run slower. The priority is to make the code readable (definitely in your case as you won't be running it in a tight loop), and easy to modify. In some cases it's better to unroll the code into a more verbose if branch than to pack it into some bizarre loop - remember a loop is also an instruction.
G,day!
I have been reading a lot lately about the new path-finding system in Unity 2018. I was wondering if you had checked it out yet?
If you wanted to create it from scratch, mad props to you - however, I would be following the documentation (on the Unity website) to create an Update script on the enemy GameObject that would find the shortest path to the player GameObject's transform position, making sure to adjust for obstacles.
Have a browse around on YouTube as well - there are heaps of great tutorials.
Otherwise - if you were looking to do it on your own, the way that I would personally do it (which probably won't be the most optimal) will be though at each frame, scanning for potential paths and then finding the shortest one and acting upon it by moving the enemy based on a predetermined speed * time.deltaTime. A great visualization of the system can be found on Devon Crawford's website (link below).
Unity Documentation Link: https://docs.unity3d.com/Manual/Navigation.html
Devon Crawford's Website: http://www.devoncrawford.io/software/pathfinding

getting really bad prefomace issue in unity when trying to move more then 1000 rigidbodies in the scene

I have an object build from aprox. 1700 small cube meshes (pretty simple ones). if there are been hit i'm trying to return it to the origin a few seconds after any other objects hits it (the trigger is any other collision).
the result is between very poor performance to complety stuck.
what i tried to do so far :
limit the object to one collision trigger to avoid activation over and over again .
disable the object physics
move the object using both Physics and the transform directly.
what seems to be the problem ? can unity even handle that much objects and collisions ?
Screenshots of profiler will make easier to think a proper solution for this situation i think. I don't think any draw calls or collisions cause this problem. More about Unity3D profiler is here. You can try to handle physics in Fixed update and try different combinations of rigidbody attributes (Interpolate etc.). Goodluck.
The problem is that Physics in Unity is not a native solution. Unity uses PhysX for physics, and but of them are used like a black box so Unity doesn't know how it works under the hood. That's why all physics-based operations are complex and have rather bad performance. 1000 physics-based objects seems to much to handle by Unity3d. And it's not the only limit in Unity, for example if you create about 10 000 gameobjects (no matter which functionality they will have) they can freeze even Unity's editor.
As for a possible solution there's not much you can do:
Look through optimization guides and best practises here, here and here.
Use Unity's profiler to optimize Physics performance (try to remove physics-based "spikes")
Try to develop some system which will disable gameobject's which are not seen on scene in current moment.
Try to simplify the meshes and collider. Or try to make 1 big mesh which will split into smaller parts when you need interaction.
Try to create your own simple mathematically-based physic. I know it will be really complicated but your not universal physical solutions may have much better performance rather than PhysX.
So anyway it will be a difficult struggle.

How to make this collision detection algorithm account for all the objects at once?

Okay, so I'm trying to make a game that uses this algorithm: http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection
But I need it to calculate all the objects that could be colliding with the player object, not just one at a time. How can I do this? Or do I need to use another algorithm? Cause this one pushes you into a wall if you're between two walls.
Detecting collisions and resolving collisions are 2 separate steps. Algorithm you've mentioned detects collisions, nothing stops you to use it to detect collisions with all objects you are interested in.
Resolving collisions is more interesting process as you need to decide what each collision actually means - i.e. collision with arrow and collision with wall should cause different effects. Resolving multiple collisions (i.e. as you've mentioned "object in the corner/narrow tunnel") may require some creativity - i.e. you may have to violate what your physics calculations say and move object in some reasonable state.
One simple thing that may work is to avoid multiple collisions by making time steps much smaller. You still will run into "object in a corner" cases, but less often and may be able to have simple workarounds.

Categories

Resources