68 lines
2.6 KiB
C#
68 lines
2.6 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
public class HeadMovement : MonoBehaviour
|
||
{
|
||
///目前暂时暴露成PUBLIC以方便调试
|
||
public Transform kTargetLookAt = null;/*看向的目标*/
|
||
public Transform kHeadTrs = null;/*头*/
|
||
public Transform kRoot = null;/*PLAYER的根节点*/
|
||
public float fEurlAngleRangeCheck = 80f;/*头部每次转向的最大角度(会分别检查头部3个轴的转向分量)*/
|
||
public float fMaxDistance = 8f;/*距离目标超过这个距离,就不注视*/
|
||
public float fMinDistance = 0.5f;/*距离目标超过小于这个距离,就不注视*/
|
||
public float fLerpSpeed = 0.3f;/*头部转向运动的插值,建议在0.3左右*/
|
||
|
||
//上一祯的头部旋转量(相对世界坐标)
|
||
private Quaternion kLastFace2 = Quaternion.identity;
|
||
void LateUpdate()
|
||
{
|
||
if (kTargetLookAt == null)
|
||
{
|
||
return;
|
||
}
|
||
if (kLastFace2.Equals(Quaternion.identity))
|
||
{
|
||
kLastFace2 = kHeadTrs.rotation;
|
||
}
|
||
Vector3 _vecDirDst =
|
||
(kTargetLookAt.transform.position - kHeadTrs.position).normalized;
|
||
float _fDistance =
|
||
Vector3.Distance(kRoot.position, kTargetLookAt.position);
|
||
Quaternion _kSrcDstQuDlt = Quaternion.FromToRotation(kRoot.forward, _vecDirDst);
|
||
if (this._checkFloatEurlRange(_kSrcDstQuDlt.eulerAngles, fEurlAngleRangeCheck) == false || _fDistance > fMaxDistance || _fDistance < fMinDistance)
|
||
{///处于越界状态,这个时候,头要往正常地转
|
||
_vecDirDst = kRoot.forward;
|
||
}
|
||
Quaternion _quSrc = kRoot.rotation;
|
||
kRoot.forward = _vecDirDst;
|
||
Quaternion _quChild = Quaternion.Lerp(kLastFace2, kHeadTrs.rotation, fLerpSpeed);
|
||
kRoot.rotation = _quSrc;
|
||
kHeadTrs.rotation = _quChild;
|
||
kLastFace2 = _quChild;
|
||
}
|
||
|
||
///对3个角度分量进行检查,如果超过_fRangeAbs
|
||
bool _checkFloatEurlRange(Vector3 _vecSrc, float _fRangeAbs)
|
||
{
|
||
float _fRangeAbs_ = Mathf.Abs(_fRangeAbs);
|
||
float[] _fTempArr = new float[] { _vecSrc.x, _vecSrc.y, _vecSrc.z };
|
||
for (int _iCounter = 0;_iCounter < _fTempArr.Length;++_iCounter)
|
||
{
|
||
_fTempArr[_iCounter] = Mathf.Abs(_fTempArr[_iCounter]);
|
||
if (_fTempArr[_iCounter] >= 0f && _fTempArr[_iCounter] < _fRangeAbs_)
|
||
{
|
||
continue;
|
||
}
|
||
if (_fTempArr[_iCounter] >= 360f - _fRangeAbs_ && _fTempArr[_iCounter] < 360f)
|
||
{
|
||
continue;
|
||
}
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
}
|