What I want to do is simple in principle, but proving to be a bit of a pain. I want my (third person) character to walk forwards and backwards then when I use the left and right keys rotate rather than move in that direction as per the current Third Person Controller.
I’m getting a little tied up with the various relationships between scripts, but I did try to put together a physics based character movement. This worked fairly well, but it was awkward trying to control sliding … great for simple cars, not so great for characters. Alongside this, I have to apply custom gravity to keep the player from ‘floating’ over slopes etc. - it would be nice to have the same kind of control over slopes as the ‘out of the box’ behaviors that come with Unity.
I’ve tried a few things and come up against problems with forcing rotations on rigidbodies …
Has anyone put anything like this together who could give me some pointers on how to go about it?
rigidbody.freezeRotation is your friend (Exposed in the inspector too). You basically want to let physics handle the position and you handle rotation explicitly by using transform.Rotate. When frozen the physics simulation will simply not affect your rotation.
That works great for rigidbody based character controls. The advantage is that it interacts with other physical objects very well. Eg. if you have a lot of joints in your environment or moving physical parts, you can easily make your character stand on it, push things down and be affected physical when something hits him etc.
That path requires some tweaking to make it feel good when slowing down the character. You specifically don’t want to use drag for this (Otherwise it feels wrong in air) but apply counter forces to slow the character down.
I’ll take a look at improving my current physics based character … for sure, using the drag wasn’t a good option when it came to jumping or big slopes. Counter-forces may well be the answer.
I’ll also take a look at the camera script there, since I’d like to try out both methods and see which gives the best final effect.
I appreciate the input a lot, as I’m still figuring out the whole wondrous beast that is Unity!
Btw. for slow down forces you want to use ForceMode.VelocityChange.
That way you can work in units that are sensible and directly relate to the current velocity.
Much appreciated. I managed to solve it by using a capsule for collisions and the Root of the character manually setting it’s position to the capsule, but remaining independent on the rotation.
That way, I can rotate the character and use its forward transform to move the capsule. Dealing with the sliding issues, well, I found some code on the Wiki that helped keep them under control:
// Calculate how fast we should be moving
var targetVelocity = pointer.transform.forward * Input.GetAxis(“Vertical”);
targetVelocity = transform.TransformDirection(targetVelocity);
targetVelocity *= speed;
// Apply a force that attempts to reach our target velocity
var velocity = rigidbody.velocity;
var velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
Again, thanks for the awesome help guys! It works great
Good. Just wondering, why don’t you rotate the capsule itself using transform.Rotate, then you don’t need to rotate the child.
(When rotation physics is frozen, you can still update the rotation manually)