更新日期:2025年3月21日。
Github 仓库:https://github.com/SaiTingHu/HTFramework
Gitee 仓库:https://gitee.com/SaiTingHu/HTFramework
索引
一、Entity实体管理器简介
实体管理器,除去UI以外,场景中的其余可见物体都应该抽象为Entity,在Entity之上配合FSM一起管理逻辑,将是一个不错的搭配。
二、简略文档
快捷调用
通过如下方式快捷调用此模块:
HT.Framework.Main.m_Entity
公开字段
字段 | 描述 |
---|---|
无 | 无 |
公开属性
属性 | 描述 |
---|---|
IsHideAll | 是否隐藏所有实体,为true 时所有实体将不可见 |
公开方法
方法 | 描述 |
---|---|
AddDefine | 添加预定义(如果已存在则覆盖,已创建的实体不受影响,销毁后再次创建生效) |
CreateEntity | 创建实体 |
DestroyEntity | 销毁实体 |
DestroyEntities | 销毁指定类型的所有实体 |
GetEntity | 获取实体 |
GetEntities | 获取实体组 |
ShowEntity | 显示实体 |
HideEntity | 隐藏实体 |
ShowEntities | 显示指定类型的所有实体 |
HideEntities | 隐藏指定类型的所有实体 |
公开类型
类型 | 描述 |
---|---|
EntityLogicBase | 实体逻辑基类,自定义实体逻辑类将继承此类 |
公开接口
接口 | 描述 |
---|---|
无 | 无 |
公开特性
特性 | 描述 |
---|---|
EntityResourceAttribute | 实体资源标记 |
三、使用Entity管理器
创建实体对象
创建任意一个游戏对象,并创建成预制体就可以了,这就是我们的实体对象(如下的张三
)。
创建实体逻辑类
每一个实体对象
都由一个实体逻辑类
所持有,且只能是一对一的关系,如果你的设计文档中不满足这个要求(比如某个实体逻辑类必须拥有两个实体对象才能实现业务需求),那请你重新设计实体(比如尝试着将这两个实体对象合并为一个,或者为另一个多余的实体对象重新设计一个实体逻辑类)。
新建一个实体逻辑类,必须满足以下条件:
1.继承至EntityLogicBase
2.标记特性EntityResource
推荐使用快捷创建方式:
Project界面右键 -> Create -> HTFramework -> C# EntityLogic Script
如下图,我新建了一个名为ZhangThree
的逻辑类,他持有的实体为上文创建的张三
:
[EntityResource("player", "Assets/HTFrameworkDemo/Script/Entity/Prefab/张三.prefab", "ResourcePath", true)]
public class ZhangThree : EntityLogicBase
{
/// <summary>
/// 初始化
/// </summary>
public override void OnInit()
{
base.OnInit();
Entity.AddClickListener(() =>
{
Entity.transform.DORotate(new Vector3(0, 360, 0), 1, RotateMode.WorldAxisAdd);
});
}
/// <summary>
/// 显示实体
/// </summary>
public override void OnShow()
{
base.OnShow();
}
/// <summary>
/// 隐藏实体
/// </summary>
public override void OnHide()
{
base.OnHide();
}
/// <summary>
/// 销毁实体
/// </summary>
public override void OnDestroy()
{
base.OnDestroy();
Entity.RemoveAllClickListener();
}
/// <summary>
/// 实体逻辑刷新
/// </summary>
public override void OnUpdate()
{
base.OnUpdate();
}
/// <summary>
/// 重置实体
/// </summary>
public override void Reset()
{
base.Reset();
}
}
实体逻辑类结构
1.EntityResource
特性标记了此实体逻辑类所指向的实体对象。
第一个参数:AssetBundleName为实体对象所打入的AB包名称;
第二个参数:AssetPath为实体对象在AB包中的路径(必须指明后缀,以便于Editor模式下加载);
第三个参数:ResourcePath为实体对象在Resources中的路径;
第四个参数:IsUseObjectPool是否使用内置对象池。
注意:当资源加载方式采用AssetBundle方式时,参数1和参数2有效;当资源加载方式采用Resources方式时,参数3有效。
2.OnInit()
:实体创建成功后呼叫一次,若中途销毁实体,再次创建会重新呼叫。
3.OnShow()
:实体显示后呼叫一次。
4.OnHide()
:实体隐藏后呼叫一次。
5.OnDestroy()
:实体销毁前呼叫一次。
6.OnUpdate()
:实体处于显示状态时,每帧呼叫。
创建实体
写好了实体逻辑类,并做好了实体对象,直接调用框架接口就可以快速创建实体:
private IEnumerator Load()
{
//方法1
//等待创建实体完成,实体名为【张三】,如果不指定名称默认使用逻辑类名
yield return Main.m_Entity.CreateEntity<ZhangThree>("张三");
//通过名称获取实体
ZhangThree hero = Main.m_Entity.GetEntity<ZhangThree>("张三");
hero.DoSomething();
//方法2
//等待创建实体完成,实体名为【张三】
yield return Main.m_Entity.CreateEntity<ZhangThree>("张三", null, (obj) =>
{
obj.DoSomething();
});
}
显示、隐藏实体
//显示实体 _hero
Main.m_Entity.ShowEntity(_hero);
//隐藏实体 _hero
Main.m_Entity.HideEntity(_hero);
//显示所有 ZhangThree 实体
Main.m_Entity.ShowEntities<ZhangThree>();
销毁实体
//销毁实体 _hero
Main.m_Entity.DestroyEntity(_hero);
//销毁所有 ZhangThree 实体
Main.m_Entity.DestroyEntities<ZhangThree>();
获取实体对象(依赖注入)
在实体逻辑类中获取实体对象,只需要调用Entity字段就可以了:
/// <summary>
/// 初始化
/// </summary>
public override void OnInit()
{
base.OnInit();
Entity.FindChildTran("Head").GetComponent<PlayerHead>().Init();
}
比如我要获取实体对象下的某一个GameObject,某一个组件,也可以使用InjectPath
依赖注入,比如此处我要获取Face对象:
代码中这样写:
public class Player : EntityLogicBase
{
//参数为路径,比如这里的:Head/Face
[InjectPath("Head/Face")]
private GameObject _face;
//也可以为组件注入依赖,比如这里的:PlayerFace
[InjectPath("Head/Face")]
private PlayerFace _playerFace;
/// <summary>
/// 初始化
/// </summary>
public override void OnInit()
{
base.OnInit();
//这里_face、_playerFace已注入依赖,可以直接使用
}
}
强制定义实体逻辑类与实体对象的对应关系
根据一个实体逻辑类对应一个实体对象的关系,每一个实体逻辑类所持有的实体对象由EntityResource
特性标记,但在某些时候,对于一些简单的程序,我们既不想使用AB包模式,也不想动态Resources加载,我们就想让某个实体逻辑类使用某个特定的实体对象。
这就需要使用Define Entity
了,在检视面板可以直接指定某个实体逻辑类使用某个实体对象,该实体对象可以是Scene
中的游戏物体,也可以是Project
中的预制体。
如下,我强制定义了ZhangThree
类始终使用张三
作为实体对象,无论他的EntityResource
标记如何改变。
四、运行时检视面板
在编辑器中运行时将会出现运行时检视面板
(Runtime Data),主要用以调试或数据监测,目前面板如下:
1.展示已创建的所有实体以及处于回收对象池中的所有实体,点击Show
按钮可以模拟显示该实体,点击Hide
按钮可以模拟隐藏该实体。