using UnityEngine; using UnityEngine.UIElements; public class DataFlowUnit : MonoBehaviour { protected Transform _transform; protected Transform _rendererTransform; protected Transform _anchorPointTransform; //首尾位置 [SerializeField] private float _startPointXPos; [SerializeField] private float _startPointYPos; [SerializeField] private float _endPointXPos; [SerializeField] private float _endPointYPos; //起始时间 [SerializeField] private float _startTime; [SerializeField] private float _endTime; SongInformationContainer _songInformation; BPMGroup _BPMGroup; /// /// 现在时间与结束点时间的差值 /// private float currentTimeInterval { get { if(_endTime - _songInformation.SongCurrentTime >= 0) { return _endTime - _songInformation.SongCurrentTime; } else return -(_endTime -_songInformation.SongCurrentTime); } } /// /// 开始时间与结束时间的差值 /// private float timeInterval { get { return _endTime - _startTime; } } /// /// 使用相似三角形原理,对两点之间进行随时间的线性插值 /// /// public Vector3 _startPoint { get { //目前时间处于两点中间, if (_songInformation.SongCurrentTime < _endTime && _songInformation.SongCurrentTime >= _startTime) { return new( _endPointXPos - currentTimeInterval * (_endPointXPos - _startPointXPos) / timeInterval, _endPointYPos - currentTimeInterval * (_endPointYPos - _startPointYPos) / timeInterval, 0 ); } //最后应该与结束点重合 if (_songInformation.SongCurrentTime >= _endTime) { return _endPoint; } //在开始时间还大于现在时间的情况下 return new( _startPointXPos, _startPointYPos, _BPMGroup.CurrentNoteSpeed * (_startTime - _songInformation.SongCurrentTime) ); } } private Vector3 _endPoint { get { return new( _endPointXPos, _endPointYPos, _BPMGroup.CurrentNoteSpeed * (_endTime - _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 _width = 0.4f; #endregion void Awake() { _transform = gameObject.GetComponent(); _rendererMeshFilter = _transform.Find("Renderer").GetComponent(); _rendererTransform = _transform.Find("Renderer").GetComponent(); _anchorPointTransform = _transform.Find("HeadAnchorPoint").GetComponent(); //将mesh标记为动态 _rendererMeshFilter.mesh.MarkDynamic(); } void Update() { //渲染层的更新,包括Mesh以及判定点 UpdateRenderer(_songInformation.SongCurrentTime); UpdateAnchorPoint(_songInformation.SongCurrentTime); if (Input.GetKeyDown(KeyCode.A)&& _songInformation.SongCurrentTime>=_startTime) { Debug.Log(this.ToString()); } } public override string ToString() { return $"开始时间{_startTime}\n"+ $"结束时间{_endTime}\n"+ $"目前开始点的位置{_startPoint}\n" + $"目前结束点的位置{_endPoint}"; } /// /// 用于更新渲染层 /// void UpdateRenderer(float currentTime) { _rendererMeshFilter.mesh.Clear(); _rendererMeshFilter.mesh = MeshEditor.DrawMeshByCoordinates(_rendererMeshFilter.mesh, _vertex, _triangles, _uvs, _startPoint, _endPoint, _width); //处于不生成生成范围时,调整为关闭状态并且返回 if (currentTime > _endTime) { _rendererTransform.gameObject.SetActive(false); return; } _rendererTransform.gameObject.SetActive(true); } /// /// 更新头部定位点的位置 /// void UpdateAnchorPoint(float currentTime) { _anchorPointTransform.position = new Vector3(_startPoint.x, _startPoint.y, 0); //处于不生成生成范围时,调整为关闭状态并且返回 if (currentTime < _startTime - _BPMGroup.InitializeOffset || currentTime > _endTime) { _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) { //赋值坐标 _startPointXPos = startPoint.x; _startPointYPos = startPoint.y; _endPointXPos = endPoint.x; _endPointYPos = endPoint.y; //给属性赋值 _width = width; _songInformation = container; //获得时间 _startTime = startTime; _endTime = endTime; _anchorPointTransform.gameObject.SetActive(false); _BPMGroup = timing; } }