using UnityEngine;
using System.Collections;
public class FinalShipControl : MonoBehaviour {
public bool queryUserInput;
public float mass = 3000;
//public int propulsorCount;
//public float waveLenght;
//public float waveHeight;
//public float jerkingLength;
//public float jerkingHeight;
public float waterLevel;
public float distanceFromWaterLevel;
public float percentUnderWater;
public AudioClip motorSound;
public float motor;
public float steer;
public float rudder = 40;
public float propellerTurningAngle = 20;
public float rpmPitch;
public float forwardVelo;
public Vector3 propellerPos;
public Vector3 propellerPosGlobal;
public Vector3 propellerDir;
public Vector3 drag = new Vector3(6.0f, 4.0f, 0.2f);
public Vector3 dragForces;
public Vector3 dragDirection;
public Vector3 dragAttackPosition;
public Vector3 buoyancyPos;
public float depth;
public float volume = 9000;
public float steeringAngle;
public float engineForce = 10000;
public Vector3 gravity;
public Vector3 size = new Vector3(3,3,10);
public float angularDrag = 0.8f;
public FloatableWater waterSurface = null;
// Use this for initialization
void Start () {
//gravity = new Vector3(0, -9, 0);
//size = GetComponent<BoxCollider>().size;
rigidbody.mass = mass;
rigidbody.angularDrag = angularDrag;
rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
}
// Update is called once per frame
void FixedUpdate () {
/*if(waveLenght <= 0)
{
waveLenght = 0.1f;
}
else if(jerkingLength <= 0)
{
jerkingLength = 0.1f;
}*/
//if there is no water surface we are colliding with, no boat physics
if(waterSurface == null)
{
return;
}
//query input axes if necessarry
//motor = 0.0f;
//steer = 0.0f;
if(queryUserInput)
{
motor = Input.GetAxis("Vertical");
steer = Input.GetAxis("Horizontal");
}
//get water level and percent under water
waterLevel=waterSurface.collider.bounds.max.y;
distanceFromWaterLevel = transform.position.y-waterLevel;
percentUnderWater = Mathf.Clamp01((-distanceFromWaterLevel + 0.5f*size.y)/size.y);
//Buoyancy (the force which keeps the boat floating above water)
//--------------------------------------------------------------
//the point the buoyancy force is applied onto is calculated based
//on the boat's picth and roll, so it will always tilt upwards:
buoyancyPos=transform.TransformPoint(-new Vector3(transform.right.y*size.x*0.5f,0,transform.forward.y*size.z*0.5f));
//then it is shifted arcording to the current waves
buoyancyPos.x+=waterSurface.waveXMotion1*Mathf.Sin(waterSurface.waveFreq1*Time.time)
+waterSurface.waveXMotion2*Mathf.Sin(waterSurface.waveFreq2*Time.time)
+waterSurface.waveXMotion3*Mathf.Sin(waterSurface.waveFreq3*Time.time);
buoyancyPos.z+=waterSurface.waveYMotion1*Mathf.Sin(waterSurface.waveFreq1*Time.time)
+waterSurface.waveYMotion2*Mathf.Sin(waterSurface.waveFreq2*Time.time)
+waterSurface.waveYMotion3*Mathf.Sin(waterSurface.waveFreq3*Time.time);
//apply the force
rigidbody.AddForceAtPosition(- volume * percentUnderWater * Physics.gravity , buoyancyPos);
//Engine
//--------------------------------------------------------------
//calculate propeller position
propellerPos = new Vector3(0,-size.y*0.5f,-size.z*0.5f);
propellerPosGlobal=transform.TransformPoint(propellerPos);
//apply force only if propeller is under water
if(propellerPosGlobal.y<waterLevel)
{
//direction propeller force is pointing to.
//mostly forward, rotated a bit according to steering angle
steeringAngle = steer * propellerTurningAngle * Mathf.Deg2Rad;
propellerDir = transform.forward*Mathf.Cos(steeringAngle) - transform.right*Mathf.Sin(steeringAngle);
//apply propeller force
rigidbody.AddForceAtPosition(propellerDir * engineForce * motor, propellerPosGlobal);
}
//Drag
//--------------------------------------------------------------
//calculate drag force
dragDirection = transform.InverseTransformDirection(rigidbody.velocity);
dragForces = -Vector3.Scale(dragDirection, drag);
//depth of the boat under water (used to find attack point for drag force)
depth = Mathf.Abs(transform.forward.y)*size.z*0.5f+Mathf.Abs(transform.up.y)*size.y*0.5f;
//apply force
dragAttackPosition = new Vector3(transform.position.x,waterLevel-depth,transform.position.z);
rigidbody.AddForceAtPosition(transform.TransformDirection(dragForces) * rigidbody.velocity.magnitude * (1 + percentUnderWater * (waterSurface.waterDragFactor - 1)), dragAttackPosition);
//linear drag (linear to velocity, for low speed movement)
rigidbody.AddForce(transform.TransformDirection(dragForces)*500);
//rudder torque for steering (square to velocity)
forwardVelo = Vector3.Dot(rigidbody.velocity,transform.forward);
rigidbody.AddTorque(transform.up*forwardVelo*forwardVelo*rudder*steer);
//Sound
//--------------------------------------------------------------
//audio.volume=0.3f+Mathf.Abs(motor);
//slowly adjust pitch to power input
rpmPitch=Mathf.Lerp(rpmPitch,Mathf.Abs(motor),Time.deltaTime*0.4f);
//audio.pitch=0.3f+0.7f*rpmPitch;
//reset water surface, so we have to stay in contact for boat physics.
waterSurface = null;
//this.transform.position = elevate(Time.time);
//this.transform.rotation = jerk(Time.time);
}
void OnTriggerStay(Collider col)
{
if(col.GetComponent<FloatableWater>() != null)
{
waterSurface = col.GetComponent<FloatableWater>();
}
}
/*public Vector3 elevate(float t)
{
//Vector3 newVec =
return new Vector3(this.transform.position.x, this.transform.position.y + (Mathf.Sin (t / waveLenght) * waveHeight), this.transform.position.z);
}
public Quaternion jerk(float t)
{
float val = (Mathf.Cos (t / jerkingLength) * jerkingHeight);
return Quaternion.Euler(new Vector3(this.transform.rotation.eulerAngles.x + val, this.transform.rotation.eulerAngles.y, this.transform.rotation.eulerAngles.z + Random.Range(0, val)));
}*/
}
Comments
0 B
|👍
/👎
0 B
|0 👍
/0 👎
0 B
|👍
/👎