Files
2025-08-13 14:54:13 +08:00

161 lines
4.2 KiB
C#

using System;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
namespace AibisDream.FixSystem
{
public class PipelineSystem : MonoBehaviour
{
#region 组件
[SerializeField] private Transform pipeline;
[SerializeField] private CheckGameHandler checkGameHandler;
[SerializeField] public Transform[] wayPoints;
[SerializeField] private Transform productRoot;
#endregion
#region 运行时数据
private int _curRuleIdx;
private CheckRule[] _checkRules;
private float _curTime;
private float _targetDuration;
private PipelineFactory _pipelineFactory;
private PipelineProduct _selectedProduct;
private CheckRule CurRule => _checkRules[_curRuleIdx];
private int _curProductNum;
private int _recycledProductNum;
public PipelineRes res;
#endregion
public event Action OnGameEnd;
public void Init(CheckRule[] checkRules, CheckData[] datas)
{
gameObject.SetActive(true);
_curRuleIdx = 0;
_checkRules = checkRules;
res = new PipelineRes();
res.totalProductNum = checkRules.Select(x => x.productNum).Sum();
_curTime = 0;
_targetDuration = Random.Range(CurRule.duration.x, CurRule.duration.y);
_pipelineFactory = new PipelineFactory(productRoot, this, datas);
checkGameHandler.LoadRules(CurRule);
_pipelineFactory.Create();
_curProductNum = 1;
_recycledProductNum = 0;
}
private void Update()
{
if (_curRuleIdx < 0)
{
return;
}
_curTime += Time.deltaTime;
if (_curTime > _targetDuration)
{
_curTime = 0;
_targetDuration = Random.Range(CurRule.duration.x, CurRule.duration.y);
_pipelineFactory.Create();
_curProductNum++;
if (_curProductNum >= CurRule.productNum)
{
_curRuleIdx++;
if (_curRuleIdx >= _checkRules.Length)
{
_curRuleIdx = -1;
return;
}
checkGameHandler.LoadRules(CurRule);
_curProductNum = 0;
}
}
}
public void Selected(PipelineProduct product)
{
if (_selectedProduct != null && _selectedProduct != product)
{
_selectedProduct.Deselect();
}
if (_selectedProduct != product)
{
_selectedProduct = product;
OnSelect(product);
}
}
private void OnSelect(PipelineProduct product)
{
checkGameHandler.Handle(product);
}
public void OnProductEnd(PipelineProduct product, bool isSuccess)
{
if (_selectedProduct == product)
{
_selectedProduct = null;
checkGameHandler.Clear();
}
// TODO
if (isSuccess)
{
res.successNum++;
}
else
{
res.failNum++;
}
_recycledProductNum++;
if (_recycledProductNum >= res.totalProductNum)
{
OnGameEnd?.Invoke();
gameObject.SetActive(false);
}
}
private void OnDrawGizmos()
{
DrawPipeline();
}
private void DrawPipeline()
{
if (wayPoints == null || wayPoints.Length < 2)
return;
for (int i = 0; i < wayPoints.Length - 1; i++)
{
Gizmos.color = Color.red;
Gizmos.DrawLine(wayPoints[i].position, wayPoints[i + 1].position);
}
}
}
public struct PipelineRes
{
public int totalProductNum;
public int successNum;
public int failNum;
}
}