using System; using System.Collections; using System.Linq; using AibisDream.FixSystem; using AibisDream.Framework; using AibisDream.Kit; using Cinemachine; using DG.Tweening; using UnityEditor; using UnityEngine; namespace AibisDream { public class GearSystem : SystemHasData { #region 索引 public GameObject gearPrefab; public GameObject shaftPrefab; private Transform _panel; private SpriteRenderer _cover; private Transform _coverStick; private Transform _needle; private ShaftGraph _shaftGraph; #endregion public Vector3 coverUpPos; public Vector3 coverDownPos; public Vector3 panelOpenPos; public Vector3 panelClosePos; public Vector3 needleEmptyPos; public Vector3[] needlePosArr; public float needleDuration; private bool _isTargetReached; private bool _isDiscReady; public bool isAvailable; public float initSpeed = 1; private void Awake() { Init(); } #region 生命周期管理 public void Init() { FixSystemCenter.SystemDic.Register(this); _cover = transform.Find("Cover").GetComponent(); _coverStick = transform.Find("Cover Stick"); _panel = transform.Find("Empty Shafts Panel"); _needle = transform.Find("Needle"); // 注册相机 var virtualCam = transform.Find("Gear Camera").GetComponent(); CameraKit.Instance.RegisterCamera(CameraEnum.Gear, virtualCam); } private void Start() { InitShaftGraph(); LinkEngineSpeed(); } private void InitShaftGraph() { var shafts = transform.Find("Shafts").GetComponentsInChildren(); var panelShafts = _panel.GetComponentsInChildren(); _shaftGraph = new ShaftGraph(shafts, panelShafts); } private void LinkEngineSpeed() { var engine = FixSystemCenter.SystemDic.Get(); _shaftGraph.StartRotate(initSpeed); engine.updateSpeedEvent.AddListener(_shaftGraph.Accelerate); } private void UnlinkEngineSpeed() { var engine = FixSystemCenter.SystemDic.Get(); _shaftGraph.StartRotate(initSpeed); engine.updateSpeedEvent.RemoveListener(_shaftGraph.Accelerate); } private void OnDestroy() { CameraKit.Instance.UnRegisterCamera(CameraEnum.Gear); } #endregion /// /// 判断吸附位置 /// /// 齿轮当前位置 /// 齿轮半径 /// 能够被吸附的轴 public Shaft CheckClosestShaft(Vector3 pos, float gearRadius) { return _shaftGraph.QuerySnapShaft(pos, gearRadius); } /// /// 判断齿轮能不能放进轴内 /// /// 当前轴 /// 齿轮半径 /// 是否可用 public bool CheckGearSuitable(Shaft sourceShaft, float gearRadius) { return _shaftGraph.CheckGearSuitable(sourceShaft, gearRadius); } /// /// 某个轴上齿轮发生变化时更新临接关系 /// /// 轴ID public void ChangeGraphVertex(int shaftId) { _shaftGraph?.ChangeVertex(shaftId); } /// /// 按轴名称弹出齿轮 /// /// 轴名称 /// public void PopupGearByShaftName(string shaftName) { var shafts = transform.Find("Shafts").GetComponentsInChildren(); var target = Array.Find(shafts, shaft => shaft.gameObject.name == shaftName); target.PopupGear(); } #region 胜利状况判断 public void CheckGearSystemState() { if (_isTargetReached) { AudioManager.PlayLoop3Audio("gears_running"); } else { AudioManager.PauseLoop3Audio(); } if (_shaftGraph.AllRunning()) { if (_shaftGraph.AllNewGear()) { DialogController.Instance?.SetVariable("$allNewGear", true); } DialogController.Instance?.StartDialogNode("AllGearsRunning"); } } public void ReachTargetSpeed() { if (!_isTargetReached) { DialogController.Instance?.SetVariable("$speedReached", true); _isTargetReached = true; } } public void ResetTargetState() { if (_isTargetReached) { DialogController.Instance?.SetVariable("$speedReached", false); _isTargetReached = false; } } #endregion public IEnumerator OpenCover() { AudioManager.PlayLoop2Audio("amb_gearbox"); // 旋转拉杆 yield return _coverStick.DORotate(new Vector3(0, 0, -90), 1.5f).WaitForCompletion(); // 开盖 var sq = DOTween.Sequence(); sq.Join(_cover.transform.DOLocalMove(coverUpPos, 1.5f)); sq.Join(_cover.DOFade(0, 1.5f)); yield return sq.WaitForCompletion(); isAvailable = true; } public IEnumerator CloseCover() { isAvailable = false; AudioManager.PauseLoopAudio(); AudioManager.PauseLoop2Audio(); AudioManager.PauseLoop3Audio(); // 关盖 var sq = DOTween.Sequence(); sq.Join(_cover.transform.DOLocalMove(coverDownPos, 1.5f)); sq.Join(_cover.DOFade(1, 1.5f)); yield return sq.WaitForCompletion(); // 旋转拉杆 yield return _coverStick.DORotate(new Vector3(0, 0, 0), 1.5f).WaitForCompletion(); } public IEnumerator OpenGearPanel() { _panel.gameObject.SetActive(true); yield return _panel.DOLocalMove(panelOpenPos, 1f).WaitForCompletion(); } public IEnumerator CloseGearPanel() { yield return _panel.DOLocalMove(panelClosePos, 1f).WaitForCompletion(); _panel.gameObject.SetActive(false); } public IEnumerator MoveNeedle(int discIdx) { Vector3 target; if (discIdx > needlePosArr.Length || discIdx <= 0) { target = needleEmptyPos; } else { target = needlePosArr[discIdx - 1]; } yield return _needle.DORotate(target, needleDuration).WaitForCompletion(); } #region 数据保存与加载 public static string DataPath = Application.streamingAssetsPath + "/LevelData/GearSystem/"; private string[] _keyOptions; public override string CurDataKey { get; set; } public override string GetConfigPath() { return DataPath; } public override void LoadLevel() { if (string.IsNullOrEmpty(CurDataKey)) { Debug.Log("配置项名称为空"); return; } if (!ConfigUtil.Instance.TryLoadConfig(DataPath + CurDataKey, out var data)) { Debug.Log("没有找到配置项"); return; } #if UNITY_EDITOR // 现将当前配置保存为temp避免丢失 if (CurDataKey != "temp.json") { SaveByKey("temp.json"); } #endif LoadByData(data); } private void LoadByData(GearSystemData gearSystemData) { // 先清除 var shaftsObj = GetComponentsInChildren(true); foreach (var oldShaft in shaftsObj) { #if UNITY_EDITOR if (!EditorApplication.isPlaying) { DestroyImmediate(oldShaft.gameObject); } else { Destroy(oldShaft.gameObject); } #else Destroy(oldShaft.gameObject); #endif } // 再添加 var shaftRoot = transform.Find("Shafts"); var shafts = new Shaft[gearSystemData.shaftLevelDataArray.Length]; for (int i = 0; i < gearSystemData.shaftLevelDataArray.Length; i++) { var newShaft = Instantiate(shaftPrefab, shaftRoot).GetComponent(); newShaft.Load(gearSystemData.shaftLevelDataArray[i]); shafts[i] = newShaft; } var panelShaftRoot = transform.Find("Empty Shafts Panel"); var panelShafts = new Shaft[gearSystemData.panelShaftArray.Length]; for (int i = 0; i < gearSystemData.panelShaftArray.Length; i++) { var newShaft = Instantiate(shaftPrefab, panelShaftRoot).GetComponent(); newShaft.Load(gearSystemData.panelShaftArray[i]); panelShafts[i] = newShaft; } _cover = transform.Find("Cover").GetComponent(); _coverStick = transform.Find("Cover Stick"); _panel = transform.Find("Empty Shafts Panel"); #if UNITY_EDITOR if (!EditorApplication.isPlaying) return; #endif UnlinkEngineSpeed(); _shaftGraph = new ShaftGraph(shafts, panelShafts); LinkEngineSpeed(); } public override void SaveLevel() { if (string.IsNullOrEmpty(CurDataKey)) return; SaveByKey(CurDataKey); } private void SaveByKey(string key) { var shaftDataArray = transform.Find("Shafts") .GetComponentsInChildren() .Select(shaft => shaft.Save()) .ToArray(); var panelShaftArray = transform.Find("Empty Shafts Panel") .GetComponentsInChildren() .Select(shaft => shaft.Save()) .ToArray(); var data = new GearSystemData { shaftLevelDataArray = shaftDataArray, panelShaftArray = panelShaftArray }; ConfigUtil.Instance.SaveConfig(data, DataPath + key); } public void AddShaft() { var shaftRoot = transform.Find("Shafts"); Instantiate(shaftPrefab, shaftRoot); } public void LoadPanelShaft(string dataKey) { // 查询 if (!ConfigUtil.Instance.TryLoadConfig(DataPath + dataKey, out var data)) { Debug.Log("没有找到配置项"); return; } // 删除面板上的齿轮 var panelShafts = transform.Find("Empty Shafts Panel").GetComponentsInChildren(); foreach (var shaftItem in panelShafts) { Destroy(shaftItem); } // 读取数据 var panelShaftRoot = transform.Find("Empty Shafts Panel"); var newPanelShafts = new Shaft[data.panelShaftArray.Length]; for (int i = 0; i < data.panelShaftArray.Length; i++) { var newShaft = Instantiate(shaftPrefab, panelShaftRoot).GetComponent(); newShaft.Load(data.panelShaftArray[i]); newPanelShafts[i] = newShaft; } _shaftGraph.UpdatePanel(newPanelShafts); } #endregion } [Serializable] public struct GearSystemData { public ShaftLevelData[] shaftLevelDataArray; public ShaftLevelData[] panelShaftArray; } }