Fantasy.Net框架中,实体与组件都继承自Entity
你自己要知道,是用作为实体还是组件:
- 用来代表一类事物的,如Scene,Unit,Session等都是作为实体,他们有各种属性,方法,还可以添加组件来扩展更多方法与属性。
- 用来代表一些功能方法的,如SessionPlayerComponent,UnitComponent,SessionKeyComponent等都是作为组件。
Fantasy.Net框架中,获取实体与组件核心机制
⛳机制一:组件添加给了哪个实体,就要先获取到这个实体,再获取这个组件。
unit.AddComponent<MoveComponent>();
unit.AddComponent<MoveSyncComponent>();
这种情况最好理解,只要有Unit实例,就通过他获取上面的组件
var moveComponent = unit.GetComponent<MoveComponent>();
var moveSync = unit.GetComponent<MoveSyncComponent>();
⛳机制二:通过服务器的“根”Scene
❓unit放在哪,从谁身上获取呢?
以UnitComponent组件为例,他里面有UnitDic的集合,我们如果想获得Unit,就得先找到UnitComponent。
当然 ,Unit是框架中特殊的实体,所以在寻址消息的Handler方法通过参数把Unit传递给到了,但是在其它没有Unit参数传递的地方,就得通过UnitComponent了。
public class UnitComponent: Entity
{
/// unit容器
public readonly Dictionary<long, Unit> UnitDic = new Dictionary<long, Unit>();
public void Add(Unit unit)
{
UnitDic.Add(unit.Id, unit);
}
public Unit Get(long id)
{
UnitDic.TryGetValue(id, out Unit unit);
return unit;
}
}
❓从哪可以获取UnitComponent组件呢?
这要看他挂在哪个实体上对吧。
UnitComponent组件可以挂在服务器所有实例与组件的“根”实体上,那就是这个服务器的Scene实体的实例。
\Server\Hotfix\OnCreateScene.cs
case SceneType.Map:
{
// Unit管理组件
scene.AddComponent<UnitComponent>();
// 添加AOI组件
scene.AddComponent<AOIComponent>();
break;
}
❓如何获取scene呢?
到这里要理解,我们写在服务器上的所有功能逻辑的起点都是当服务器收到消息的时候,也就是所有消息的Handler。
去看下一各种消息类型的Handler写法 Fantasy框架各端间发消息与请求的写法示例
所有类型的消息Handler的第一个参数有Session,Unit,Scene这几种,而所有的实体都有一个Scene属性,正是他所在服的“根”实体的实例。
var SessionKeyComponent = session.Scene.GetComponent<SessionKeyComponent>();
var aoiComponent = unit.Scene.GetComponent<AOIComponent>();
var unitComponent = scene.GetComponent<UnitComponent>();
所以 ,在服务器任何组件或逻辑中,你必然有一个实体的实例,或者通过参数获得一个实体的实例,
这时就可以通过entity.Scene获得了所在服的“根“Scene实例。