精华内容
下载资源
问答
  • unity3d框架
    千次阅读
    2020-05-08 20:00:58

    一、Unity关键类继承关系

    (1)、继承关系如下图:
    在这里插入图片描述
    用户定义的每一个类在引擎中都属于一个组件,引擎中每个Component类定义了GameObject类型的对象,用于申明当前组件所属的游戏对象。

    二、用户实现的接口与引擎调用关系

    Unity3D引擎为游戏开发者提供了脚本语言(例如:C#、Javascript)编写代码,基于Unity引擎的开发者通用可通过如下如下几种方式实现接口的调用:

    • 基于引擎帧更新机制调用用户实现的接口。
    • 基于引擎的消息事件响应机制调用用户接口。
    • 引擎的延迟调用机制。
    • 其他直接调用方式。

    (1)、基于引擎帧更新机制调用用户实现的接口
    创建Unity引擎的C#脚本文件,会默认为类生成Start和Update函数,其中Start函数仅在Update函数第一次调用时会被引擎调用,用户通过Start实现初始化操作,类似于类的构造函数。
    Unity引擎为用户提供了多种帧更新操作,例如常用的三种更新操作为:Update、FixedUpdate、LateUpdate,三种Update调用机制不相同,三种函数调用机制如下:
    Update:引擎会在每帧更新的过程中遍历对象并更新该组件的Update函数。
    FixedUpdate:引擎以固定时间调用组件的FixedUpdate函数。
    LateUpdate:在Update函数调用之后调用,通过该功能可调整脚本执行的顺序,例如:当无敌在Update里移动时,跟随物体的相机可在LateUpdate里实现镜头移动。
    用户定义组件对象默认继承MonoBehaviour,用户实现的每帧更新Update函数于引擎的PlayerLoop函数调用(该函数于Player.cpp实现),其中GetBehaviourManager()是获取管理Update方式每帧更新的调用方法,其中GetBehaviourManager().update()函数及所属类的GetBehaviourManager().update()函数内部由CommonUpdate模版实现。用户实现的FixedUpdate属于固定时间的调用方式,对应在PlayerLoop函数中调用。GetTimeManager().StepFixedTime()函数会判断是否需要处理固定时间的相关操作,例如用户定义的FixedUpdate函数更新逻辑,所有的组件Update调用之后才调用LateUpdate函数。

    (2)、基于引擎消息事件的调用机制
    Unity引擎提供给用户感知某些消息类事件的感知,例如某游戏的EntityCollider.cs文件中实现了EntityCollider::OntriggerEnter方法。
    其中OnTriggerEnter为用户感知碰撞探测相关事件,OnTriggerEnter函数绑定了kEnterTrigger函数,在PhysicsManager::ProcesssRecordedreports函数内部调用,在判断当前MessageID为kEnterTrigger之后,已消息方式调用SendMessage函数让引擎调用用户实现的OnTriggerEnter接口。其中PhysicsManager::ProcesssRecordedreports函数由PhysicsManager::FixedUpdate调用,消息处理机制是引擎以固定时间的方式在PhysicsManager类的FixedUpdate方法中不断调用实现。

    (3)、引擎的延迟调用机制
    Unity为用户提供了延迟调用某方法,对应通过Invoke和InvokeRepeating 函数实现,其中Invoke和InvokeRepeat接口定义如下:
    function Invoke (methodName : string, time : float) : void
    function InvokeRepeating (methodName : string, time : float, repeatRate : float) : void
    Invoke为延迟调用一次,InvokeRepeating 为延迟调用多次,延迟调用通过引擎的InvokeDelayed函数实现,延迟调用机制较为简单,延迟的时间、重复调用的次数都由用户控制。

    (4)、其他机制
    其他机制包括用户定义的C#函数之间调用,该类调用方式与C++函数调用方式类似,不在进行详细阐述。

    三、Unity整理框架及帧更新机制

    Unity引擎将所有重要事件于主线程中实现,如帧更新逻辑、渲染逻辑、碰撞检测逻辑等,Unity引擎初始化及运行帧更新相关执行流程如下图所示:
    在这里插入图片描述
    其中UpdateScene负责更新游戏场景中所有帧更新时间。PlayerLoop函数属于每帧更细都会调用,该函数负责处理游戏中所有组件的Update、及消息事件相应处理。
      Unity引擎会以一定间隔时间不断更新游戏场景中所有相关事件,每次需要计算下一次帧更新所需的间隔时间,对应时间计算在MainMessageLoop函数实现,通过Sleep方式将执行权切换给其他线程,防止出现CPU 100%的情况。

    四、Unity引擎对象链表组织方式

    每个游戏都会通过某种方式存储场景中的所有对象,Unity引擎的场景对象通过GameObjectManager进行管理,GameObjectManager通过STL的List结构存储了游戏场景中所有对象,通过遍历List链表便可获取到游戏场景中所有对象,Unity通过GameObject::FindGameObjectWithTag函数可通过传入对象的标识从而获取到对象指针,函数通过遍历List链表的所有信息查找所需的对象。每个GameObject对象都包含了Tag字段,该字段用于区分不同的对象

    更多相关内容
  • 目标是作为无框架经验的公司,独立开发者,以及Unity3D初学者们的第一套框架框架内部堆积了多个项目的在各个技术方向的解决方案。学习成本低,接收成本低,重组成本低,二次开发成本低,文档内容丰富(提供使用...
  • 本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,记录整合过程中对原有的脚本进行调整的过程。专栏文章后续加入AssetBundle+ILRuntime热更新技术过程。

    本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,并记录了集成过程中对原脚本的调整过程。增加了Asset Bundle+ILRuntime热更新技术流程。

    效果展示

    1.通过框架中的BasePanel.cs脚本进行UI事件的注册。
    BasePanel.cs的脚本将寻找UI控件并完成事件的注册,使得注册事件变得异常简单。

           /// <summary>
            /// 找到子对象的对应控件
            /// </summary>
            /// <typeparam name="T"></typeparam>
            private void FindChildrenControl<T>() where T : UIBehaviour
            {
                T[] controls = this.GetComponentsInChildren<T>();
                for (int i = 0; i < controls.Length; ++i)
                {
                    string objName = controls[i].gameObject.name;
                    Debug.Log("面板获取:"+objName);
                    if (controlDic.ContainsKey(objName))
                        controlDic[objName].Add(controls[i]);
                    else
                        controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
                    //如果是按钮控件
                    if (controls[i] is Button)
                    {
                        (controls[i] as Button).onClick.AddListener(() =>
                        {
                            OnClick(objName);
                        });
                    }
                    //如果是单选框或者多选框
                    else if (controls[i] is Toggle)
                    {
                        (controls[i] as Toggle).onValueChanged.AddListener((value) =>
                        {
                            OnValueChanged(objName, value);
                        });
                    }
                }
            }
    

    要实现自己的事件逻辑,只需要进行重写以下方法。

          /// <summary>
            /// 显示自己
            /// </summary>
            public virtual void ShowMe()
            {
            }
            /// <summary>
            /// 隐藏自己
            /// </summary>
            public virtual void HideMe()
            {
            }
            public virtual void OnClick(string btnName)
            {
            }
            protected virtual void OnValueChanged(string toggleName, bool value)
            {
            }
    

    完整代码如下

     /// <summary>
        /// 面板基类 
        /// 帮助我门通过代码快速的找到所有的子控件
        /// 方便我们在子类中处理逻辑 
        /// 节约找控件的工作量
        /// </summary>
        public class BasePanel : MonoBehaviour
        {
            //通过里式转换原则 来存储所有的控件
            private Dictionary<string, List<UIBehaviour>> controlDic = new Dictionary<string, List<UIBehaviour>>();
            // Use this for initialization
            public virtual void Awake()
            {
                FindChildrenControl<Button>();
                FindChildrenControl<Image>();
                FindChildrenControl<Text>();
                FindChildrenControl<Toggle>();
                FindChildrenControl<Slider>();
                FindChildrenControl<ScrollRect>();
                FindChildrenControl<InputField>();
            }
    
            /// <summary>
            /// 显示自己
            /// </summary>
            public virtual void ShowMe()
            {
            }
    
            /// <summary>
            /// 隐藏自己
            /// </summary>
            public virtual void HideMe()
            {
            }
    
            public virtual void OnClick(string btnName)
            {
            }
    
            protected virtual void OnValueChanged(string toggleName, bool value)
            {
            }
    
            public static Transform FindTheChild(GameObject goParent, string childName)
            {
                Transform searchTrans = goParent.transform.Find(childName);
                if (searchTrans == null)
                {
                    foreach (Transform trans in goParent.transform)
                    {
                        searchTrans = FindTheChild(trans.gameObject, childName);
                        if (searchTrans != null)
                        {
                            return searchTrans;
                        }
                    }
                }
                return searchTrans;
            }
    
            /// <summary>
            /// 得到对应名字的对应控件脚本
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="controlName"></param>
            /// <returns></returns>
            protected T GetControl<T>(string controlName) where T : UIBehaviour
            {
                if (controlDic.ContainsKey(controlName))
                {
                    for (int i = 0; i < controlDic[controlName].Count; ++i)
                    {
                        if (controlDic[controlName][i] is T)
                            Debug.Log(controlDic);
                            return controlDic[controlName][i] as T;
                    }
                }
    
                return null;
            }
    
            /// <summary>
            /// 找到子对象的对应控件
            /// </summary>
            /// <typeparam name="T"></typeparam>
            private void FindChildrenControl<T>() where T : UIBehaviour
            {
                T[] controls = this.GetComponentsInChildren<T>();
                for (int i = 0; i < controls.Length; ++i)
                {
                    string objName = controls[i].gameObject.name;
                    Debug.Log("面板获取:"+objName);
                    if (controlDic.ContainsKey(objName))
                        controlDic[objName].Add(controls[i]);
                    else
                        controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
                    //如果是按钮控件
                    if (controls[i] is Button)
                    {
                        (controls[i] as Button).onClick.AddListener(() =>
                        {
                            OnClick(objName);
                        });
                    }
                    //如果是单选框或者多选框
                    else if (controls[i] is Toggle)
                    {
                        (controls[i] as Toggle).onValueChanged.AddListener((value) =>
                        {
                            OnValueChanged(objName, value);
                        });
                    }
                }
            }
        }
    

    业务应用:将MainBaseUI.cs继承BasePanel.cs脚本,给按钮BtnCloseBtnResetBtnSet注册事件,按钮的命名一定要和脚本中的名称对应上,否则注册不上。
    在这里插入图片描述
    MainBaseUI.cs重写BasePanel.cs基类的OnClick事件

        public override void OnClick(string btnName)
        {
            if (btnName== "BtnClose")
            {
                Debug.Log("关闭");
            }
            else if (btnName == "BtnReset")
            {
                Debug.Log("重置");
            }
            else if (btnName == "BtnSet")
            {
                animator.SetBool("isout", !animator.GetBool("isout"));
            }
        }
    

    ToggleUI注册事件设置标注隐藏显示

        public override void OnValueChanged(string toggleName, bool value)
        {
            if (toggleName == "MemoToggle")
            {
                SwitchOperation.Instance.hideInfo(value);
            }
       }
    

    MainBaseUI.cs注册事件完整脚本代码

    public class MainBaseUI : BasePanel
    {
        public static MainBaseUI Instance;
    
        private Animator animator;
        public override void Awake()
        {
            Instance = this;
            base.Awake();
        }
        public void InitData() {
            Debug.Log("初始化信息!");
            animator = this.GetComponent<Animator>();
    
        }
        [FormerlySerializedAs("taskPrefabs")]
        [Tooltip("Prefab of the  object. Prefab must have a Info component. May be an empty game object or a full avatar.")]
        public GameObject taskPrefabs;
        public Transform taskParentTransform;
        // Start is called before the first frame update
        void Start()
        {
        }
        public override void OnClick(string btnName)
        {
            if (btnName== "BtnClose")
            {
                Debug.Log("关闭");
            }
            else if (btnName == "BtnReset")
            {
                Debug.Log("重置");
            }
            else if (btnName == "BtnSet")
            {
                animator.SetBool("isout", !animator.GetBool("isout"));
            }
        }
        public override void OnValueChanged(string toggleName, bool value)
        {
            if (toggleName == "MemoToggle")
            {
                SwitchOperation.Instance.hideInfo(value);
            }
       }
    
        // Update is called once per frame
        void Update()
        {
            
        }
    
    }
    

    2.通过框架中的ResMgr.cs脚本进行开关预制体初始化。
    MyGameManager.cs脚本中将预制体的路径传入即可

    ResMgr.GetInstance().Load<GameObject>("Prefabs/Switch");
    

    由于现在是动态加载预制体,所以要控制一下出现的位置(parentObj)以及进行加载后预制体命名,完整代码如下
    在这里插入图片描述

    public class MyGameManager : MonoBehaviour
    {
        public GameObject parentObj;
        // Start is called before the first frame update
        void Start()
        {
            var tempDD = ResMgr.GetInstance().Load<GameObject>("Prefabs/Switch");
            tempDD.transform.SetParent(parentObj.transform);
            tempDD.name = "Switch";
        }
    }
    

    下一篇将物体自由观察通过Cinemachine进行实现。

    专栏:Unity 3D模型展示Unity程序基础小框架

    关于框架资源包,评论处留下你的邮箱地址。

    展开全文
  • 一个设计师友好,编辑器驱动的Unity3D框架,用于连接数据和事件
  • 此为Unity3D完整流程管理框架,可直接用于项目开发,流程管理,UI框架,事件处理,json配置读取,计时器,UI打字效果,动作,animator,animation,doTween等等,全部支持。可商用!
  • Unity3D UI 框架

    2018-11-08 09:27:19
    一套完整的UI框架,基于MVVM的原理,方便快速开发,简单快捷
  • Unity3D框架学习_基于FairyGUI的UI框架

    千次阅读 2019-04-03 01:34:20
    Unity3D框架学习_基于FairyGUI的UI框架 目录 1、博客介绍 2、FGUI介绍 3、框架介绍 (1)Core (2)结构 (3)FGUI工程目录 (4)命名规范 4、推送 5、结语 1、博客介绍 最近一段时间一直都在使用FGUI...

                            Unity3D框架学习_基于FairyGUI的UI框架


    目录

    1、博客介绍

    2、FGUI介绍

    3、框架介绍

    (1)Core

    (2)结构

    (3)FGUI工程目录

    (4)命名规范

    4、推送

    5、结语


    1、博客介绍

           最近一段时间一直都在使用FGUI,真心觉得非常好用,目前还处在学习阶段,在Github上扒了一些稍作整理,做了一个非常简单的框架,目前还处在初级阶段,后续发现问题了会持续更新,文章末尾会贴上github地址,有兴趣的关注,本篇文章只介绍相关结构和思路。


    2、FGUI介绍

    话不多少:http://www.fairygui.com/


    3、框架介绍

    (1)Core

            主要思想就是,FGUI的每个包作为UI的场景,在每个包内包含多个Window作为不同的UI页面,UI页面继承了FGUI的Window属性,本身作为一个窗口组件去拓展,方便展示关闭。

    (2)结构

    PanelManager用来管理FGUI包的加载和卸载,UIManager用来管理包内UI页面的调用

    (3)FGUI工程目录

    (4)命名规范

    这里命名规范只是建议,唯一一点强制的是继承了window属性的UI页面脚本内的winName必须和当前类名保持一致


    4、推送

    工程github:https://github.com/KingSun5/FGUI_Framework  内含演示小例子

    学习借鉴:https://github.com/YKPublicGame/LayaYKFamework


    5、结语

            FGUI是个非常好用的UI编辑器,大大的提高了工作效率,学习成本低,在此感谢作者谷主大人的无私奉献,这里的小框架很简单,博主也还在学习阶段,希望对读者能有所帮助,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

           QQ交流群:806091680(Chinar)

           该群为CSDN博主Chinar所创,推荐一下!我也在群里!

           本文属于原创文章,转载请著名作者出处并置顶!!!!!

    展开全文
  • unity3D ui框架

    2016-11-01 11:35:30
    一个简单的UI框架
  • 这个项目是在3D原型制作原型期间创建的,其中可以通过访问和控制游戏对象。 这是概念验证项目,因此服务器的功能保持在最低限度。 GET范例用于请求游戏对象的颜色。 路径:/ color / {游戏对象名称} 开机自检...
  • UI框架文章的demo代码
  • Unity3d游戏框架中的消息机制,解耦合,代码有文档参阅
  • 本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,记录整合过程中对原有的脚本进行调整的过程。专栏文章后续加入AssetBundle+ILRuntime热更新技术过程。

    本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,并记录了集成过程中对原脚本的调整过程。增加了Asset Bundle+ILRuntime热更新技术流程。

    在Unity 3D模型展示专栏中自由观察物体使用的第三方脚本实现,这篇文章使用Unity为开发者提供专业的虚拟摄像机插件Cinemachine,虚拟摄像机可以实现电影级别的分镜,推拉式镜头等,需要2017以上的版本才能使用,配合TimeLine一起使用和Animator可以做些项目漫游、案例展示、行业工作标准流程演示等。
    下面这个就是Cinemachine结合TimeLine做的案例

    斜切进刀场景模拟

    本篇文章只涉及其中一个虚拟摄像机cinemachineFreeLook的使用,首先需要在PackageManager中搜索并安装Cinemachine
    在这里插入图片描述
    在搜索框中搜索 Cinemachine进行安装即可。
    在这里插入图片描述
    安装之后,创建cinemachineFreeLook虚拟摄像机,并命名为CMFreeLook
    在这里插入图片描述
    Main Camera下增加一个名为CinemachineBrain组件,相当于虚拟相机的总管理。这里使用默认参数即可。
    在这里插入图片描述
    CMFreeLook组件参数进行如下设置。来调整观察的最佳位置
    在这里插入图片描述
    调整过程是运行时不断进行修正的…,调整上中下轨道范围。能够完美的从不同角度观察物体。
    在这里插入图片描述
    在这里插入图片描述

    重点来了,如果是观察的物体提前创建好可以进行提前设置LookAtFollow以及Middle Rig等参数,由于本项目是动态创建的观察物体,所以需要使用脚本进行设置修改MyGameManager以上参数在此脚本中进行设置。

    public class MyGameManager : MonoBehaviour
    {
        public GameObject parentObj;
        public CinemachineFreeLook camera;
        // Start is called before the first frame update
        void Start()
        {
            var tempGB = ResMgr.GetInstance().Load<GameObject>("Prefabs/Switch");
            tempGB.transform.SetParent(parentObj.transform);
            tempGB.name = "Switch";
            camera.LookAt = tempGB.transform;
            camera.Follow = tempGB.transform;
            tempGB.transform.position = new Vector3(5f, 0f, 50f);
            camera.GetRig(1).LookAt = tempGB.transform;
        }
    }
    

    说明:关于 camera.GetRig(1).LookAt GetRig是个数组索引值分别对应下面参数 GetRig(1)是对Middle Rig进行设置。
    在这里插入图片描述
    注意:cinemachineFreeLook默认是鼠标左键控制视角的,在此项目中用起来非常不便。所以需要使用脚本改变控制方式。

    CMFreelookOnlyWhenRightMouseDown脚本内容:鼠标右键控制视角,鼠标滚轮控制焦距。

    
    public class CMFreelookOnlyWhenRightMouseDown : MonoBehaviour
    {
        private CinemachineFreeLook cinemachineFreeLook;
        // Start is called before the first frame update
        void Start()
        {
            cinemachineFreeLook = GetComponent<CinemachineFreeLook>();
            CinemachineCore.GetInputAxis = GetAxisCustom;
        }
        public float GetAxisCustom(string axisName)
        {
            if (axisName == "Mouse X")
            {
                if (Input.GetMouseButton(1))
                {
                    return UnityEngine.Input.GetAxis("Mouse X");
                }
                else
                {
                    return 0;
                }
            }
            else if (axisName == "Mouse Y")
            {
                if (Input.GetMouseButton(1))
                {
                    return UnityEngine.Input.GetAxis("Mouse Y");
                }
                else
                {
                    return 0;
                }
            }
            return UnityEngine.Input.GetAxis(axisName);
        }
        // Update is called once per frame
        void FixedUpdate()
        {
            if (Input.GetAxis("Mouse ScrollWheel") < 0)
            {
                if (cinemachineFreeLook.m_Lens.FieldOfView <= 62)
                {
                    cinemachineFreeLook.m_Lens.FieldOfView += 0.5f;
                }
                //cinemachineFreeLook.m_Lens.OrthographicSize
            }
            if (Input.GetAxis("Mouse ScrollWheel") > 0)
            {
                if (cinemachineFreeLook.m_Lens.FieldOfView >= 4)
                {
                    cinemachineFreeLook.m_Lens.FieldOfView -= 0.5f;
                }
            }
        }
    }
    

    将其挂载到CMFreeLook上。

    效果展示

    展开全文
  • ET是一个开源的游戏客户端(基于unity3d)服务端双端框架,服务端是使用C# .net core开发的分布式游戏服务端,其特点是开发效率高,性能强,双端共享逻辑代码,客户端服务端热更机制完善,同时支持可靠udp tcp ...
  • 基于Qt的分析数据软件辅助Unity3D分析模型状态源码 Unity3D是一个比较常见的游戏引擎,可以很方便地驱动游戏模型。但是数据分析似乎不太好,因此,借助Qt框架做一个便于分析数据的软件。以下是做完后展示的效果。 ...
  • Unity3D AI和过程生成框架 入门 build4_Data文件夹和build4可执行文件共同构成了我们的游戏演示的正常运行。 它旨在作为示例说明您可以使用我们的框架执行的操作。 要使用此功能,请下载build4可执行文件和build4_...
  • Unity中的框架知识

    2022-06-15 09:11:28
    框架是一堆包含了常量,方法,类等代码的集合,他是一个半成品的应用,只包含了一些项目开发的时候所用使用的底层架构,并不包含业务逻辑,框架同时还包含一些优秀的设计模式。 从作用上说 框架是一个支撑整个系统...
  • unity3d mvc框架

    2015-12-17 14:04:50
    unity3d mvc框架, Code Control v1.2.unitypackage,代码控制器
  • unity3d客户端框架
  • 基于Unity3D在基本游戏框架下客户端研究与实现
  • 一个极简的基于unity3d引擎与c#语言的游戏框架/架构(包括客户端与服务器)。本工程使用作为服务端基础通信设施。 受此启发,我在想是否也能够采用分层虚拟机的样式来实现游戏框架框架部分就像内核,游戏特定逻辑...
  • CatLib for Unity是为Unity3D开发的服务提供商框架,对某些功能性业务的发展非常有帮助。 我们还通过集成通用开发组件来减少开发人员的不必要工作。 入门 随安装 $ bucket require catlib/catlib 学习CatLib ...
  • Unity 3D模型展示框架篇之项目整理

    热门讨论 2022-05-24 16:22:02
    本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,记录整合过程中对原有的脚本进行调整的过程。专栏文章后续加入AssetBundle+ILRuntime热更新技术过程。
  • Unity3d 框架信息收集

    2017-11-29 09:44:00
    之前收集过Unity3d框架,但是不知道为什么丢失了,所以重新把这些框架信息记录下来 StrangeIoC StrangeIoC Entitas Entitas 是一款超级快速的Entity组件系统框架特别用于C#和Unity。 GameFramework ...
  • Unity3D进阶4-8】Unity3D 游戏框架

    千次阅读 2020-05-21 09:52:29
    一、目录 【Unity3D从入门到进阶】文章目录及设置这个专栏的初衷
  • 3D城市交通系统 对应Unity3D资源
  • Unity3D的一个MVC框架
  • 代码 unity3d 游戏插件 Shooter Kit - Halloween Range v1.2射击游戏框架源码代码 unity3d 游戏插件 Shooter Kit - Halloween Range v1.2射击游戏框架源码代码 unity3d 游戏插件 Shooter Kit - Halloween Range v1.2...
  • Unity3D 集成 高德地图SDK 地图-附件资源
  • 开源承诺 我们很荣幸为社区提供这个有用的工具,并鼓励那些正在开发项目的人从中受益。 迄今为止,Zenject已经分叉了300多次,我们很高兴看到它为用户带来的好处并支持! Modest Tree的Zenject是开源的,以支持社区...
  • 运动框架MotionFramework是一套基于Unity3D引擎的游戏框架框架整体遵循轻量化,易用性,低转换,扩展性强的设计理念。工程结构清晰,代码注释详细,该框架已被纳入多款商业化的游戏项目,是作为创业游戏公司,独立...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,191
精华内容 4,876
关键字:

unity3d框架