rabidus-test/Assets/BNG Framework/Scripts/Core/JoystickVehicleControl.cs

173 lines
6.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BNG {
/// <summary>
/// This component is similar to the JoystickControl, but is designed to be used on fast moving Rigidbodies
/// </summary>
public class JoystickVehicleControl : MonoBehaviour {
[Header("Grab Object")]
public Grabbable JoystickGrabbable;
[Header("Movement Speed")]
[Tooltip("Set to True to Lerp towards the held hand. Set to False for Instant movement")]
public bool UseSmoothLook = true;
public float SmoothLookSpeed = 15f;
[Header("Hinge X")]
public Transform HingeXTransform;
public float MinXAngle = -45f;
public float MaxXAngle = 45f;
[Header("Hinge Y")]
public Transform HingeYTransform;
public float MinYAngle = -45f;
public float MaxYAngle = 45f;
[Header("Return To Center")]
[Tooltip("How fast to return to center if nothing is holding the Joystick. Set to 0 if you do not wish to Return to Center")]
public float ReturnToCenterSpeed = 5f;
[Header("Deadzone")]
[Tooltip("Any values below this threshold will not be passed to events")]
public float DeadZone = 0.001f;
/// <summary>
/// Event called when Joystick value is changed
/// </summary>
public FloatFloatEvent onJoystickChange;
/// <summary>
/// Event called when Joystick value is changed
/// </summary>
public Vector2Event onJoystickVectorChange;
[Header("Shown for Debug : ")]
/// <summary>
/// Current Percentage of joystick on X axis (left / right)
/// </summary>
public float LeverPercentageX = 0;
/// <summary>
/// Current Percentage of joystick on Y axis (forward / back)
/// </summary>
public float LeverPercentageY = 0;
public Vector2 LeverVector;
public float angleX;
public float angleY;
Quaternion originalRot = Quaternion.identity;
void Update() {
if(JoystickGrabbable != null) {
if(JoystickGrabbable.BeingHeld) {
Transform lookAt = JoystickGrabbable.GetPrimaryGrabber().transform;
// Look towards the Grabber
if (HingeXTransform) {
originalRot = HingeXTransform.rotation;
HingeXTransform.LookAt(lookAt, Vector3.left);
angleX = HingeXTransform.localEulerAngles.x;
if (angleX > 180) {
angleX -= 360;
}
HingeXTransform.localEulerAngles = new Vector3(Mathf.Clamp(angleX, MinXAngle, MaxXAngle), 0, 0);
if (UseSmoothLook) {
Quaternion newRot = HingeXTransform.rotation;
HingeXTransform.rotation = originalRot;
HingeXTransform.rotation = Quaternion.Lerp(HingeXTransform.rotation, newRot, Time.deltaTime * SmoothLookSpeed);
}
}
if (HingeYTransform) {
originalRot = HingeYTransform.rotation;
HingeYTransform.LookAt(lookAt, Vector3.left);
angleY = HingeYTransform.localEulerAngles.y;
if (angleY > 180) {
angleY -= 360;
}
HingeYTransform.localEulerAngles = new Vector3(0, Mathf.Clamp(angleY, MinYAngle, MaxYAngle), 0);
if (UseSmoothLook) {
Quaternion newRot = HingeYTransform.rotation;
HingeYTransform.rotation = originalRot;
HingeYTransform.rotation = Quaternion.Lerp(HingeYTransform.rotation, newRot, Time.deltaTime * SmoothLookSpeed);
}
}
}
// Return to center if not being held
else if (ReturnToCenterSpeed > 0) {
if (HingeXTransform) {
HingeXTransform.localRotation = Quaternion.Lerp(HingeXTransform.localRotation, Quaternion.identity, Time.deltaTime * ReturnToCenterSpeed);
}
if (HingeYTransform) {
HingeYTransform.localRotation = Quaternion.Lerp(HingeYTransform.localRotation, Quaternion.identity, Time.deltaTime * ReturnToCenterSpeed);
}
}
CallJoystickEvents();
}
}
public virtual void CallJoystickEvents() {
// Call events
angleX = HingeXTransform.localEulerAngles.x;
if (angleX > 180) {
angleX -= 360;
}
angleY = HingeYTransform.localEulerAngles.y;
if (angleY > 180) {
angleY -= 360;
}
LeverPercentageY = (angleX - MinXAngle) / (MaxXAngle - MinXAngle) * 100;
LeverPercentageX = (angleY - MinYAngle) / (MaxYAngle - MinYAngle) * 100;
OnJoystickChange(LeverPercentageX, LeverPercentageY);
// Lever Vector Changed Event
float xInput = Mathf.Lerp(-1f, 1f, LeverPercentageX / 100);
float yInput = Mathf.Lerp(-1f, 1f, LeverPercentageY / 100);
// Reset any values that are inside the deadzone
if (DeadZone > 0) {
if (Mathf.Abs(xInput) < DeadZone) {
xInput = 0;
}
if (Mathf.Abs(yInput) < DeadZone) {
yInput = 0;
}
}
LeverVector = new Vector2(xInput, yInput);
OnJoystickChange(LeverVector);
}
// Callback for lever percentage change
public virtual void OnJoystickChange(float leverX, float leverY) {
if (onJoystickChange != null) {
onJoystickChange.Invoke(leverX, leverY);
}
}
public virtual void OnJoystickChange(Vector2 joystickVector) {
if (onJoystickVectorChange != null) {
onJoystickVectorChange.Invoke(joystickVector);
}
}
}
}