前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity3d+Gameframework:entity实体代码分析,基于StarForce

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

作者头像
立羽
发布2023-08-24 15:41:07
3660
发布2023-08-24 15:41:07
举报
文章被收录于专栏:Unity3d程序开发Unity3d程序开发

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

EntityGroup

内部包含对象池

实体加载成功订阅

代码语言:javascript
复制
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;
            }
        }

EntityManager

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

创建实体

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

代码语言:javascript
复制
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);

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

代码语言:javascript
复制
  IDataTable<DREntity> dtEntity = GameEntry.DataTable.GetDataTable<DREntity>();
            DREntity drEntity = dtEntity.GetDataRow(data.TypeId);

正在加载中实体释放

代码语言:javascript
复制
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;
            }

Entity

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

代码语言:javascript
复制
 /// <summary>
        /// 创建实体。
        /// </summary>
        /// <param name="entityInstance">实体实例。</param>
        /// <param name="entityGroup">实体所属的实体组。</param>
        /// <param name="userData">用户自定义数据。</param>
        /// <returns>实体。</returns>
        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>();
        }

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

代码语言:javascript
复制
   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;

ObjecBase

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

EntityInstanceObject

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

代码语言:javascript
复制
//实例化出来
            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);

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

EntityLogic

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

代码语言:javascript
复制
public static void ShowMyAircraft(this EntityComponent entityComponent, MyAircraftData data)
        {
            entityComponent.ShowEntity(typeof(MyAircraft), "Aircraft", Constant.AssetPriority.MyAircraftAsset, data);
        }

SurvivalGame

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

TargetableObject

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

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

Weapon

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

代码语言:javascript
复制
protected override void OnShow(object userData)
        {
            base.OnShow(userData);

            m_WeaponData = userData as WeaponData;
             GameEntry.Entity.AttachEntity(Entity, m_WeaponData.OwnerId, AttachPoint);
        }

AttachEntity

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

代码语言:javascript
复制
             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);

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

代码语言:javascript
复制
 protected internal virtual void OnAttachTo(EntityLogic parentEntity, Transform parentTransform, object userData)
        {
            CachedTransform.SetParent(parentTransform);
        }

InternalHideEntity隐藏实体

代码语言:javascript
复制
//先隐藏子实体
            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);

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

代码语言:javascript
复制
//处理回收队列的实体
            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);
            }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • EntityGroup
  • 实体加载成功订阅
  • EntityManager
  • 创建实体
  • 正在加载中实体释放
  • Entity
  • ObjecBase
  • EntityInstanceObject
  • EntityLogic
  • SurvivalGame
  • TargetableObject
  • Weapon
  • AttachEntity
  • InternalHideEntity隐藏实体
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档