• 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人!


  • 相关阅读:
    行转列(FOR XML PATH)
    非聚集索引的注意事项
    避免JS全局变量冲突
    如何做个好员工?
    SQL Server 执行计划中的扫描方式举例说明
    SqlServer with递归查询的使用
    Excel插件类库的设计思路
    使用log4javascript记录日志
    布局
    Image控件的简单使用示例1
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7367673.html
Copyright © 2020-2023  润新知