Unity3D 之 C# 脚本

引用类型 :class ,interface, 数组 , delegate , object ,string (object 是C#中所有类型,包括所有的值类型和引用类型的根类,string 类型是一个从object类直接继承的密封类型(不能再被继承),其实例表示Unicode字符串)

try后面一个finally,try中有一个return,那么finally中的代码会不会运行?如果运行,是在return后还是return前答:会运行,并且在return 后运行。

public static const int A=1;这段代码有错误么?是什么? —— const成员都是static所以应该去掉static



谈谈final,finally,finalize的区别
   防止重写,
   try{}catch{}
   在垃圾回收之前,尝试释放资源并执行其他清理操作

const和static readonly 区别是什么?
   编译时常量
   运行时常量



net中什么类不能被继承?答:如果在类前加上sealed关键字,则表示该类为密封类,密封类不能被继承。sealed 除了可以应用于类外,还可以应用于实例方法和属性。密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed 修饰符必须始终与override一起使用

C#支持多重继承么?—— 不支持。可以用接口来实现。

私有成员会被继承么?—— 会,但是不能被访问。所以看上去他们似乎是不能被继承的,但实际上确实被继承了。

被virtual修饰的方法可以被子类覆写。

能够实现允许某个类被继承,但不允许其中的某个方法被覆写么?—— 可以,标记这个类为public,并标记这个方法为sealed。

为什么不能指定接口中方法的修饰符?—— 接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。他们默认为公有方法。接口中所有方法必须是抽象的,并且不能指定方法的访问修饰符。抽象类中可以有方法的实现,也可以指定方法的访问修饰符。



String/StringBuilder的异同

string是一个不可变的数据类型,一旦对字符串对象进行了初始化,该字符串对象就不能改变了。修改字符串内容的方法

和运算符实际上是创建一个新的字符串.

stringbuilder分配好内存,对字符串的修改就在赋予stringbuilder实例的存储单元中进行.str=null,声明而不分内存空间,str=""声明而分内存空间

String s = new String("xyz");创建了几个String Object? —— 两个对象,一个是“xyx”,一个是指向“xyx”的引用对像s



协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程。

在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在MonoBehaviour或继承于MonoBehaviour的类中调用。

在Unity3D中,使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启一个线程。区别在于使用字符串作为参数可以开启线程并在线程结束前终止线程,相反使用IEnumerator 作为参数只能等待线程的结束而不能随时终止(除非使用StopAllCoroutines()方法);另外使用字符串作为参数时,开启线程时最多只能传递一个参数,并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制。

在Unity3D中,使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序。协同程序的返回类型为Coroutine类型。在Unity3D中,Coroutine类继承于YieldInstruction,所以,协同程序的返回类型只能为null、等待的帧数(frame)以及等待的时间。



Unity是不支持多线程的,也就是说我们必须要在主线程中操作它,可是Unity可以同时创建很多脚本,并且可以分别绑定在不同的游戏对象身上

每个脚本的Awake、Update、LateUpdate、FixedUpdate等等,方法在后台都有一个总汇。

后台的Awake()

{

       脚本0中的Awake();

       脚本1中的Awake();

       脚本2中的Awake();

}

       后台的方法 Awake、Update、LateUpdate、FixedUpdate等等都是按照顺序,等所有子脚本中的Awake执行完毕后在去执行 Start 、Update、LateUpdate等等。所以这里也就解释了Unity没有多线程的概念。

在脚本2的Awake方法中创建一个立方体对象。在脚本0的Awake方法中去获取这个立方体对象。如果脚本的执行顺序是 先执行Script2 然后在执行Script0那么Script0中的Awake就可以获取到该立方体对象,可是如果脚本的执行顺序是先Script0然后在Script2,那么Script0肯定会报空指针错误的。

          那么实际项目中的脚本会非常非常多,他们的先后顺序我们谁也不知道。所以我的建议一般在Awake方法中创建游戏对象或在Resources.Load(Prefab) 对象。在Start方法中去获取游戏对象,或者游戏组件,这样就可以确保万无一失了。

     如果说你非要控制脚本的执行先后顺序,也不是完全不行!Unity可以设置脚本执行的顺序。如下图所示,选择任意脚本在Inspector视图中点击Execution Order..按钮。点击右下角的“+”将弹出下拉窗口,包括游戏中的所有脚本。添加脚本完毕后,Default Time下方数值越小的排在越前面脚本将率先执行,如果没有设置的脚本将按默认的顺序执行。



Unity 脚本的生命周期

Update —— 正常更新,用于更新逻辑,此方法每帧都会由系统自动调用一次

LateUpdate —— 推迟更新,此方法在Update方法执行完后调用,同样每一帧都调用

Awake —— 脚本唤醒,为系统执行的第一个方法,用于脚本的初始化,在脚本的生命周期中只执行一次

FixedUpdate —— 固定更新,设置更新频率

Start —— 在Awake方法之后,Update方法执行之前执行,并且只执行一次

OnDestroy —— 当前脚本销毁时使用

使用脚本调用游戏对象 —— 将脚本绑定在一个游戏对象身上,也可以在代码中动态绑定脚本和删除脚本。任何一个游戏对象都可以同时绑定多条游戏脚本,并且这些脚本互不干涉,各自完成自己的生命周期

GameObject.CreatePrimitive —— 用于创建一个原始游戏对象,其参数可设置为立方体,球体,圆柱体等系统默认提供的游戏对象

AddComponet —— 用于给游戏对象添加组件

renderer.material.color —— 设置渲染材质的颜色或者贴图

transform.position —— 设置该游戏对象的位置



获取游戏对象:

通过对象名称获取对象 —— 使用Find 方法传入对象的完整路径名称即可在代码中获取游戏对象

通过标签获取单个游戏对象 —— “Add Tag ”中 Element 0 选项右侧直接输入标签名称即可添加新标签 FindWithTag() —— FindWithTag 方法只能获取一个游戏对象,如果程序中多个对象都添加了同样的标签,那么这个方法只能获取第一个添加此标签的对象

通过标签获取多个游戏对象 —— FindGameObjectsWithTag() 方法并将相应的标签名称作为参数传入,即可返回一个游戏对象数组

添加组件与修改组件

添加游戏组件时,可以使用AddComponent()方法,由于组件自身没有对应的删除方法,需要使用父类执行Object.Destroy()

render.material 引用当前脚本绑定对象的材质,直接为其赋值即可修改对象材质

一个游戏对象可以绑定多条脚本,实现这些脚本之间的交互就可以使用广播机制

游戏对象之间发送的广播与消息大致分为:

1,向子对象发送,将发送至该对象的同辈对象或者子孙对象中;

gameObject.BroadcastMessage("ReceiveBroadcastMessage","A0---BroadcastMessage()");

接受父类发送的消息:

function ReceiveBroadcastMessage(str: String)

{ Debug.Log(); }

2,给自己发送,发送至自身对象;

gameObect.SendMessage();

3,向父对象发送,发送至该对象的同辈或者父辈对象中

gameObject.SendMessageUpwards();

克隆游戏对象        Instantiate()

动态地为某个游戏对象添加脚本组件 ——  AddComponent(),将脚本的名称作为参数传入即可完成脚本组件的添加

obj.transform.position 引用得到obj游戏对象在三维坐标系中的位置,存储在Vector3容器中(保存着xyz轴的坐标)

transform.Rotate() —— 用于设置模型绕自身旋转,参数为旋转的速度与旋转的方向

transform.RotateAround() —— 用于设置模型围绕某一个点旋转

Time.deltaTime —— 用于记录上一帧所消耗的时间,用作模型旋转的速度系数

Vector3.right —— x轴方向

Vector3.up —— y轴方向

Vector3.forward —— z轴方向

transform.Translate() 唯一参数为平移模型的方向    obj.transform.Translate(Vector3.forward * Time.deltaTime)



命名规则 —— 必须与项目资源视图中该脚本的名称对应,否则无法成功绑定至游戏对象

Unity3D     工具类

Time —— 获取当前的系统时间

Time.time —— 从游戏开始后计时开始,表示截至目前共运行的游戏时间

Time.deltaTime —— 获取Update() 方法中完成上一帧所消耗的时间

Time.fixedTime —— FixedUpdate() 方法中固定消耗的时间总和

使用 WaitForSeconds() 方法可以以秒为单位让程序等待一段时间,此方法可直接使游戏主线程进入等待状态。该方法的返回值为IEnumerator类型,在需要等待的地方 调用 yield return new WaitForSeconds(2)

Unity中所有用到的模型旋转的,底层都是由四元数实现,可以精确计算模型的旋转的角度

时间: 2024-08-26 15:55:15

Unity3D 之 C# 脚本的相关文章

[转]关于Unity3D对象和脚本实例调用的顺序探究

http://blog.csdn.net/liangzg_2011/article/details/8150844 关于Unity3D对象和脚本实例调用的顺序探究 我们先来看一些有趣Unity实例顺序的小实验.有图有真相!! 注:以上打印的代码语句如下: [csharp] view plaincopy <span style="font-size:18px;">    void Start () { print("-----" + this.transf

unity3d抛物线的脚本

using UnityEngine; using System.Collections; public class ProjectileTest : MonoBehaviour { public GameObject target; public float speed = 10; private float distanceToTarget; private bool move = true; void Start () { distanceToTarget = Vector3.Distanc

扩展Unity3D编辑器的脚本模板

??最近在学习Shader时感觉Shader语言参数众多.语法诡异,如果每次都从头开始写Shader一定是一件痛苦的事情.如果可以在本地定义好一组标准的Shader模板,这样当我们需要实现某些效果类似的Shader时,就可以在这个Shader模板的基础上进行修改.因为Shader文件是一个文本文件,所以我们可以非常容易地创建这样一个模板,在这个模板中我们可以进一步完善相关的参数注释,这样就不用每次写Shader的时候都需要查文档了,从这个角度出发,就进入了这篇文章的正题:扩展Unity3D编辑器

unity3d旋转摄像机脚本

void Update () { if(Input.GetMouseButton(1)) { if (axes == RotationAxes.MouseXAndY) { // Read the mouse input axis rotationX += Input.GetAxis("Mouse X") * sensitivityX; rotationY += Input.GetAxis("Mouse Y") * sensitivityY; rotationX =

Unity3D 在自定义脚本中实现Button组件上的OnClick面板

Unity3D 在自定义脚本中实现Button组件上的OnClick面板UnityEvent脚本代码事件传参多参数传入下述内容不对c#语法做过多讲解,仅对已入门并有兴趣的同学做为学习和拓展的资料 大家在Unity制作的过程中一定都使用过UI功能,那么很多人也一定见过这个面板: 那么我们如何能在自己的脚本中添加上像OnClick这样的面板呢. UnityEventUnity中内置了一个UnityEvent类作为事件处理的类,我们只要在脚本中声明出来,Unity便会自动添加到脚本面板上,这样便可以在

Unity3D如何使用脚本实现跳跃的效果

欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多U3D资源.U3D培训视频.U3D教程.U3D常见问题.U3D项目源码,我们致力于打造业内unity3d培训.学习第一品牌. 这里介绍的是如何使用脚本最简单的模拟出跳跃的效果. 脚本源码如下: var speed = 3.0; //This data type is a float.var jumpSpeed = 50.0;var grounded = true; function Update () {       

【unity3d游戏开发脚本笔记之一:坐标系选择对物体运动的影响】

时间:2016年9月24日17:38:21   作者:yexiaopeng 博客园     在unity3d的世界中,其坐标系可分为四种,世界坐标系-WorldSpace   本地坐标系-LocalSpace  屏幕坐标系-ScreenSpace 视口坐标-ViewPortSpace.其中作者本人当前面对的是世界坐标系和本地坐标系的问题.本文讲诉这两个坐标系对物体运动的影响,其他的坐标系涉及到再做说明.    在学习unity3d官方例子(太空大战)的过程中,编写脚本对陨石的运动进行控制时发现旋

Unity3d中关于脚本的启用和禁用的意义及脚本前面的复选框消失的解释

大家好,我是小熊猫. 转载请注明出处:http://blog.csdn.net/a237653639/article/details/45766101 先总结,再证明. 总结: 禁用脚本的目的就是为了让该脚本"不执行",而启用的目的就是为了让该脚本"执行".以上是我原来的想法,其实这样的理解有偏差.准确地说,即使脚本为禁用状态,别的脚本也能够成功地调用 被禁用的脚本的成员(后面将给以证明). 那么,您可能会发问,那我禁用脚本有什么意义呢? 其实意义就是,脚本为启用状

unity3d 延迟运行脚本语句

在Unity3D中.有yield语句它负责延迟操作,yield return WaitForSeconds(3.0); //等待 3 秒 查看unity3d脚本手冊,使用方法须要在对应的格式. 以下代码含义就是,载入图片显示等待6秒后进入场景level1中. using UnityEngine; using System.Collections; public class init : MonoBehaviour { // Use this for initialization public T