- Home /
[C#] Game runs oddly slow
BRIEF SUMMARY
I wrote a single-thread physics engine in C# and compiled it into a DLL.
The engine and my Unity game by themselves can be run on a single core at the same time (I tried to put both processes' affinity to the same core and they run without any problem), but when I call my engine from within a MonoBehavior things get super slow.
Can anyone help?
DETAILS
I have some code which is quite "fast" when outside Unity, but gets very slow if I use it inside a game.
I am working on a physics engine in C#, which I developed and tested without Unity, and doesn't use any Unity type.
After I got to a milestone, since I needed to draw the scene in 3d, I decided to plug the engine into Unity. So I created a dll and a scene with an empty object (which I will call Simulator), a camera and a cube with a rigidbody. I added the following script to the Simulator:
public class Simulation : MonoBehaviour
{
World world;
void Start()
{
/* initialization logic, not important */
world = new World();
}
void FixedUpdate()
{
world.Update(Time.deltaTime);
}
}
"World" is a class I imported from my dll, and world.Update(..) performs one step of update in my physics engine (which is single-threaded, if that might help). The constructor initializes a lot of objects and other things (this is just to say: it's not empty in this example).
I am not drawing the content of my engine because I wanted to test for physics performance before that.
Now the thing is this:
Before embedding the dll in a Unity game, I put it in a test C# project (just console), and I could run the world.Update() method at 60fps taking 18% of my CPU (again, single thread). This was true only if I ran it with all the compiler optimizations (i.e. Release, not Debug profile)
The Unity game itself consumes around 2-4% of CPU time when I don't execute the world.Update() inside it, by disabling the Simulator object
However, if I leave the Simulator enabled, the game runs SUPER slow, I'd say around 0.5 fps. And I'm not drawing anything except for a falling cube, which I already tried disabling, and I keep only to test for framerate.
I already tried switching to the Update() instead of FixedUpdate(), which made little difference, if any.
I also built the game into a release package for Windows and run it at lowest graphics possible, with the exact same result.
The DLL is pre-compiled for .NET 3.5 in Release mode, and imported into Unity as an asset.
Could anyone explain this to me? I am at a loss.
My theory is that Unity "doesn't like" a single fixed update to take almost all of a fixed frame, even though I know it takes less than 16 ms, but I can't think of a reason why that would happen (again, I can run the two codes on the same core in separate processes both at 60 fps T_T).
Also, as I said, using Update instead of FixedUpdate led to no improvement.
MY SPECS
OS: Windows 8.1
Processor: i5 dual-core, 2 threads per core
Ram: 8 GB
Graphics Card: Mobility Radeon 5470 512MB
I know it's not a monster PC, but I don't think it matters in this case.
EDIT:
I also tried compiling my engine for .NET 2.0, to check if that was the problem (I was compiling for .NET 3.5), but nothing changed. If I use a stopwatch to measure the time it takes to complete a world.Update(), I get 10 ms in a test console project (on average), while with Unity it takes 18 ms.
Also, I tried to change the Time settings in Unity, trying 16, 20 and 30 ms fixed timesteps, with no luck (which is even weirder because with 30ms the world.Update() takes only half of the frame and still it doesn't go smoothly).
Answer by Atonez · Sep 24, 2014 at 01:52 AM
I have written scripts before and attached them to an gameobject, and it was colliding with another rigidbody which made it slow down or "lag". see if there is another rigidbody that is colliding with what you have attached your script with. *
Sigh, it didn't change anything. I tried to move the Simulator away with no result. The problem is that the only rigidbody (and the only collider, for that matter) is on the cube, which is far from anything else and I can even remove it without any gain.
Answer by Seneral · Oct 09, 2014 at 07:17 AM
I know this list is VERY long but that could be a reason for this. Unity uses a custom build of Mono and there might be compability issues: http://docs.unity3d.com/410/Documentation/ScriptReference/MonoCompatibility.html
Hi, thanks for the link, but I double checked.. I am already building against .NET 2.0, and the only .NET classes I am currently using are Dictionary, List and Queue (plus String and StringBuilder in the ToString overrides).
The Unity project is set to use the full .NET 2.0, and I build it for Windows Desktop, so I don't think that's the problem either.
$$anonymous$$aybe the custom build of $$anonymous$$ono is less efficient for some reason
Your answer
Follow this Question
Related Questions
Improve Script Performance Physics 2 Answers
Why Do Inputs Have to Been in Update (Rather than FixedUpdate)? 3 Answers
Distribute terrain in zones 3 Answers
What is the reason of FixedUpdate() being invoked more than 1 time on low framerate ? 2 Answers
Understanding Raycast How Actually works in Unity [As Algorithm] 2 Answers