322 lines
9.7 KiB
C#
322 lines
9.7 KiB
C#
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<SpriteRenderer>();
|
|
_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<Shaft>();
|
|
var panelShafts = _panel.GetComponentsInChildren<Shaft>();
|
|
_shaftGraph = new ShaftGraph(shafts, panelShafts);
|
|
|
|
_panel.gameObject.SetActive(false);
|
|
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 判断吸附位置
|
|
/// </summary>
|
|
/// <param name="pos">齿轮当前位置</param>
|
|
/// <param name="gearRadius">齿轮半径</param>
|
|
/// <returns>能够被吸附的轴</returns>
|
|
public Shaft CheckClosestShaft(Vector3 pos, float gearRadius)
|
|
{
|
|
return _shaftGraph.QuerySnapShaft(pos, gearRadius);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断齿轮能不能放进轴内
|
|
/// </summary>
|
|
/// <param name="sourceShaft">当前轴</param>
|
|
/// <param name="gearRadius">齿轮半径</param>
|
|
/// <returns>是否可用</returns>
|
|
public bool CheckGearSuitable(Shaft sourceShaft, float gearRadius)
|
|
{
|
|
return _shaftGraph.CheckGearSuitable(sourceShaft, gearRadius);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 某个轴上齿轮发生变化时更新临接关系
|
|
/// </summary>
|
|
/// <param name="shaftId">轴ID</param>
|
|
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();
|
|
// 关盖
|
|
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<GearSystemData>(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<Shaft>(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<Shaft>();
|
|
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<Shaft>();
|
|
newShaft.Load(gearSystemData.panelShaftArray[i]);
|
|
panelShafts[i] = newShaft;
|
|
}
|
|
|
|
_cover = transform.Find("Cover").GetComponent<SpriteRenderer>();
|
|
_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<Shaft>()
|
|
.Select(shaft => shaft.Save())
|
|
.ToArray();
|
|
var panelShaftArray = transform.Find("Empty Shafts Panel")
|
|
.GetComponentsInChildren<Shaft>()
|
|
.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;
|
|
}
|
|
} |