using System; using Sirenix.OdinInspector; using UnityEngine; namespace Game.Component { public class Tentacle2D : MonoBehaviour { public int length; //节点数量 public LineRenderer lineRend; //线段绘制器 private Vector3[] segmentPoses; //节点状态 private Vector3[] _segmentV; private Transform _targetDir; public float targetDist; //单位距离 [Header ("柔韧度,越大越柔韧") , Range (0 , 100)] public float _smoothSpeed; [Header ("拖尾速度")] public float trailSpeed; [BoxGroup ("wiggle"), Header ("波形运动器")] public bool wiggle; [BoxGroup ("wiggle"), ShowIf ("wiggle")] public float wiggleSpeed; [BoxGroup ("wiggle"), ShowIf ("wiggle")] public float wiggleMagnitude; //是否固定长度 public bool HasFixedLength = false; public bool AutoPlay; private Vector3 _defaultAngle; private void Start () { Init (); } private void Update () { UpdateLineRend (); } public void Init () { this._targetDir = this.transform; this.lineRend.positionCount = this.length; this.segmentPoses = new Vector3[this.length]; this._segmentV = new Vector3[this.length]; this._defaultAngle = this._targetDir.localRotation.eulerAngles; ResetPos (); } public void UpdateLineRend () { if (this.wiggle) { this._targetDir.localRotation = Quaternion.Euler (this._defaultAngle.x , this._defaultAngle.y , this._defaultAngle.z + Mathf.Sin (Time.time * this.wiggleSpeed) * this.wiggleMagnitude); } var smoothSpeed = this._smoothSpeed * 0.01f; this.segmentPoses[0] = this._targetDir.position; for (int i = 1; i < this.length; i++) { if (trailSpeed > 0) { this.segmentPoses[i] = Vector3.SmoothDamp (this.segmentPoses[i] , this.segmentPoses[i - 1] - this._targetDir.up * this.targetDist , ref this._segmentV[i] , smoothSpeed + i / this.trailSpeed); } else { Vector3 targetPos = this.segmentPoses[i - 1] + (this.segmentPoses[i] - this.segmentPoses[i - 1]).normalized * this.targetDist; this.segmentPoses[i] = Vector3.SmoothDamp (this.segmentPoses[i] , targetPos , ref this._segmentV[i] , smoothSpeed); } if (HasFixedLength) { this.segmentPoses[i] = this.segmentPoses[i -1] + (this.segmentPoses[i] - this.segmentPoses[i -1]).normalized * (this.targetDist); } } this.lineRend.SetPositions (this.segmentPoses); } private void ResetPos () { this._targetDir.localRotation = Quaternion.Euler (this._defaultAngle); this.segmentPoses[0] = this._targetDir.position; for (int i = 1; i < this.length; i++) this.segmentPoses[i] = this.segmentPoses[i - 1] - this._targetDir.up * this.targetDist; this.lineRend.SetPositions (this.segmentPoses); } } }