zoukankan      html  css  js  c++  java
  • 初级知识

     脚本概览

    Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的。在脚本对象内部不同的函数被特定的事件调用。最常用的列在下面:

    Update:这个函数在渲染第一帧之前被调用,这里是大部分游戏行为代码被执行的地方,除了物理代码。

    FixedUpdate:这个函数在每个物理时间被调用一次,这是处理基于物理游戏的地方。

    在任何函数之外的代码在物体被加载的时候运行,这个可以用来初始化脚本状态。

    你也能定义事件句柄,它们的名称都以On开始,(例如OnCollisionEnter)。

    常用操作

    大多数游戏物体的操作是通过游戏物体的Transform或Rigidbody来做的,在行为脚本内部它们可以分别通过transform和rigidbody访问,因此如果你想绕着Y轴每帧旋转5度,你可以如下写:

    function Update(){

    transform.Rotate(0,5,0);

    }

    如果你想向前移动一个物体,你应该如下写:

    function Update(){

    transform.Translate(0,0,2);

    }

    跟踪时间

    Time类包含了一个非常重要的类变量,称为deltaTime,这个变量包含从上一次调用Update或FixedUpdate(根据你是在Update函数还是在FixedUpdate函数中)到现在的时间量。

    所以对于上面的例子,修改它使这个物体以一个恒定的速度旋转而不依赖于帧率:

    function Update(){

    transform.Rotate(0,5*Time.deltaTime,0);

    }

    移动物体:

    function Update(){

    transform. Translate (0, ,0,2*Time.deltaTime);

    }

    如果你加或是减一个每帧改变的值,你应该将它与Time.deltaTime相乘。当你乘以Time.deltaTime时,你实际的表达:我想以 10米/秒移动这个物体不是10米/帧。这不仅仅是因为你的游戏将独立于帧而运行,同时也是因为运动的单位容易理解。( 米/秒)

    另一个例子,如果你想随着时间增加光照的范围。下面的表达式,以2单位/秒改变半径。

    function Update (){

    light.range += 2.0 * Time.deltaTime;

    }

    当通过力处理刚体的时候,你通常不必用Time.deltaTime,因为引擎已经为你考虑到了这一点。

    访问其他组件

    组件被附加到游戏物体,附加Renderer到游戏物体使它在场景中渲染,附加一个Camera使它变为相机物体,所有的脚本都是组件,因为它们能被附加到游戏物体。

    最常用的组件可以作为简单成员变量访问:

    Component             可如下访问

    Transform             transform

    Rigidbody             rigidbody

    Renderer              renderer

    Camera                camera (only on camera objects)

    Light                 light (only on light objects)

    Animation             animation

    Collider              collider

    …等等。

    对于完整的预定义成员变量的列表。查看Component,Behaviour和MonnoBehaviour类文档。如果游戏物体没有你想取的相同类型的组件,上面的变量将被设置为null。

    任何附加到一个游戏物体的组件或脚本都可以通过GetComponent访问

    transform.Translate(0,3,0);  //等同于

    GetComponent(Transform).Translate(0, 1, 0);

    注意transfom和Transform之间大小写的区别,前者是变量(小写),后者是类或脚本名称(大写)。大小写不同使你能够从类和脚本名中区分变量。

    应用我们所学,你可以使用GetComponent找到任何附加在同一游戏物体上的脚本和组件,请注意要使用下面的例子能够工作,你需要有一个名为 OtherScript的脚本,其中包含一个DoSomething函数。OtherScript脚本必须与下面的脚本附加到相同的物体上。

    function Update(){

    otherScript = GetComponent(OtherScript); //这个在同一游戏物体内找到名为OtherScript的脚本

    otherScript.DoSomething(); //并调用它上加的DoSomething

    }


    向量

    Unity使用Vector3类同一表示全体3D向量,3D向量的不同组件可以通过想x,y和z成员变量访问。

    var aPosition : Vector3;
    aPosition.x = 1;
    aPosition.y = 1;
    aPosition.z = 1;

    你也能够使用Vector3构造函数来同时初始化所有组件。

    var aPosition = Vector3(1, 1, 1);
    Vector3也定义了一些常用的变量值。
    var direction = Vector3.up; // 与 Vector3(0, 1, 0);相同

    单个向量上的操作可以使用下面的方式访问:

    someVector.Normalize();

    使用多个向量的操作可以使用Vector3类的方法;

    theDistance = Vector3.Distance(oneVector, otherVector);

    (注意你必须在函数名之前写Vector3来告诉JavaScript在哪里找到这个方法,这适用于所有类函数)

    你也可以使用普通数学操作来操纵向量。

    combined = vector1 + vector2;

    查看Vector3类文档获取完整操纵和可用属性的列表。

    成员变量 & 全局变量(Javascript 版本)

    定义在任何函数之外的变量是一个成员变量Field。在Unity中这个变量可以通过检视面板来访问,任何保存在成员变量中的值也可以自动随工程保存。

    public int memberVariable = 0.0;

    上面的变量将在检视面板中显示为名为"Member Variable"的数值属性。

    如果你设置变量的类型为一个组件类型(例如Transform, Rigidbody, Collider,任何脚本名称,等等)然后你可以在检视面板中通过拖动一个游戏物体来设置它们。

    public Transform enemy;

    function Update()
    {

    if ( Vector3.Distance( enemy.position, transform.position ) < 10 );
    print("I sense the enemy is near!");

    }
    }

    你也可以创建私有成员变量。私有成员变量可以用来存储那些在该脚本之外不可见的状态。私有成员变量不会被保存到磁盘并且在检视面板中不能编辑。当它被设置为调试模式时,它们在检视面板中可见。这允许你就像一个实时更新的调试器一样使用私有变量。

    private var lastCollider : Collider;

    function OnCollisionEnter( collisionInfo : Collision ) {

    lastCollider = collisionInfo.other;

    }

     全局变量

    你也可以使用static关键字创建全局变量,这创造了一个全局变量,名为someGlobal

    static var someGlobal = 5;// 你可以在脚本内部像普通变量一样访问它

    print(someGlobal);// 'TheScriptName.js'中的一个静态变量

    someGlobal = 1;

    为了从另一个脚本访问它,你需要使用这个脚本的名称加上一个点和全局变量名。

    print(TheScriptName.someGlobal);
    TheScriptName.someGlobal = 10;


    用C#编写脚本

    除了语法,使用C#编写脚本还有一些不同。最需要注意的是:

    1.从MonoBehaviour继承

    所有的行为脚本必须从MonoBehaviour继承(直接或间接)。在Javascript中这自动完成,但是必须在C#脚本中显示申 明。如果你在Unity内部使用Asset -> Create -> C Sharp菜单创建脚本,创建模板已经包含了必需的定义。

    public class NewBehaviourScript : MonoBehaviour {...} // C#

    2.使用Awake或Start函数来初始化

    Javascript中放置在函数之外的代码,在C#中要放置在Awake或Start中。

    Awake和Start的不同是Awake在场景被加载时候运行,而Start在第一次调用Update或FixedUpdate函数之前被调用,所有Awake函数在任何Start函数调用之前被调用。

    3.类名必须与文件名相同

    Javascript中,类名被隐式地设置为脚本的文件名(不包含文件扩展名)。在c#中必须手工做。

    4.在C#中Coroutines有不同语法。

    Coroutines必有一个IEnumerator返回类型,并且yield使用yield return… 而不是yield…

    using System.Collections;

    using UnityEngine;

    public class NewBehaviourScript : MonoBehaviour {

    // C# coroutine

    IEnumerator SomeCoroutine ()

    {

    yield return 0;// 等一帧

    yield return new WaitForSeconds (2);//等两秒

    }
    }

    5.不要使用命名空间

    目前Unity还不支持将代码放置在一个命名空间中,这个需要将会出在未来的版本中。

    6.避免使用构造函数

    不要在构造函数中初始化任何变量,使用Awake或Start实现这个目的。即使是在编辑模式中Unity也自动调用构造函数,这通常发生在一个脚 本被编译之后,因为需要调用构造函数来取向一个脚本的默认值。构造函数不仅会在无法预料的时刻被调用,它也会为预设或未激活的游戏物体调用。

    单件模式使用构造函数可能会导致严重的后果,带来类似随机null引用异常。

    因此如果你想实现,如,一个单件模式,不要使用构造函数,而是使用Awake。其实上,没有理由一定要在继续自MononBehaviour类的构造函数中写任何代码。

    脚本编译顺序:

    1.所有在"Standard Assets", "Pro Standard Assets" 或 "Plugins"的脚本被首先编译。

    在这些文件夹之内的脚本不能直接访问这些文件夹之外脚本。不能直接引用或它的 变量,但是可以使用GameObject.SentMessage与它们通信。

    2.所有在"Standard Assets/Editor", "Pro Standard Assets/Editor" 或 "Plugins/Editor"的脚本被首先编译。

    如果你想使用UnityEditor命名空间你必须放置你的脚本在这些文件夹中,例如添加菜单项或自定义的向导,你都需要放置脚本到这些文件夹。这些脚本可以访问前一组中的脚本。

    3.然后所有在"Editor"中的脚本被编译。

    如果你想使用UnityEditor命名空间你必须放置你的脚本在这些文件夹中。例如添加菜单单项或自定义的向导,你都需要放置脚本到这些文件夹。 这些脚本可以访问所有前面组中的脚本,然而它们不能访问后面组中的脚本。这可能会是一个问题,当编写编辑器代码编辑那些在后面组中的脚本时。有两个解决方 法:1、移动其他脚本到"Plugins"文件夹 2、利用JavaScript的动态类型,在javascript中你不需要知道类的类型。在使用GetComponent时你可以使用字符串而不是类 型。你也可以使用SendMessage,它使用一个字符串。

    4.所有其他的脚本被最后编译

    所有那些没有在上面文件夹中的脚本被最后编译。所有在这里编译的脚本可以访问第一个组中的所有脚本("Standard Assets","ProStandard Assets" or "Plugins")。这允许你让不同的脚本语言互操作。例如,如果你想创建一个JavaScript。它使用一个C#脚本;放置C#脚本 到"Standard Assets"文件夹并且JavaScript放置在"Standard Assets"文件夹之外。现在JavaScript可以直接引用c#脚本。放置在第一个组中的脚本,将需要较长的编译时间,因为当他们被编译后,第三组 需要被重新编译。因此如果你想减少编译时间,移动那些不常改变的到第一组。经常改变的到第四组

  • 相关阅读:
    hdu2795-Billboard(线段树应用好题)
    AC自动机模板
    kmp模板
    字符串Hash模板
    (可持久化)带修莫队的实现方法
    HZNU1544众数问题
    NOIP2006提高组第二题-金明的预算方案
    Python学习笔记
    (模板)唯一分解定理
    Java 7 源码学习系列(二)——Enum
  • 原文地址:https://www.cnblogs.com/shawnzxx/p/2841892.html
Copyright © 2011-2022 走看看