Search Unity

Lots of physics collisions slowing game down, but why exactly?

Discussion in 'Physics' started by Osirius, Jun 25, 2015.

  1. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    Hi everyone

    So I've been messing around with a kind of physics concept game which spawns hundreds of cubes which follow the player and collide with each other and you can tinker with the physics in real-time to get different effects. It all works quite nicely but there's something that's been bothering me.

    I know physics calculations are CPU heavy and wont task the GPU much but I've included GPU usage anyway.

    At the 1500 cubes mark, Task Manager is reporting 40% CPU usage, GPU-Z is reporting 20% usage, CoreTemp shows that no core ever exceeds 60% at any time and hardly any memory is being used, yet my FPS drops down to about 6. So what exactly is struggling? Is there a collision limitation within Unity? Is this a bug in Unity itself? Bare in mind, this is ONLY happening when these cubes are all colliding with each other (each has a box collider and a rigidbody). When I have 1500 of these spread out the fps jumps way back up to around 100. All the time the CPU/GPU usage barely changes.

    TL;DR - Game is lagging because of physics collisions but CPU and GPU usage is low.

    Oh, and sort of a secondary question: Does anyone know anything about Unity and Crossfire/SLI setups? I have crossfired GPUs but I've never been able to make a Unity game that utilises both.


    Can anyone shed any light on this? Thanks :)
     
  2. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    are there any scripts on the cubes?
     
  3. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    Yes. The script does:
    Code (csharp):
    1. transform.position = Vector3.MoveTowards(transform.position, Player.transform.position, Time.deltaTime * speed);
    every Fixed Update to move towards the player. I know you're not supposed to use transform.position on Rigidbodys but I used it because it seems to give the best looking result (and also seems much more efficient in my testing). The cubes float after you and then you can trigger an explosion to send them flying.
    Could the usage of transform.position be the problem? But even if it is, would it explain the CPU usage/FPS discrepancy?
     
  4. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    well, that's part of (if not entirely) your problem.

    you should never move a transform directly. That penalizes the physics system by making it perform recalculations. I assume when it realises something isnt where it should be.

    use MovePosition instead.
     
  5. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    Thanks for the suggestion!
    Changing it to:
    Code (csharp):
    1.  
    2. Vector3 direction = (Player.transform.position - transform.position).normalized;
    3.                 GetComponent<Rigidbody>().MovePosition(transform.position + direction *  Time.deltaTime * speed );
    Does increase the amount of cubes I can display (also everything does run smoother generally) but the same problem still occurs: As the framerate drops out there's no relative increase in CPU or GPU usage. I can spawn cubes until it's down to around 1 or 2FPS and the CPU usage will hover around the 40% mark.
     
  6. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
  7. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    I do, and the culprit is the Physics collisions, like I said. I use Task Manager and Core Temp to monitor overall CPU usage and individual core usage. The problem isn't what is causing the slowdown, the problem is why it's slowing down when it isn't stressing my CPU in the slightest.
    Is this a limitation within Unity?
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    As you have 1500 cubes, it becomes relatively expensive to call GetComponent <Rigidbody> in every FixedUpdate for each of them. You should definitely cache them.

    Edit: It won't make a huge difference, but as it is about performance, it definitely matters.
     
  9. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    What do you mean by caching them? I already have them set up in a pool which increased performance quite dramatically.

    The issue isn't really about whether it's expensive to call something or not (at this point in testing, the more expensive the better), the problem I'm having is why can't Unity max out my CPU with physics calculations? It only uses a maximum of 40% CPU whilst the FPS is low. Is this a limitation within Unity? Am I "breaking" the Physics engine somehow?
     
  10. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    How does the graph in profiler looks? Is there lots of peaks for example? Taskmanager might not show 100% cpu usage if its not all the time 100% whatever the interwall for measuring usage is, but i suppose game still start lagging if one frame here and there takes too long.
     
    Last edited: Jun 26, 2015
  11. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    GetComponent <Rigidbody> () is not very expensive, but if you call it so often, it sums up. By caching I mean to only call it once in Awake () or Start () and keeping the result.

    Code (csharp):
    1. private Rigidbody m_Rigidbody;
    2. private void Start () {
    3.     m_Rigidbody = GetComponent <Rigidbody> ();
    4. }
    After that you can just use m_Rigidbody instead of using GetComponent <Rigidbody> ().
     
  12. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    It's relatively stable when the FPS drops (difference in flat and peaks never seems to be more than 3ms) and it's always Physics.Processing at the top at around 55%.
    I never trust TaskManager entirely which is why I have CoreTemp measuring each core. No core ever exceeds 60% at any point.

    Ah, I get you! I changed them all (there wasn't many to begin with) but it didn't seem to affect the framerate or help with the problem, sadly :( Thanks for the help though!
     
    Last edited: Jun 26, 2015
  13. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    No one has any ideas about this?
    I gave my concept to a few friends and everyone experienced the same thing: High physics object count results in low FPS and low CPU usage.
    Is there a limit on physics collisions? Can Unity's physics engine only use a limited amount of the CPU? Does the Physics engine only allow a certain amount of collisions? Have I bugged-out or broken the physics engine in some way?

    This is starting to seem like a rather serious bug/limitation in Unity, especially as this would render Unity completely useless for any kind of physics-heavy software, especially any form of benchmarking.
     
    Last edited: Jun 27, 2015
  14. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    Have you tried vsync off?
     
  15. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    Yes, vsync has no effect on the problem.
     
  16. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Out of curiosity, if you change the maximum allowed timestep, does it allow you to use more cpu?
    Edit -> Project settings -> Time
     
    Last edited: Jun 27, 2015
  17. Osirius

    Osirius

    Joined:
    Oct 10, 2014
    Posts:
    47
    Unfortunately not. As the game starts struggling the CPU is still hovering around 40% overall and 60% on one core.

    I hadn't messed with this option before though and setting the max timestep to the same value as the fixed timestep (0.02) gave a much nicer experience at lower framerates (for heavy-physics based stuff anyway). Instead of "chugging" the whole scene kind of slowed down, same effect as lowering timescale, to accommodate and everything still ran smooth . Strangely, it did completely screw up my FPS counter and lock it at 50.

    I'm starting to think that this is a Unity limitation; it seems to be locked to a single core for physics calculations and unable to actually max out said core. Rather a serious limitation in my opinion, especially seeing as I have a third of the core left to use. By the way, the GPU is almost completely untouched throughout all of this (15% usage, max).
     
    Last edited: Jun 28, 2015
  18. Game_DevKH

    Game_DevKH

    Joined:
    Jun 11, 2017
    Posts:
    23
    Hello, I got this message when press play (Android platform)

    Target Graphics API does not support Compute Shaders. Please refer to Minimum Requirements on GPUInstancer/ReadMe.txt for detailed information.
     
  19. TurboNuke

    TurboNuke

    Joined:
    Dec 20, 2014
    Posts:
    69
    Can you get to 100% CPU usage through other means in your code?
     
  20. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Just a friendly reminder to look at the dates of a post before replying. I don't think anyone minds when a thread is necro'd when it adds new/helpful information, but this post of four years old. It's very likely the OP is no longer looking for troubleshooting steps on their issue.
     
    rahulk1991 likes this.