C#开发Unity游戏教程之游戏对象的行为逻辑方法
C#开发Unity游戏教程之游戏对象的行为逻辑方法
游戏对象的行为逻辑——方法
方法(method),读者在第1章新建脚本时就见过了,而且在第2章对脚本做整体上的介绍时也介绍过,那么上一章呢,尽管主要内容是变量,但是在章节的最后为了展示游戏效果,也用到了它。现在看来方法真的是无处不在,并且不可或缺。它甚至都可以影响游戏对象的行为逻辑!因此本章终于到了不得不介绍它的时候了。
Unity游戏对象的行为逻辑
游戏场景中,有些游戏对象是静止的,例如,树木、山峰、石头等等。而另外一些游戏对象则是运动的,它们都有自己的行为逻辑。例如,由电脑控制的游戏对象可能会按照预定的线路行进,如果行进的途中遇到了玩家控制的游戏对象,还会发起进攻。如图4-1所示,行为逻辑在游戏《合金弹头》中的体现。不管是行进还是进攻,这都属于游戏对象的行为逻辑,而决定这一行为逻辑的就是脚本中的方法。
图4-1 《合金弹头》中各游戏对象的行为逻辑
Unity脚本中的方法
前两章做过两个游戏示例,第一个示例中的立方体对象会边前行边转动,第二个示例中的立方体则会在玩家单击指定的按钮后,进行移动、旋转和缩放。在这两个游戏中,立方体都表现出了特定的行为逻辑,而决定这些行为逻辑的就是方法。如图4-2所示的是第一个游戏示例中的脚本方法。
图4-2 脚本中决定游戏对象行为逻辑的方法
上一章的末尾向读者介绍过语句,那么再来看脚本中的方法,它的外在表现形式就是由一条或多条语句组成的。通常情况下,脚本中声明的变量是用来存储数据的,而脚本中的方法则会对这些数据做一些处理,然后将这些数据应用到游戏对象行为逻辑的控制中。例如,上一章演示的示例,通过在Inspector视图里调节属性的值,进而影响到立方体对象的缩放大小,如图4-3所示。
图4-3 脚本中的方法,将属性中的数据应用到对游戏对象行为逻辑的控制中
Unity中使用脚本方法
通过本章前面的介绍,读者也许已经认识到了方法是有多重要,以至于前面两章介绍的游戏示例,都必须在方法的协助下,才实现了最终的效果。方法这么神奇,读者现在一定有兴趣来了解,那么本节就来逐步揭开方法的神秘面纱。
Unity中的方法与变量
方法与变量有很多相似的地方。例如,变量与变量名不等价,方法与方法名同样如此。具体的说明如下:
- q 方法也是一块儿特定的存储空间,只不过方法里存储的不是数据,而是代码语句;
- q 方法名也需要遵守C#的命名规则,即名称必须由字母、数字和下划线组成,且数字不能作为名称的首字母,否则就是犯了语法错误;
- q 为了区别方法名与变量名,读者可以考虑遵守这样一个约定,即变量名的首字母小写,方法名的首字母大写。既然说这是一个约定,读者当然可以不遵守,也不会犯语法错误;
- q 就像是变量名一样,方法名也应该取的有意义些。例如,既然方法可以控制游戏对象的逻辑行为,那么就可以考虑给控制立方体移动的方法定一个类似于CubeWalking的方法名;
- q 同样可以使用public和private修饰,只不过方法使用什么修饰,结果都不会体现在Inspector视图中,只是会反应在对方法的使用上。即使用public修饰的方法,可以被其它脚本使用,而使用private修饰,则正好相反。如果省略了对方法的修饰,Unity会认为方式是被private修饰的。
Unity中定义方法
就像是在使用变量前需要声明变量一样,使用方法前,需要定义方法。这就像是在告诉Unity:存在这样一个方法,此方法可以控制游戏对象做出特定的行为。方法的定义形式如下:
- 返回值类型 方法名()
- {
- //方法中的语句
- }
- q 方法名后的一对括号“( )”是必不可少的;
- q 被大括号“{ }”括住的语句,就可以看作是存储于方法中的数据;
- q 声明变量时,有些读者注意到,它的末尾是以分号“;”结尾的,但是对于方法的定义,大括号中的“}”就是结束标识,读者无需“画蛇添足”;
- q 方法可以“返回特定类型的数据”;
例如,前面章节编写游戏时,用到的脚本中的一个方法如下:
- void Update()
- {
- transform.Translate(new Vector3(xPosition,0,0),Space.World);
- transform.Rotate(Vector3.up*yRotation,Space.World);
- }
对于此方法,Unity会这样理解:
- q 这个方法名为Update();
- q 方法中一共有两条语句;
- q 方法返回的数据类型是void。此类型表示方法不会返回任何值。因此,与其说void表示一种类型,还不如说它是一种标志,即不返回任何类型数据的标志;
- q 省略了对方法的修饰,因此Unity会认为它是被private修饰的,因此其它脚本无法使用这个方法;
Unity中调用方法
方法定义好以后,就可以直接使用了。使用方法在脚本中有个专门术语,就是“调用方法”。在脚本中调用方法的方式很简单,直接使用方法名就可以了,但是千万不要忘了带上后面的一对括号“( )”。如下:
- //方法的定义部分
- … //省略
- //调用方法
- AddTwoNumber();
Unity中方法使用示例
理论部分已经写了很多,读者应该对方法的概念有印象了才对。那现在就趁热打铁,以一个示例来说明方法的定义和调用。实现示例的操作步骤如下:
(1)在Project视图里,新建一个脚本文件,命名为MyScript,打开此脚本文件并添加下面的代码:
- 01 using UnityEngine;
- 02 using System.Collections;
- 03
- 04 public class MyScript : MonoBehaviour
- 05 {
- 06 private int number1 = 15;
- 07 private int number2 = 59;
- 08 void OnGUI()
- 09 {
- 10 GUILayout.Label ("number1 = " + number1);
- 11 GUILayout.Label ("number2 = " + number2);
- 12 GUILayout.Label ("number1 + number2 = " + AddTwoNumber ()); //使用方法
- 13 }
- 14 int AddTwoNumber() //定于方法
- 15 {
- 16 return number1 + number2;
- 17 }
- 18 }
对于此脚本的06、07行代码,读者一定不陌生。这里的代码完成了变量的声明和初始化。变量是上一章重点介绍的内容,而本章主要关心14~17行方法的定义部分,以及12行方法的调用部分。
- q 从方法的定义上来看,方法名为AddTwoNumber(),会返回int类型的数据,方法里只有一行语句,语句的含义是计算两个整数的和。
- q 从方法的调用上来看,使用方法的方式很简单,直接书写AddTwoNumber()就可以了。
(2)将脚本MyScript添加到Main Camera对象上,除此以外游戏场景中不需要任何其它游戏对象。直接运行游戏,在游戏视图的左上角会出现3行文本信息,如图4-4所示。
图4-4 游戏视图左上角的文本信息
(3)这只是一个示例,是让读者熟悉方法定义和调用的示例。所以没有让方法控制游戏对象的行为逻辑,至于方法的游戏示例,会在本章后续内容讲解结束以后给出。
Unity内置的方法
在Unity中新建的脚本文件,里面会自动添加一些代码,如图4-5所示。读者在学习完方法以后,有没有觉得自动添加的代码中,Start()和Update()的书写形式很像方法。没错,它们就是方法。只不过它们是Unity内置的方法,他们会被游戏程序调用。
图4-5 脚本中Unity自动添加的代码
因为这两个方法在脚本中很常用,所以Unity直接在新建的脚本中添加了它们。那么,读者可能要问了,这两个方法会如何作用于游戏对象呢?代码中使用了注释(双斜杠“//”以及后面的部分就是注释)对这两个方法进行了简单的说明:前者在初始化时被调用,后者在游戏运行过程的每一帧被调用。如果读者并不满足于注释上的解释,可以考虑查阅Unity的帮助文档。在第1章中,作者介绍过帮助文档的打开和检索方式,忘了的话可以去复习以下。
现以查找Start()方法的使用说明为例。在帮助文档的检索框中输入MonoBehaviour.start,开始查找。一般情况下会查找出很多结果,选择需要的结果,打开它就可以了。整个过程如图4-6所示。
在帮助文档中,会首先对这个方法的功能和使用步骤做简要说明,并在最后给出这个方法的使用示例。
提示:Unity 的脚本可以使用三种语言编写,它们是C#、JavaScript和Boo,因此帮助文档会给出分别使用这3种语言的使用示例。因为本书讲解时使用的语言是C#,所以建议读者看C#语言编写的示例。
图4-6 使用Unity提供的帮助文档,查看Start()方法的使用说明
下面使用一个示例来说明,Unity内置方法Start()和Update()的使用。示例的操作步骤如下:
(1)打开脚本MyScript,为其添加下面的代码:
- 01 using UnityEngine;
- 02 using System.Collections;
- 03
- 04 public class MyScript : MonoBehaviour
- 05 {
- 06 private int frameCount = 0;
- 07 void Start()
- 08 {
- 09 Debug.Log ("这是Start()里输出的信息");
- 10 }
- 11 void Update()
- 12 {
- 13 frameCount++;
- 14 if(frameCount == 100)
- 15 {
- 16 Debug.Log ("这是Update()里输出的信息");
- 17 frameCount = 0;
- 18 }
- 19 }
- 20 }
新添加的代码,分别为Start()和Update()添加了一条语句(09行)和多条语句(13~18行),实现的功能均是在Unity的Console视图里输出一行文本信息。读者可以从输出的信息中了解到,Start()和Update()的调用情况。
(2)运行游戏,这次观察的焦点不是Game视图,而是Console视图,输出的文本信息,如图4-7所示。
图4-7 Console视图的文本信息输出结果
通过Unity提供的帮助文档,读者应该了解到,方法Start()是在游戏对象初始化的时候调用,且是在Update()前被调用。因此,Console视图中首先输出的是Start()方法里的文本信息,而后Update()方法才被调用,因此随后就输出了Update()方法里的文本信息。并且,由于Update()方法在每帧都会被调用,因此Update()方法里的文本信息会在游戏运行的过程中,持续输出。
提示:如果让Update()方法每帧都输出信息的话,Console视图很快就会被“刷屏”了。为了阻止这种现象的发生,脚本代码只是让Update()方法每100帧输出一次文本信息,但是Update()方法依然在每帧被调用。
Unity中的方法的参数
出现在脚本中的方法,无论是在定义的时候,还是使用的时候,后面都跟着一对括号“( )”,有意义吗?看起来最多也就是起个快速识别方法的作用吧。既然C#的语法规定方法就应该这么写,肯定是有一定道理的。如果是上升到战略意义的道理,连作者也不是很明白,但是作者知道这对括号里可以添加“参数”。
Unity中参数的作用
要说明参数的作用,就必须从方法说起。方法可以处理变量中的数据,进而影响游戏对象的行为逻辑,这是本章前面一直在强调的。但是就前面脚本中一直在使用的,方法的括号里没有参数的情况而言,方法总是在处理特定变量里的数据。例如,下面是前面一个示例中定义的方法:
- int AddTwoNumber()
- {
- return number1 + number2;
- }
这个方法的括号里没有参数,它处理的数据总是变量number1和number2里的数据。既然这只是一个用于求和的方法,没有必要指定它只计算变量number1和number2里的数据和。如果有其它变量的数据也要求和的话,就只能再定义一个方法了。为方法引入参数就可以很好的解决这类的问题。
对于游戏的实际意义
开发者定义了一个方法,可以控制一个游戏对象的逻辑行为。如果其它对象也需要做出与之类似的行为,就没有必要再定义一个方法了。例如下面的游戏示例所做的那样。
(1)为游戏场景添加Cube、Cylinder和Directional light,这3个游戏对象。前两者将作为脚本方法控制行为逻辑的游戏对象,最后一个游戏对象负责游戏场景的照明。合理设置它们各自的位置,得到的Scene和Game视图,如图4-8所示。
图4-8 在Scene和Game视图里,查看各对象的相对位置,以及游戏视图的效果
(2)在Project视图里,新建脚本文件,命名为MyScript,打开此脚本并添加下面的代码:
- 01 using UnityEngine;
- 02 using System.Collections;
- 03
- 04 public class MyScript : MonoBehaviour
- 05 {
- 06 public GameObject myCube;
- 07 public GameObject myCylinder;
- 08 void OnGUI()
- 09 {
- 10 //当鼠标左键按下的时候
- 11 if(Input.GetMouseButton(0))
- 12 RotateObject (myCube);
- 13 //当鼠标右键按下的时候
- 14 if(Input.GetMouseButton(1))
- 15 RotateObject (myCylinder);
- 16 }
- 17 //改变游戏对象朝向的方法
- 18 void RotateObject(GameObject myObject)
- 19 {
- 20 myObject.transform.Rotate(Vector3.right*100,Space.World);
- 21 }
- 22 }
- q 脚本代码的18~21行,是有参数方法的定义部分。从代码来看,传入的参数是一个游戏对象,而方法中的语句,就是通过修改游戏对象Transform组件下的Rotation属性,实现改变游戏对象朝向的目地的;
- q 脚本代码的12、15行,调用了两次方法RotateObject(),先后传入的参数也是不一样的;
(3)将脚本MyScript赋予Main Camera对象,并在后者的Inspector视图里,设置My Script组件里的My Cube和My Cylinder属性为游戏场景中的Cube和Cylinder对象,属性的设置方法是,直接拖动Hierarchy视图里的Cube和Cylinder对象到对应的属性框中即可,如图4-9所示。
图4-9 设置My Script组件下的属性
(4)运行游戏,在Game视图里,一直按下鼠标左键,读者会看到立方体对象在原地滚动。如果一直按下鼠标右键,那么原地滚动的就成了圆柱体。如果同时按住鼠标左键和右键,立方体和圆柱体就会同时滚动了,如图4-10所示。
图4-10 游戏效果展示图
(5)游戏中,控制游戏对象滚动的方法是RotateObject(),它是一个需要传入参数的方法。正是因为需要传入参数,所以它才能被用于游戏场景中,所有游戏对象滚动的行为逻辑控制中。而不只是单独的控制一个对象的行为逻辑。
本文选自:C#游戏开发快速入门大学霸内部资料,转载请注明出处,尊重技术尊重IT人!
C#开发Unity游戏教程之游戏对象的行为逻辑方法的更多相关文章
- C#开发Unity游戏教程之游戏对象的属性变量
C#开发Unity游戏教程之游戏对象的属性变量 Unity游戏对象的属性——变量 通过对上一章的学习,读者应该了解到了,游戏对象上的属性与脚本中的变量,建立联系的方式就是将脚本赋予游戏对象.上一章只是 ...
- 使用Visual Studio Comunity 2019开发Unity C#脚本没有自动补全的解决方法
最近开始试着玩Unity3D,要为场景中的物体编辑脚本.Unity3D推荐的脚本语言是C#,在Unity打开C#就会使用Visual Studio来进行编辑. 启动Visual Studio之后注意到 ...
- C#游戏开发高速新手教程Unity5.5教程
C#游戏开发高速新手教程Unity5.5教程 试读文档下载地址:http://pan.baidu.com/s/1slwBHoD C#是微软公布的高级程序设计语言.这门语言和C语言一样,已经成为了大学计 ...
- 3ds Max光照纹理导入Unity的教程.
原地址:http://www.cocoachina.com/gamedev/gameengine/2010/0531/1581.html 相信这个3ds Max光照纹理导入Unity的教程对游戏设计师 ...
- C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例
C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...
- C#开发Unity游戏教程之判断语句
C#开发Unity游戏教程之判断语句 游戏执行路径的选择——判断 玩家在游戏时,无时无刻不在通过判断做出选择.例如,正是因为玩家做出的选择不同,才导致游戏朝着不同的剧情发展,因此一个玩家可以对一个游戏 ...
- C#开发Unity游戏教程之使用脚本变量
C#开发Unity游戏教程之使用脚本变量 使用脚本变量 本章前面说了那么多关于变量的知识,那么在脚本中要如何编写关于变量的代码,有规章可循吗?答案是有的.本节会依次讲解变量的声明.初始化.赋值和运算. ...
- Unity 2D游戏开发教程之游戏精灵的开火状态
Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
随机推荐
- linux command ------ watch
watch命令以周期性的方式执行给定的指令,指令输出以全屏方式显示.watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果, ...
- linux driver error ------ 编译驱动出现 ERROR: Kernel configuration is invalid
ERROR: Kernel configuration is invalid. include/generated/autoconf.h or include/config/au ...
- SQL提高查询效率【in、not in、between、like】等条件讲述
在使用SQL语句查询数据库记录时,如果要查询相同的内容,有着不同的多种方法. 仍然,尽管使用多种方法可以得到相同的结果,但是,如果您使用不同的方法,在执行效益上是截然不同的.因此,我们得仔细考虑,如果 ...
- 各种遍历输出(经典版)----java基础总结
前言:关于共有3中遍历输出方式,很早之前我就想整理,无奈一直没有抽出时间,分别是传统的for循环遍历,迭代器Iterator,foreach,这次我通过测试代码,测试了一下. 先用一张草图,大概有个印 ...
- Scala进阶之路-I/O流操作之文件处理
Scala进阶之路-I/O流操作之文件处理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 说起Scala语言操作文件对象其实是很简单的,大部分代码和Java相同. 一.使用Scal ...
- JAVA 位操作学习
一,基础知识 计算机中数值的编码方式中,原码.反码.补码. 正数的补码与原码相同,负数的补码为:负数的原码符号位不变,其它位取反,再加1. 在计算机中,数值是以补码的形式存储的.补码的好处: ①用补码 ...
- 20155230 2016-2017-2 《Java程序设计》第五周学习总结
20155230 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 1.错误处理通常称为异常处理. 2.catch括号中列出的异常不得有继承关系,否则会发生编译 ...
- kali的中文输入法-安装后无中文选项的解决办法
我在我实体电脑上安装了kali 本想安装个中文输入法但是有时候输入发中根本没有选择输入法的这一项.所以导致很别扭,之前在虚机上安装过没有问题但是挪到实体机上就是没有用的也是fcitx,这一度让我这个小 ...
- mitmdump 屏蔽443错误
mitmdump --ignore-hosts ".*443$" -s test.py
- win7下iis中配置php.ini文件
将php.ini-development配置文件重命名为php.ini配置文件即可. 接着做如下配置操作: 1.修改php.ini配置文件 打开php.ini配置文件,找到 12 ; On windo ...