精华内容
下载资源
问答
  • Unity继承MonoBehaviour的单利类 学习记录 继承于MonoBehaviour的单例类,方便调用 /* * FileName: SingletonM * CreateTime: #CreateTime# * Version: #Version# * Description: * */ using System; using...

    Unity继承于MonoBehaviour的单利类

    学习记录
    继承于MonoBehaviour的单例类,方便调用

    /*
     * FileName:     SingletonM
     * CreateTime:   #CreateTime#
     * Version:     #Version#
     * Description:
     * 
    */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using UnityEditor;
    using UnityEngine;
    /// <summary>
    /// 继承于MonoBehaviour的单利类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingletonM<T> : MonoBehaviour where T : MonoBehaviour
    {
        static T _instance = default(T);
    
        public static T Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = (T)FindObjectOfType(typeof(T));
                    if (_instance == null)
                    {
                        GameObject go = new GameObject(typeof(T).Name);
                        _instance = go.AddComponent<T>();
                    }
                }
                return _instance;
            }
        }
        protected virtual void Awake()
        {
            if (_instance == null)
            {
                _instance = this as T;
            }
            else
            {
                //  Destroy(this.gameObject);
            }
            Init();
        }
        /// <summary>
        /// 可用于初始化
        /// </summary>
        protected virtual void Init()
        {
    
        }
    }
    
    展开全文
  • 一、Unity继承MonoBehaviour多次运行构造函数 1.首先创建Test类继承MonoBehaviour 在Unity中执行查看 可以看出从 挂载脚本——>运行——>结束一共执行了4次 2.接下来我们在试试有参构造函数 有参...

    一、Unity继承MonoBehaviour多次运行构造函数

    1.首先创建Test类继承MonoBehaviour

    在Unity中执行查看 可以看出从 挂载脚本——>运行——>结束一共执行了4次

    2.接下来我们在试试有参构造函数

     

     有参函数缺不会多次执行

     官方说明:

    Never initialize any values in the constructor. Instead use Awake or Start for this purpose. Unity automatically invokes the constructor even when in edit mode. This usually happens directly after compilation of a script, because the constructor needs to be invoked in order to retrieve default values of a script. Not only will the constructor be called at unforeseen times, it might also be called for prefabs or inactive game objects.
    不要在构造函数中初始化任何变量.要用Awake或Start函数来实现.即便是在编辑模式,Unity仍会自动调用构造函数.这通常是在一个脚本编译之后,因为需要调用脚本的构造函数来取回脚本的默认值.我们无法预计何时调用构造函数,它或许会被预置体或未激活的游戏对象所调用.

    原因官方文档也没有具体说明,只是说如果继承MonoBehaviour的类初始化变量需要在Awake或Start函数来实现

    总结:

    继承MonoBehaviour的类会多次执行构造函数,虽然有参函数在测试时没有执行但还是根据官方文档所说初始化变量还是在Awake或Start函数来实现比较好

    展开全文
  • } } public abstract class MonoSingleton : MonoBehaviour where T : class { void Awake() { if(Service.IsRegistered) { DestroyImmediate(this); return; } #if UNITY_EDITOR var type = GetType(); var attrs ...

    仅作欣赏~
    实际业务中顶多Ins = this(但是得保证挂载得script仅一份啊,不然就没有单例的味道了)
    最多加个static、构造、DontDestroy和Destroy,哈哈。

    /*
    *R0-V1.0
    *Modify Date:2020-04-20
    *Modifier:ZoJet
    */
    
    using System;
    using UnityEngine;
    
    namespace UCL.Core {
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
        [System.Diagnostics.Conditional("UNITY_EDITOR")]
        sealed class ServiceFilterAttribute : Attribute {
            public string Name;
            public ServiceFilterAttribute(string name) {
                Name = name;
            }
        }
    
        public abstract class MonoSingleton<T> : MonoBehaviour where T : class {
            void Awake() {
                if(Service<T>.IsRegistered) {
                    DestroyImmediate(this);
                    return;
                }
    #if UNITY_EDITOR
                var type = GetType();
                var attrs = type.GetCustomAttributes(typeof(ServiceFilterAttribute), true);
                if(attrs.Length > 0) {
                    var sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                    var i = attrs.Length - 1;
                    for(; i >= 0; i--) {
                        if(System.Text.RegularExpressions.Regex.IsMatch(sceneName, ((ServiceFilterAttribute)attrs[i]).Name)) {
                            break;
                        }
                    }
                    if(i == -1) {
                        throw new UnityException(
                            string.Format("\"{0}\" service cant be used at scene \"{1}\"", type.Name, sceneName));
                    }
                }
    #endif
                Service<T>.Register(this as T);
                OnCreateService();
            }
    
            void OnDestroy() {
                if(Service<T>.IsRegistered) {
                    OnDestroyService();
                    Service<T>.Unregister(this as T);
                }
            }
    
            protected abstract void OnCreateService();
    
            protected abstract void OnDestroyService();
        }
    
        public static class Service<T> where T : class {
            static T _instance;
    
            public static bool IsRegistered {
                get {
                    return _instance != null;
                }
            }
    
            public static T Get() {
                if(_instance != null) {
                    return _instance;
                }
    
                var type = typeof(T);
                if(type.IsSubclassOf(typeof(ScriptableObject))) {
                    var list = Resources.FindObjectsOfTypeAll(type);
                    if(list == null || list.Length == 0) {
                        throw new UnityException(
                            string.Format("Service<{0}>.Get() can be used only with exists / loaded asset of this type", type.Name));
                    }
                    _instance = list[0] as T;
                    return _instance;
                }
    
    #if UNITY_EDITOR
                if(type.IsSubclassOf(typeof(Component)) && !type.IsSubclassOf(typeof(MonoSingleton<T>))){
                    throw new UnityException(
                        string.Format("\"{0}\" - invalid type, should be inherited from MonoSingleton", type.Name));
                }
    #endif
    
                if(type.IsSubclassOf(typeof(MonoSingleton<T>))) {
    #if UNITY_EDITOR
                    if(!Application.isPlaying) {
                        throw new UnityException(
                            string.Format("Service<{0}>.Get() can be used only at PLAY mode", type.Name));
                    }
    #endif
                    new GameObject(
    #if UNITY_EDITOR
                     "_SERVICE_" + type.Name
    #endif
                     ).AddComponent(type);
                } else {
                    Register(Activator.CreateInstance(type) as T);
                }
                return _instance;
            }
    
            public static void Register(T instance) {
                if(IsRegistered) {
                    throw new UnityException(
                        string.Format("Cant register \"{0}\" as service - type already registered", typeof(T).Name));
                }
                if(instance == null) {
                    throw new UnityException(
                        string.Format("Cant register null instance as service"));
                }
                _instance = instance;
            }
    
            public static void Unregister(T instance, bool force = false) {
                if(instance == _instance || force) {
                    _instance = null;
                }
            }
        }
    }
    
    展开全文
  • Unity中的MonoBehaviour

    万次阅读 多人点赞 2019-03-05 22:58:38
    从第一次在unity创建C#脚本开始就会发现每个脚本都继承了一个叫MonoBehviour的类,那么MonoBehaviour是做什么的呢? 首先明确一点,Unity引擎将所有的代码的执行都放在了一个主线程中,Update,FixedUpdate等都是...

    从第一次在unity创建C#脚本开始就会发现每个脚本都继承了一个叫MonoBehviour的类,那么MonoBehaviour是做什么的呢?


    首先明确一点,Unity引擎将所有的代码的执行都放在了一个主线程中,Update,FixedUpdate等都是按照Unity调度机制依次自行,没有任何一个地方是并行执行的,都是依次执行的。

    一层层进入MonoBehaviour父类,不妨看出MonoBehaviour间接继承了Component,所以继承自MonoBehaviour脚本的作用其中之一就是充当组件的角色,所以当我们需要将一个自定义脚本以组件的形式添加到对应的GameObject时(Unity中Inspector面板中的每一项都称为组件,包括创建的脚本),该脚本是必须要继承MonoBehaviour,否则无法添加为组件。


    那么如果继承了MonoBehaviour,那么这个类的生命周期是怎样的呢?
    首先可以将生命周期分为两种状态

    • 编辑器下的状态:只有Reset函数一个
    • 运行状态(真正的生命周期):除Reset函数外,其余函数都在运行状态执行(加特殊字段,也可以在编辑器运行)

    Reset函数:

    只能在编辑器模式下执行,与脚本是否激活无关,点击Reset或者添加该脚本到游戏物体上时执行(这个方法我几乎没有用过不是很常用)


    Awake,OnEnable,Start函数:

    Awake:仅执行一次,当游戏物体被创建的时候执行,无论该脚本是否处于激活状态,只要游戏物体处于激活状态即可执行。
    在Inspector面板中的组件上有一个复选框,这是在脚本中有生命周期函数时才会显示的,但是测试后发现只有Awake和Reset并不会出现复选框,因为这两个函数与脚本是否激活无关。
    OnEnable:可执行多次,当组件设置enable = true或游戏物体设置active = true时调用(包括脚本一开始处于激活状态时运行游戏的第一次)。
    Start:仅执行一次,当游戏物体处于激活状态并且脚本也处于激活状态才可以执行。



    上述是生命周期的开始,先将生命周期的运行跳过,先来说说生命周期的结束。

    OnApplicationQuit,OnDisable,OnDestroy函数:

    OnApplicationQuit:当你的应用程序退出时,会先调用OnApplicationQuit。
    OnDisable:除在OnApplicationQuit调用时会调用,还会在设置enable = false 或设置active = false时调用(如果脚本一开始处于未激活状态则不会调用)。
    OnDestory:除在OnApplicationQuit调用时会调用,还有在Destroy游戏物体时调用。

     



    看完了生命周期的开始与结束,下面是比较重要的部分——生命周期的运行过程


    FixedUpdate,Update,LateUpdate函数:
    可以将生命周期的运行以Update函数作为分割线,FixedUpdate,物理系统,输入系统的相关函数都是在Update之前先执行,携程是在Update之前LateUpdate函数之后执行。



    FixedUpdate与Update:
    FixedUpdate:每帧调用而且每帧的时间间隔是固定的,不受帧率(FPS)影响。每一帧的时间是在Edit->Project Settings->Time面板中的Fixed Timestep设置,默认为0.02s,则0.02s为一帧也就是每帧之间的间隔是0.02s。
    对于更新频率比较稳定的物理系统来说就合适放在FixedUpdate中处理
    Update:每帧调用但是每帧的时间间隔不固定,受到帧率影响,而帧率(FPS)与电脑性能有关。
    例如FPS是30,则每秒执行30帧,如果FPS是10,则每秒执行10帧。是不稳定的。

    在Update和FixedUpdate中输出Time.time:因为FixedUpdate每帧之间是固定的时间间隔0.02秒(Fixed Timestep设置的值),所以不难发现FixedUpdate中的Time.time数值每帧都加了固定0.02,而Update中是不稳定的。

    不能在Update中直接移动的原因:

    例如:

    1.人物移动会出现抖动:因为Update中每帧的间隔是不一样的,所以移动不是平滑的则会抖动。
    2.性能不同的设备帧率不同:假如A和B两台电脑,A电脑的帧率为50则人物一秒钟移动50米,B电脑的帧率为30则人物一秒钟移动30米,这肯定是不行的。

     

    解决办法就是乘上Time.deltaTime。

    ->Time类的相关详解:Time类详解


    LateUpdate比较好理解:
    LateUpdate:与Update一样每帧之间的时间是不固定的,受到帧率影响,而帧率(FPS)与电脑性能有关。
    LateUpdate是三个Update中最后一个执行的,举个例子,比如一家三口要出去玩,每个人的起床都在Update中执行,则出发应该在LateUpdate中执行,这样就保证了在都都起床之后才出发。

    我们在Update,FixedUpdate,LateUpdate中都输出Time.realtimeSinceStartup,明显发现每一帧都是FixedUpdate->Update->LateUpdate的执行顺序。

    所以相机的跟随一般在LateUpdate中实现,这样可以确保在人物移动结束后再进行相机的跟随。



    很重要的一点,官方对于LateUpdate解释成一句话:LateUpdate是在所有Update函数调用后被调用。
    比如写两个脚本,挂载到同一个游戏物体上,同时拥有这三个关于Update的方法,运行查看输出结果。


    每个游戏物体中脚本上的同名函数会被放在同一个线程中,执行完Awake线程再执行Stat线程.....
    也就是说在Unity中所有脚本的Awake函数执行完才会执行Start函数,所有Start函数执行完才会执行Update函数。


    普通类与继承MonoBehaviour类的区别:

    1.继承MonoBehaviour的类不需要创建它的实例,也不能自己创建(用new),因为从MonoBehaviour继承过来的类Unity会自动创建实例,并且调用被重载的函数(Awake,Start.....)。
    如果用new会出现以下警告:


    警告说的很明显,就是如果继承了MonoBehaviour就不允许你用new创建,你可以用添加组件的方式替代,或者根本没有基类(不继承MonoBehaviour的普通类),但是好像并不影响程序,这点很奇怪。
    2.不继承MonoBehaviour不能使用Invoke,Coroutine,print以及生命周期函数等。
    3.不继承MonoBehaviour不能挂在到Inspector上,也就是说不能当组件使用也不能看到一些数据。

    展开全文
  • Unity中,需要挂载到游戏对象上的脚本都要继承MonoBehaviour,记住了,继承了MonoBehaviour的类,不要写它的构造函数,因为Unity中对于MonoBehaviour的构造函数何时调用,调用几次,咱都清楚。   所以如果想...
  • unity 浅谈MonoBehaviour

    千次阅读 2020-06-26 17:55:55
    MonoBehaviour 学于事件函数的执行顺序-unity官方文档 概述 MonoBehaviour is the base class ...MonoBehaviour是所有脚本的基类,所有C#都需要显性的继承MonoBehaviour,这样才能被挂载到game Object上。 MonoBehavi
  • Unity编程篇 MonoBehaviour 类 ...wfr=spider&...通过unity建的脚本默认都是继承MonoBehaviour 的 , 我们今天来学习 MonoBehaviour 的九大生命周期 : Awake 函数 : 在加载场景时运行 , 即在游戏开始...
  • MonoBehaviour是所有脚本的基类,使用javascript的话,每个脚本都会自动继承MonoBehaviour,但使用C#或Boo就必须显式从MonoBehaviour继承。 注意:复选框控件(在编辑中)仅仅会阻止Start、Awake、Update、...
  • Unity继承MonoBehaviour的静态单例

    千次阅读 2016-10-29 11:15:27
    using UnityEngine;...public class Singleton : MonoBehaviour where T : MonoBehaviour { private static T _instance; private static object _lock = new object(); public static T Instance {
  • unity 入门 Monobehaviour
  • 从第一次在unity创建C#脚本开始就会发现每个脚本都继承了一个叫MonoBehviour的类,那么MonoBehaviour是做什么的呢? 首先明确一点,Unity引擎将所有的代码的执行都放在了一个主线程中,Update,FixedUpdate等都是...
  • 解决方法链接:https://blog.csdn.net/weixin_39543044/article/details/109593898 在unity的菜单选项中点击Edit--proferenrens--External Tools 然后点击External Script Editor后面的可点击空白区域,选择你的C#...
  • MonoBehaviour 是 Unity 中所有脚本的基类,如果你使用JS的话,脚本会自动继承MonoBehaviour。如果使用C#的话,你需要显式继承MonoBehaviour。 在我们使用MonoBehaviour的时候,尤其需要注意的是它有哪些可重写函数...
  • 通过unity建的脚本默认都是继承MonoBehaviour 的 , 我们今天来学习 MonoBehaviour 的九大生命周期 : Awake 函数 : 在加载场景时运行 , 即在游戏开始之前初始化变量或者游戏状态 . 只执行一次 2. OnEnable 函数...
  • Unity中的MonoBehaviour

    千次阅读 2015-07-21 10:56:00
    MonoBehaviour是所有脚本的基类,使用javascript的话,每个脚本都会自动继承MonoBehaviour,但使用C#或Boo就必须显式从MonoBehaviour继承。注意:复选框控件(在编辑中)仅仅会阻止Start、Awake、Update、...
  • Unity3D中MonoBehaviour类整理类的继承变量函数定时器相关:协程相关:消息:1.代码运行周期:2.动画:3.相机:4.Collider(碰撞体):5.连接服务器:6.鼠标点击:7.其他: 类的继承 继承层次:Object->Component...
  • Unity事件及MonoBehaviour

    2019-05-08 02:47:23
    简单了解以下Unity的事件循环,顺带了解一下反射,协程之类的;通过这些来理解MonoBehaviour
  • Unity中所有使用C#编写的脚本都应该继承自[MonoBehaviour]
  • Unity 脚本基类 MonoBehaviour 与 GameObject 的关系

    万次阅读 多人点赞 2017-03-27 12:55:57
    MonoBehaviour 是 Unity 中所有脚本的基类,如果你使用JS的话,脚本会自动继承MonoBehaviour。如果使用C#的话,你需要显式继承MonoBehaviour
  • 红色框勾选对应继承MonoBehaciour脚本的继承变量enabled enabled 官方解释:启用行为被更新,禁用行为更新。  即enabled == false 执行Update函数 enabled == true 执行Update函数   *如果运行前...
  • 继上文,有个蠢货单例模式只是用来引用,突然遇到了一个继承MonoBehaviour的类,然后unity跟你讲:!你可以在我这里这么用! 啊这……吓得我当场百度... **************正文开始************** 第一个脚本 ...
  • Unity3D推崇组件式开发,而MonoBehaviour是核心所在,虽然在实际项目中,我要求尽可能使用继承MonoBehaviour的对象(我们自己做了封装),但是对于MonoBehaviour中各种系统回调函数的执行顺序还是要了解清楚。...
  • MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[]; foreach(MonoBehaviour monoScript in monoScripts) { if((monoScript is InteractionManager) &&.....
  • Unity3D的MonoBehaviour与Component与Tranform与GameObjectC#的修饰符internal,default,virtual,sealed从一个空类说起private:加scope修饰符则为private(建议这样使用)internal:internal的作用域为一个工程...
  • Unity 脚本基类 MonoBehaviour 与 GameObject 的关系 标签: unity脚本 2017-03-27 12:55 395人阅读 评论(0) 收藏 举报  分类: Unity3D(4)  版权声明:本文为博主原创文章,未经博主允许不得转载。...
  • 载入一个prefab并实例化后,获取该prefab上挂载的一个MonoBehaviour组件,例如: public class Foo: MonoBehaviour { public bool newValue = true; void Awake(){ Debug.Log(newValue); } } 此时,Awake中的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,314
精华内容 2,525
关键字:

unity继承不了monobehaviour