- Home /
how to tilt boat on turning
I have my boat set up like this:
Player
---boat
---camera
i have two scripts. One on the Player parent to rotate and move forward and backwards:
//DEBUG VARIABLES
var currentVelocity = 0.0;
//---------------
var thrust : float = 100;
var rotSpeed : float = 35;
var thisRBody : Rigidbody;
var maxTilt : float = 10;
function Start () {
thisRBody = GetComponent(Rigidbody);
}
function Update () {
//Get input value of axis (vary between 0 - 1.20)
var vAxis : float = Input.GetAxis("Vertical");
var hAxis : float = Input.GetAxis("Horizontal");
//Lower speed for reverse
if(vAxis < 0){
vAxis = vAxis/2;
}
//Apply forces to forward(up-down) and torque(left-right rotation)
thisRBody.AddRelativeForce(Vector3.forward * vAxis * thrust);
thisRBody.AddRelativeTorque(Vector3.up * rotSpeed * hAxis); //<---- this is the line that messes it up
//Make it harder to turn as speed increases
currentVelocity = thisRBody.velocity.magnitude;
var X = currentVelocity/1.20;
thisRBody.angularDrag = Mathf.Lerp(8,15,X);
}
and for the boat:
var originalRotation : float;
function Start () {
originalRotation = transform.rotation.z;
}
function Update () {
//Get input value of axis (vary between 0 - 1.20)
var hAxis : float = Input.GetAxis("Horizontal");
if (Input.GetKey(KeyCode.A))
transform.Rotate(Vector3.forward * 20 * Time.deltaTime);
if (Input.GetKey(KeyCode.D))
transform.Rotate(Vector3.back * 20 * Time.deltaTime);
if (!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D) && transform.rotation.z != 0.000){
transform.rotation.z = Mathf.Lerp(transform.rotation.z, originalRotation, Time.deltaTime * 10);
}
}
I have it set up like that so that the tilt wouldnt affect the turning. But it still tilts and turns and then gets into weird positions. How can i rotate the boat in way that it wont conflict with the tilt?
this particular section
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.A))
transform.Rotate(Vector3.forward * 20 * Time.deltaTime);
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.D))
transform.Rotate(Vector3.back * 20 * Time.deltaTime);
could also be written as
if (Input.GetAxis("Horizontal") != 0) // if we're pressing left or right
transform.Rotate(Vector3.forward * 20 * Time.deltaTime);
And also note that Vector3.forward is the forward of world space this means regardless as to which way your boat is facing it will always rotate along the forward axis of the world not its own personal forward, Simplified this means If you were facing forward you would rotate forward but if u were facing left right would become forward and thus u would roll along the wrong axis
changing it from Vector3.forward to transform.forward will mean that it always uses the forward direction of the transform, very important.
Answer by Akabuu · Apr 20, 2016 at 03:49 PM
EDIT: I figured it out.
For anyone else that comes across this topic, here's the solution i got. I only had to change the tilt script:
var angle = 0.0;
var tiltSpeed = 30.0;
var startRot;
function Start () {
startRot = transform.localRotation;
}
function Update () {
var hAxis : float = Input.GetAxis("Horizontal");
angle += tiltSpeed * Time.deltaTime * hAxis;
angle = Mathf.Clamp( angle, -10, 10 );
if(hAxis != 0){
transform.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
}else{
if(Mathf.Approximately(angle, 0))
angle = 0;
angle = Mathf.Lerp(angle, 0, 2.5 * Time.deltaTime);
transform.localRotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
Answer by skylem · Apr 20, 2016 at 01:29 AM
The actual tilt process could be handled by either
Transform.Rotate(transform.forward * 5);
or
rigidbody.AddTorque(transform.forward * 100);
the next step would be making sure you can't exceed a set limit to rotation when adding limitation i prefer to use
limitedZ = Mathf.Clamp(maxRot, -10, 10); // limit a float value to never
be less then -10 or more then 10.
so next is how u actually apply this rotation value, you could simply use one of the above to rotate and then clamp heres some ideas for application
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, limitedZ); // and u would simply affect
limitedZ somewhere else using limitedZ + = Input.GetAxis("Vertical");
there are some exceptions to how practical using eulerAngles can be, so an alternative is to create an actual rotation from the above vector which could be done like so
Vector3 newEulers = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, limitedZ);
rotation = Quaternion.Euler(newEulers);
hope its all useful Good Luck. EDIT --- Here is a motorboat controller i wrote a while back, maybe it will help u along here you go
public class MotorboatController : MonoBehaviour {
public Rigidbody Boat;
public Transform Propeller;
public Transform Motor;
//public bool engineOn;
public float desiredSpeed;
public float speedRate;
public int Maxspeed;
public int Minspeed;
public int propulsion;
float velocityfalloff = 2;
public float currentSpeed;
float newSteer;
public float steerAngle;
void Start (){
InvokeRepeating("Speed", 0.1f, 0.1f);
}
void Speed (){
if (Input.GetAxis("Vertical") > 0.1f && desiredSpeed < Maxspeed){
Mathf.Repeat(1,Time.time);
desiredSpeed+=speedRate;
}
if (Input.GetAxis("Vertical") < -0.1f && desiredSpeed > Minspeed){
Mathf.Repeat(1,Time.time);
desiredSpeed-=speedRate;
}
}
void SteeringAngle() {
if(Motor != null) {
if(Input.GetAxis("Horizontal") != 0) {
// create a float of the steer angle based off the vehicles default lowsteer, to the power of 20 by horizontal presses
float steerPivot = (steerAngle * 20) * -Input.GetAxis("Horizontal");
// lerp the new float for smooth spin motion
newSteer = Mathf.Lerp(0, steerPivot, 0.1f);
// create a new Euler rotation vector with the newSteer as the local Y
Vector3 steerVector = new Vector3(Motor.transform.localEulerAngles.x, newSteer, Motor.transform.localEulerAngles.z);
// convert our new steer vector to a quaternion rotation
Quaternion newRot = Quaternion.Euler(steerVector);
// set the local rotation to the new quaternion
Motor.transform.localRotation = Quaternion.Lerp(Motor.transform.localRotation, newRot, 0.1f);
}
// this is where steering falls back to its default rotation of 0
else {
Vector3 steerVector = new Vector3(Motor.transform.localEulerAngles.x, 0, Motor.transform.localEulerAngles.z);
Quaternion newRot = Quaternion.Euler(steerVector);
Motor.transform.localRotation = Quaternion.Lerp(Motor.transform.localRotation, newRot, 0.1f);
}
}
// the roll of vector left needs to be a fixed rotation value similar to the motor angle multiply by speed
Boat.GetComponent<Rigidbody>().AddRelativeTorque(Vector3.up * Input.GetAxis("Horizontal") * currentSpeed + Vector3.up * newSteer * GetComponent<Rigidbody>().mass / 40);
Debug.Log (newSteer.ToString());
}
void Update (){
SteeringAngle ();
currentSpeed = Boat.velocity.magnitude;
// spin the propeller if we're going
if(Propeller != null) {
Propeller.transform.Rotate (desiredSpeed * 10, 0, 0);
}
if(desiredSpeed >= Minspeed && desiredSpeed <= Maxspeed){
if(desiredSpeed != 0)
if(currentSpeed < Maxspeed && currentSpeed > Minspeed) {
Boat.GetComponent<Rigidbody>().AddRelativeForce(0, 0, propulsion * desiredSpeed);
}
}
}
}