- Home /
Rotating my character only while moving in a 2D plane
Hi everyone. I've spent about 6 hours now trying to figure this out... I've tried so many different versions of code and nothing seems to work. I'm creating a 2D side scroller and when my character moves I want him to rotate around. Think of sonic the hedgehog when sonic spins and rolls. Or even just think of a sphere that rotates in the direction you move it. I want my character to spin at a very fast rate. I've tried adjusting torque and force to my rigidbody over every axis and all that does is make him very choppy; it does not affect his rotation at all. I'm doing something wrong wrong and reaching out in hopes someone might be able to lend a hand. Anyone have any solutions, code snippets or tips using Java?
are you using the position and rotation in the same control object?
yes i'm using position and rotation in same control object... i'm using a modified version of the platform controller
Answer by aldonaletto · Jan 10, 2012 at 11:48 PM
You should use the actual velocity to calculate the rotation, and use transform.Rotate to make it spin. If your character is a rigidbody, you can use:
var factor = 120; // degrees per meter
function FixedUpdate(){ var angle = rigidbody.velocity.x Time.deltaTime factor; transform.Rotate(0, 0, angle); } This will rotate the character in the direction it's moving in the X axis (invert angle sign if it spins to the wrong side). You can adjust factor to get the spinning velocity you want.
NOTE: Set rigidbody.freezeRotation=true at Start to avoid interference from physics rotational effects.
EDITED: Well, since you're using a CharacterController, things must be somewhat different: you must child your model to the character object and rotate it proportionally to the distance travelled each Update (model script):
var speed: float = 120; private var lastPos: Vector3;
function Update(){ var dist = transform.position - lastPos; lastPos = transform.position; var angle = dist.x * speed; transform.Rotate(0, 0, angle); }
I understand what you are telling me to do but perhaps there is something conflicting with this code already written. I'm using the standard character controller script (slightly modified) to control my character. When you note to set the rigidbody.freezeRotation = true at start... do you declare this at top of file or under the Awake function?
Character Controller mixed with a rigidbody doesn't work very well from what I've read...
but as for the rotation freeze, you can set that in the inspector panel on your rigidbody contraints , or in Start() like @aldonaletto suggested.
I had a feeling this was the issue. I'll just write my own character control script. Was trying to cut a few corners but it will probably be easier if I do it this way. Thanks for the help guys
The code above actually rotates the character proportionally to the distance walked. To make this work with a CharacterController, you must measure the distance walked between Updates and rotate the character proportional angle - but there's a big problem: rotating a CharacterController is a recipe for disaster. To avoid problems, you must child the model to the character and rotate only the model. I'll edit my answer to include this CharacterController alternative.
Thank you for the tips. So I made the character mesh the child to the character object and I created a new script for the character to rotate and applied it to the character object. I changed the vector 3 to (angle, 0, 0) so it rotates the way I wanted it to but other than that the code you provided for me is definately helping me get on the right track! The only issue is that my character now stops rotating when he turns 90 degrees on his axis and just moves along at that angle. The character does not continually rotate. I'm sure there's a quick fix and I'll try and figure out a way for him to continually rotate... basically whatever direction he moves I want him to continually rotate when he's being controlled... not just rotate 90 degrees and stay fixed in that position hehe... I probably wasn't too clear but you've been a huge help so far! Thank you!
Answer by stingman · Jan 14, 2012 at 05:03 AM
fyi what aldonaletto wrote works correctly for anyone trying to do this w/ a character controller. Just make sure you adjust the rotate smoothing to 0 and the speed smoothing to a small value (I set it to 0.2) The roll effect works like a charm! :) Thanks again!
Answer by ReytheRed · Mar 23, 2014 at 04:07 AM
The best solution may be to separate the visual representation from the physics representation. Keep the rigidbody and collider as they are, but have the visible mesh be a component of a child object, then use transform.Rotate on it.