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; } }