using System; using AibisDream.Utility; using UnityEngine; namespace AibisDream { public class EngineSystem : MonoBehaviour { [SerializeField] private float oilDownRatio; [SerializeField] private float oilUpRatio; [SerializeField] private float acceleratedSpeed; [SerializeField] private float resistance; [SerializeField] private float airMaxRatio; [SerializeField] private float airMinRatio; [SerializeField] private float baseAirMax; [SerializeField] public int maxLevel; private EngineData _engineData; public event Action UpdateDashboard; private void OnEnable() { _engineData = new EngineData(); } private void Update() { // 更新部分按时间自然计算的指标 DataAutoChange(); // 更新看板 UpdateDashboard?.Invoke(_engineData); } private void DataAutoChange() { // 自然减速 _engineData.OilChange(-oilDownRatio); _engineData.CalcAir(airMaxRatio, airMinRatio, baseAirMax); // 推算速度 _engineData.CalcSpeed(acceleratedSpeed, resistance); } /// /// 加速过程 /// public void AddOil() { _engineData.OilChange(oilUpRatio); } public void SubtractAirLevel() { _engineData.SubtractAirLevel(); } public void AddAirLevel() { _engineData.AddAirLevel(); } } public struct EngineData { public float curSpeed; public float curOil; public float curAir; public float curAirMin; public float curAirMax; public int curAirLevel; public void OilChange(float oilChangeRatio) { curOil = CommonUtil.LimitedAdd(curOil, oilChangeRatio * Time.deltaTime, 1f, 0f); } public void CalcSpeed(float acceleratedSpeed, float resistance) { var addNum = InAirLevel() ? (curOil * acceleratedSpeed - curSpeed * resistance) * Time.deltaTime : -curSpeed * resistance * Time.deltaTime; curSpeed = CommonUtil.LimitedAdd(curSpeed, addNum, 1f, 0f); } public void CalcAir(float airMaxRatio, float airMinRatio, float baseAirMax) { curAir = curOil; curAirMax = curSpeed * (curAirLevel + 1) * airMaxRatio + baseAirMax; curAirMin = curSpeed * (curAirLevel + 1) * airMinRatio; } public void AddAirLevel() { curAirLevel += 1; if (curAirLevel > 5) { curAirLevel = 4; } if (curAirLevel < 0) { curAirLevel = 0; } } public void SubtractAirLevel() { curAirLevel -= 1; if (curAirLevel > 5) { curAirLevel = 4; } if (curAirLevel < 0) { curAirLevel = 0; } } private bool InAirLevel() { return curAir <= curAirMax && curAir >= curAirMin; } } }