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