transform.rotation interferes with transform.Rotate
I would like to create a script for a flying player that rotates (turns) the player object along the world Y axis, and rolls (banks) the player along the local Z axis.
I am using the Kinect for motion gesture input, so this script would just control turning & banking left. I'll copy and modify it for the right sided action. I've tried many other more complicated "solutions" I found in forums that haven't worked. This almost works except for this snag.
Issue: Rotation stops at about -100 degrees. It should continue smoothly through 360 degrees. Also note that both the roll and the rotate work correctly individually, if you comment out the either one or the other.
To test this I created this minimal script...
Press S to start object rotation
Press and hold horizontal inputs to control object roll
private Quaternion newRotation;
void Update () {
float leanAngle = Input.GetAxis("Horizontal") * 20;
if(Input.GetKey ("s")){
//Rolls Player
newRotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y, leanAngle);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime);
//Rotates Player
transform.Rotate(-Vector3.up * 2 , Space.World);
}
}
Code (C#)
Answer by Glurth · Sep 24, 2015 at 01:59 PM
GetAxis returns a value between -1 and 1. Multiple this by 20 , and you will be settings your lean angle to a min/max of -20 to +20 degrees, with this line newRotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y, leanAngle);
Though I'm not sure why that line is INSIDE your if statement.
The transform.Rotate(euler_angle_parameter,Space.World) function can thought of as equivalent to: transform.roation.eulerAngles= transform.rotation.eulerAngles + euler_angle_parameter; So, using both, the rotate function AND directly assigning rotations can get a bit confusing.
Maybe try something like this (uncompiled- just an example):
Vector3 amount_to_rotate_and_turn= Vector3.zero;
amount_to_rotate_and_turn.z = Input.GetAxis("Horizontal") * 20; //we will turn this much every frame, so multiplying by 20 might be too fast of a turn
if(Input.GetKey ("s")){
amount_to_rotate_and_turn.y = 1; //we will turn this much every frame
}
if(Input.GetKey ("a")){
amount_to_rotate_and_turn.y = -1;//we will turn this much every frame
}
transform.Rotate(amount_to_rotate_and_turn, Space.World);
@Ncartist note- I edited the answer significantly, please check-out updated version (as opposed to emailed version).
@Glurth - Thank you for the response. $$anonymous$$y intent was to actually set the roll angle using the leanAngle input from the $$anonymous$$inect (i.e. a float + or - 20 around 0) rather than constantly rotating.
I also noticed that line 7 of your code (amount_to_rotate_and_turn.y = -1;) produces strange rotations in multiple axis. Did you also get that behavior?
"rather than constantly rotating." -- AH, now I see now why you were assigning a rotation to the transform AND using the Rotate function. So, rather than use rotate, might as well directly set the eulerAngles, like so...
Vector3 amount_to_rotate_and_turn= Vector3.zero; //this is now a poor variable name, but wanted $$anonymous$$imal changes
Vector3 current_orientation= transform.eulerAngles;
amount_to_rotate_and_turn.z = Input.GetAxis("Horizontal") * 20; //we will turn this much every frame, so multiplying by 20 might be too fast of a turn
if(Input.Get$$anonymous$$ey ("s")){
amount_to_rotate_and_turn.y = 1; //we will turn this much every frame
}
if(Input.Get$$anonymous$$ey ("a")){
amount_to_rotate_and_turn.y = -1;//we will turn this much every frame
}
current_orientation.z =amount_to_rotate_and_turn.z;
current_orientation.y+=amount_to_rotate_and_turn.y;
transform.eulerAngles = current_orientation;
I don't know why line 7 should produce strange rotations... it should just rotate in the opposite direction from line 4.
Excellent! Thanks so much.
I realized the reason for the strange rotations from the line starting " if(Input.Get$$anonymous$$ey ("a")){" was because the "a" key was also mapped as a horizontal input, so I was getting both rotations at the same time.
simplified/clarified edit:
Vector3 current_orientation= transform.eulerAngles;
current_orientation.z = Input.GetAxis("Horizontal") * 20; //sets to this angle "="
if(Input.Get$$anonymous$$ey ("s")){
current_orientation.y += 1; //we will turn this much every frame "+="
}
if(Input.Get$$anonymous$$ey ("a")){
current_orientation.y -= 1;//we will turn backwards this much every frame "-="
}
transform.eulerAngles = current_orientation;