Unity脚本开发基础(摘要)

创建并运行脚本:

unity 使用 C# 和 JavaScript 作为脚本语言,在创建一个脚本时会自动创建 Start 和 Update 两个常用函数。Unity 中会有些特定的函数,这些特定的函数在一定条件下会被调用,称为必然事件(Certain Events)

名称 触发条件 用途
Awake 脚本实例被创建时调用 用于游戏对象的初始化,注意Awake的执行早于所有的 Start 脚本
Start Update函数第一次运行之前调用 用于游戏对象的初始化
Update 每帧调用一次 用于更新游戏场景和状态(和物理状态有关的更新应该放在FixedUpdate里)
FixedUpdate 每个固定物理时间间隔(Physics Time Step)调用一次 用于物理状态的更新
LateUpdate 每帧调用一次(在Update调用之后) 用于更新游戏场景和状态,和相机有关的更新一般放在这里FixedUpdate里)

Awake 早于 Start 调用,Awake在MonoBehavior创建后就立刻调用,Start将在MonoBehavior创建后在该帧Update之前,在该Monobehavior.enabled == true的情况下执行。

在Update 中尽量不要使用耗时过高的函数(例如 GetComponent),因为这样会大大减少程序的运行效率。如果要使用 GetComponent,应该在初始化的时候把组件的引用保存在变量中。

在Unity中,开发者编写的每一个脚本都被视为一个自定义组件(Component),游戏对象可以理解为容纳各个组件的容器,所以可以通过 Add Component 来将脚本添加到对象中。
  首先创建一个脚本,Assets -> Create -> C# Script 命令,命名为 HelloWorld,在Start 函数中填加以下语句

Debug.Log("Hello World!");//输出Hello World 到 Console 视图

脚本本身只是一个组件,是无法脱离游戏对象独立运行的,它必须添加到游戏对象上才会生效。
  依次选择菜单栏中的 GameObject ->Create Empty 命令即可创建一个空游戏对象。再 Inspector 视图中单击对象属性下方的 Add Component 按钮,在弹出的菜单中依次打开 Scripts -> HelloWorld。这样就将HelloWorld脚本绑定到新建的游戏对象中。也可以在 Project 视图中将 HelloWorld 脚本直接拖动到 Inspector 视图中的 GameObject 对象上来完成绑定操作。
  按下播放按钮,会在 Console 视图中输出 “Hello World!”,如果用户当前编辑器页面没有 Console 视图,可以通过 【Ctrl+Alt+C】组合键的方式把该视图显示出来。
  在 Start 函数中输出只会输出一句 “Hello World!”,而如果将上述语句加入到 Update 中,将会每帧输出一次。

访问游戏对象和组件:

MonoBehaviour 类

Unity中的脚本都是继承自MonoBehaviour,它定义了基本的脚本行为,必然事件也是从 MonoBehaviour 继承而来。除了必然事件, MonoBehaviour还定义了对各种特定事件(例如模型碰撞、鼠标移动)的响应函数,这些函数均以 On 作为开头。

常用事件响应函数:
名称 用途
OnMouseEnter 鼠标移入GUI控件或者碰撞体时调用
OnMouseOver 鼠标停留在GUI控件或者碰撞体时调用
OnMouseExit 鼠标移出GUI控件或者碰撞体时调用
OnMouseDown 鼠标在GUI控件或者碰撞体上按下时调用
OnMouseUp 鼠标按键释放时调用
OnTriggerEnter 当其他碰撞体进入触发器时调用
OnTriggerExit 当其他碰撞体离开触发器时调用
OnTriggerStay 当其他碰撞体停留在触发器时调用
OnCollisionEnter 当碰撞体或者刚体与其他碰撞体或者刚体接触时调用
OnCollisionExit 当碰撞体或者刚体与其他碰撞体或者刚体停止接触时调用
OnCollisionStay 当碰撞体或者刚体与其他碰撞体或者刚体保持接触时调用
OnControllerColliderHit 当控制器移动时与碰撞体发生碰撞时调用
OnBecameVisible 对于任意一个相机可见时调用
OnBecameInvisible 对于任意一个相机不可见时调用
OnEnable 对象启用或者激活时调用
OnDisable 对象禁用或者取消激活时调用
OnDestroy 脚本销毁时调用
OnGUI 渲染GUI和处理GUI消息时调用
访问游戏对象:

1.通过名称查找:
  GameObject.Find() 如果场景中存在指定名称的游戏对象,那么返回该对象的引用,否则返回 null。如果存在多个游戏对象使用同一名称,那么返回第一个对象的引用。第一个的含义是在 Hierarchy 中排列顺序第一个,而不是创建顺序。

GameObject player;
palyer = GameObject.Find("player");

