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; [Header("系统数据")] [SerializeField] 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 UpdateAirLevel(int curLevel) { engineData.UpdateAirLevel(curLevel, maxLevel); } } [Serializable] 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 UpdateAirLevel(int level, int maxLevel) { curAirLevel = level; if (curAirLevel > maxLevel) { curAirLevel = maxLevel - 1; } if (curAirLevel < 0) { curAirLevel = 0; } } private bool InAirLevel() { return curAir <= curAirMax && curAir >= curAirMin; } } }