• Unity3d+Gameframework:entity实体代码分析,基于StarForce


    游戏场景中,动态创建的一切物体定义为实体。此模块提供管理实体和实体组的功能,如显示隐藏实体、挂接实体(如挂接武器、坐骑,或者抓起另一个实体)等。实体使用结束后可以不立刻销毁,从而等待下一次重新使用。

    EntityGroup

    内部包含对象池

    实体加载成功订阅

    GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, OnShowEntitySuccess);
    protected virtual void OnShowEntitySuccess(object sender, GameEventArgs e)
            {
                ShowEntitySuccessEventArgs ne = (ShowEntitySuccessEventArgs)e;
                if (ne.EntityLogicType == typeof(MyAircraft))
                {
                    m_MyAircraft = (MyAircraft)ne.Entity.Logic;
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    EntityManager

    GameFramework.Entity.EntityManager.Update
    实体组轮询,变为单一实体OnUpdate

    创建实体

    StarForce.GameBase.Initialize
    与加载UI类似
    GameFramework.Entity.EntityManager.ShowEntity

    GameFramework.Entity.EntityManager.ShowEntity 
    
     EntityInstanceObject entityInstanceObject = entityGroup.SpawnEntityInstanceObject(entityAssetName);
                if (entityInstanceObject == null)
                {
                    int serialId = ++m_Serial;
                    m_EntitiesBeingLoaded.Add(entityId, serialId);
                    m_ResourceManager.LoadAsset(entityAssetName, priority, m_LoadAssetCallbacks, ShowEntityInfo.Create(serialId, entityId, entityGroup, userData));
                    return;
                }
    
                InternalShowEntity(entityId, entityAssetName, entityGroup, entityInstanceObject.Target, false, 0f, userData);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如果实体组中对象池能实例出来,即立即返回
    否则调用资源加载
    实体资源表中确定ID与asset的关系

      IDataTable<DREntity> dtEntity = GameEntry.DataTable.GetDataTable<DREntity>();
                DREntity drEntity = dtEntity.GetDataRow(data.TypeId);
    
    
    • 1
    • 2
    • 3

    正在加载中实体释放

    public void HideEntity(int entityId, object userData)
            {
                if (IsLoadingEntity(entityId))
                {
                    GameFrameworkLog.Info("实体{0}正在加载等待释放", entityId);
                    m_EntitiesToReleaseOnLoad.Add(m_EntitiesBeingLoaded[entityId]);
                    m_EntitiesBeingLoaded.Remove(entityId);
                    return;
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Entity

    实体接口,包含被挂载,或者挂载别的方法
    根据资源加载出的GameObject–》挂载Entity脚本(继承了于MonoBehaviour)

     /// 
            /// 创建实体。
            /// 
            /// 实体实例。
            /// 实体所属的实体组。
            /// 用户自定义数据。
            /// 实体。
            public override IEntity CreateEntity(object entityInstance, IEntityGroup entityGroup, object userData)
            {
                GameObject gameObject = entityInstance as GameObject;
                         Transform transform = gameObject.transform;
                transform.SetParent(((MonoBehaviour)entityGroup.Helper).transform);
    
                return gameObject.GetOrAddComponent<Entity>();
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    实体统一设置到实体组子物体下,那么武器跟随人动如何实现

       namespace UnityGameFramework.Runtime
       {
         public sealed class Entity : MonoBehaviour, IEntity
        {
            private int m_Id;
            private string m_EntityAssetName;
            private IEntityGroup m_EntityGroup;
            private EntityLogic m_EntityLogic;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ObjecBase

    对象基类
    UI面板,资源(asset,resource),实体都是继承对象基类

    EntityInstanceObject

    实体实例对象,不会继承自MonoBehavior,在实体资源加载成功后调用创建
    GameFramework.Entity.EntityManager.LoadAssetSuccessCallback

    //实例化出来
                EntityInstanceObject entityInstanceObject = EntityInstanceObject.Create(entityAssetName, entityAsset, m_EntityHelper.InstantiateEntity(entityAsset), m_EntityHelper);
                showEntityInfo.EntityGroup.RegisterEntityInstanceObject(entityInstanceObject, true);
    
                InternalShowEntity(showEntityInfo.EntityId, entityAssetName, showEntityInfo.EntityGroup, entityInstanceObject.Target, true, duration, showEntityInfo.UserData);
                ReferencePool.Release(showEntityInfo);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    把预制体加载完成,然后实例化后GameObject设置为实体的Target

    EntityLogic

    public abstract class EntityLogic : MonoBehaviour
    实体逻辑基类
    实体挂载好Entity,后Entity初始化时挂载逻辑处理脚本
    public abstract class Entity : EntityLogic,此实体与gf实体不是同样东西(不在同个命名空间中)
    创建时,通过逻辑类型就传递下去

    public static void ShowMyAircraft(this EntityComponent entityComponent, MyAircraftData data)
            {
                entityComponent.ShowEntity(typeof(MyAircraft), "Aircraft", Constant.AssetPriority.MyAircraftAsset, data);
            }
    
    • 1
    • 2
    • 3
    • 4

    SurvivalGame

    继承GameBase
    游戏模式
    Update中随机产生陨石实体
    GameEntry.Entity.ShowAsteroid

    TargetableObject

    所有的实体逻辑继承
    OnTriggerEnter,碰撞检测

    放入到回收池,什么时候彻底去除引用

    Weapon

    增加武器实体,为什么能挂载人身上
    武器挂载
    在创建完成后,挂载在主角身上
    StarForce.Weapon.OnShow

    protected override void OnShow(object userData)
            {
                base.OnShow(userData);
    
                m_WeaponData = userData as WeaponData;
                 GameEntry.Entity.AttachEntity(Entity, m_WeaponData.OwnerId, AttachPoint);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    AttachEntity

    附加子实体GameFramework.Entity.EntityManager.AttachEntity

                 IEntity childEntity = childEntityInfo.Entity;
                IEntity parentEntity = parentEntityInfo.Entity;
                DetachEntity(childEntity.Id, userData);
                childEntityInfo.ParentEntity = parentEntity;
                parentEntityInfo.AddChildEntity(childEntity);
                parentEntity.OnAttached(childEntity, userData);
                childEntity.OnAttachTo(parentEntity, userData);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在childEntity.OnAttachTo(parentEntity, userData);设置unity 父子物体关系

     protected internal virtual void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData)
            {
                CachedTransform.SetParent(parentTransform);
            }
    
    • 1
    • 2
    • 3
    • 4

    InternalHideEntity隐藏实体

    //先隐藏子实体
                while (entityInfo.ChildEntityCount > 0)
                {
                    IEntity childEntity = entityInfo.GetChildEntity();
                    HideEntity(childEntity.Id, userData);
                }
                //把自己从父实体上移除
                IEntity entity = entityInfo.Entity;
                DetachEntity(entity.Id, userData);
                entityInfo.Status = EntityStatus.WillHide;
                entity.OnHide(m_IsShutdown, userData);
                entityInfo.Status = EntityStatus.Hidden;
                
                //实体组移除
                EntityGroup entityGroup = (EntityGroup)entity.EntityGroup;
                entityGroup.RemoveEntity(entity);
                
                //放入到回收队列
                m_RecycleQueue.Enqueue(entityInfo);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    GameFramework.Entity.EntityManager.Update 中轮询处理实体进入实体组的对象池

    //处理回收队列的实体
                while (m_RecycleQueue.Count > 0)
                {
                    EntityInfo entityInfo = m_RecycleQueue.Dequeue();
                    IEntity entity = entityInfo.Entity;
                    EntityGroup entityGroup = (EntityGroup)entity.EntityGroup;
                    entityInfo.Status = EntityStatus.WillRecycle;
                    entity.OnRecycle();
                    entityInfo.Status = EntityStatus.Recycled;
                    entityGroup.UnspawnEntity(entity); //实体组回收,相当于对象池
                    ReferencePool.Release(entityInfo);
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    asp.net get请求base64解密报错问题
    vs中集成vcpkg
    荧光染料Cy7 酰肼,Cy7 hydrazide,Cy7 HZ参数及结构式解析
    pytorch-Normalization
    今年十八,喜欢文件上传
    注意!11月PMP考试时间已定!
    美食杰项目 -- 菜品信息(五)
    Vue.js+Node.js全栈开发教程:Vue.js指令修饰符详解
    如何读取maven依赖的jar包中的代码?
    NC16884 [NOI2001]食物链
  • 原文地址:https://blog.csdn.net/luoyikun/article/details/126755564