我尝试编写一个脚本来显示手指跟随的 Sprite 。但是我需要这个 Sprite 只能在距 anchor 指定的距离上移动,并且只能在指定的角度之间移动。现在,我有下一个代码:
public class GunPowerController : MonoBehaviour {
public GameObject _fingerprint;
public Transform _anchor;
public Gun _gun;
public float _maxPower = 1f;
public float _maxAngle = 15f;
public float _minAngle = 0f;
private Camera _camera;
private GameObject _fingerprintInstance;
void Awake()
{
_maxPower = Mathf.Abs(_maxPower);
_camera = Camera.main;
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
var touchWorldPosition = _camera.ScreenToWorldPoint(Input.mousePosition);
var hitInfo = Physics2D.Raycast(touchWorldPosition, Vector2.zero);
if (hitInfo && hitInfo.transform.gameObject.Equals(gameObject))
{
touchWorldPosition.z = transform.position.z;
_fingerprintInstance = (GameObject)Instantiate(_fingerprint, touchWorldPosition, Quaternion.identity);
}
}
else if (_fingerprintInstance != null)
{
if (Input.GetMouseButtonUp(0))
{
Destroy(_fingerprintInstance);
}
else
{
var touchWorldPosition = _camera.ScreenToWorldPoint(Input.mousePosition);
Move(touchWorldPosition);
}
}
}
private void Move(Vector3 target)
{
target.z = transform.position.z;
Vector3 distance = target - _anchor.position;
Vector3 axis = _anchor.position;
axis.x = -1f;
float angle = Vector3.Angle(axis, distance) * Mathf.Sign(distance.y - axis.y);
if (distance.sqrMagnitude > _maxPower * _maxPower)
{
distance.Normalize();
distance *= _maxPower;
target = _anchor.position + distance;
}
if(_minAngle > angle)
{
//Here I need to hold vector rotation while the user doesn't
//return to the available space between angles.
}
else if (_maxAngle < angle)
{
//Here I need to hold vector rotation while the user doesn't
//return to the available space between angles.
}
_fingerprintInstance.transform.position = Vector3.Lerp(_fingerprintInstance.transform.position, target,
10f * Time.deltaTime);
}
}
我尝试根据差异 _min|maxAngle - angle
旋转矢量 target
但它工作不正常。怎么做到的?
目前的问题:
附言我重试了很多变体,但没有成功。如果需要一些细节,请写信给我,我会发布。
最佳答案
基本上,我不是试图计算旋转数学,而是在法线(但具有与目标向量相同的幅度)之间 lerp,将其视为零旋转,以及上限向量,并使用矢量超过了目标角度的上限,以确定 lerp 的距离。
public static Vector3 ClampAngle(Vector3 vector, Vector3 normal, float maxAngle, float magnitude = float.NaN)
{
//Get the angle between the normal and the current vector
float angle = Vector3.Angle(normal, vector);
//If the angle isn't greater than max angle, then we don't need to do anything
if(angle > maxAngle)
{
//Avoid sqr root calculation in magnitude if we already know it, otherwise get magnitude from the original vector
if(float.IsNaN(magnitude))
{
magnitude = vector.magnitude;
}
//Value becomes the percentage from zero to our overcapped angle, so by lerping to that percentage place we can shift the vector to the max angle
float value = maxAngle / angle;
//We use the given normal, times the magnitude of the original line to get our un-rotated positon, we then multiply that by value to apropriatlly
//shorten the vector based on how long it would have to have been to be a the same position at a different angle.
//Then we lerp betwen that vector and the original vector to find a vector that has an angle that is not greater than given angle based on the percentage value we got above.
vector = Vector3.Lerp(normal.normalized * magnitude * value, vector, value);
}
//Return the vector
return vector;
}
关于c# - 如何限制矢量的角度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38555988/