using System; using System.Collections; using System.Linq; using AibisDream.FixSystem; using AibisDream.Framework; using AibisDream.Kit; 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; 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"); } public void Start() { _shaftGraph?.Clear(); var shafts = transform.Find("Shafts").GetComponentsInChildren(); var panelShafts = _panel.GetComponentsInChildren(); _shaftGraph = new ShaftGraph(shafts, panelShafts); _panel.gameObject.SetActive(false); gameObject.SetActive(false); } #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); } #region 胜利状况判断 public void CheckGearSystemState() { if (_isTargetReached) { AudioManager.PlayLoop3Audio("gears_running"); } else { AudioManager.PauseLoop3Audio(); } DialogController.Instance.StartDialogNode("齿轮系统状态变化"); } 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(); } public IEnumerator CloseCover() { 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[] GetDataKeyOptions() { return _keyOptions ??= ConfigUtil.Instance.GetFileNames(DataPath); } public override void Load() { 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 _shaftGraph?.Clear(); _shaftGraph = new ShaftGraph(shafts, panelShafts); } public override void Save() { if (string.IsNullOrEmpty(CurDataKey)) return; SaveByKey(CurDataKey); if (!_keyOptions.Contains(CurDataKey)) { // 重新读取key _keyOptions = ConfigUtil.Instance.GetFileNames(DataPath); } } 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); } #endregion } [Serializable] public struct GearSystemData { public ShaftLevelData[] shaftLevelDataArray; public ShaftLevelData[] panelShaftArray; } }