A thing to consider - physics in Update() vs FixedUpdate()

Hi guys, first let me introduce myself :slight_smile: my name’s Hubert, I’m a game programmer with some experience (mostly C++), though I’m new to Unity.

I’ve been reading in documentation and on forums that the proper way of doing physics in Unity is to put all the physics code inside FixedUpdate() and everything else in Update().

Sound’s ok in theory, but in the case of PlayerController which has a camera attached to it (through spring), doing it like this:

/*
Perhaps you recognize that it's slightly modified code taken from one of the official tutorials, so I'd expect it to work properly :)

IIRC initally everything was in FixedUpdate
*/

var walkSpeed = 6.0;
var runMultiplier = 1.25;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

function FixedUpdate()
{
	// Apply gravity
	moveDirection.y -= gravity * Time.deltaTime;
	
	// Move the controller
	var controller : CharacterController = GetComponent(CharacterController);
	var flags = controller.Move(moveDirection * Time.deltaTime);
	grounded = (flags  CollisionFlags.CollidedBelow) != 0;

}


function Update()
{

	if (grounded)
	{
		// We are grounded, so recalculate movedirection directly from axes
		moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		
		// following line makes movement player orientation dependent
		//moveDirection = transform.TransformDirection(moveDirection);
		moveDirection *= walkSpeed;
		
		if (Input.GetButton ("Jump"))
		{
			moveDirection.y = jumpSpeed;
		}		
				
	}

}

@script RequireComponent(CharacterController)

… introduces subtle jarring movement of the player.

You can see it by yourself in this simple prototype:

http://student.agh.edu.pl/~koshmaar/shared/echo/prototype001.html

Jarring is visible with a fixed timestep = 0.02 (default value), but after increasing it to 0.01 the movement is smooth. I don’t want to change “Fixed Timestep” because it is a global value, so it will have global effect on all physics code - player, enemies, bullets etc possibly a lot of stuff, so by “fixing” the problem in this way, I would be possibly slowing down the physics by 50%.

I’m new to Unity and perhaps it’s acceptable, or the prefered way of doing, but personally it seems to me more like a hack than a fix.

So I was looking for another solution. After moving the code from FixedUpdete() to Update(), the problem has been solved - player movement is very smooth.

However, I’m not sure whether it’s a good way of solving the problem - perhaps Unity / PhysX make some (presumably important) assumptions about the update order, which become invalidated at this point, and certain things in certain areas might not work as expected in the future, making hard to find bugs. Also, is it a viable solution for multiplayer games?

Thanks in advance

Then the problem is solved, no?

Whether or not spending 2X the CPU time on physics entirely depends on the effect on framerate.

With the current state of my project, moving from 20Hz to 1000Hz physics update does not lower the framerate at all, but of course I do run on a 2.8Ghz Core2Duo, which helps a lot.

Note that on today’s machines game performance is GPU-bound and the CPU is generally sitting around with nothing to do most of the time. Running at 1280x800 with a 1000Hz update I see that CPU usage is only 40% (out of 200%). Once I have more active objects this may go up, and my machine is high spec for the market, but it’s a good idea to make engineering decisions based on experiments and not assumptions.

Subtle is almost an understatement. It’s pretty annoying for the eyes.

Hmm, for example here my game runs at 75fps, but the Physics update runs with 50fps (timestep=0.02s), so for every third frame there is no physics update.
If you reduce the physics timestep to 0.015s, roughly every 8th frame won’t have a physics update. That’s better but not really a solution, not only because it depends on the framerate…

Thank you guys for replies, unfortunately lately I was burried under other projects and had no time to reply.

Hehe, not really :slight_smile:

The thing I’m worried about is that in this way everything in physics is updated twice as often and perhaps that’s not needed, because only the player is causing problems. Perhaps other entities won’t be observed so much and won’t be as big (ie bullets) so it’s not worth spending cycles on giving them smoother animation. Therefore, it’s not a question whether changing timestep solves the problem, but it’s a dillema - it solves the player jarring movement at a price of 100% increase of physics update of everything in game.

It’s completely another story whether it’s acceptable or not to do it, based on FPS behaviour. For me going this route sounds like a bad idea because IMHO it’s wasting of cycles.

True, I agree about the CPU vs GPU utilization. Also, I know that the premature optimization is the root of all evil etc. But still, if one chooses to work around some problems very early in the production of the game, later he might find that all he can do about low FPS is to say to players “buy better computers”.

That’s why I’m asking about the alternative way of doing physics in Unity… anybody got any positive experiences with using physics update code (ie Euler integration) inside Update()? How about mixing some objects with FixedUpdate() and some with normal Update()? How about multiplayer??

Also, btw, how it is possible to have 1000Hz update - for me it means that the physics would be updated every 1ms which AFAIK is impossible.

Hmmm, it’s not really annoying for me on my pc (2 Ghz, decent video card = more than 150 fps in editor), but it’s good to know that there are setups which cause problems. Perhaps you could share what are your specs and fps so that we will know whether it’s caused by low fps, or is it sth wrong on my part :]

Point taken about reserving some performance leeway for end-stage development!

:shrug: I my experience things measured in microseconds are usually insignificant, only when we’re talking millisecond scale do I get interested.

2Ghz Core2Duo is the basic baseline on Macs these days so 1000hz is 4Mhz per cycle. I don’t have sound or anything going so the CPU is mostly sitting around.

But yeah, I put 14 fully physic-ed cars on my track and found my framerate go from 80 to 20 with the CPU pegged at 95% (out of 200%).

Backing off from 1000 to 500hz gave me 40fps, and 60fps came at around 166Hz, and the same at 100Hz update, indicating that 60fps is the GPU limit with 14 cars and 150hz about right for the update step.

I admit that 1000hz is kinda silly.

Here it runs on a Quadcore and GeForce 8800 GTS, so the hardware should not be the problem. I guess, the 75 fps come from VSync… and I was talking about my own project, but it’s the very same problem.