using UnityEngine; public class DataFlowUnit : MonoBehaviour { protected Transform _transform; protected Transform _rendererTransform; protected Transform _anchorPointTransform; public RuntimeSnakeData SelfRef; //首尾位置 private float _UnitStartPointXPos; private float _UnitStartPointYPos; private float _UnitEndPointXPos; private float _UnitEndPointYPos; //起始时间 private float _UnitStartTime; private float _UnitEndTime; SongInformationContainer _songInformation; BPMGroup _BPMGroup; /// /// 现在时间与结束点时间的差值 /// private float currentTimeInterval { get { if(_UnitEndTime - _songInformation.SongCurrentTime >= 0) { return _UnitEndTime - _songInformation.SongCurrentTime; } else return -(_UnitEndTime -_songInformation.SongCurrentTime); } } /// /// 开始时间与结束时间的差值 /// private float timeInterval { get { return _UnitEndTime - _UnitStartTime; } } /// /// 使用相似三角形原理,对两点之间进行随时间的线性插值 /// /// public Vector3 _startPoint { get { //目前时间处于两点中间, if (_songInformation.SongCurrentTime < _UnitEndTime && _songInformation.SongCurrentTime >= _UnitStartTime) { return new( _UnitEndPointXPos - currentTimeInterval * (_UnitEndPointXPos - _UnitStartPointXPos) / timeInterval, _UnitEndPointYPos - currentTimeInterval * (_UnitEndPointYPos - _UnitStartPointYPos) / timeInterval, 0 ); } //最后应该与结束点重合 if (_songInformation.SongCurrentTime >= _UnitEndTime) { return _endPoint; } //在开始时间还大于现在时间的情况下 return new( _UnitStartPointXPos, _UnitStartPointYPos, _BPMGroup.CurrentNoteSpeed * (_UnitStartTime - _songInformation.SongCurrentTime) ); } } private Vector3 _endPoint { get { return new( _UnitEndPointXPos, _UnitEndPointYPos, _BPMGroup.CurrentNoteSpeed * (_UnitEndTime - _songInformation.SongCurrentTime) ); } } #region Mesh相关字段 private MeshFilter _rendererMeshFilter; private int[] _triangles = new int[] { //front 2,1,0, 0,3,2, //left 4,5,6, 4,6,7, //back 9,11,8, 9,10,11, //right 12,13,14, 12,14,15, //up 16,17,18, 16,18,19, //buttom 21,23,22, 21,20,23, }; private Vector2[] _uvs = new Vector2[] { // Front new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f), new Vector2(0.0f, 0.0f), // Left new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), // Back new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(1.0f, 0.0f), new Vector2(0.0f, 0.0f), // Right new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), //// Top new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), // Bottom new Vector2(0.0f, 0.0f), new Vector2(1.0f, 0.0f), new Vector2(1.0f, 1.0f), new Vector2(0.0f, 1.0f), }; private Vector3[] _vertex = new Vector3[24]; private float _unitWidth = 0.4f; #endregion public DataFlowUnitAnchorController _anchorController; void Awake() { _transform = gameObject.GetComponent(); _rendererMeshFilter = _transform.Find("Renderer").GetComponent(); _rendererTransform = _transform.Find("Renderer").GetComponent(); _anchorPointTransform = _transform.Find("HeadAnchorPoint").GetComponent(); //由于锚点是独立于物件存在的,所以需要额外设置脚本 _anchorController = _anchorPointTransform.gameObject.GetComponent(); //将mesh标记为动态 _rendererMeshFilter.mesh.MarkDynamic(); } void Update() { //渲染层的更新,包括Mesh以及判定点 UpdateRenderer(_songInformation.SongCurrentTime); UpdateAnchorPoint(_songInformation.SongCurrentTime); if (Input.GetKeyDown(KeyCode.A)&& _songInformation.SongCurrentTime>=_UnitStartTime) { Debug.Log(this.ToString()); } } public override string ToString() { return $"开始时间{_UnitStartTime}\n"+ $"结束时间{_UnitEndTime}\n"+ $"目前开始点的位置{_startPoint}\n" + $"目前结束点的位置{_endPoint}"; } /// /// 用于更新渲染层 /// void UpdateRenderer(float currentTime) { _rendererMeshFilter.mesh.Clear(); _rendererMeshFilter.mesh = MeshEditor.DrawMeshByCoordinates(_rendererMeshFilter.mesh, _vertex, _triangles, _uvs, _startPoint, _endPoint, _unitWidth); //处于不生成生成范围时,调整为关闭状态并且返回 if (currentTime > _UnitEndTime) { _rendererTransform.gameObject.SetActive(false); return; } _rendererTransform.gameObject.SetActive(true); } /// /// 更新头部定位点的位置 /// void UpdateAnchorPoint(float currentTime) { _anchorPointTransform.position = new Vector3(_startPoint.x, _startPoint.y, 0); //处于不生成生成范围时,调整为关闭状态并且返回 if (currentTime < _UnitStartTime - _BPMGroup.InitializeOffset || currentTime > _UnitEndTime) { _anchorPointTransform.gameObject.SetActive(false); return; } //发现自己已经开启时,返回 if (_anchorPointTransform.gameObject.activeSelf == true) { return; } _anchorPointTransform.gameObject.SetActive(true); } public void Init(Vector2 startPoint, Vector2 endPoint, float startTime, float endTime, float width, SongInformationContainer container, BPMGroup timing) { //赋值坐标 _UnitStartPointXPos = startPoint.x; _UnitStartPointYPos = startPoint.y; _UnitEndPointXPos = endPoint.x; _UnitEndPointYPos = endPoint.y; //给属性赋值 _unitWidth = width; _songInformation = container; //获得时间 _UnitStartTime = startTime; _UnitEndTime = endTime; _anchorPointTransform.gameObject.SetActive(false); _BPMGroup = timing; Debug.Log(SelfRef); _anchorController.SetSelfRef(SelfRef); } }