- Home /
Collider Movement Script and Physics.Simulate FPS Drop
Good day dear Unity community.
My team is working on a game and we finally reached the point of finishing the map assets, which happens to be a city. I imported everything last night and started to work with it today.
After putting all assets there, lots of assets as you may see in the following picture, something expected happened: I got an FPS drop. What is odd to me is that the FPS drop (of about 160 FPS!) wasn't caused by the new assets' rendering, at least that's what the profiler said. Checking the profiler I was able to isolate the source of the FPS drop, and it happens to be my movement script.
Before I imported the assets I used the same movement script, I actually used the same scripts I have now for core gameplay testing purposes, and I noticed nothing, I had like 250 FPS, but there were no assets to truly work the rendering, so I expected a loss after the assets were imported, but now such big loss, and surely not because of the collider script.
I wasn't aware that Physics.Simulate can eat so much FPS, and checking the forunms and unityanswers, I was not the only one surprised by such, and I use a very simplistic movement script, which is possibly shadowing my judgement of what is going on... I have no idea.
Can any good soul give me a light here?
This is a picture showing the FPS difference with the script on and off, as well as the settings around,also, both pictures have directional light on.
This is the script:
#pragma strict
//Movement Calculation Variables
private var runSpeed = 2.0; //Running Speed
private var walkSpeed = 1.0; //Walking Speed
private var controller : CharacterController; //Character Controller Caller
private var hRotation : float;
var horizontal = Horizontal();
var rotationObject : GameObject;
@HideInInspector
//Function Start
function Start () {
controller = GetComponent(CharacterController); //Getting the character controller
}
//Function Update
function Update () {
//Here we calculate the movement variables
var up = cInput.GetButton ("Forward"); //Movement Button
var dwn = cInput.GetButton("Backward"); //Movement Button
var lft = cInput.GetButton("LeftStrafe"); //Movement Button
var rgt = cInput.GetButton("RightStrafe"); //Movement Button
var aim = cInput.GetButton ("Aim"); //Aim Setting
var run = cInput.GetButton ("Run");
var rotation = cInput.GetAxis("Mouse X");
if (up && dwn) return; //Conflict Move Cancel
if (lft && rgt) return; //Conflic Move Cancel
var i = 0; //Aim Movement Variable
if (run)
i = 1;
if (aim)
i = 0.1;
var move = Vector3.zero; //Our Movement Variable
if (up)
move += transform.forward; //Forward Move
if (dwn)
move -= transform.forward; //Backward Move
if (rgt)
move += transform.right; //Right Move
if (lft)
move -= transform.right; //Left Move
if (rotation)
transform.Rotate(0, rotation * 2, 0);
if (i == 0)
move *= walkSpeed;
else if (i == 1)
move *= runSpeed;
else if (i > 1)
move *= walkSpeed;
controller.SimpleMove(move); //Movement Variable
hRotation += cInput.GetAxis("Mouse X") * horizontal.mouseSensitivity ;
hRotation = AngleClamp( hRotation, horizontal.minimumAngle, horizontal.maximumAngle);
rotationObject.transform.localEulerAngles.y = hRotation;
}//End of script
function AngleClamp ( rotation : float , min : float, max : float) {
if(rotation < -360)
rotation = rotation + 360;
if(rotation > 360)
rotation = rotation - 360;
rotation = Mathf.Clamp(rotation, min, max);
return rotation;
}
This is the picture of both scenarios:
Since now I appreciate the attention and help.
Does the city have one big mesh collider? The general practice, I believe, is to $$anonymous$$imize the use of mesh colliders where possible by replacing them with primitive colliders like box colliders. If this is one big mesh with one big collider, the physics system will suffer when querries are made of it, such as when it is interacted with by any operation, like charactercontroller's internals.
I'd think you could prove to yourself quickly whether an overly complex mesh collider is the source of the problem by throwing in a bunch of rigidbody primitives and watching the performance before they sleep.
I believe so, I used the Generate Colliders from the important setting to all imported meshes but characters and enemies. $$anonymous$$y main big mesh is the City Layout, which is the whole of the walkable streets in the city, and that's pretty big, however, I don't believe they're the source of the problem because the performance does not improve it I remove the collider from it and just let my character fall down to the infinite, also, the performance also doesn't change if I move the character to somewhere with just a simple plane. The only lead I have now is that the performance returns to ''normal'' if I disable the script.
EDIT: Oh yeah, one thing that I can add, the City Layout was there in the project while I had the ''normal'' fps.
Try to comment out the call to Simple$$anonymous$$ove() to deter$$anonymous$$e whether that's the source?
No, no real change. I dismembered the script part by part and nothing happened... This is making me absolutely confused... I'll write a new script just for the movement and see if I can figure out something.
----EDIT: I managed to isolate the source of the fps drop within the script, it is contained in this line of code:
rotationObject.transform.localEulerAngles.y = hRotation;
I use this part of the script to rotate the character around, allowing for a change of direction... While I cannot understand why it is the source of the problem, at least I have the source of the problem and can work to create an alternative.
I appreciate the help you gave me, many thanks.
----EDIT: I remade the script without the rotation part, but now I added the Simple$$anonymous$$ove component, and guess what? The FPS goes all the way down again.
Err, I can't see that you're calling Physics.Simulate anywhere in the script you posted?
Also, it makes no sense that setting the rotation of the object should take a bunch of time, unless the rotationObject is something like a gigantic mesh collider, and you're rotating the world ins$$anonymous$$d of the character.
Answer by devluz · Oct 30, 2014 at 12:01 AM
I read that there are performance issues with moving colliders if they aren't rigidbodies at the same time.
Try adding a kinematic rigidbody to your character. Not sure if it helps but trying should only cost a few seconds :)
Huh... This bring the expression ''the hell just happened?'' to whole new levels... it worked!
I don't quite understand why, always thought that Rigidbodies and Character Controllers would conflict if used at once...
Well... I've always heard that part of coding is NOT knowing how stuff happened...
$$anonymous$$any thanks devluz, I really appreciate the help.
Glad I could help. I read a while ago a blog about unity 5 where they want to solve that problem. Current unity versions expect collider without rigidbody to be stationary. If you move them they have to recalculate internal structures which are needed for collision detection (if I remember correctly).
Anyway, even the standard assets don't use rigidbodies and the documentation doesn't explain anything ... Guess that is the real problem ;)