✅ 项目说明
- 引擎版本建议:Unity 2021.3 LTS 或 Unity 2022+
- 适用于:Top-down RPG、模拟类、策略类等有“世界-角色-行为”结构的项目
- 架构风格:面向接口、职责分离、可单元测试
📁 目录结构
Assets/
├── Scripts/
│ ├── Core/
│ │ ├── GameWorld.cs
│ │ └── GameWorldContext.cs
│ ├── Interfaces/
│ │ ├── IGameContext.cs
│ │ └── IEventDispatcher.cs
│ ├── Characters/
│ │ ├── NPC.cs
│ │ └── Player.cs
│ ├── Events/
│ │ └── DefaultEventDispatcher.cs
│ ├── Tests/
│ │ └── MockGameContext.cs
│ └── Entry/
│ └── GameStartup.cs
└── Scenes/
└── SampleScene.unity
✏️ 脚本模板内容(部分示例)
IGameContext.cs
public interface IGameContext
{
Player GetPlayer();
Vector3 GetSpawnPoint();
IEventDispatcher GetEventDispatcher();
}
IEventDispatcher.cs
public interface IEventDispatcher
{
void Dispatch(string eventName, object data = null);
void Subscribe(string eventName, Action<object> callback);
void Unsubscribe(string eventName, Action<object> callback);
}
GameWorld.cs
using UnityEngine;
public class GameWorld : MonoBehaviour
{
private GameWorldContext context;
private Player player;
private List<NPC> npcs = new();
private void Awake()
{
context = new GameWorldContext(this);
player = new GameObject("Player").AddComponent<Player>();
player.Init(context);
for (int i = 0; i < 3; i++)
{
var npcObj = new GameObject($"NPC_{i}");
var npc = npcObj.AddComponent<NPC>();
npc.Init(context);
npcs.Add(npc);
}
}
public Player GetPlayer() => player;
public Vector3 GetSpawnPoint() => Vector3.zero;
}
GameWorldContext.cs
public class GameWorldContext : IGameContext
{
private GameWorld world;
private IEventDispatcher dispatcher;
public GameWorldContext(GameWorld world)
{
this.world = world;
this.dispatcher = new DefaultEventDispatcher();
}
public Player GetPlayer() => world.GetPlayer();
public Vector3 GetSpawnPoint() => world.GetSpawnPoint();
public IEventDispatcher GetEventDispatcher() => dispatcher;
}
NPC.cs
using UnityEngine;
public class NPC : MonoBehaviour
{
private IGameContext context;
public void Init(IGameContext context)
{
this.context = context;
}
public void Act()
{
context.GetEventDispatcher().Dispatch("NPC_Acted", this);
Debug.Log("NPC acting...");
}
}
Player.cs
using UnityEngine;
public class Player : MonoBehaviour
{
private IGameContext context;
public void Init(IGameContext context)
{
this.context = context;
}
public void Interact()
{
context.GetEventDispatcher().Dispatch("Player_Interacted", this);
}
}
DefaultEventDispatcher.cs
using System;
using System.Collections.Generic;
public class DefaultEventDispatcher : IEventDispatcher
{
private Dictionary<string, Action<object>> listeners = new();
public void Dispatch(string eventName, object data = null)
{
if (listeners.TryGetValue(eventName, out var callback))
{
callback?.Invoke(data);
}
}
public void Subscribe(string eventName, Action<object> callback)
{
if (listeners.ContainsKey(eventName))
listeners[eventName] += callback;
else
listeners[eventName] = callback;
}
public void Unsubscribe(string eventName, Action<object> callback)
{
if (listeners.ContainsKey(eventName))
listeners[eventName] -= callback;
}
}
GameStartup.cs
(用于启动游戏)
using UnityEngine;
public class GameStartup : MonoBehaviour
{
private void Start()
{
var worldObj = new GameObject("GameWorld");
worldObj.AddComponent<GameWorld>();
}
}
MockGameContext.cs
(测试用)
using UnityEngine;
public class MockGameContext : IGameContext
{
public Player GetPlayer() => new GameObject("MockPlayer").AddComponent<Player>();
public Vector3 GetSpawnPoint() => Vector3.zero;
public IEventDispatcher GetEventDispatcher() => new DefaultEventDispatcher();
}
🔨 使用方法
- 新建 Unity 项目,导入上述目录结构和脚本。
- 在
SampleScene
中放置一个空物体并挂载 GameStartup.cs
。
- 运行场景,将看到
Player
和多个 NPC
在控制台输出行为。