C#开发Unity游戏教程之游戏对象的行为逻辑方法

C#开发Unity游戏教程之游戏对象的行为逻辑方法

游戏对象的行为逻辑——方法

方法(method)。读者在第1章新建脚本时就见过了。并且在第2章对脚本做总体上的介绍时也介绍过。那么上一章呢,虽然主要内容是变量,可是在章节的最后为了展示游戏效果,也用到了它。如今看来方法真的是无处不在。并且不可或缺。它甚至都能够影响游戏对象的行为逻辑!

因此本章最终到了不得不介绍它的时候了。

Unity游戏对象的行为逻辑

游戏场景中。有些游戏对象是精巧的,比如。树木、山峰、石头等等。

而另外一些游戏对象则是运动的。它们都有自己的行为逻辑。

比如。由电脑控制的游戏对象可能会依照预定的线路行进。假设行进的途中遇到了玩家控制的游戏对象。还会发起进攻。如图4-1所看到的。行为逻辑在游戏《合金弹头》中的体现。无论是行进还是进攻。这都属于游戏对象的行为逻辑。而决定这一行为逻辑的就是脚本中的方法。


4-1  《合金弹头》中各游戏对象的行为逻辑

Unity脚本中的方法

前两章做过两个游戏演示样例,第一个演示样例中的立方体对象会边前行边转动。第二个演示样例中的立方体则会在玩家单击指定的button后。进行移动、旋转和缩放。在这两个游戏中,立方体都表现出了特定的行为逻辑,而决定这些行为逻辑的就是方法。如图4-2所看到的的是第一个游戏演示样例中的脚本方法。


4-2  脚本中决定游戏对象行为逻辑的方法

上一章的末尾向读者介绍过语句,那么再来看脚本中的方法,它的外在表现形式就是由一条或多条语句组成的。通常情况下,脚本中声明的变量是用来存储数据的,而脚本中的方法则会对这些数据做一些处理,然后将这些数据应用到游戏对象行为逻辑的控制中。比如。上一章演示的演示样例。通过在Inspector视图里调节属性的值,进而影响到立方体对象的缩放大小,如图4-3所看到的。


4-3  脚本中的方法,将属性中的数据应用到对游戏对象行为逻辑的控制中

Unity中使用脚本方法

通过本章前面的介绍,读者或许已经认识到了方法是有多重要,以至于前面两章介绍的游戏演示样例。都必须在方法的协助下,才实现了终于的效果。方法这么奇妙,读者如今一定有兴趣来了解。那么本节就来逐步揭开方法的神奇面纱。

Unity中的方法与变量

方法与变量有非常多相似的地方。比如,变量与变量名不等价。方法与方法名相同如此。

详细的说明例如以下:

  • q  方法也是一块儿特定的存储空间,仅仅只是方法里存储的不是数据,而是代码语句;

  • q  方法名也须要遵守C#的命名规则,即名称必须由字母、数字和下划线组成。且数字不能作为名称的首字母。否则就是犯了语法错误;

  • q  为了差别方法名与变量名。读者能够考虑遵守这样一个约定。即变量名的首字母小写,方法名的首字母大写。既然说这是一个约定,读者当然能够不遵守,也不会犯语法错误;

  • q  就像是变量名一样,方法名也应该取的有意义些。

    比如,既然方法能够控制游戏对象的逻辑行为。那么就能够考虑给控制立方体移动的方法定一个类似于CubeWalking的方法名。

  • q  相同能够使用publicprivate修饰,仅仅只是方法使用什么修饰,结果都不会体如今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中调用方法

方法定义好以后,就能够直接使用了。

用法在脚本中有个专门术语。就是“调用方法”。

在脚本中调用方法的方式非常easy,直接用法名就能够了。可是千万不要忘了带上后面的一对括号“( )”。

例如以下:

  • //方法的定义部分

  • …                                           //省略

  • //调用方法

  • 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     }

对于此脚本的0607行代码,读者一定不陌生。这里的代码完毕了变量的声明和初始化。

变量是上一章重点介绍的内容,而本章主要关心14~17行方法的定义部分。以及12行方法的调用部分。

  • q  从方法的定义上来看,方法名为AddTwoNumber(),会返回int类型的数据。方法里仅仅有一行语句,语句的含义是计算两个整数的和。

  • q  从方法的调用上来看,用法的方式非常easy,直接书写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#JavaScriptBoo。因此帮助文档会给出分别使用这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行),实现的功能均是在UnityConsole视图里输出一行文本信息。

读者能够从输出的信息中了解到,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;

  • }

这种方法的括号中没有參数,它处理的数据总是变量number1number2里的数据。既然这仅仅是一个用于求和的方法。没有必要指定它仅仅计算变量number1number2里的数据和。假设有其他变量的数据也要求和的话,就仅仅能再定义一个方法了。为方法引入參数就能够非常好的解决这类的问题。

对于游戏的实际意义

开发人员定义了一个方法。能够控制一个游戏对象的逻辑行为。

假设其他对象也须要做出与之类似的行为。就没有必要再定义一个方法了。比如以下的游戏演示样例所做的那样。

1)为游戏场景加入CubeCylinderDirectional light,这3个游戏对象。

前两者将作为脚本方法控制行为逻辑的游戏对象,最后一个游戏对象负责游戏场景的照明。

合理设置它们各自的位置,得到的SceneGame视图。如图4-8所看到的。


4-8  SceneGame视图里,查看各对象的相对位置。以及游戏视图的效果

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  脚本代码的1215行,调用了两次方法RotateObject(),先后传入的參数也是不一样的;

3)将脚本MyScript赋予Main Camera对象。并在后者的Inspector视图里,设置My Script组件里的My CubeMy Cylinder属性为游戏场景中的CubeCylinder对象。属性的设置方法是,直接拖动Hierarchy视图里的CubeCylinder对象到相应的属性框中就可以,如图4-9所看到的。


4-9  设置My Script组件下的属性

4)执行游戏。在Game视图里,一直按下鼠标左键,读者会看到立方体对象在原地滚动。

假设一直按下鼠标右键。那么原地滚动的就成了圆柱体。假设同一时候按住鼠标左键和右键。立方体和圆柱体就会同一时候滚动了,如图4-10所看到的。


4-10  游戏效果展示图

5)游戏中,控制游戏对象滚动的方法是RotateObject(),它是一个须要传入參数的方法。正是由于须要传入參数。所以它才干被用于游戏场景中。全部游戏对象滚动的行为逻辑控制中。而不仅仅是单独的控制一个对象的行为逻辑。

本文选自:C#游戏开发高速入门大学霸内部资料。转载请注明出处,尊重技术尊重IT人!


原文地址:https://www.cnblogs.com/zhchoutai/p/7367673.html