Professional Documents
Culture Documents
脚本语言
创建脚本
脚本编译工具
自定义组件 _ 脚
Unity 脚本 脚本绑定到游戏对象
本
Unity 脚本
脚本介绍
• 在前面内容中,我们介绍了场景、游戏对象、组件这三
者之前的关系。组件,实际描述的就是“功能”,使用
系统内置的组件(如: Transform 、 Mesh 、)虽然可
知 以满足为指定游戏对象添加功能的操作,但远远不够。
识
讲
实际上我们最简单的游戏也需要处理响应用户的作操作、
解 游戏场景中的事件触发、游戏对象的创建和销毁等,内
置组件已不能实现。而脚本的出现,就帮助我们解决了
这个问题。
• 脚本,其实就是组件,只不过是一种特殊的自定义组件,
又叫自定义脚本。
脚本介绍(续 1 )
• 什么是脚本?
在 Unity 中,脚本可以理解为附加在游戏对象上的用
于于定义游戏对象行为的指令代码,脚本与组件的用法
知 相同,必须绑定在游戏上才能开始它的生命周期。
识
讲
解
脚本介绍(续 2 )
• 创建脚本
注:以下将通过创建 Hello World 来开始 Unity 编程之
旅。
知
识
讲
• 在 Unity 中有两种创建脚本的方法,如下:
解
I. 依次选择菜单栏中的 Assets->Create->C# Script 命
令, 也可以根据需要选择 JavaScript ,如下图所
示:
创建脚本(续 1 )
III.Project 视图灰色区域右击,在弹出的快捷菜单中选择
Create->C# Script (或 JavaScript )来创建脚本,如
下
知
识
讲
解
创建脚本(续 3 )
知
识
讲
解
• 在 Project 视图区域双击创建的脚本文件
HelloWorld.cs ,默认情况下 Unity 会自动遍历
Mono 脚本编辑器来编辑脚本,如下图所示:
知
识
讲
解
脚本编译工具(续 1 )
• 说明: VS 安装目录默认在:
脚本编译工具(续 5 )
知
识 注: class 后面跟的类
讲 • 名一定要和创建脚本
解
时脚本的名字保持一
致,否则为游戏对象
设置此脚本时,设置
不了。
脚本绑定到游戏对象
• 脚本创建完成,如何将脚本绑定到游戏对象上呢?
Unity 提供了多种方式将绑定绑定到指定的对象上的方
式:
知
识 将脚本文件直接拖动到 Hierarchy 面板的游戏对象上;
讲
解 单击操作的游戏对象,此时 Inspector 面板中显示该对
象的一系列组件,将脚本文件直接拖动到 Inspector 面
板的靠下部分( Add Compont 按钮下面任何位置都
可);
单击选择操作的游戏对象,然后选择 Inspector 区域
的 "Add Component" 按钮,最底部有一个 Add
Scripts ,这样可在创建脚本时便自动将脚本绑定到操作
脚本绑定到游戏对象(续 1 )
• 注意:
绑定脚本时要注意,脚本文件的名字一定要和脚本打开
class 后面的类名保持一致,否则会导致脚本不能绑定到
知 游戏对象上,并给出错误提示,如下:
识
讲
解
脚本文件:
类名为: TestScript
Test.cs
脚本生命周期
• Unity 中有些特定的方法,这些特定的方法在一定条件下
会被自动调用,称为必然事件 ( Certain Events ) 。
• 在 Unity 中创建的每个脚本文件,默认都包含两个方法:
知 Start() 和 Update() ,这俩方法是最常用的两个事件,所
识
讲 以新建脚本时会自动创建,除此之外还有其它必然事件。
解
• 这些必然事件描述了一个脚本从最初的创建到最后被销
毁的完整流程,所以这些必然事件也被称为 Unity 脚本
的生命周期方法。
脚本生命周期(续 1 )
• Unity 生命周期中涉及到的常用方法:
Awake ():
OnEnable (): 初始化模块
知 Start ():
识
讲 FixedUpdate ():
解
Update (): 更新模块
LateUpdate ():
OnGUI ():
OnDisable ():
OnDestory (): 销毁模块
脚本生命周期(续 2 )
• 第一阶段:初始化模块。与初始化相关的生命周期方法:
Awake()
知 OnEnable()
识
讲
Start()
解
脚本生命周期(续 3 )
• 初始化模块: Awake()
以下针对 Awake() 方法四个方面介绍(方法完整定义、
方法何时调用、方法作用、被调用次数)
知 Awake() 的完整形式: private void Awake() {......}
识
讲 Awake() 是整个生命周期中最先执行的方法,当脚本实
解
例被加载时会自动调用这个方法。
该方法主要用于在游戏开始之前初始化对象或游戏状态,
如:使用 "GameObject.FindWithTag()" 查询游戏对象。
Awake() 方法在整个生命周期内只执行一次;
脚本生命周期(续 4 )
知
识
讲
解
脚本生命周期(续 5 )
• 初始化模块: OnEnable()
以下针对 OnEnable() 四个方面介绍(方法完整定义形式、
方法何时调用、方法作用、被调用次数)
知 OnEnable() 完整形式: private void OnEnable()
识
讲 {......}
解
执行完 Awake() 方法后,如果当前脚本可用或可激活,
按正常执行顺序则会执行 OnEnable() 方法。
通常在这个地方将当前脚本禁用 :this.enable=false ,若
执行此操作则会直接跳到 OnDisable() 方法执行一次,
其它生命周期方法都不会再执行。
OnEnable() 方法在整个生命周期内执行的次数不确定。
脚本生命周期(续 6 )
知
识
讲
解
脚本生命周期(续 7 )
• 初始化模块: Start()
以下针对 Start() 四个方面介绍(方法完整定义形式、
方法何时调用、方法作用、被调用次数)
知 Start() 的完整形式: private void Start() {......}
识
讲 执行完 OnEnable() 方法之后,在第一次执行 Update()
解
方法之前, Start() 会进行一次判断:若之前没有执行过
该方法,则会执行;若之前已执行过,则不会再执行。
该方法主要用于对变量等进行初始化或赋值的相关操作。
可将一些需要依赖 Awake 的变量放在 Start() 里面初始
化。
Start() 方法在整个生命周期中只执行一次
脚本生命周期(续 8 )
• 比如说:游戏对象 A 的初始化代码需要依赖对象 B 已被
初始化的情况下,此时 B 的初始化应该在 Awake 中完成,
而 A 应该在 Start 中完成。
知
识
讲
解
脚本生命周期(续 9 )
知
识
讲
解
脚本生命周期(续 10 )
• 第二阶段:更新模块,与生命周期对应的三个方法:
• 更新模块
Update() 和 FixedUpdate() 在更新时有什么区别吗?
1. 不同点一:调用时间上
知 Update() 方法会在每次渲染新的一帧时被自动调用,而
识
讲 FixedUpdate() 会在每个固定时间点被调用。也就是说:
解
Update() 方法的更新频率与硬件设备性能和被渲染的物
体有关,有时快有时慢,帧率会发生变化。当 Update()
被调用时,每帧的时间间隔也自然会发生变化。简单来
讲,硬件设施的好坏会影响 Update() 的更新速率,但
是 FixedUpdate() 则不受帧率变化的影响,它是以固定
时间被调用,从而实现更新操作。
脚本生命周期(续 12 )
2. 不同点二:负责更新的内容上
一般, FixedUpdate() 适合做物理状态的更新,如:
Unity 中的 Rigidbody 是一个操作重力的刚体组件,
知 如果为某游戏对象添加了这个 Rigidbody 组件时,那
识
讲
么与该组件相关的代码处理要放在 FixedUpdate() 中
解 完成;而 Update() 方法,比较适合完成一般的逻辑更
新或界面数据的更新操作。
脚本生命周期(续 13 )
• 更新模块: LateUpdate()
以下针对 LateUpdate() 四个方面介绍(方法完整定义
形式、方法何时调用、方法作用、被调用次数)
知 LateUpdate() 形式: private void LateUpdate()
识
讲 {......}
解
该方法会在 Update() 之后执行,也就是说,执行完本次
更并且在开始执行下一次更新之前,都会先调用一下
LateUpdate() 方法,该方法也是以帧为单位执行。
脚本生命周期(续 14 )
• 在场景中添加一个立方体,实现立方体沿 Z 轴移动(向
前移动),并打印距离上一帧执行所用的时间。通过该
例子观察立方体移动时, Update() 和 FixedUpdate()
课 两个执行时每一帧耗用时间的问题。
堂
练
习
通过物体移动观察更新区别(续
1)
• 创建一个场景文件: Demo1Scene( 由 Plane,Cube) 组
成:
课
堂
练
习
通过物体移动观察更新区别(续
2)
• Hierarchy 面 板 中 的 内 容 , 如 图 1 。 场 景 中 地 板
( Plane )的 Inspector 主要内容,如图 2 。场景中立
方体( Cube )的 Inspector 主要内容如图 3 :
课
堂
练
习 图2
图3
图1
通过物体移动观察更新区别(续
3)
• 创建一个脚本文件: Demo1Script.cs ,下面的结果是伤
使用 FixedUpdate() 实现及控制台打印内容:
课
堂
练
习
通过物体移动观察更新区别(续
4)
• 创建一个脚本文件: Demo1Script.cs ,下面的结果是伤
使用 Update() 实现及控制台打印内容:
课
堂
练
习
脚本生命周期(续 15 )
• 渲染模块: OnGUI()
OnGUI() 方法的完整形式是什么?什么时候被调用呢?
主要负责完成的工作的又是什么呢?
知 OnGUI() 的完整形式: private void OnGUI() {......}
识
讲 执行完 Start() 方法后,会接着执行 OnGUI() 方法,并且
解
会循环调用该方法来绘制图形界面。
在处理和渲染与 GUI 有关的事件时调用,由于后面会使
用 NGUI ,所以对 OnGUI() 了解就可以。
• 比如:你画一个 button 或 label 时常常用到它。这意味
着 OnGUI() 也是每帧执行一次。
脚本生命周期(续 16 )
知
识
讲
解
脚本生命周期(续 17 )
• 销毁模块: OnDisable()
OnDisable() 方法的完整定义形式是什么?什么时候调
用此方法?方法主要作用是什么?会被调用多少次呢?
知 OnDisable() 完整形式: private void OnDisable()
识
讲 {......}
解
当前对象不可用或脚本处于非激活状态时会调用该方法;
如何才能体现 OnApplicationQuit 调用时会调用 , 还会
再设置 enable = false 或 active = false 调用。
这个方法会在一个对象销毁前一帧调用,会在所有帧更
新一个对象存在的最后一帧之后执行,对象也许会响应
Object.Destroy 或一个场景关闭时被销毁。
脚本生命周期(续 18 )
• 销毁模块: OnDestory()
OnDestory() 方法的完整定义形式是什么?什么时候调
用此方法?方法主要作用是什么?会被调用多少次呢?
知 OnDestory() 完整形式: private void OnDestory()
识
讲 {.....}
解
当对象或脚本被销毁时会调用本方法。体现在代码中:
1. 在 OnApplicationQuit() 时会调用 2. 通过
Destory( 列表 ) 销毁游戏对象时也会调用。这个函数在
会在一个对象销毁前一帧调用,会在所有帧更新一个对
象存在的最后一帧之后执行,对象也许会响应
Object.Destroy 或一个场景关闭时被销毁。
脚本生命周期(续 19 )
• 以下是官方网站提供的脚本完整生命周期执行流程图:
知
识
讲
解
脚本生命周期(续 20 )
• 创建工程,并在工程下创建一个场景, ScriptLife
• 1 )在场景下添加游戏对象, 3D Object->Cube ;然后
添加了一个脚本, LiftScript1.cs 。如图 1
知 • 2 )在 LiftScript1.cs 中,添加了完整的 8 个生命周期方
识
讲 法,每个方法打印了一句话,如图 2 ;
解
• 3 )然后,将此脚本绑定到 Cube 游戏对象上。最后,运
行程序,如图 3
脚本生命周期(续 21 )
知
识
讲
解
图1
图2
访问游戏对象
• 在 Unity 场景中出现的所有物体都属于游戏对象,
( GameObject ) ,游戏对象和脚本是紧密相联的,游戏
对象间的交互通常也是通过脚本来实现的。在 Unity 中,
知 开发者可通过以下几种方式来访问游戏对象。
识
讲
解
访问游戏对象(续 1 )
• 当场景前工程下面创建一个场景, FindGameObect1 ;
在该场景下放一个游戏对象, 3D Object->Cube ,
然后创建一个脚本文件, FindByTagScript.cs ,在脚本
知 文件中查找场景中的 Cube 游戏对象,代码如下:
识
讲
解
访问游戏对象(续 2 )
知 运行结果
识
讲
解
总结和答疑