using System; using AibisDream.FixSystem; using AibisDream.Framework; using AibisDream.Utility; using Cinemachine; using UnityEngine; using UnityEngine.Events; namespace AibisDream { public class EngineSystem : MonoBehaviour { private CordPull _cordPull; private StaticGear _centerGear; [Header("系统配置")] public EngineConfig engineConfig; [Header("系统数据")] public EngineData engineData; public bool isAvailable; [HideInInspector] public UnityEvent updateSpeedEvent = new(); [SerializeField] private float coverMoveDuration = 5f; [SerializeField] private float coverMoveDistance = 2.8f; private void Awake() { FixSystemCenter.SystemDic.Register(this); _cordPull = transform.Find("拉绳").GetComponent(); _centerGear = transform.Find("中央齿轮").GetComponent(); _centerGear.initSpeed = engineConfig.gearSpeed; // 注册相机 var virtualCam = transform.Find("Engine Camera").GetComponentInChildren(); CameraKit.Instance.RegisterCamera(CameraEnum.Engine, virtualCam); } private void Start() { // 初始化数据 engineData = new EngineData { config = engineConfig }; _centerGear.StartRotate(); } private void OnDestroy() { CameraKit.Instance.UnRegisterCamera(CameraEnum.Engine); } public void Update() { // 收集数据 engineData.curOil = _cordPull.GetCurOil(); // 更新数据 engineData.CalcSpeed(); // 传递速度 updateSpeedEvent.Invoke(engineData.GetRealSpeed()); if (engineData.CheckSuccess()) { Debug.Log("引擎成功"); DialogController.Instance?.StartDialogNode("EngineSuccess"); } } /// /// 开启系统交互 /// public void EnableSystem() { isAvailable = true; } /// /// 关闭系统交互 /// public void DisableSystem() { isAvailable = false; } } [Serializable] public struct EngineConfig { [Header("油门倍率")] public float oilRate; [Header("阻力倍率")] public float resistance; [Header("齿轮基础速度")] public float gearSpeed; [Header("齿轮速度倍率")] public float speedRate; [Header("成功所需时间")] public float targetDuration; [Header("拉绳最大速度")] public float pullMaxSpeed; [Header("拉绳回缩速度")] public float returnSpeed; } [Serializable] public struct EngineData { public EngineConfig config; public float curSpeed; public float curOil; public float curAcceleration; public bool isSuccess; public float reachTargetTime; public void CalcSpeed() { if (curOil != 0) { curAcceleration = curAcceleration < 0 ? 0 : curAcceleration; curAcceleration = CommonUtil.Limit(curOil * config.oilRate * Time.deltaTime + curAcceleration, 100, 0); } else { curAcceleration = -config.resistance * (1f + curSpeed); } curSpeed = CommonUtil.Limit(curSpeed + curAcceleration * Time.deltaTime, 1, 0); } public bool CheckSuccess() { // 已经成功就不用校验了 if (isSuccess) return false; if (curSpeed >= 0.95f) { reachTargetTime += Time.deltaTime; } else { reachTargetTime = 0; } // 如果速度达标时间足够就判断成功 if (!(reachTargetTime >= config.targetDuration)) return false; isSuccess = true; return true; } /// /// 获取处理后的速度 /// /// 速度 public float GetRealSpeed() { return 1 + curSpeed * config.speedRate; } } }