2.通过标签查找 :
  GameObject.FindWithTag() 如果场景中存在指定标签的游戏对象,那么返回该对象的引用
  如果想要获取全部相同标签的对象,可以通过 FindGameObjectsWithTag() 方法

GameObject player;
GameObject[] enemies;
palyer = GameObject.FindWithTag("player");
enemies = GameObject.FindGameObjectsWithTag("Enemy");

访问组件:
   在Unity中脚本可以被认为是用户自定义的组件,并且可以添加到游戏对象上来控制游戏对象的行为,而游戏对象则可视为容纳各种组件的容器
  对于系统内置的常用组件,Unity 提供了非常便捷的访问方式,只需要在脚本里直接访问组件对应的成员变量即可,这些成员变量定义在 MonoBehaviour 中并被脚本继承了下来。
常用组件及其变量:

组件名称 变量名 组件作用
Transform transform 设置对象位置、旋转、缩放
Rigibody rigibody 设置物理引擎的刚体属性
Renderer renderer 渲染物体模型
Light light 设置灯光属性
Camera camera 设置相机属性
Collider collider 设置碰撞体属性
Animation animation 设置动画属性
Audio audio 设置声音属性

如果游戏对象上不存在某组件,则该组件对应变量的值将为空值(null)
如果要访问的组件不属于上表中的常用组件,或者访问的是游戏对象上的脚本,可以通过一下函数得到组件的引用

函数名 作用
GetComponent 得到组件
GetComponents 得到组件列表(用于有多个同类型组件的时候)
GetComponentlnChildren 得到对象或对象子物体上的组件
GetComponentslnChildren 得到对象或对象子物体上的组件列表

再次强调,GetComponent 比较耗时,因此尽量避免在 Update 中调用这些获取组件的函数,而是应该在初始化时把组件的引用保存在变量中。
简单示例:

Example script = GetComponent<Example>();//得到游戏对象上的 Example 脚本组件
Transform t = GetComponent<Transform>(); //得到游戏对象上的 Transform 组件

**除了用函数获取外, Unity还有一种非常便捷访问组件或游戏对象的方法,通过声明访问权限为 Public 的变量然后将要访问的组件或者对象赋值给该变量,就可以在脚本中通过变量访问组件或对象了。
(1)在脚本中添加类型分别为 GameObject 和 Transform 的两个成员变量,访问权限设置为 Public,示例代码如下:

using UnityEngine;
using System.Collections;

public class Hello : MonoBehaviour {
    public GameObject cube;
    public Transform sphereTransform;
    // Use this for initialization
    void Start () {
    }
    // Update is called once per frame
    void Update () {        
    }
}

(2)保存脚本,查看 Player 游戏对象的Inspector视图,可以看到Hello脚本的视图参数添加了两项,正是刚才添加的两个成员变量,目前没有对其赋值,所以变量的值均显示为 None。
(3)用鼠标左键在 Hierarchy 视图中将Cube游戏对象拖到 Inspector 视图 Cube参数上,接着拖动sphere游戏对象到 Inspector视图的 Sphere Transform 参数上,完成对两个成员变量的赋值。
  此时Hello 脚本的两个成员变量分别保存了 Cube 对象的引用和 Sphere 对象的 Transform 组件引用,这样在脚本中访问两个成员变量即可。

常用脚本API

Transform 组件:

transform组件控制游戏对象在Unity场景中的位置、旋转和大小比例,每个游戏对象都包含一个 Transform 组件。在游戏中如果想要更新玩家位置,设置相机观察角度都免不了要和Transform组件打交道。

Transform 组件的成员变量:

成员变量 说明
position 世界坐标系中的位置
localPosition 父对象局部坐标系中的位置
eulerAngles 世界坐标系中以欧拉角表示的旋转
localEulerAngles 父对象局部坐标系中的欧拉角
right 对象在世界坐标系中的右方向
up 对象在世界坐标系中的上方向
forward 对象在世界坐标系中的前方向
rotation 世界坐标系中以四元数表示的旋转
localRotation 父对象局部坐标系中以四元数表示的旋转
localScale 父对象局部坐标系中的缩放比例
parent 父对象的Transform 组件
worldToLocalMatrix 世界坐标系到局部坐标系的变换矩阵 (只读)
localToWorldMatrix 局部坐标系到世界坐标系的变换矩阵(只读)
root 对象层次关系中根对象的 Transform组件
childCount 子孙对象的数量
lossyScale 全局缩放比例(只读)

Transform组件的成员函数:

