- Home /
Why my framerate fall down to 5-6FPS once I use CharacterController.Move()
I need to make several enemies (AI) move.
Once I use CharacterController.Move() or CharacterController.SimpleMove(), the framerate would gradually fall down to 5-6FPS (SimpleMove() would be a little better, but still not acceptable).
But if I simply use Transform.Translate(), the enemies would not be able to climb/descend along the terrain. They would rather penetrate into the terrain.
So anyone could help me find out a way out of this issue?
Answer by justbecrazy · Aug 10, 2011 at 03:51 PM
I finally got it!!!!!!!!!!!!!!!!!!!!!!!!!!!!After one whole day work,at last!!!!!!!!!!!!!!!!!!!!!!!!
It's all about the setting of my CharacterController. I used to set it too large in Height,Radius,....all other parameters, because my model imported is big.
And then I changed all of these stuff back into the values suggested in the official Reference page. And the FPS now is 80+ for 10 enemies!
Oh yeah!!
From weedhopper to Jedi knight with a simple click! Go with the force...
Of all the parameters, the most crucial one is Radius. It would significantly drag down the FPS if it gets larger. Could someone tell me why?
Holly crap, you're right! I had a small model that I scaled. I set the Character Controller radius to 0.5 so it matches the sizes of a model and got 50 fps drop on Simple$$anonymous$$ove() call. Now when I set radius to 0.15 I get 70 fps again.
Unity should address this issue I$$anonymous$$HO.
Had you Scaled those Enemies programatically or You have Created a new Prefab's of Enemy with required sizes. I had Scaled those objects in my Prefabs only and saved them as new. For FPS should i care in these case of scaling ?
Answer by aldonaletto · Aug 09, 2011 at 06:09 PM
There must be something wrong - the CharacterControllers would slow down Unity this way only if you had an entire enemy army! I bet on some coroutine being continuously called in your AI - this creates an always increasing number of coroutines running in parallel, which gradually slows down your game.
Post your AI script - only analyzing it we can help you to find the culprit.
Thank you very much! 1.They're more or less 25 enemies right now. And I guess it would be 50 at maximum. Would that be too much to use CharacterController.$$anonymous$$ove()?
2.Do I have to use FixedUpdate(), ins$$anonymous$$d of Update(), to call CharacterController.$$anonymous$$ove()?
I don't believe 25 enemies could slow down your game this way (unless it's a mobile device game - is it?)
You must use FixedUpdate to do rigidbody things (to add a continuos force, for instance), since the physics engine syncs with FixedUpdate. But the CharacterController doesn't use the physics engine, so it's better to keep it in Update. I really suspect that some out-of-control yield or StartCoroutine is the responsible for your problem.
Its not about the number of physical enemies but about the number of parallel processes going on.
That's what I think too. This often is caused by coroutines being called at each Update - they are like the butler in these cases: always the first suspect. @justbecrazy, post your script, or you will just be driven crazy!
Hi @aldonaletto and @overunity3d , Thank you vey much! I didn't use yield or StartCoroutine in any of my scripts, nor it's a mobile game. Here's my scirpt:
protected void Update ()
{
Walk(targetNodeTr.position);
}
protected void Walk (Vector3 targetNode)
{
float speed = Time.deltaTime * walkSpeed;
Vector3 forward =myTransform.TransformDirection(Vector3.forward);
myTransform.animation.Play("run");
myTransform.LookAt(targetNode);
myTransform.GetComponent《CharacterController》().$$anonymous$$ove(speed * forward);
}
protected void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.transform == targetNodeTr)
{
if (targetNodeTr.position == enemyEndPoint)
Destroy(gameObject);
else if (pathIndex < pathList.Count-2)
{
pathIndex++;
GameObject targetNodeGO = GameObject.Find (pathList[pathIndex].ToString());
targetNodeTr = targetNodeGO.transform;
}
}
}
Answer by overunity3d · Aug 10, 2011 at 02:50 AM
Just an overview here:
myTransform.animation.Play("run");
You are doing this every update. Is the animation shorter than an update cycle? Is the 'run' cycle really necessary this quickly?
If the animation is several frames then you want to call this at a slower rate.
Hope I called this correctly.
Answer by overunity3d · Aug 10, 2011 at 03:13 AM
put a Debug.Log() in each if and else statement. The maniac activity should show up in the console. If it doesn't then you got bigger problems than Answers.unity.
Rightnow I'm thinking about it's about the number of my enemies, because I changed this number to 1, and the FPS stays in 40+.
But it would be impossible to make my game only 1 enemy at a time. So do you guys have some ways to fix this?
Big thanks!!!
But if I increased the enemies' number up to 5, the Fps started to fall down to lower than 20FPS.
Answer by husbandofemily · Feb 25, 2012 at 06:36 PM
for changing the radius of the capsule. I only have one enemy in the scene, and the CharacterController only gets called if the Player is too close. The only things in the function are transform.LookAt (player) and SimpleMove (direction*Speed). Changing the radius of the CharacterController from 0.02 to 0.01 solves my slowdown issue (that only happens when you get too close to the NPC, and the chase function is called) HTH Ian