Skip to content

Instantly share code, notes, and snippets.

@benthroop
Last active August 8, 2022 21:50
Show Gist options
  • Save benthroop/8fe0a3a9e192c37dd4b31d265e479c1f to your computer and use it in GitHub Desktop.
Save benthroop/8fe0a3a9e192c37dd4b31d265e479c1f to your computer and use it in GitHub Desktop.
Unity Clamp Direction Angle
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ClampDirection : MonoBehaviour
{
public Transform targetObj;
public float clampAngle;
public Vector3 clampedDir;
public float smooth;
private void Update()
{
Vector3 dir = targetObj.position - transform.position;
Debug.DrawRay(transform.position, dir.normalized * 3f, Color.green);
Debug.DrawRay(transform.position, transform.forward * 3f, Color.red);
var newClampedDir = GetClampedDirection(dir, transform.forward, transform.up, clampAngle);
clampedDir = Vector3.Slerp(clampedDir, newClampedDir, smooth * Time.smoothDeltaTime);
Debug.DrawRay(transform.position, clampedDir * 3f, Color.cyan);
}
public Vector3 GetClampedDirection(Vector3 currentDir, Vector3 basisDir, Vector3 up, float maxAngle)
{
float APPROX_180 = 179.0f;
float angle = Vector3.SignedAngle(basisDir, currentDir, up);
var ratio = Mathf.Abs(angle) / APPROX_180;
ratio = Mathf.Clamp(ratio, 0f, maxAngle / APPROX_180);
var behindLeftRotation = Quaternion.AngleAxis(-APPROX_180, up);
var behindRightRotation = Quaternion.AngleAxis(APPROX_180, up);
var behindLeftVector = behindLeftRotation * basisDir;
var behindRightVector = behindRightRotation * basisDir;
var newClampedDir = currentDir;
if (angle < 0f)
{
newClampedDir = Vector3.Slerp(transform.forward, behindLeftVector, ratio);
}
else
{
newClampedDir = Vector3.Slerp(transform.forward, behindRightVector, ratio);
}
return newClampedDir;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment