<repo_name>ChadGatling/Sand-Dune<file_sep>/Sand Dune/Assets/MyAssets/Scripts/Rudder.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rudder : DriveComponent {

	public MoveShip ship;
	LeverAction throttle;

	void Start () {
		throttle = transform.Find("Rudder/LeverArm").GetComponent<LeverAction>();
	}
	
	void Update () {
		ship.turn = throttle.howActive;
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/ObjectData.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectData : MonoBehaviour {
    private static float leverAngle;
    private static bool handsOnly;

    public virtual bool GetHandsOnly()
    {
        return handsOnly;
    }

    public virtual void SetHandsOnly(bool value)
    {
        handsOnly = value;
    }

    public static float GetLeverAngle()
    {
        return leverAngle;
    }

    public static void SetLeverAngle(float value)
    {
        leverAngle = value;
    }
}
<file_sep>/README.md
# Sand-Dune
A game about survival on land-ships in a post post-apocalyptic desert sea.
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/MoveShip.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
    
[System.Serializable]
public class WheelComponent {
    public WheelCollider wheel;
	/// <summary>
	/// Is this wheel attached to motor?
	/// </summary>
    public bool isPowered;
	/// <summary>
	/// Does this wheel apply steer angle?
	/// </summary>
    public bool isSteerable;
	/// <summary>
	/// Is this a front wheel?
	/// </summary>
	public bool isFore;
	/// <summary>
	/// Is this a starboard wheel?
	/// </summary>
	public bool isStarboard;
}

public class MoveShip : DriveComponent {

	Rigidbody shipPhysics;
	[SerializeField] private float Knots;
	// [Range(0f, 30f)] // make the high end the same as maxRPG
	float wheelRPM;
	// [SerializeField] float maxRPM;
	[HideInInspector] public float[] turnRange = {-1f, 1f};
	// [HideInInspector] public float[] throttleRange = {0f, 1f};
	// [HideInInspector] public float[] clutchRange = {0f, 1f};
	[HideInInspector] public float[] brakingRange = {0f, 1f};
	[Range(-1f, 1f)] public float turn;
	// [Range(0f, 1f)]	public float throttle;
	// [Range(0f, 1f)]	public float clutch;
	[Range(0, 1f)] public float braking;
	[SerializeField] bool reverse;
    [SerializeField] List<WheelComponent> wheels; // the information about each individual wheel
    // [SerializeField] float maxMotorTorque; // maximum torque the motor can apply to wheel
    [SerializeField] float maxSteeringAngle; // maximum steer angle the wheel can have
    // [SerializeField] float maxBraking; // maximum steer angle the wheel can have
	[SerializeField] DriveComponent fuelSide;
	[SerializeField] AnimationCurve frictionCurve;

	void Start () {
		shipPhysics = GetComponent<Rigidbody>();
	}
	
	void FixedUpdate () {
		// input = fuelSide.downStream;
		turn = Mathf.Clamp(turn, turnRange[0], turnRange[1]);
		// throttle = Mathf.Clamp(throttle, throttleRange[0], throttleRange[1]);
		// clutch = Mathf.Clamp(clutch, clutchRange[0], clutchRange[1]);
		braking = Mathf.Clamp(braking, brakingRange[0], brakingRange[1]);

        torqueCurrent = upStream.torqueCurrent;
        float steering = maxSteeringAngle * turn;
        // float brake = 100f;
		int reversing = reverse ? -1 : 1;

		wheelRPM = 0;

		float sprungMass = 0;

        foreach (WheelComponent wheelUnit in wheels) {
			float frictionTorque = frictionCurve.Evaluate(wheelUnit.wheel.rpm);

			wheelRPM += wheelUnit.wheel.rpm;
			sprungMass = wheelUnit.wheel.sprungMass;

            if (wheelUnit.isSteerable) {
				if (wheelUnit.isFore) {
					wheelUnit.wheel.steerAngle = steering;
				} else {
					wheelUnit.wheel.steerAngle = -steering;
				}
            }

			if (wheelUnit.isPowered)
				if (torqueCurrent >= 0){
					wheelUnit.wheel.motorTorque = torqueCurrent;
					wheelUnit.wheel.brakeTorque = frictionTorque;
				} else {
					wheelUnit.wheel.motorTorque = 0;
					wheelUnit.wheel.brakeTorque = -torqueCurrent + frictionTorque;
				}
				
            ApplyLocalPositionToVisuals(wheelUnit.wheel);
        }

		rpmCurrent = wheelRPM / wheels.Count;
		sprungMass = sprungMass / wheels.Count;
		// fuelSide.currentRpm = ;
		Knots = Mathf.Round(shipPhysics.velocity.magnitude * 1.943844f * 100) / 100;
	}
	
    public void ApplyLocalPositionToVisuals(WheelCollider collider)
    {
        if (collider.transform.childCount == 0) {
            return;
        }
     
        Transform visualWheel = collider.transform.GetChild(0);
     
        Vector3 position;
        Quaternion rotation;
        collider.GetWorldPose(out position, out rotation);
     
        visualWheel.transform.position = position;
        visualWheel.transform.rotation = rotation;
    }
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/AttatchToShip.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttatchToShip : MonoBehaviour {

	[SerializeField]GameObject player;

	void OnTriggerEnter(Collider col) {
		if (col.gameObject == player) {
			player.GetComponent<PlayerMove>().hasParent = true;
			player.transform.parent = transform;
		}
	}

	void OnTriggerExit(Collider col) {
		if (col.gameObject == player)
			player.GetComponent<PlayerMove>().hasParent = false;
			player.transform.parent = null;
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/ObjectAction.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectAction : MonoBehaviour {

	public bool isActive = false;
	public float howActive = 0;
	[HideInInspector] public static float rangeMax;
	[HideInInspector] public float rangeMin;
	public float angleMax;

	public virtual void Action (RaycastHit hit) {
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/PlayerLook.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerLook : MonoBehaviour {
	public float mouseSensitivity;
	public Transform playerBody;

	private float mouseX = 0f, mouseY = 0f;
	public bool inspectView = false;
	
	private void Update() {
		CameraRotation();
		LookMode();
	}

	private void LookMode() {
		if (inspectView && (Mathf.Abs(Input.GetAxis("Vertical")) >= .9f || Mathf.Abs(Input.GetAxis("Horizontal"))  >= .9f)) {
			inspectView = false;
		}

		if (Input.GetButtonDown("Look Mode")) {
			inspectView = !inspectView;
		}
	}

	private void CameraRotation() {
		// if (Input.GetButton("Build"))
		// 	return;

		if (inspectView) {
			Cursor.lockState = CursorLockMode.None;
		} else {
			mouseX += Input.GetAxis("Mouse X") * mouseSensitivity;
			mouseY += -Input.GetAxis("Mouse Y") * mouseSensitivity;
			mouseY = Mathf.Clamp(mouseY, -90f, 90f);

			Cursor.lockState = CursorLockMode.Locked; // seems take up a good amount of cpu time. Replace this with a UI reticle.
			transform.eulerAngles = new Vector3(mouseY, transform.eulerAngles.y, 0);
		}
		
		playerBody.eulerAngles = new Vector3(0, mouseX, 0); // I think this is the one that needs to be active for the player to ride on the ship

		#if UNITY_EDITOR
		Cursor.visible = true;
		#else
		Cursor.visible = false;
		#endif
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/Clutch.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Clutch : DriveComponent {

	LeverAction clutch;

	void Start () {
		clutch = transform.Find("Clutch/LeverArm").GetComponent<LeverAction>();
	}
	
	void Update () {
		torqueCurrent = upStream.torqueCurrent * clutch.howActive;
		isRunning = upStream.isRunning;
		rpmCurrent = Mathf.Lerp(upStream.rpmCurrent, downStream.rpmCurrent, clutch.howActive);

		if (downStream) {
			torqueToTurnMax = torqueToTurnCurve.Evaluate(rpmCurrent) - downStream.torqueToTurnMax;
		} else {
			torqueToTurnMax = torqueToTurnCurve.Evaluate(rpmCurrent);
		}
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/PlayerWorldClick.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerWorldClick : MonoBehaviour {

	[SerializeField] float raylength;
	
	private LayerMask LayerMask;

	void Start () {
		LayerMask = LayerMask.GetMask("Action" ,"Default");		
	}
	
	void Update () {
		RaycastHit hit;
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		bool raycast = Physics.Raycast(ray, out hit, raylength, LayerMask);

		if (raycast && hit.collider.tag == "Interactable") {
			hit.collider.GetComponent<ObjectAction>().Action(hit);
		}
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/Engine.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Engine : DriveComponent {

	[SerializeField] float torqueMax;
	[SerializeField] float torqueStart;
	[SerializeField] AnimationCurve torqueCurve;

	[SerializeField] float rpmMax;
	[SerializeField] float rpmMin;
	// [SerializeField] AnimationCurve rpmCurve;

	[SerializeField] float preasure;
	LeverAction throttle;
	ButtonAction ignition;
	PushPullAction choke;
	ParticleSystem exhaust;
	[SerializeField] float temperature = 70;

	float startTime;

	void Start () {
		throttle = transform.Find("Throttle/LeverArm").GetComponent<LeverAction>();
		ignition = transform.Find("Ignition").GetComponent<ButtonAction>();
		choke = transform.Find("Choke").GetComponent<PushPullAction>();
		exhaust = GetComponent<ParticleSystem>();
		
		SetOutput();
	}
	
	void FixedUpdate () {
		if (isRunning) {
			IncreaseTemperature();
			SetRpm();
			Stall();
			SetTorque();
		} else {
			rpmCurrent = 0;
			Ignition();
			DecreaseTemperature();
		}

		SetOutput();
	}

	void IncreaseTemperature() {
		if (temperature < 250) {
			temperature += Time.fixedDeltaTime;
			temperature = Mathf.Clamp(temperature, 70, 250);
		}
	}

	void DecreaseTemperature() {
		if (temperature > 70) {
			temperature -= Time.fixedDeltaTime;
			temperature = Mathf.Clamp(temperature, 70, 250);
		}
	}

	void SetTorque() {
		var rpmRatio = rpmCurrent/rpmMax;
		// var torqueMaxThisRpm = Utility.EvaluateCurve(torqueCurve, rpmRatio, torqueMax);
		// float engineBrakeTorque = torqueMaxThisRpm - torqueMaxThisRpm * throttle.howActive;
		float torqueGross = Utility.EvaluateCurve(torqueCurve, rpmRatio, torqueMax) * throttle.howActive;		
		torqueCurrent = (torqueGross) - Utility.EvaluateCurve(torqueToTurnCurve, rpmRatio, torqueToTurnMax) - 1; // add torque to turn friction as the unit wears

		if (downStream != null) {
			float clutchHowActive = downStream.transform.Find("Clutch/LeverArm").GetComponent<LeverAction>().howActive;
			torqueCurrent -= downStream.torqueToTurnMax * clutchHowActive;  
		}

		if (torqueCurrent < 0)
			torqueCurrent *= 3; // might be as good as I can get for now. Meant to simulate engine brake.
		
		if (!isRunning)
			torqueCurrent *= 5;

		#if UNITY_EDITOR
		if (torqueCurrent > torqueMax) { // Remove after some time when it is shown that it will not happen.
			Debug.Break();
			Debug.Log("torqueCurrent has exceded torqueMax");
			torqueCurrent = torqueMax;
		};
		#endif
	}

	void SetRpm() {
 		if (downStream != null) {
			float clutchHowActive = downStream.transform.Find("Clutch/LeverArm").GetComponent<LeverAction>().howActive;
			rpmCurrent = Mathf.Lerp(rpmCurrent + torqueCurrent * Time.fixedDeltaTime * 20, downStream.rpmCurrent, clutchHowActive);
		} else
			rpmCurrent += torqueCurrent * Time.fixedDeltaTime;

		rpmCurrent = Mathf.Clamp(rpmCurrent, 0, rpmMax);
		
        ParticleSystem.EmissionModule emission = exhaust.emission;
		emission.rateOverTime = rpmCurrent / 60;
	}

	void Ignition() {
		if (!ignition.isActive) {
			// torqueCurrent = 0;
			startTime = 0;
			return;
		}
		
		if (startTime <= 0.5) {
			startTime += Time.fixedDeltaTime;
			torqueCurrent += torqueStart * Time.fixedDeltaTime * 2;
			torqueCurrent = Mathf.Clamp(torqueCurrent, 0, torqueStart);
		}

		SetRpm();
		
		if (choke.isActive && rpmCurrent >= rpmMin) {
			isRunning = true;
			exhaust.Play();
		}
	}

	void Stall() {
		if (rpmCurrent <= 0 || throttle.howActive <= 0) {
			isRunning = false;
			exhaust.Stop();
		}
	}

	void SetOutput() {
	}
}<file_sep>/Sand Dune/Assets/MyAssets/Scripts/PushPullAction.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PushPullAction : ObjectAction {

	void Start () {
		
	}
	
	void Update () {
		
	}

	public override void Action(RaycastHit hit) {
		bool onClick = Input.GetButtonDown("Action");
		
		if (onClick) {
            isActive = !isActive;
			Vector3 move = new Vector3(0, isActive ? .25f : -.25f, 0);
			transform.Translate(move);
		}
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/LeverAction.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LeverAction : ObjectAction {

	// [SerializeField] string control;

	// System.Reflection.FieldInfo controlField;
	// MoveShip moveShip;

	[SerializeField] bool allowNegative;

	public void Start() {
		// moveShip = transform.root.GetComponent<MoveShip>();
		// System.Reflection.FieldInfo rangeField = moveShip.GetType().GetField(control + "Range");
		// float[] range = (float[])rangeField.GetValue(moveShip);
		rangeMin = allowNegative ? -1 : 0;
		rangeMax = 1;
		// controlField = moveShip.GetType().GetField(control);
	}

	void Update() {
		transform.parent.localEulerAngles = new Vector3(howActive * 60, 0, 90);
	}

	public override void Action(RaycastHit hit) {
		float mouseScroll = Input.GetAxis("Mouse ScrollWheel");
		bool onClick = Input.GetButtonDown("Action");
		bool onHold = Input.GetButton("Action");

		// if (mouseScroll != 0) {			
		// 	// controlField = moveShip.GetType().GetField(control);
		// 	// float controlValue = Mathf.Clamp((float)controlField.GetValue(moveShip) + mouseScroll, rangeMin, rangeMax);
		// 	// controlField.SetValue(moveShip, controlValue);
		// 	howActive += mouseScroll;
		// 	howActive = Mathf.Clamp(howActive, rangeMin, rangeMax);
		// 	transform.parent.localEulerAngles = new Vector3(howActive * 60, 0, 90);
		// }

		if (onHold) {
			Plane axlePlane = new Plane(transform.parent.up, hit.point);
			Vector3 localPoint = axlePlane.ClosestPointOnPlane(hit.point);
			float angle;
			// angle = Vector3.Angle(Vector3.up, localPoint - axlePlane.ClosestPointOnPlane(transform.parent.position));
			angle = Vector3.SignedAngle(Vector3.up, localPoint - axlePlane.ClosestPointOnPlane(transform.parent.position), -transform.up);
			Debug.Log(angle);
			howActive = Mathf.Clamp(angle/angleMax, rangeMin, rangeMax);
			transform.parent.localEulerAngles = new Vector3(howActive * angleMax, 0, 90);
		}

		// if (onClick) {
		// 	// controlField.SetValue(moveShip, 0);
		// 	howActive = 0;
		// 	transform.parent.localEulerAngles = new Vector3(howActive * 60, 0, 90);
		// }
	}

	// float GetAngle() {

	// }
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/ButtonAction.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ButtonAction : ObjectAction {

	void Update() {

	}

	public override void Action(RaycastHit hit) {
		isActive = Input.GetButton("Action");
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/Utility.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Custom utility functions.
/// </summary>
public class Utility {
	/// <summary>Computes and returns the value of a given ratio on a given curve.</summary>
	/// <param name ="curve">The curve on which the ratio will be computed.</param>
	/// <param name="ratio">The value to compute on the curve. Usually a float between 0 and 1.</param>
	/// <returns>Returns the Y-value of the curve at the given X-value as a float.</returns>
	public static float EvaluateCurve(AnimationCurve curve, float ratio) {
		return curve.Evaluate(ratio);
	}
	
	/// <summary>Computes and returns the value of a given ratio on a given curve applied to a given maximum.</summary>
	/// <param name ="curve">The curve on which the ratio will be computed.</param>
	/// <param name="ratio">The value to compute on the curve. Usually a float between 0 and 1.</param>
	/// <param name="multiplier">The maximum value that should be returned. Return value will be relative to multiplier.</param>
	/// <returns>Returns the Y-value of the curve at the given X-value as a float multiplied by the constant multiplier.</returns>
	public static float EvaluateCurve(AnimationCurve curve, float ratio, float multiplier) {
		return curve.Evaluate(ratio) * multiplier;
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/PlayerMove.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove : MonoBehaviour {

	private CharacterController charController;
	private bool isJumping;

	[HideInInspector] public bool hasParent;
	public float movementSpeed;
	public AnimationCurve jumpFallOff;
	public float jumpMultiplier;
	[SerializeField] Rigidbody shipPhysics;

	Vector3 moveDirection;

	void Awake () {
		charController = GetComponent<CharacterController>();
	}

	void Update() {
		JumpInput();
	}

	void FixedUpdate() {
		PlayerMovement();
	}

	void PlayerMovement() {
		bool isGrounded = charController.isGrounded;

		if (isGrounded) {
			float vertInput = Input.GetAxis("Vertical");
			float horInput = Input.GetAxis("Horizontal");

			Vector3 forwardMovement = transform.forward * vertInput;
			Vector3 rightMovement = transform.right * horInput;
			
            moveDirection = rightMovement + forwardMovement;
            moveDirection *= movementSpeed;
		} else {			
			moveDirection.y -= 20 * Time.fixedDeltaTime;
		}
		
		// if (Input.GetButton("Vertical") || Input.GetButton("Horizontal") || !isGrounded) // still need to figure out how to move the player with the ship at all times.
		charController.Move(moveDirection * Time.fixedDeltaTime);
	}
	
	void JumpInput() {
		if (Input.GetButtonDown("Jump")) {
 			if (!isJumping){
				isJumping = true;
				StartCoroutine(JumpEvent());
			}
		}
	}

	IEnumerator JumpEvent() {
		charController.slopeLimit = 90.0f;
		float timeInAir = 0.0f;

		do {
			float jumpForce = jumpFallOff.Evaluate(timeInAir);
			charController.Move(Vector3.up * jumpForce * jumpMultiplier * Time.deltaTime);
			timeInAir += Time.deltaTime;
			yield return null;
		} while (!charController.isGrounded && charController.collisionFlags != CollisionFlags.Above);

		charController.slopeLimit = 45.0f;
		isJumping = false;
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/UserInterface.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UserInterface : MonoBehaviour {

	void Start () {
		// Cursor.lockState = CursorLockMode.Locked;
	}
	
	void Update () {		
		if (Input.GetButtonDown("Cancel")){
			#if UNITY_EDITOR
			UnityEditor.EditorApplication.isPlaying = false;
			#elif UNITY_WEBPLAYER
			Application.OpenURL(webplayerQuitURL);
			#else
			Application.Quit();
			#endif
		}
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/Weather.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Weather : MonoBehaviour {

	ParticleSystem precipitation;

	void Start () {
		precipitation = GetComponent<ParticleSystem>();
	}
	
	void Update () {
        ParticleSystem.EmissionModule emission = precipitation.emission;
		emission.rateOverTime = Time.timeSinceLevelLoad;
	}
}
<file_sep>/Sand Dune/Assets/MyAssets/Scripts/DriveComponent.cs
﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DriveComponent : MonoBehaviour {
	[HideInInspector] public bool isRunning;
	public DriveComponent downStream;
	public DriveComponent upStream;
	public float rpmCurrent;
	public float torqueCurrent;
	public float torqueToTurnMax;
	public AnimationCurve torqueToTurnCurve;
}

// [System.Serializable]
// public class DriveData {
// 	public float rpm;
// 	public float torque;
// }