aboutsummaryrefslogtreecommitdiff
path: root/Assets/Scripts
diff options
context:
space:
mode:
authorWeicao-CatilGrass <1992414357@qq.com>2026-05-30 19:35:16 +0800
committerWeicao-CatilGrass <1992414357@qq.com>2026-05-30 19:35:16 +0800
commit7735b716401f630697d5b02910d50dbf8f3416af (patch)
tree52d23e7e0434a569bbafdfca6ad196e3ef24af3f /Assets/Scripts
parent4408cc53e044a9c649572991a764f46d247c67bf (diff)
正在编写动态场景加载
Diffstat (limited to 'Assets/Scripts')
-rw-r--r--Assets/Scripts/ActiveGroup.cs52
-rw-r--r--Assets/Scripts/ActiveGroup.cs.meta11
-rw-r--r--Assets/Scripts/AnimatorHandler.cs3
-rw-r--r--Assets/Scripts/Boot.cs23
-rw-r--r--Assets/Scripts/Boot.cs.meta11
-rw-r--r--Assets/Scripts/FragmentManager.cs137
-rw-r--r--Assets/Scripts/FragmentManager.cs.meta11
-rw-r--r--Assets/Scripts/FragmentRequire.cs46
-rw-r--r--Assets/Scripts/FragmentRequire.cs.meta11
-rw-r--r--Assets/Scripts/PlayerPosition.cs30
-rw-r--r--Assets/Scripts/PlayerPosition.cs.meta11
-rw-r--r--Assets/Scripts/SoulCoreGameLoop/UI/AreaHint.cs26
-rw-r--r--Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs39
-rw-r--r--Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs.meta11
-rw-r--r--Assets/Scripts/SoulCoreGameLoop/UI/UIEventListener.cs43
15 files changed, 426 insertions, 39 deletions
diff --git a/Assets/Scripts/ActiveGroup.cs b/Assets/Scripts/ActiveGroup.cs
new file mode 100644
index 0000000..c2e32d0
--- /dev/null
+++ b/Assets/Scripts/ActiveGroup.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using UnityEngine;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+[ExecuteAlways]
+public class ActiveGroup : MonoBehaviour
+{
+ public List<GameObject> members = new();
+
+ private void Awake()
+ {
+ foreach (var member in members)
+ member.SetActive(gameObject.activeSelf);
+
+ MarkDirty();
+ }
+
+ private void OnEnable()
+ {
+ foreach (var member in members)
+ member.SetActive(true);
+
+ MarkDirty();
+ }
+
+ private void OnDisable()
+ {
+ foreach (var member in members)
+ member.SetActive(false);
+
+ MarkDirty();
+ }
+
+#if UNITY_EDITOR
+ private void OnValidate()
+ {
+ if (!Application.isPlaying)
+ EditorUtility.SetDirty(this);
+ }
+
+ private void MarkDirty()
+ {
+ if (!Application.isPlaying)
+ EditorUtility.SetDirty(this);
+ }
+#else
+ // 非编辑器平台下,MarkDirty为空方法
+ private void MarkDirty() { }
+#endif
+} \ No newline at end of file
diff --git a/Assets/Scripts/ActiveGroup.cs.meta b/Assets/Scripts/ActiveGroup.cs.meta
new file mode 100644
index 0000000..4ba3787
--- /dev/null
+++ b/Assets/Scripts/ActiveGroup.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 74b926f5f9539684bbdce17adbc0d976
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/AnimatorHandler.cs b/Assets/Scripts/AnimatorHandler.cs
index 665a1ca..16f0f67 100644
--- a/Assets/Scripts/AnimatorHandler.cs
+++ b/Assets/Scripts/AnimatorHandler.cs
@@ -154,9 +154,6 @@ namespace DS
// 获取当前帧的根运动位移向量
var rootMotion = GetRootMotion();
- // 输出调试日志,用于查看根运动数据
- Debug.Log(rootMotion);
-
// 将根运动数据传递给 PlayerLocomotion 组件
// PlayerLocomotion 会将这些位移应用到角色控制器上
playerLocomotion.rootMotion = rootMotion;
diff --git a/Assets/Scripts/Boot.cs b/Assets/Scripts/Boot.cs
new file mode 100644
index 0000000..ddefd0b
--- /dev/null
+++ b/Assets/Scripts/Boot.cs
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+public class SceneLoader : MonoBehaviour
+{
+ [SerializeField] private List<SceneAsset> scenes;
+
+ private void Awake()
+ {
+ foreach (var sceneAsset in scenes)
+ {
+ string sceneName = sceneAsset.name;
+ if (!SceneManager.GetSceneByName(sceneName).isLoaded)
+ {
+ SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/Boot.cs.meta b/Assets/Scripts/Boot.cs.meta
new file mode 100644
index 0000000..00e0ea0
--- /dev/null
+++ b/Assets/Scripts/Boot.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c4d77beacb22bba47962777552841ef3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/FragmentManager.cs b/Assets/Scripts/FragmentManager.cs
new file mode 100644
index 0000000..3bac110
--- /dev/null
+++ b/Assets/Scripts/FragmentManager.cs
@@ -0,0 +1,137 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+public class FragmentManager : MonoBehaviour
+{
+ private static readonly HashSet<string> LoadedSceneNames = new();
+
+ /// <summary>
+ /// 刷新场景需要列表(基于场景名称)
+ /// </summary>
+ /// <param name="requiredSceneNames">需要的场景名称列表(需与 Build Settings 中的名称一致,不带 .unity 扩展名)</param>
+ public static void UpdateSceneRequirements(List<string> requiredSceneNames)
+ {
+ var toUnload = new List<string>();
+ var toLoad = new List<string>();
+
+ // 需要卸载的:当前已加载但不在 requiredSceneNames 中
+ foreach (var loadedName in LoadedSceneNames)
+ {
+ if (!requiredSceneNames.Contains(loadedName))
+ toUnload.Add(loadedName);
+ }
+
+ // 需要加载的:requiredSceneNames 中尚未加载的
+ foreach (var reqName in requiredSceneNames)
+ {
+ if (!LoadedSceneNames.Contains(reqName))
+ toLoad.Add(reqName);
+ }
+
+ UnloadScenes(toUnload);
+ LoadScenes(toLoad);
+ }
+
+ /// <summary>
+ /// 重置所有场景(先卸载全部,再重新加载)
+ /// </summary>
+ public static void ReloadAllScenes()
+ {
+ var scenesToReload = new List<string>(LoadedSceneNames);
+
+ // 先卸载所有
+ foreach (var sceneName in scenesToReload)
+ {
+ var asyncOp = SceneManager.UnloadSceneAsync(sceneName);
+ if (asyncOp != null)
+ {
+ asyncOp.completed += _ =>
+ {
+ if (LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Remove(sceneName);
+ };
+ }
+ else
+ {
+ // 同步卸载后备(已过时,仅用于兼容)
+ if (SceneManager.UnloadScene(sceneName))
+ LoadedSceneNames.Remove(sceneName);
+ }
+ }
+
+ // 重新加载(注意:卸载异步,立即加载可能导致短暂重叠,但通常可接受)
+ foreach (var sceneName in scenesToReload)
+ {
+ var asyncOp = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
+ if (asyncOp != null)
+ {
+ asyncOp.completed += _ =>
+ {
+ var scene = SceneManager.GetSceneByName(sceneName);
+ if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Add(sceneName);
+ };
+ }
+ else
+ {
+ // 同步加载后备
+ SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
+ var scene = SceneManager.GetSceneByName(sceneName);
+ if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Add(sceneName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 异步卸载场景列表,完成后从 LoadedSceneNames 中移除
+ /// </summary>
+ private static void UnloadScenes(List<string> sceneNames)
+ {
+ foreach (var sceneName in sceneNames)
+ {
+ var asyncOp = SceneManager.UnloadSceneAsync(sceneName);
+ if (asyncOp != null)
+ {
+ asyncOp.completed += _ =>
+ {
+ if (LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Remove(sceneName);
+ };
+ }
+ else
+ {
+ if (SceneManager.UnloadScene(sceneName))
+ LoadedSceneNames.Remove(sceneName);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 异步加载场景列表,完成后加入 LoadedSceneNames
+ /// </summary>
+ private static void LoadScenes(List<string> sceneNames)
+ {
+ foreach (var sceneName in sceneNames)
+ {
+ var asyncOp = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
+ if (asyncOp != null)
+ {
+ asyncOp.completed += _ =>
+ {
+ var scene = SceneManager.GetSceneByName(sceneName);
+ if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Add(sceneName);
+ };
+ }
+ else
+ {
+ SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
+ var scene = SceneManager.GetSceneByName(sceneName);
+ if (scene.isLoaded && !LoadedSceneNames.Contains(sceneName))
+ LoadedSceneNames.Add(sceneName);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Assets/Scripts/FragmentManager.cs.meta b/Assets/Scripts/FragmentManager.cs.meta
new file mode 100644
index 0000000..7427464
--- /dev/null
+++ b/Assets/Scripts/FragmentManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8ed3c0bca3fd03a42bd614ec3abc535d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/FragmentRequire.cs b/Assets/Scripts/FragmentRequire.cs
new file mode 100644
index 0000000..71ce602
--- /dev/null
+++ b/Assets/Scripts/FragmentRequire.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
+[RequireComponent(typeof(BoxCollider))]
+[ExecuteAlways]
+public class FragmentRequire : MonoBehaviour
+{
+ public List<SceneAsset> requiredScenes = new();
+
+ private BoxCollider _boxCollider;
+
+ private void Awake()
+ {
+ _boxCollider = GetComponent<BoxCollider>();
+ _boxCollider.isTrigger = true;
+ }
+
+ private void OnTriggerEnter(Collider other)
+ {
+ var sceneName = new List<string>();
+ foreach (SceneAsset sceneAsset in requiredScenes)
+ sceneName.Add(sceneAsset.name);
+ FragmentManager.UpdateSceneRequirements(sceneName);
+ }
+
+ private void Update()
+ {
+ _boxCollider.size = Vector3.one;
+ }
+
+ private void OnDrawGizmos()
+ {
+ if (_boxCollider == null) return;
+
+ var cs = _boxCollider.size;
+ var ts = Vector3.one;
+ var size = new Vector3(cs.x * ts.x, cs.y * ts.y, cs.z * ts.z);
+
+ Gizmos.color = new Color(1f, 0.18f, 0.29f, 0.5f);
+ Gizmos.matrix = transform.localToWorldMatrix;
+ Gizmos.DrawCube(_boxCollider.center, size);
+ }
+}
diff --git a/Assets/Scripts/FragmentRequire.cs.meta b/Assets/Scripts/FragmentRequire.cs.meta
new file mode 100644
index 0000000..20db4a6
--- /dev/null
+++ b/Assets/Scripts/FragmentRequire.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8b72db117845309468398fb2b199c144
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/PlayerPosition.cs b/Assets/Scripts/PlayerPosition.cs
new file mode 100644
index 0000000..9b839f8
--- /dev/null
+++ b/Assets/Scripts/PlayerPosition.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections;
+using DS;
+using UnityEngine;
+
+public class PlayerPosition : MonoBehaviour
+{
+ private PlayerLocomotion _playerLocomotion;
+
+ private void Awake()
+ {
+ StartCoroutine(FindPlayer());
+ }
+
+ private void Update()
+ {
+ if (_playerLocomotion != null)
+ transform.position = _playerLocomotion.transform.position;
+ }
+
+ IEnumerator FindPlayer()
+ {
+ while (true)
+ {
+ yield return new WaitUntil(() => _playerLocomotion == null);
+ _playerLocomotion = GetComponent<PlayerLocomotion>();
+ yield return new WaitForSeconds(5f);
+ }
+ }
+}
diff --git a/Assets/Scripts/PlayerPosition.cs.meta b/Assets/Scripts/PlayerPosition.cs.meta
new file mode 100644
index 0000000..cbe7659
--- /dev/null
+++ b/Assets/Scripts/PlayerPosition.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8035635bcbd329a49b7b0fe4d301f6e5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/SoulCoreGameLoop/UI/AreaHint.cs b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHint.cs
index ab03647..6b676fe 100644
--- a/Assets/Scripts/SoulCoreGameLoop/UI/AreaHint.cs
+++ b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHint.cs
@@ -1,31 +1,31 @@
using System;
-using TMPro;
-using UnityEditor;
using UnityEngine;
+using TMPro;
namespace SoulCoreGameLoop.UI
{
[RequireComponent(typeof(Animator))]
public class AreaHint : MonoBehaviour, IUIEventSender<AreaHintMessage>
{
- private const String TriggerPlay = "Play";
+ private static readonly int TriggerPlay = Animator.StringToHash("Play");
public TMP_Text areaName;
private Animator _animator;
- [InitializeOnLoadMethod]
- public static void RegisterListener ()
- => UIEventListener.JoinListener<AreaHintMessage>();
-
- public void OnReceive(AreaHintMessage evt)
+ private void Awake()
{
- areaName.text = evt.AreaName;
- _animator.Play(TriggerPlay);
+ _animator = GetComponent<Animator>();
+ UIEventListener.Register(this);
}
+
+ private void OnDestroy()
+ => UIEventListener.Unregister<AreaHintMessage>();
+
- private void Start()
+ public void OnReceive(AreaHintMessage evt)
{
- _animator = GetComponent<Animator>();
+ areaName.text = evt.AreaName;
+ _animator.SetTrigger(TriggerPlay);
}
}
@@ -38,4 +38,4 @@ namespace SoulCoreGameLoop.UI
AreaName = areaName;
}
}
-}
+} \ No newline at end of file
diff --git a/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs
new file mode 100644
index 0000000..efc5e5f
--- /dev/null
+++ b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs
@@ -0,0 +1,39 @@
+using UnityEngine;
+
+namespace SoulCoreGameLoop.UI
+{
+ [RequireComponent(typeof(BoxCollider))]
+ public class AreaHintGenerator : MonoBehaviour
+ {
+ [Header("名字")]
+ public new string name = "土豆祭祀场";
+
+ private BoxCollider _collider;
+
+ private void Awake()
+ {
+ _collider = GetComponent<BoxCollider>();
+ _collider.isTrigger = true;
+ }
+
+ private void OnTriggerEnter(Collider other)
+ {
+ Debug.Log("AreaHintGenerator OnTriggerEnter");
+ // 向监听器发送消息
+ UIEventListener.Send(new AreaHintMessage(name));
+ }
+
+ private void OnDrawGizmosSelected()
+ {
+ if (_collider == null) return;
+
+ var cs = _collider.size;
+ var ts = transform.lossyScale;
+ var size = new Vector3(cs.x * ts.x, cs.y * ts.y, cs.z * ts.z);
+
+ Gizmos.color = new Color(1f, 1f, 1f, 0.5f);
+ Gizmos.matrix = transform.localToWorldMatrix;
+ Gizmos.DrawCube(_collider.center, size);
+ }
+ }
+}
diff --git a/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs.meta b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs.meta
new file mode 100644
index 0000000..1282763
--- /dev/null
+++ b/Assets/Scripts/SoulCoreGameLoop/UI/AreaHintGenerator.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 33b85f0adc67b1a43b0e1033f466d85e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/SoulCoreGameLoop/UI/UIEventListener.cs b/Assets/Scripts/SoulCoreGameLoop/UI/UIEventListener.cs
index 2d33a9b..0b17b6f 100644
--- a/Assets/Scripts/SoulCoreGameLoop/UI/UIEventListener.cs
+++ b/Assets/Scripts/SoulCoreGameLoop/UI/UIEventListener.cs
@@ -1,52 +1,49 @@
using System;
using System.Collections.Generic;
-using Object = System.Object;
namespace SoulCoreGameLoop.UI
{
/// <summary>
- /// UI 事件监听器
+ /// UI 事件总线(消息类型 → 处理器)
/// </summary>
public static class UIEventListener
{
- private static readonly Dictionary<TypeCode, Object> TypeSets = new ();
+ private static readonly Dictionary<Type, object> Handlers = new();
/// <summary>
- /// 向 UI 事件监听器添加发送器实例
+ /// 注册某个消息类型的处理器(同一类型只能有一个处理器)
/// </summary>
- /// <typeparam name="T"> 发送器绑定类型 </typeparam>
- public static void JoinListener<T>() where T : new()
+ public static void Register<T>(IUIEventSender<T> handler)
{
- var typeCode = Type.GetTypeCode(typeof(T));
- TypeSets.Add(typeCode, new T());
+ Handlers[typeof(T)] = handler;
}
/// <summary>
- /// 向 UI 事件监听器发送消息
+ /// 移除某个消息类型的处理器
+ /// </summary>
+ public static void Unregister<T>()
+ {
+ Handlers.Remove(typeof(T));
+ }
+
+ /// <summary>
+ /// 发送消息
/// </summary>
- /// <param name="message"> 发送器 </param>
- /// <typeparam name="T"> 消息类型 </typeparam>
public static void Send<T>(T message)
{
- var typeCode = Type.GetTypeCode(typeof(T));
- if (TypeSets.TryGetValue(typeCode, out var set))
+ Type type = typeof(T);
+ if (Handlers.TryGetValue(type, out object handlerObj))
{
- var sender = (IUIEventSender<T>) set;
- sender.OnReceive(message);
+ ((IUIEventSender<T>)handlerObj).OnReceive(message);
}
}
}
/// <summary>
- /// UI 事件发送器
+ /// 消息处理器接口
/// </summary>
- /// <typeparam name="TEvent"></typeparam>
public interface IUIEventSender<in TEvent>
{
- /// <summary>
- /// 当接收到 UI 事件时的处理
- /// </summary>
- /// <param name="evt"></param>
- public void OnReceive(TEvent evt);
+ void OnReceive(TEvent evt);
}
-}
+} \ No newline at end of file