成员函数 说明
Translate 按指定的方向和距离移动
Rotate 按指定的欧拉角旋转
RotateAround 按给定旋转轴和欧拉角进行旋转
LookAt 旋转是的自身的前方巷指向目标的位置
TransformDirection 将一个方向从局部坐标系变换到世界坐标系
InverseTransformDirection 讲一个方向从世界坐标系变换到局部坐标系
TransformPoint 将一个位置从局部坐标系变换到世界坐标系
InverseTransformPoint 将一个位置从世界坐标系转换到局部坐标系
DetachChildren 与所有子物体解除父子关系
Find 按名称查找子对象
IsChildOf 判断是否是指定对象的子对象

Time 类

在 Unity 中可以通过 Time 类来获取和时间有关的信息,可以用来计算帧速率,调整时间流逝速度等功能。Time 类包含了一个重要的类变量 deltaTime,他表示距上一次调用所用的时间。
Time类成员变量:

成员函数 说明
time 游戏从开始到现在经理的时间(秒)(只读)
timeSinceLevelLoad 此帧的开始时间(秒)(只读),从辞官加载完成开始计算
deltaTime 上一帧耗费的时间(秒)(只读)
fixedTime 最近FixedUpdate的时间。该时间从游戏开始计算
fixedDeltaTime 物理引擎和FixedUpdate的更新时间间隔
maximumDeltaTime 一帧的最大耗费时间
smoothDeltaTime Time.deltaTime的平滑淡出
timeScale 时间流逝速度的比例。可用来制作慢动作特效
frameCount 已渲染的帧的总数(只读)
realtimeSinceStartup 游戏从开始到现在经理的真实时间(秒),改时间不会受timeScale影响
captureFramerate 固定帧率设置
Random类:

Random类可以用来生成随机数。
Random类的成员变量:

成员变量 说明
seed 随机数生成器种子
value 返回一个0~1之间的随机浮点数,包含 0 和 1
insideUnitSphere 返回位域半径为1的求体内的一个随机点
insideUnitCircle 返回位域半径为1的圆内的一个随机点(只读)
onUnitSphere 返回半径为1的球面上的一个随机点(只读)
rotation 返回一个随机旋转(只读)
rotationUniform 返回一个均匀分布的随机旋转(只读)

Random类的成员变量:

成员函数 说明
Range 返回 min 和 max 之间的一个随机浮点数,包含 min 和 max
Mathf类

Mathf类的变量:

变量 说明
PI 圆周率π,即3.14159265358979...(只读)
Infinity 正无穷大 ∞(只读)
NegativeInfinity 负无穷大 - ∞ (只读)
Deg2Rad 度到弧度的转换系数(只读)
Rad2Deg 弧度到度的转换系数(只读)
Epsilon 一个很小的浮点数(只读)

Mathf类的常用方法:.

常用方法 说明
Sin 计算角度(单位为弧度)的正弦值
Cos 计算角度(单位为弧度)的余弦值
Tan 计算角度(单位为弧度)的正切值
Asin 计算反正弦值(返回的角度值单位为弧度)
Acos 计算反余弦值(返回的角度值单位为弧度)
Atan 计算反正切值(返回的角度值单位为弧度)
Sqrt 计算平方根
Abs 计算绝对值
Min 返回若干数值中的最小值
Max 返回若干数值中的最大值
Pow Pow(f,p)返回 f 的 p 次方
Exp Exp(p)返回 e 的 p 次方
Log 计算对数
Log10 计算基为10的对数
Ceil Ceil(f)返回大于或等于 f 的最小整数
Floor Floor(f)返回小于或等于f的最大整数
Round Round(f)返回浮点数 f 进行四舍五入后得到的整数
Clamp 将数值限制在 min 和 max 之间
Clamp01 将数值限制在 0 和 1 之间
Coroutine协同程序

Coroutine也称为协同程序或者协程,协同程序可以和主线程并行运行,和多线程有些类似。协同程序可以用来实现让一段程序等待一段时间后继续运行的效果。

与协同程序有关的函数:

函数 说明
StartCoroutine 启动一个协同程序
StopCoroutine 中指一个协同程序
StopAllCoroutines 中指所有协同程序
WaitForSeconds 等待若干秒
WaitForFixedUpdate 等待直到下一次 FixedUpdate调用

C#协程例子:

using UnityEngine;
using System.Collections;

public class Hello : MonoBehaviour {
    
    // Use this for initialization
    IEnumerator Start () {
        Debug.Log ("Starting " + Time.time);
        yield return StartCoroutine(WaitAndPrint());//启动协同程序 WaitAndPrint
        print("Done " + Time.time);
    }

    IEnumerator WaitAndPrint(){
        yield return new WaitForSeconds (5f);
        print ("WaitAndPrint " + Time.time);
    }
}

在C#中,协同程序的返回类型必须为 IEnumerator ,yield 要用 yield return 代替,并且启动协同程序要用 StartCoroutine 函数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容