Last active
December 30, 2017 03:23
-
-
Save gamemachine/573baf607f68036f71692bf8d38d7d29 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Collections; | |
| using System.Collections.Generic; | |
| using UltimateWater; | |
| using UnityEngine; | |
| namespace AiGame | |
| { | |
| public class KinematicBuoyancy : MonoBehaviour | |
| { | |
| public float DefaultHeight; | |
| public float Width = 6f; | |
| public float Length = 14f; | |
| public Vector3 Gravity = new Vector3(0, -9.81f, 0); | |
| public float AccelerationMulti = 1f; | |
| public float MaxAccel = 0.01f; | |
| public float AccelerationSmooth = 1f; | |
| public float DecelerationConstant = 0.5f; | |
| public float RotationSpeed = 5f; | |
| public float RotationAngleMulti = 6f; | |
| [SerializeField] | |
| private float Height; | |
| private Water Water; | |
| // For debugging | |
| [SerializeField] | |
| private Vector3 front; | |
| [SerializeField] | |
| private Vector3 back; | |
| [SerializeField] | |
| private Vector3 left; | |
| [SerializeField] | |
| private Vector3 right; | |
| private Accelerator Accelerator; | |
| void Awake() | |
| { | |
| Accelerator = new Accelerator(0f, 50f, DecelerationConstant); | |
| if (Water == null) | |
| { | |
| Water = FindObjectOfType<Water>(); | |
| } | |
| } | |
| public float GetHeight(Vector3 position) | |
| { | |
| return CalculateVerticalVelocity(position.y, GetWaterLevel(position.x, position.z)); | |
| } | |
| public Vector3 GetRotation(Vector3 position) | |
| { | |
| float halfLength = Length / 2f; | |
| float halfWidth = Width / 2f; | |
| front = new Vector3(position.x, position.y, position.z + halfLength); | |
| front.y = GetWaterLevel(front.x, front.z); | |
| back = new Vector3(position.x, position.y, position.z - halfLength); | |
| back.y = GetWaterLevel(back.x, back.z); | |
| left = new Vector3(position.x - halfWidth, position.y, position.z); | |
| left.y = GetWaterLevel(left.x, left.z); | |
| right = new Vector3(position.x + halfWidth, position.y, position.z); | |
| right.y = GetWaterLevel(right.x, right.z); | |
| float zangle = 0f; | |
| float xangle = 0f; | |
| if (front.y > back.y) | |
| { | |
| zangle = -(front.y - back.y); | |
| } | |
| else if (back.y > front.y) | |
| { | |
| zangle = (back.y - front.y); | |
| } | |
| else | |
| { | |
| zangle = 0f; | |
| } | |
| if (left.y > right.y) | |
| { | |
| xangle = -(left.y - right.y); | |
| } | |
| else if (right.y > left.y) | |
| { | |
| xangle = (right.y - left.y); | |
| } | |
| else | |
| { | |
| xangle = 0f; | |
| } | |
| Vector3 targetRot = new Vector3(xangle * RotationAngleMulti, 0f, zangle * RotationAngleMulti); | |
| Quaternion rot = Quaternion.Slerp(transform.rotation, Quaternion.Euler(targetRot), RotationSpeed * Time.deltaTime); | |
| return new Vector3(rot.eulerAngles.x, 0f, rot.eulerAngles.z); | |
| } | |
| public float GetWaterLevel(float x, float z) | |
| { | |
| if (Water == null) | |
| { | |
| return DefaultHeight; | |
| } else | |
| { | |
| //return Water.transform.position.y + Water.GetUncompensatedHeightAt(x, z, Time.time); | |
| return Water.transform.position.y + Water.GetHeightAt(x, z, Time.time); | |
| } | |
| } | |
| private float CalculateVerticalVelocity(float current, float waterLevel) | |
| { | |
| float height = current; | |
| Accelerator.Max = MaxAccel; | |
| height += Gravity.y * Time.deltaTime; | |
| if (height < waterLevel) | |
| { | |
| float force = (waterLevel - height) * Mathf.Exp(AccelerationMulti * Time.deltaTime); | |
| Accelerator.Accelerate(force); | |
| } | |
| Accelerator.Decelerate(DecelerationConstant); | |
| height += Accelerator.Current; | |
| height = Mathf.Lerp(height, waterLevel, AccelerationSmooth * Time.deltaTime); | |
| height = Mathf.Clamp(height, -20f, 20f); | |
| return height; | |
| } | |
| } | |
| } | |
| public class Accelerator | |
| { | |
| public float Min { get; set; } | |
| public float Max { get; set; } | |
| public float Current { get; set; } | |
| public float Deceleration { get; set; } | |
| public Accelerator(float min, float max, float decel) | |
| { | |
| Min = min; | |
| Max = max; | |
| Deceleration = decel; | |
| } | |
| public void Accelerate(float accel) | |
| { | |
| Current = Current + (accel * Time.deltaTime); | |
| Clamp(); | |
| } | |
| public void Decelerate(float decel) | |
| { | |
| Current = Current - (decel * Time.deltaTime); | |
| Clamp(); | |
| } | |
| private void Clamp() | |
| { | |
| Current = Mathf.Clamp(Current, Min, Max); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment