Skip to content

Instantly share code, notes, and snippets.

@eman41
Last active June 4, 2017 18:43
Show Gist options
  • Save eman41/c635d84207a35eec2a882f604793bd68 to your computer and use it in GitHub Desktop.
Save eman41/c635d84207a35eec2a882f604793bd68 to your computer and use it in GitHub Desktop.
Two axis joystick rotation
// Joystick.cs - 06/02/2017
// Eric Policaro
using UnityEngine;
namespace Esp.Entity
{
public class Joystick : MonoBehaviour
{
public Transform Target;
[Header("Joystick Handle")]
public Transform TopOfHandle;
public Transform HandleJoint;
public float LengthOfHandle = 0.8f;
[Header("Movement Limits")]
[Range(0f, 90f)]
public float MaxAngle = 60f;
public float SmoothingSpeed = 100f;
public float WiggleRoom = 0.025f;
[Header("[RUNTIME]")]
[Range(0f, 1f)]
public float Normalized;
public Vector3 InputDirection;
void OnDrawGizmosSelected()
{
Color c = Gizmos.color;
Gizmos.color = Color.cyan;
Gizmos.DrawWireSphere(TopOfHandle.position, WiggleRoom);
Gizmos.color = c;
}
void Update()
{
// Direciton of the pull, normalized to the orientation of the joystick
Vector3 toTarget = (Target.position - transform.position);
Vector3 dir = transform.InverseTransformDirection(
Vector3.ProjectOnPlane(toTarget, transform.up).normalized);
dir.y = 0f;
// Deflection amount of the stick
float alpha = Vector3.Angle(transform.up, toTarget);
Normalized = Mathf.InverseLerp(0f, MaxAngle, alpha);
// Rotate a small amount around the origin
if (toTarget.magnitude <= WiggleRoom)
{
Quaternion target = Quaternion.FromToRotation(
transform.InverseTransformDirection(transform.up),
toTarget);
HandleJoint.rotation = Quaternion.RotateTowards(
HandleJoint.rotation, target, SmoothingSpeed * Time.deltaTime);
}
else
{
// If we go too far, lock in to the dominant cardinal direction
Quaternion target;
if (Mathf.Abs(dir.z) > Mathf.Abs(dir.x))
{
dir.x = 0f;
target = GetClampedRelativeRotation(dir.z, transform.right);
}
else
{
dir.z = 0f;
target = GetClampedRelativeRotation(-dir.x, transform.forward);
}
HandleJoint.localRotation = Quaternion.RotateTowards(
HandleJoint.localRotation, target, SmoothingSpeed * Time.deltaTime);
}
// Set the joystick input value, this is a valid value regardless of orientation
InputDirection = dir * Normalized;
}
private Quaternion GetClampedRelativeRotation(float lockedDirection, Vector3 rotateAxis)
{
float scale = MaxAngle * Normalized * Mathf.Sign(lockedDirection);
Vector3 localDirection = transform.InverseTransformDirection(rotateAxis);
return Quaternion.Euler(scale * localDirection);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment