- Home /
Unity Simulate Local Rotation
I've run into a situation where I need to be able to use a relative Y rotation for my player. This is so the player can walk on walls, floors, and ceilings and operate "the same way" regardless of actual rotation (I've already got gravity and such sorted out). The game in which I'll be using this is an FPS if that info is relevant.
I came across this: http://answers.unity3d.com/questions/518399/simulate-child-parent-relationship.html
But it doesn't quite apply to what I'm trying to accomplish.
This is my present code for turning the player, but it isn't suited for different orientations (it successfully works between a floor or ceiling for obvious reasons though).
angle = new Vector3(_yMouseAxisLocked ? transform.localEulerAngles.x : currentYPos += yCoord,
xMouseAxisLocked ? transform.localEulerAngles.y : currentXPos += xCoord,
transform.localEulerAngles.z);
transform.localRotation = Quaternion.Euler(angle);
Ideally, I'd be able to pass the resulting Vector3 in the above code into a method that does the work of figuring out what value each axis should be set to based on the players current orientation.
Something like:
Quaternion RelativeRotation (Quaternion baseRotation, Quaternion relativeRotation){
// Do math
// return final result
}
My usage of the method would look something like
angle = new Vector3(_yMouseAxisLocked ? transform.localEulerAngles.x : currentYPos += yCoord,
xMouseAxisLocked ? transform.localEulerAngles.y : currentXPos += xCoord,
transform.localEulerAngles.z);
transform.localRotation = RelativeRotation(Quaternion.Euler(_rotation), Quaternion.Euler(angle));
Its been quite a puzzle trying to find anybody in the same boat as me. I'll admit I'm not math savvy or that knowledgable when it comes to Quaternions.
This image should clarify the application of this.
Note: Take no mind to my present code using local rotation. The script this is from runs on game objects with parents, and game objects without parents. A check will be added to determine if the game object has a parent or not.
Edit:
Started toying with the following code. Only partially works when on walls, If I look at a veiwing angle greater than 45 degrees either direction the player starts spinning out of control.
if (isOutsideGameObject) {
angle = new Vector3(_yMouseAxisLocked ? transform.localEulerAngles.x : currentYPos += yCoord,
_xMouseAxisLocked ? transform.localEulerAngles.y : currentXPos -= xCoord,
transform.localEulerAngles.z);
Quaternion startParentRotationQ = Quaternion.Euler(new Vector3(
!_yMouseAxisLocked ? angle.x : 0, !_xMouseAxisLocked ? angle.y : 0, 0));
transform.rotation = (Quaternion.Euler(player._rotation)
* Quaternion.Inverse(startParentRotationQ))
* startChildRotationQ;
} else {
angle = new Vector3(_yMouseAxisLocked ? transform.localEulerAngles.x : currentYPos += yCoord,
_xMouseAxisLocked ? transform.localEulerAngles.y : currentXPos += xCoord,
transform.localEulerAngles.z);
transform.localRotation = Quaternion.Euler(angle);
}
Best general advice might be to learn about using a Local Frame of Reference (just general math); and how, in Unity, to use Quaternion.FromToRotation, Quat.Inverse and transform.transformPoint and inverseTransformPoint, to go between global and local frames of reference.
I'm also a little puzzled by the use of += inside those ?:'s. That's one of those things which could be incredibly clever, but is really almost always not what you wanted.
Your answer
Follow this Question
Related Questions
Complicated Rotation Issue 1 Answer
Camera Rotation Question 1 Answer
Rotating multiple points in space. 0 Answers
Rotating on a plane 2 Answers
Quaternion lerp is not rotating my object to the desired rotation? 1 Answer