I am trying to create a ship controller that will rotate the ship for roll and pitch. It’s a hard concept for me as I don’t fully understand what yaw is either. But that is besides the point, I think.
The issue I am having is that if I rotate around the z axis, I can limit rotation to 30 degrees, creating roll. I can then rotate around x axis and limit the rotation to 15.
Both work fine. I think I was pulling the local angles to check for the limit.
The problem is when I rotate around both, the object begins to tumble.
Sorry I have scrapped the old code so all I have left is this explanation. I’ve tried a ton of different approaches but cannot seem to solve this.
Can anyone point me in the right direction? Links or functions to use? An explanation of how to limit the amount of pitch and roll? I don’t really want code … I want to be able to understand this kind of stuff so I can apply it to future controllers.
Thanks
azmundai
Ok I think I have this working. I actually switched to rotatearound … again (i had tried it before but it had a similar problem) … it was still not resetting the rotation right until I added the slerps. Any other suggestions welcome
EDIT 1 : took out some bools I didn’t need, added comments.
using UnityEngine;
using System.Collections;
public class GliderControllerTwo : MonoBehaviour {
public float moveSpeed = 1.0f; // Speed at which glider is moving
private int maxSpeed = 64; // Maximum Speed of glider (when pitching forward).
public int glideSpeed = 32; // Gliding Speed (neutral stick)
public int turnSpeed = 50; // Speed glider turns; rotates
public float rollSpeed = 2.0f; // Speed at which model rotates when rolling.
public float pitchSpeed = 1.2f; // Speed at which model rotates when pitching.
public float altitudeChangeSpeed; // Speed at which model is changing altitudes
public int upSpeed = 24; // Maximum Speed when pulling back on stick; pitching up
private bool slerped; // bool to prevent double slerping
public float roll; // amount to rotate on the z axis
public float pitch; // amount to rotate on the x axis
public float rollAngle; // amount the glider model has rotated on the z axis.
public float pitchAngle; // amount the glider model has rotated on the x axix.
private float maxPitch = 0.15f; // maximum angle to pitch model
private float maxRoll = 0.35f; // maximum angle to roll model.
private Vector3 moveDirection = Vector3.zero; // x y z movement amounts
public CharacterController controller; // the character controller
private Transform playerModel; // the model or parent of the model. child of object containing controller.
// Use this for initialization
void Start () {
controller = GetComponent<CharacterController>();
playerModel = transform.FindChild("PlayerModel");
}
// Update is called once per frame
void Update () {
slerped = false;
roll = pitch = 0;
// Prevent Slerp when pitching or rolling
if(Input.GetAxis("Horizontal") != 0) rolling = true;
if(Input.GetAxis ("Vertical") != 0) pitching = true;
// Roll Right when player stears right if roll angle doesnt exceed max roll
if( (rollAngle + (Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime) < maxRoll) && Input.GetAxis("Horizontal") > 0){
roll = Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime;
rollAngle += Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime;
}
// Roll Left when player stears left if roll angle doesnt exceed max roll
if( (rollAngle + (Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime) > -maxRoll) && Input.GetAxis("Horizontal") < 0){
roll = Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime;
rollAngle += Input.GetAxis("Horizontal") * rollSpeed * Time.deltaTime;
}
// Pitch Back when player pulls back if pitch angle doesnt exceed max pitch and slow speed
if( (pitchAngle + (Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime) < maxPitch) && Input.GetAxis("Vertical") > 0){
pitch = Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime;
pitchAngle += Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime;
altitudeChangeSpeed = Mathf.Lerp(altitudeChangeSpeed, 10, 0.1f);
if(moveSpeed - 1 >= upSpeed)
moveSpeed--;
}
// Pitch Forward when player pushed forward if pitch angle doesnt exceed max pitch and increase speed
if( (pitchAngle + (Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime) > -maxPitch) && Input.GetAxis("Vertical") < 0){
pitch = Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime;
pitchAngle += Input.GetAxis("Vertical") * pitchSpeed * Time.deltaTime;
altitudeChangeSpeed = Mathf.Lerp(altitudeChangeSpeed, -10, 0.1f);
if(moveSpeed + 1 <= maxSpeed)
moveSpeed++;
}
// Roll Back towards neutral when player not turning. Slerp when not pitching or rolling.
if( Input.GetAxis("Horizontal") == 0 ){
if( rollAngle - (0.5f * rollSpeed * Time.deltaTime) > 0 ){
roll = 0.5f * -rollSpeed * Time.deltaTime;
rollAngle -= 0.5f * rollSpeed * Time.deltaTime;
} else if( rollAngle + (0.5f * rollSpeed * Time.deltaTime) < 0 ){
roll = 0.5f * rollSpeed * Time.deltaTime;
rollAngle += 0.5f * rollSpeed * Time.deltaTime;
} else if(Input.GetAxis("Vertical") == 0 && Input.GetAxis("Horizontal") == 0){
playerModel.rotation = Quaternion.Slerp (playerModel.rotation, transform.rotation, Time.deltaTime * rollSpeed);
slerped = true;
}
}
// Pitch Back towards neutral when player not pitching. Slerp when not pitching, rolling or slerping in horizontal.
if( Input.GetAxis("Vertical") == 0 ){
altitudeChangeSpeed = Mathf.Lerp(altitudeChangeSpeed, -6, 0.1f);
// Ramp up to glide speed
if(moveSpeed < glideSpeed)
moveSpeed += moveSpeed * Time.deltaTime;
if(moveSpeed > glideSpeed)
moveSpeed = glideSpeed;
if( pitchAngle - (0.5f * pitchSpeed * Time.deltaTime) > 0 ){
pitch = 0.5f * -pitchSpeed * Time.deltaTime;
pitchAngle -= 0.5f * pitchSpeed * Time.deltaTime;
} else if( pitchAngle + (0.5f * pitchSpeed * Time.deltaTime) < 0 ) {
pitch = 0.5f * pitchSpeed * Time.deltaTime;
pitchAngle += 0.5f * pitchSpeed * Time.deltaTime;
} else if (!slerped && Input.GetAxis("Vertical") == 0 && Input.GetAxis("Horizontal") == 0)
playerModel.rotation = Quaternion.Slerp (playerModel.rotation, transform.rotation, Time.deltaTime * rollSpeed);
}
// set move direction from speeds
moveDirection = new Vector3( 0, altitudeChangeSpeed, moveSpeed );
// roll and pitch child.
playerModel.RotateAroundLocal(Vector3.forward, -roll);
playerModel.RotateAroundLocal(Vector3.right, -pitch);
//transform direction
moveDirection = transform.TransformDirection(moveDirection);
// rotate transform when turning
transform.Rotate(0 , Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime, 0, 0);
// move controller
controller.Move(moveDirection * Time.deltaTime);
}
}