我在demo基础上做了玩家离线时 UnitComponent 移除对应 Unit
public void Offline()
{
var session = this.Parent as Entity;
long unitId = session.GetComponent<SessionPlayerComponent>().Player.UnitId;
Game.Scene.GetComponent<UnitComponent>().Remove(unitId);//这里remove掉了
}
但玩家再次登录时问题来了,在新建 unit 后 AddComponent<UnitGateComponent 时:
unit.AddComponent<UnitGateComponent, long>(request.GateSessionId);
其内部会从对象池内拿之前的component来使用:
public virtual K AddComponent<K, P1>(P1 p1) where K : Component, new()
{
Type type = typeof (K);
if (this.componentDict.ContainsKey(type))
{
throw new Exception($"AddComponent, component already exist, id: {this.Id}, component: {typeof(K).Name}");
}
K component = ComponentFactory.CreateWithParent<K, P1>(this, p1, this.IsFromPool);//从对象池创建
this.componentDict.Add(type, component);
if (component is ISerializeToEntity)
{
this.components.Add(component);
}
return component;
}
但之前当玩家下线时 UnitGateComponent 的 IsDisconnect 会设置为true :
public class G2M_SessionDisconnectHandler : AMActorLocationHandler<Unit, G2M_SessionDisconnect>
{
protected override async ETTask Run(Unit unit, G2M_SessionDisconnect message)
{
unit.GetComponent<UnitGateComponent>().IsDisconnect = true;//掉线后设置为IsDisconnect
await ETTask.CompletedTask;
}
}
于是此时从对象池中拿出来用的 UnitGateComponent 的 IsDisconnect 是 true。这造成了第二次上线,新建unit后不下发给客户端的情况。因为unit消息广播前会判断是否 IsDisconnect 。
然后我的解决方法:
public class UnitGateComponent : Component, ISerializeToEntity
{
public long GateSessionActorId;
public bool IsDisconnect;
public void Awake(long gateSessionId)
{
this.IsDisconnect = false;//在这里增加一个重新赋值
this.GateSessionActorId = gateSessionId;
}
public ActorMessageSender GetActorMessageSender()
{
return Game.Scene.GetComponent<ActorMessageSenderComponent>().Get(this.GateSessionActorId);
}
}
最后 发帖子除了分享 主要是想问一下这样处理是最好的解决方式么?每个单独处理会不会太麻烦,是否存在可以统一重置的可能?