using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; using UnityEngine.Events; namespace AibisDream.FixSystem { public class BodyModuleSystem : SystemHasData { public static string DataPath = Application.streamingAssetsPath + "/LevelData/BodyModuleSystem/"; #region 内部索引 public BodyModule[] BodyModules { get; private set; } public CableSystem CableSystem { get; private set; } public GameObject bodyModulePrefab; public Transform bodyModuleGroup; #endregion #region 数据保存相关 public override string CurDataKey { get; set; } private string[] _keyOptions; #endregion #region 事件 [HideInInspector] public UnityEvent plugInEvent; [HideInInspector] public UnityEvent plugOutEvent; #endregion [SerializeField] public float plugSnappingRange = 1f; private void Awake() { InitComponentRefs(); } private void InitComponentRefs() { // 处理内部索引 BodyModules = transform.GetComponentsInChildren(); CableSystem = transform.Find("Cable System").GetComponent(); bodyModuleGroup = transform.Find("Body Module Group"); FixSystemCenter.SystemDic.Register(this); } /// /// 寻找最接近的Module /// /// 源位置 /// 最近的Module /// 是否能找到目标范围内的Module public bool TryFindClosestModule(Vector3 sourcePos, out BodyModule targetModule) { var closestDistance = Mathf.Infinity; BodyModule closestModule = null; // 寻找最接近的BodyModule foreach (var bodyModule in BodyModules) { float tempDistance = Vector3.Distance(sourcePos, bodyModule.GetSocketPos()); if (tempDistance < closestDistance) { closestDistance = tempDistance; closestModule = bodyModule; } } // 判断距离是否在目标范围内,在的话就返回,不在的话返回个空的 if (closestDistance < plugSnappingRange && closestModule) { targetModule = closestModule; return true; } else { targetModule = null; return false; } } /// /// 深入检查 /// public void HandleDeepIn() { if (CableSystem.curBodyModule) { CableSystem.curBodyModule.DeepIn(); } } #region 数据加载与保存 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 // 加载数据 LoadData(data); } private void LoadData(BodyModuleSystemData systemData) { var oldModules = GetComponentsInChildren(); // 先销毁旧的Module foreach (var oldModule in oldModules) { #if UNITY_EDITOR DestroyImmediate(oldModule.gameObject); #else Destory(oldModule); #endif } // 再加载新的Module foreach (var newModuleData in systemData.moduleDataArray) { BodyModule newModule = Instantiate(bodyModulePrefab, bodyModuleGroup).GetComponent(); newModule.Load(newModuleData); } } 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 oldModules = GetComponentsInChildren(); var moduleDataArray = new BodyModuleData[oldModules.Length]; for (int i = 0; i < oldModules.Length; i++) { moduleDataArray[i] = oldModules[i].Save(); } var systemData = new BodyModuleSystemData { moduleDataArray = moduleDataArray }; ConfigUtil.Instance.SaveConfig(systemData, DataPath + key); } public void AddBodyModule() { Instantiate(bodyModulePrefab, bodyModuleGroup); } #endregion /// /// 插线系统是否插在插槽里 /// /// public bool IsPlugInSocket() { return CableSystem.curSocket != null; } } public struct BodyModuleSystemData { public BodyModuleData[] moduleDataArray; } }