Unity脚本类为什么要尽量避免继承monobehaviour new类

使用c写unity3d的脚本需要注意的问题
使用C#写脚本除了语法外,使用C#或Boo会有一些差别,最明显的是:
继承自MonoBehaviour类。所有的行为脚本代码必须继承自MonoBehaviour类(直接或间接)。如果使用的是javascript的话
会自动(隐性)的继承,如果使用的是&C#或Boo就必须明确地指定其继承于MonoBehaviour。如果你是在u3d中通过
“Asset-&Create-&C&Sharp&Script/Boo&Script”来创建了脚本代码文件的话,u3d的脚本创建模板将
会提前将相关继承语句定义在脚本代码文件中。
2、使用Awake或Start方法进行初始化,你(需要)在C#或Boo中使用Awake或Start方法。
Awake和Start之间的区别在于:Awake是当一个场景调入过程完成后会自动运行,而Start则是会在Update或FixedUpdate方法被第一次调用之前被运行。所有的Awake方法运行的优先级会高于任意的Start方法。
3、(文件中)主类名必须与文件名相同。在javascript脚本文件中,u3d虽然没有明确地定义主类,但事实上,u3d已经隐性地自动定义了主类,并将类名设置为等于脚本文件名(不包括扩展名)。
如果使用的是C#a或Boo脚本,那就必须得手动的将主类名设置为与文件同名。
4、使用C#实现协同,在语法上会有一处不同。这个用的比较少。(U3D中的)协同会(同时)用一个属于IEnumerator接口类型(枚举)的返回值和你使用的yield&返回值…;来替代yield……;
5、不要使用命名空间。U3D目前不支持你在脚本中使用命名空间,这个需求会在未来的版本中实现。
只有(public公有的)成员变量是可以在U3D程序的Inspector栏中会被以序列形式显示出来。私有类型(private)和成员类型
(protected)变量只能在专家模式(Expert&Mode)下可见,(而且)属性(Properties)不能序列化或者
(shown&in&the&inspector)不能在inspector窗口中被反射出来。
7、避免使用构造函数。不要通过构造函数来
初始化变量。这些工作可以使用第2条中的Awake方法和Start方法来替代(换句话来说就是在u3d中,Awake方法和&Start方法是每个脚本
文件类中默认的构造函数)。U3D甚至可以在标准编辑模式下就调用它们。它们通常是直接汇编在脚本中,因为构造函数需要检索默认脚本变量用于引用。
(u3d)在任意的时候不光可以调用构造函数,还可能会调用预设(物体)或未被唤醒的游戏物体。
实例化(C#脚本文件)时,单脚本文件状态下使用(自定义的)构造函数(可能)会导致严重的后果,并且会产生引用为空的异常。
以,如果你实例化C#脚本文件(即运行C#脚本文件。这是c#程序运行的基本方式,详细内容可以从C#专门的教材中了解),单脚本文件不要使用(自定义
的)的构造函数,直接使用Awake方法替代即可,实在没有理由为一个继承MonoBehaviour的(文件)类写任何的(构造函数)代码。
8、不同类之间方法调用问题。两个类之间调用单纯的用new&来进行实例化会产生空引用的错误,需要借助GetComponent&&()。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。unity3d学习笔记(六)单例脚本和单例类
unity3d学习笔记(六)单例脚本和单例类
本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢。http://blog.csdn.net/lzhq1982/article/details/要写到英雄与怪物之间的攻击交互了,在这之前,有必要插播一下单例脚本和单例类,因为我的交互都是在单例脚本上交互的。这样有什么好处呢,降低耦合度,这是任何一个程序员都关注的事情,编程也是一门艺术嘛,试想想,如果你的交互总是建立在两个或多个脚本之间,我用你的脚本实例,你用他的脚本实例,他用不知道谁的脚本实例,反正越多就越乱,到最后你都不想维护了,尤其是公司项目,你拍拍屁股走人了,后面维护的人就要骂娘了,你都不好意思说这代码是你写的,吐槽的有点多,其实我是看了雨松大神的文章有感而发,向雨松大神致敬,我是跟他一路学过来的,这有一篇他写的有关脚本架构的文章,有兴趣的拜读一下,给个地址:在我的demo中,单例脚本和单例类都用上了,单例脚本用来处理英雄和怪物之间的交互,单例类用来过度游戏场景。下面给出代码:单例脚本:[csharp]&private&static&BattleScene&&&&&&&&&&&public&static&BattleScene&GetInstance()&&&&&&{&&&&&&&&&&if&(!instance)&{&&&&&&&&&&&&&&instance&=&(BattleScene)GameObject.FindObjectOfType(typeof(BattleScene));&&&&&&&&&&&&&&if&(!instance)&&&&&&&&&&&&&&&&&&Debug.LogError("There&needs&to&be&one&active&MyClass&script&on&a&GameObject&in&your&scene.");&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&return&&&&&&&}&&单例脚本是要绑定到GameObject上的,生命周期随着这个GameObject的结束而结束,需要继承MonoBehaviour,一般在场景过度后就结束了,我把这个单例脚本绑定到了战斗场景的Main Camera上,用法也很简单,比如我这个BattleScene里有个函数hideNpcPanel(),我在Hero这个脚本中就这么用BattleScene().GetInstance().hideNpcPanel();单例类:[csharp]&public&class&Global&{&&&&&&public&string&loadN&&&&&&&&&&&&private&static&Global&&&&&&&public&static&Global&GetInstance()&&&&&&{&&&&&&&&&&if&(instance&==&null)&&&&&&&&&&&&&&instance&=&new&Global();&&&&&&&&&&&&&&&&&&&&return&&&&&&&}&&}&&单例类的脚本不用绑定到任何GameObject上,不需要继承MonoBehaviour,生命周期是整个程序运行周期,用法和单例脚本一样,比如你可以这样用:[csharp]&Global.GetInstance().loadName&=&"GameScene";&&你还可以定义一种类,甚至都不用实例化它,但里面的变量和函数要是全局的,也就是要带static的,比如同样是上面这个类:[csharp]&public&class&Global&{&&&&&&public&static&string&loadN&&}&&然后你可以这样用:[csharp]&Global.loadName&=&"GameScene";&&怎么用就看你的实际需求了。单例类和单例脚本就说到这里,下一篇我们就要用单例脚本实现英雄与怪物的交互了。
发表评论:
TA的最新馆藏&Unity中的脚本都是继承自MonoBehaviour。
MonoBehaviour 表示一个单一的行为。Unity中用户对游戏对象的操作被分割成若干个单一行为。每个单一行为都作为一个MonoBehaviour类来封装。再生成每个MonoBehaviour类的实例,并作为组件嵌入游戏对象。然后按照一定的顺序(从下到上)调用每个对象的重载方法来实现游戏对象的全部行为。 继承自MonoBehaviour的类,不需要自己创建它的实例,也不能自己创建(如 new
类名)。因为所有从MonoBehaviour继承过来的类,unity都会自动创建实例,并且调用被重载的方法,如我们经常用到的Awake,Start, Update等。而普通类,就可以用new来创建实例了。
一、基础函数:
1.Start() &&& 在Update方法被调用之前开始调用Start方法,而且Start方法在整个MonoBehaviour生命周期内只被调用一次。Awake和Start不同的地方在于Start方法仅仅在脚本初始化后被调用,这样允许你延迟加载任何代码,直到代码真正被使用时。Awake方法总是在Start方法执行之前被调用,这样允许你初始化脚本代码。
2.Awake() &&& 当脚本被加载后立即调用Awake方法,这个方法通常在Start()开始之前声明某些变量或者游戏的状态标记符。同样,Awake也是在MonoBehaviour声明周期内被调用一次。Awake在所有的对象(个人认为是GameObject)实例化后被调用,因此绑定这个脚本的对象能与其他对象之间相互作用,例如,同过GameObjectFindWithTag方法查找其他对象。
3.Update() &&& 在Start方法执行过后,游戏的每一帧都在调用此方法。
4.FixedUpdate() &&& 每一帧都在调用此方法。当处理Rigdibody时FixedUpdate应该代替Update方法,比如,当一个物体需要增加一个力时,应该将这个力的代码写在FixedUpdate()里面。 &&&
void FixedUpdate() { &&&&&
&& rigidbody.AddForce(Vector3.up);
5.LateUpdate() &&& 每一帧都在调用此方法。当每一帧的Update方法全部执行完后,此方法开始被调用。举个例子来说吧,当一个角色移动而摄像机也要跟着移动时,摄像机的处理就应该在LateUpdate()里面了。
6.OnGUI() &&& OnGUI()在每一帧被调用数次(several times),假如MonoBehaviour的enabled属性设置为false时,OnGUI()就失去作用了。
7.DontDestroyOnLoad() &&& 进入另一个场景时,保证绑定此脚本的对象的内存不被释放掉。也就是说绑定此脚本的GameObject在下一个场景中依然存在。
二、事件响应函数:
MonoBehaviour中的事件响应函数都是已On开头的,比如:鼠标事件,脚本激活、销毁,碰撞等。
OnApplicationFocus:当玩家获得或失去焦点时发送给所有游戏物体。可以作为协同程序,在函数中使用yield语句即可
OnApplicationPause:当玩家暂停时发送到所有的游戏物体。可以作为协同程序,在函数中使用yield语句即可。
OnApplicationQuit:在应用退出之前发送给所有的游戏物体。当用户停止运行模式时在编辑器中调用。当web被关闭时在网络播放器中被调用。
OnBecameInvisible:当renderer(渲染器)在任何相机上都不可见时调用OnBecameInvisible。
OnBecameVisible:当renderer(渲染器)在任何相机上可见时调用OnBecameVisible。
OnCollisionEnter:当此collider/rigidbody与另一个rigidbody/collider接触时调用。
OnCollisionExit:当此collider/rigidbody停止触发另一个rigidbody/collider时。
OnCollisionStay:当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionStay将会在每一帧被调用。
OnConnectedToServer:当你成功连接到服务器时,在客户端调用。
OnDisconnectedFromServer:失去连接或从服务器端断开时在客户端调用。
OnFailedToConnectToMasterServer:当连接主服务器出现问题时在客户端或服务器端调用。
OnControllerColliderHit:在移动的时,当controller碰撞到collider时OnControllerColliderHit被调用。
OnDestroy:脚本销毁时调用。
OnDisable:对象禁用或者取消激活时调用。
OnEnable:对象变为可用或激活状态时此函数被调用。
OnDrawGizmosSelected:如果想在物体被选中时绘制gizmos,执行这个函数。
OnGUI:渲染和处理GUI事件时调用。
OnJointBreak:当附在同一对象上的关节被断开时调用。
OnLevelWasLoaded:一个新关卡被载入时此函数被调用。
OnMouseDown、OnMouseDrag、OnMouseEnter、OnMouseExit、OnMouseOver、OnMouseUp:鼠标事件。
OnMouseUpAsButton:只有当鼠标在同一个GUIElement或Collider按下,在释放时调用。
OnTriggerEnter:当Collider(碰撞体)进入trigger(触发器)时调用OnTriggerEnter。
OnTriggerExit:当Collider(碰撞体)停止触发trigger(触发器)时调用OnTriggerExit。
OnTriggerStay:当碰撞体接触触发器时,OnTriggerStay将在每一帧被调用。
三、默认组件
注意组件对应的变量名是组件名的小写。
Transform:对象的位置,角度,缩放。变量名:transform
Rigidbody:刚体属性。
Render:渲染物体模型。
Light:灯光属性。
Camera:相机属性。
Collider:碰撞体属性。
Animation:动画属性。
Audio:声音属性。
四、组件获取函数
获取组件的方法由于比较耗时,所以如果你在update修改transform的话,一般可以先在Start中获取这个组件的引用,然后在update中使用引用去修改。
GetComponent:获取组件。
GetComponents:获取组件列表。
GetComponentInChildren:返回Type类型组件,在GameObject或它的任何子物体使用深度优先搜索,仅返回激活的组件。
GetComponentsInChildren:在GameObject或任何它的子物体,返回全部Type类型组件。
五、获取场景中的游戏对象
同样和获取组件一样,该方法比较费时,一般在Start中获取引用。
GameObject cube1 = GameObject.Find(&Cube1&);
GameObject cube1 = GameObject.FindWithTag(&tag_cube1&);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38次
排名:千里之外参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4386次
排名:千里之外
原创:10篇一种是单例脚本&一种是单例类
准确来说 应该 是有两种脚本 一种是单例脚本 一种是单例类。
1.单例脚本
private static JFCamera
public static JFCamera
GetInstance()&
if (!instance)&
instance =
(JFCamera)GameObject.FindObjectOfType(typeof(JFCamera));&
if (!instance)&
Debug.LogError("There needs to be one active MyClass script on a
GameObject in your scene.");&
private static JFSocket
public static JFSocket
GetInstance()&
if (instance == null)&
instance = new JFSocket();
单例脚本 是需要绑定在游戏对象身上的 , 但是场景一旦切换 游戏对象会释放
那么单例脚本也会被释放。。
为了避免场景切换脚本释放的问题, 我们需要使用单例类,,
单例脚本需要继承MonoBehaviour 单例类不用继承 MonoBehaviour
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 monobehaviour类 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信