C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

2023-11-11

C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

Unity中循环遍历每个数据,并做出判断

很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判定玩家是否有权限做出这种选择,然后才决定是否为玩家执行此选择。例如,《仙剑奇侠传》这款游戏,进入剧情“荷叶迷宫时”,会要求玩家击碎迷宫里的5尊雕塑,如图5-12所示。但是击碎的前提是,玩家身上必须携带有“锤子”。也就是说系统会遍历玩家身上所有的资源,如果有锤子才能击碎雕塑。


5-12  《仙剑奇侠传》,荷叶迷宫全图

判断是否有指定的数据,可以使用本章前面所学的if语句来解决。但是目前还存在两个其它的问题:

  • q  如何在脚本中存储和引用这大量的数据,如果使用变量,显然要声明大量的变量,这样做显然不妥;

  • q  如果已经得到了大量的数据,该使用什么方式去一一判别呢,难道说要使用大量if语句,去对数据一一判别,这样做显然也不妥;

C#倒是提供了两种机制,可以很有效的解决以上的两个问题,本节会逐个详解介绍它们。

Unity中大量数据的存储与引用

C#指定了3种存储与引用大量数据的方法,分别是:数组、列表和字典。本小节会使用简单的小示例依次讲解它们,至于大的游戏示例,会在本章讲解完所有的知识点以后给出。

1.数组

数组可以存储大量同类型的数据,它的声明格式为:

  • 数据类型[ ] 数组名;

  • q  所有常用的数据类型,在本书第3章中已经使用表格列出了;

  • q  数据类型后面跟着的是一对中括号“[ ]”;

  • q  数组名与变量名一样,必须遵循C#的命名规定;

例如,下面的代码语句声明,并且初始化了数组:

  • int[] myIntArray = {1,3,5,7,9};

读者应该可以从这条语句中看出,声明的是int类型的数组,数组名为myIntArray,存储了5int类型的数据,分别是13579

引用数组中指定数据的格式为:

  • 数组名[下标];

  • q  下标是从0开始的整数,当下标为0时,表示引用的是数组中的第1个数据;若为3时,表示引用的是数组中的第4个数据;其它数据的引用方式依此类推;

为脚本MyScript添加下面的代码:

  • 01     using UnityEngine;

  • 02     using System.Collections;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private int[] myIntArray = {1,3,5,7,9};                //数组的声明和初始化

  • 07              void Start()

  • 08              {

  • 09                        Debug.Log ("数组中的第1个数据是:" + myIntArray[0]);          //数组数据的引用

  • 10                        Debug.Log ("数组中的第5个数据是:" + myIntArray[4]);          //数组数据的引用

  • 11              }

  • 12     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-13所示。


5-13  使用数组的示例

2.列表

列表与数组类似,同样用于存储大量同类的数据。但是似乎C#开发人员相对于数组,更偏爱列表一些。除非逼不得已,否则他们不会从列表和数组二者间选择后者,基本上是因为下面的几个原因:

  • q  数组在被声明了以后,存储的数据的个数就是固定的了,而列表则比较灵活,没有这方面的限制,如果开发者需要,它还可以存储更多的数据;

  • q  列表可以更方便的增加和删除存储于其中的数据;

这次作者打算在演示一个示例以后,在具体介绍列表的声明和使用等等。为脚本MyScript添加下面的代码:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;                                                                 //必须添加的语句

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private List<int> myIntList = new List<int>();                                       //声明列表

  • 07              void Start()

  • 08              {

  • 09                       myIntList.Add (1);                                                                               //添加数据到列表

  • 10                       myIntList.Add (3);

  • 11                       myIntList.Add (5);

  • 12                        Debug.Log ("列表中总共存储的数据个数是:" + myIntList.Count);

  • 13                        Debug.Log ("列表中第1个数据是:" + myIntList[0]);                 //引用列表中的数据

  • 14                        Debug.Log ("列表中第3个数据是:" + myIntList[2]);

  • 15    

  • 16                       myIntList.Add (7);

  • 17                        Debug.Log ("列表中第4个数据是:" + myIntList[3]);

  • 18              }

  • 19     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-14所示。


5-14  使用列表的示例

  • q  脚本02行的语句,与以往不同,需要读者主动修改成这个样子,此语句是在脚本中使用列表的前提,顺便提及新建脚本时,语句是下面的这个样子:

  • 02     using System.Collections;

  • q  脚本06行的语句如下:

  • 06              private List<int> myIntList = new List<int>();                                       //声明列表

此语句声明了列表,其名为myIntList,目前还没有存储任何数据;和数组一样,声明列表时也需要指定指定列表中可以存储的数据的类型,本示例中存储的类型是int

  • q  脚本09~11行编写了类似于下面的语句:

  • 09                       myIntList.Add (1);                                                                               //添加数据到列表

通过这种方式,一个int类型的数据1,才被存储到了列表中。

  • q  脚本1314行,引用列表数据的方式如下:

  • 09                       myIntList[0]

单从编写样式上看,它的引用方式与数组引用自身数据的方式一模一样,而且它的下标也是从0开始,表示存储的第1个数据,其它数据的存储下标以此类推。

  • q  脚本1617行,是列表区别于数组的使用方法,因为列表中可以存储的数据的个数是没有限定的;

3.字典

字典的使用方法与列表类似,但是它的声明需要指定一对数据类型,即键(Key)和值(Value)这两个数据的数据类型。使用字典最大的好处就是,可以通过Key,找到与之对应的Value。对于游戏的实际意义是,一个网络游戏一定需要存储大量用户的游戏信息,而游戏程序定位这些信息的方式通常是使用ID。也就是说,一个玩家就有一个ID,而ID关联了用户的所有信息,所以只要知道用户的ID,就不愁找不到玩家的其它游戏信息了。

在讲解字典的语法前,同样先演示一个示例,为脚本MyScript添加下面的代码:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              private Dictionary<int,string> myDic = new Dictionary<int,string>();              //声明字典

  • 07              void Start()

  • 08              {

  • 09                       myDic.Add(10,"Monday");                                   //添加数据到字典

  • 10                       myDic.Add(20,"Tuesday");

  • 11                       myDic[30] = "Wednesday";

  • 12                        Debug.Log ("字典中总共存储的数据个数是:" + myDic.Count);

  • 13                        Debug.Log ("字典中key10的数据是:" + myDic[10]);                   //引用字典中的数据

  • 14                        Debug.Log ("字典中key20的数据是:" + myDic[20]);

  • 15                       myDic[40] = "Thursday";

  • 16                        Debug.Log ("字典中key40的数据:" + myDic[40]);

  • 17              }

  • 18     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-15所示。


5-15  使用字典的示例

  • q  脚本02行的语句,对于在脚本中使用字典同样是不可缺少的,

  • q  脚本06行的语句:

  • 06              private Dictionary<int,string> myDic = new Dictionary<int,string>();

是字典的声明部分,从格式上来看与列表的声明方式十分相近。只不过声明字典需要同时指定键和值两个数据的数据类型。

  • q  脚本09~10行,为字典添加数据的方式与列表相似:

  • 09                       myDic.Add(10,"Monday");                                   //添加数据到字典

但是字典还有其它的方式,即脚本11行的代码

  • 11                       myDic[30] = "Wednesday";

这种方式,乍看之下与数组存储数据的方式一样,但是此种方式里,中括号“[ ]”里的数字可不是“下标”,而是“键”。

  • q  脚本131416行,字典引用数据的形式与数组和列表一致,但是中括号“[ ]”里的数字可不是“下标”,而是“键”。

  • 13                        myDic[10]

Unity中遍历大量的数据

如果需要在脚本中使用同样的操作去一一判别大量的数据,C#倒是提供了一种不错的机制,读者或许会有兴趣,就是“循环”。C#里有3种用于实现循环的语句,分别是:foreachforwhile。本小节打算依次介绍它们的使用方法,最后再将这种机制应用到游戏中。

1.foreach循环

为了更好的说明foreach循环的使用方法,下面将演示一个示例,此示例会使用foreach循环遍历数组、列表和字典里的所有数据,并使用if语句选择所需的数据。为MyScript脚本添加下面的代码:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       string[] myArray = new string[] {"Monday","Tuesday","Wednessday"};

  • 09                       foreach(string myStrArray in myArray)                                        //循环遍历数组

  • 10                       {

  • 11                                 if(myStrArray == "Monday")

  • 12                                          Debug.Log("There is "+myStrArray+" in array.");

  • 13                       }

  • 14    

  • 15                       List<string> myList = new List<string> {"Monday","Tuesday","Wednessday"};

  • 16                       foreach(string myStrList in myList)                                              //循环遍历列表

  • 17                       {

  • 18                                 if(myStrList == "Tuesday")

  • 19                                          Debug.Log("There is "+myStrList+" in list.");

  • 20                       }

  • 21    

  • 22                       Dictionary<int,string> myDict = new Dictionary<int,string>

  • 23                                          {{10,"Monday"},{20,"Tuesday"},{30,"Wednessday"}};

  • 24                       foreach(KeyValuePair<int,string> myStrDic in myDict)          //循环遍历字典

  • 25                       {

  • 26                                 if(myStrDic.Key == 30)

  • 27                                          Debug.Log ("There is "+myStrDic.Value+" in dictionary");

  • 28                       }

  • 29              }

  • 30     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-16所示。


5-16  使用foreach循环的示例

  • q  脚本081522行的代码,分别声明了数组、列表和字典,并且为它们初始化了3组数据;

  • q  脚本091624行的代码,则分别开始使用foreach语句遍历数组、列表和字典。以09行的语句为例:

  • 09                       foreach(string myStrArray in myArray)                                        //循环遍历数组

foreach后括号“( )”里的语句,表示的含义是:要遍历的是myArray数组,而数组中的每个数据都将先被存储于同类型的myStrArray变量中。语句的书写格式如下:

  • foreach(数据类型 变量名 in 数组名)

  • q  脚本111826行的代码,分别使用if语句判断变量中的数据,是否是指定的数据。以11行的代码为例:

  • 11                                 if(myStrArray == "Monday")

if后括号“( )”里的语句,是一个关系表达式,当变量myStrArray里的数据字符串是Monday时,表达式的值才是true

  • q  脚本121927行的代码,则表示当使用if语句判断出数组、列表和字典中存在指定数据时,会输出文字信息到Console视图。以12行的代码为例:

  • 12                                          Debug.Log("There is "+myStrArray+" in array.");

如果数组中存在数据“Monday”,则会在Console视图里输出“There is Monday in array”。

2.for循环

for循环也可以遍历数组、列表与字典中的所有数据,但是它与foreach语句的些许区别在于,for循环表达的含义更像是:让一段代码执行指定的次数。例如,执行5次输出语句,做10次同样的操作等等。下面是使用for循环的一个简单示例:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       List<string> myList = new List<string> {"Monday","Tuesday","Wednessday"};

  • 09                       for(int i = 0;i < myList.Count;i++)

  • 10                       {

  • 11                                 Debug.Log(myList[i]);

  • 12                                 if(myList[i] == "Tuesday")

  • 13                                          Debug.Log("There is "+myList[i]+" in list.");

  • 14                       }

  • 15              }

  • 16     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-17所示。


5-17  使用for循环的示例

  • q  脚本08行的代码,声明了一个列表,且为列表添加了3组数据

  • q  脚本09行的代码,就是一个for语句,如下:

  • 09                       for(int i = 0;i < myList.Count;i++)

for后面括号里的语句,所表示的含义是:一共要循环myList.Count次。变量i类似于一个计数器,记录着当前循环的次数。例如,要循环15次,可以使用下面的for循环语句:

  • for(int i = 0;i < 15;i++)

  • q  脚本11~13行的多条语句,是要执行指定循环次数的代码。其中11行的语句用于在Console视图中输出列表中的所有数据;1213行的代码,是一个if语句,用于判断列表中是否存在指定的数据,如果存在就会输出相应的信息到Console视图;

3.while循环

while循环与for循环的操作效果是相同的,即让循环执行一定的次数。但不同的是,从for循环的语句中可以很明确的看出循环的次数,在达到指定次数以后就停止。while循环表达的没有这么明确,但它会明确的告诉Unity,什么时候停止循环。下面的脚本代码,是将for循环的示例改写成了while循环,如下:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              void Start()

  • 07              {

  • 08                       List<string> myList = new List<string> {"Monday","Tuesday","Wednessday"};

  • 09                       int i = 0;

  • 10                       while(i < myList.Count)

  • 11                       {

  • 12                                 Debug.Log(myList[i]);

  • 13                                 if(myList[i] == "Tuesday")

  • 14                                          Debug.Log("There is "+myList[i]+" in list.");

  • 15                                 i++;

  • 16                       }

  • 17              }

  • 18     }

运行游戏,在Console视图里查看脚本输出的信息,如图5-18所示。


5-18  使用while循环的示例

  • q  脚本10行的语句,就是while循环语句,它后面的括号里,只有一个关系表达式,此关系表达式决定了循环在什么时候结束;

其它部分与for循环的示例一样,这里就不做重复说明了。

Unity游戏示例

本章先后学习了C#语法里,3个部分的内容。这3个部分是:

  • q  判断语句,包括ifif-elseif-else-ifswitch

  • q  数据存储方式,包括数组(array)、列表(list)和字典(dictionary);

  • q  大量数据的遍历方式,包括foreachforwhile

为了更方便的说明各部分的语法实现,以及书写方式,前面多以非游戏的示例来说明。但是读者也许并不知道它们在游戏中的应用是怎样的,因此本节应用本章所学习的知识编写了本节的游戏示例。

Unity游戏运行效果

本游戏想要实现的效果是:游戏会要求玩家按照顺序依次按下指定的几个按键,如果玩家成功的按下这组按键,就给出表示成功的图片提示;反之,就给出表示失败的图片提示。游戏运行效果如图5-195-205-21所示。


5-19  游戏视图中给出了3组预定义的组合键


5-20  按照组合键2的提示                        5-21  没有按照任何组合键的提示

补充:此游戏示例的灵感来源于,《拳皇》打斗时的组合键。玩过此游戏的读者,应该知道在此种游戏中,只有玩家按下了指定的按键以后,角色才会打出绝技!如图5-22所示。


5-22  《拳皇》中,按下指定的按键以后,所展示出的绝技

虽然本游戏示例没有这么精彩的打斗画面,但是却和它有着一样的对特定按键组合的判断,也就是说,程序首先需要知道玩家是否按下了指定的组合键,然后才决定是否展示特定的特技。而本示例就是运用了本节所学的知识,实现了前一部分的功能。

Unity游戏实现步骤

游戏的具体实现步骤如下:

1为游戏项目导入6张图片,其中4个是用于表示方向的,2个是用于表示成功和失败时的表情的。本游戏示例导入的6张图片,如图5-23所示。


5-23  为游戏项目导入的6张图片

2新建游戏项目时,新的游戏场景也被创建了,而且此游戏场景中还有一个游戏对象——Main Camera。本节所创建的游戏示例,由于是通过界面的绘制实现的,因此不需要读者继续往游戏场景里添加其它游戏对象了。

3Project视图里,新建一个脚本,命名为MyScript。本游戏的所有运行逻辑都将在此脚本中实现。此脚本将被赋予Main Camera游戏对象。

Unity游戏脚本的编写

脚本的代码,涉及了游戏的所有运行逻辑,内容较多,就将其划分成了一个小节。本小节也因此得以为读者详细介绍脚本代码的思考和编写过程。

1.声明变量

1游戏项目中有6张图片,脚本会操作这6张图片,然后按照指定的游戏逻辑,将它们显示在游戏视图中。因此脚本中需要声明存储这6张图片(数据)的变量,如下:

  •          public Texture[] image;

既然都是图片,联想到本章所学的知识,就很容易想到使用数组,当然读者也可以选择使用列表。

提示:TextureUnity脚本中是表示用于存储图片这种数据的数据类型。

因为变量被public修饰,所以它会以属性的形式,出现在Inspector视图的组件下。读者需要在此视图里,将图片作为属性值,赋予这个数组。具体的赋值方式就是拖动,即将图片从Project视图,拖动到Inspector视图,如图5-24所示。


5-24  脚本组件属性的设置

提示:读者一定要注意数组各图片数据的排列顺序,因为后面要编写的脚本代码将直接使用下标,引用数组中存储的图片数据。对于本示例,图片数组中的存储顺序是:updownleftrightsuccessfail

2同样需要声明数组的地方,还有表示预定义的3组组合键的数据,如下:

  •          int[,] Sample =

  •          {

  •                    //++++空格

  •                    {KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  •                    //++++空格

  •                    {KEY_UP,KEY_DOWN,KEY_UP,KEY_DOWN,KEY_SPACE},

  •                    //+++

  •                    {KEY_LEFT,KEY_RIGHT,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  •          };

代码中声明的是“二维数组”,而本节详细介绍的是“一维数组”,关于二维数组的介绍读者可以参考专业的书籍。实际上,读者可以简单的将“二维数组”看作是“一维数组中存储的数据是一维数组”。这段代码在声明二维数组的时候,还对数组进行了初始化。初始化的数据是预定义的3组组合键,从代码的注释中,读者很容易就可以看出哪些按键,及其顺序构成了组合键。但是,读者也许对于那些大些字母感到陌生,它们实际上是“整型常量”,同样需要声明在MyScript脚本中,如下:

  •          public const int KEY_UP = 0;

  •          public const int KEY_DOWN = 1;

  •          public const int KEY_LEFT = 2;

  •          public const int KEY_RIGHT = 3;

  •          public const int KEY_SPACE = 4;

3脚本还需要声明的变量有:

  • q  实时记录玩家按下了哪些按键的变量,由于玩家肯定会按下不只一个按键,因此这里选择列表存储这类数据,如下:

  •          private List<int> playerInput;

  • q  玩家在一个时间点,按下的是何种按键:

  •          private int currentKeyDown;

  • q  玩家是否成功的按下了一组组合按键:

  •          private bool isSuccess = false;

2.定义方法

1在声明表示列表的变量,并不意味着就为列表变量分配了存储空间。因此,脚本需要在被初始化时,为列表分配存储空间,如下:

  •          void Start()

  •          {

  •                    playerInput = new List<int>();

  •          }

Start()方法是Unity定义的方法,此方法会在脚本被初始化时调用,因此将为列表分配存储空间的代码置于此方法中,再合适不过。

2在脚本中,自己定义一个方法,用于记录每一个时刻,玩家按下的指定按键,如下:

  •          void UpdateKey()

  •          {

  •                    if(Input.GetKeyDown (KeyCode.UpArrow))

  •                             currentKeyDown = KEY_UP;

  •                    if(Input.GetKeyDown (KeyCode.DownArrow))

  •                             currentKeyDown = KEY_DOWN;

  •                    if(Input.GetKeyDown (KeyCode.LeftArrow))

  •                             currentKeyDown = KEY_LEFT;

  •                    if(Input.GetKeyDown (KeyCode.RightArrow))

  •                             currentKeyDown = KEY_RIGHT;

  •                    if(Input.GetKeyDown (KeyCode.Space))

  •                             currentKeyDown = KEY_SPACE;

  •          }

判断玩家是否按下了指定按键,可以使用if语句,如果按下的话,就将表示此按键的数据存储于变量currentKeyDown中。if语句的判断部分,是用于检测键盘上的按键是否被按下的Unity定义的方法。从此段代码中可以看出,游戏检测的按键有5个,包括键盘上的4个方向键和1个空格键。

3Unity每帧调用的Update()方法中,添加表示下列用途的代码:

  • q  要想确保前面定义的方法UpdateKey(),在游戏中的每个时刻都被调用,最好借助于Update()方法;

  • q  脚本还需要时刻将玩家按下的按键,存储于列表中;

  • q  当列表中有5个数据的时候,就去与预定义的组合键做比较,如果一致就表示输入成功,不一致就表示输入失败;

  • q  无论失败与否,都需要将列表清空,因为列表还需要存储下一轮玩家按下的按键。

具体的代码实现过程如下:

  • 01              void Update()

  • 02              {

  • 03                        //检测当前玩家按下的按键

  • 04                       UpdateKey ();

  • 05                        //当前有任何按键被按下的时候

  • 06                       if(Input.anyKeyDown)

  • 07                       {

  • 08                                 if(isSuccess)

  • 09                                 {

  • 10                                          isSuccess = false;

  • 11                                          playerInput.Clear ();

  • 12                                 }

  • 13                                 //将玩家按下的方向键添加到列表中

  • 14                                 playerInput.Add (currentKeyDown);

  • 15                                 //获取当前列表数据个数

  • 16                                 int listCount = playerInput.Count;

  • 17                                 //如果已经按下了5个键,就判断是否是组合键

  • 18                                 if(listCount == 5)

  • 19                                 {

  • 20                                          for(int i = 0;i < 3;i++)

  • 21                                          {

  • 22                                                   int SuccessCount = 0;

  • 23                                                   for(int j = 0;j < 5;j++)

  • 24                                                   {

  • 25                                                             int tempKey = playerInput[j];

  • 26                                                             if(tempKey == Sample[i,j])

  • 27                                                                      SuccessCount++;

  • 28                                                   }

  • 29                                                   if(SuccessCount == 5)

  • 30                                                             isSuccess = true;

  • 31                                          }

  • 32                                 }

  • 33                                 if(listCount > 5)

  • 34                                          playerInput.Clear();

  • 35                       }

  • 36              }

4对于本游戏示例,游戏视图需要实时显示的元素有,如图5-25所示。

  • q  玩家此时按下了哪些预定义的按键,即“上、下、左、右”4个方向键中的哪一个,至于“空格”按键嘛,由于没有表示此按键的图片,所以就不显示了;

  • q  表示玩家是否按下了5个指定按键的图片,即successfail所表示的图片;

  • q  用于提示玩家有哪些组合按键的文字信息;


5-25  游戏视图上,各元素的显示

因为Unity是通过调用OnGUI()方法来决定,在游戏视图上绘制哪些界面元素的,因此需要将显示上面所列元素的代码,置于此方法中,如下:

  • 01              void OnGUI()

  • 02              {

  • 03                       GUILayout.BeginHorizontal();

  • 04                        //表示链表中存储的数据个数

  • 05                       int listCount = playerInput.Count;

  • 06                        //遍历链表中的所有数据

  • 07                       for(int i = 0;i < listCount;i++)

  • 08                       {

  • 09                                 //显示方向按键对应的图片到游戏视图

  • 10                                 int key = playerInput[i];

  • 11                                 Texture tempTex = null;

  • 12                                 switch(key)

  • 13                                 {

  • 14                                 case KEY_UP:

  • 15                                          tempTex = image[0];

  • 16                                          break;

  • 17                                 case KEY_DOWN:

  • 18                                          tempTex = image[1];

  • 19                                          break;

  • 20                                 case KEY_LEFT:

  • 21                                          tempTex = image[2];

  • 22                                          break;

  • 23                                 case KEY_RIGHT:

  • 24                                          tempTex = image[3];

  • 25                                          break;

  • 26                                 }

  • 27                                 if(tempTex != null)

  • 28                                          GUILayout.Label (tempTex,GUILayout.Width (70),GUILayout.Height (70));

  • 29                       }

  • 30                       if(isSuccess)

  • 31                                 GUILayout.Label (image[4],GUILayout.Width (70),GUILayout.Height (70));

  • 32                       else if(!isSuccess && listCount == 5)

  • 33                                 GUILayout.Label (image[5],GUILayout.Width (70),GUILayout.Height (70));

  • 34                       GUILayout.EndHorizontal();

  • 35                       GUILayout.Space (20);

  • 36                        GUILayout.Label ("组合键1:上、下、左、右、空格");

  • 37                        GUILayout.Label ("组合键2:上、下、上、下、空格");

  • 38                        GUILayout.Label ("组合键3:左、右、左、右、空格");

  • 39              }

3.脚本代码概览

前面已经详细的介绍了在脚本中,方法的声明、方法的定义,以及变量和方法对于游戏效果的意义。但是读者也许还无法将它们组合成一个整体,相信下面的脚本代码概览对读者有帮助,如下:

  • 01     using UnityEngine;

  • 02     using System.Collections.Generic;

  • 03    

  • 04     public class MyScript : MonoBehaviour

  • 05     {

  • 06              //4个方向图片,2个表示按键成功和失败的图标

  • 07              public Texture[] image;

  • 08              //自定义方向键的存储值

  • 09              public const int KEY_UP = 0;

  • 10              public const int KEY_DOWN = 1;

  • 11              public const int KEY_LEFT = 2;

  • 12              public const int KEY_RIGHT = 3;

  • 13              public const int KEY_SPACE = 4;

  • 14              //表示各组合键

  • 15              int[,] Sample =

  • 16              {

  • 17                        //++++空格

  • 18                       {KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  • 19                        //++++空格

  • 20                       {KEY_UP,KEY_DOWN,KEY_UP,KEY_DOWN,KEY_SPACE},

  • 21                        //+++

  • 22                       {KEY_LEFT,KEY_RIGHT,KEY_LEFT,KEY_RIGHT,KEY_SPACE},

  • 23              };

  • 24              //记录玩家按下的所有键

  • 25              private List<int> playerInput;

  • 26              //记录当前的按键

  • 27              private int currentKeyDown;

  • 28              //表示是否成功的按下了组合键

  • 29              private bool isSuccess = false;

  • 30              //初始化脚本

  • 31              void Start()

  • 32              {

  • 33                       playerInput = new List<int>();

  • 34              }

  • 35              //获取玩家按下的方向键

  • 36              void UpdateKey()

  • 37              {

  • 38                        …                                                                       //省略

  • 39              }

  • 40              void Update()

  • 41              {

  • 42                        …                                                                       //省略

  • 43              }

  • 44              //绘制游戏视图的界面元素

  • 45              void OnGUI()

  • 46              {

  • 47                        …                                                                       //省略

  • 48              }

  • 49     }

小结

一款游戏,玩家可以百玩不厌,究其原因就在于游戏允许玩家通过选择,进而左右游戏剧情的发展。游戏本身则需要判断玩家做出了怎样的选择,判断的方式就是使用判断语句,因此本章介绍了ifswitch。又由于玩家有时需要从大量的数据中做出选择,例如,玩家的角色会数十种技能,要从中选择一个技能。这又涉及到大量数据的存储,因此本章介绍了数组、列表和字典。游戏本身要从大量数据中判断出玩家选择的是哪一个数据,因此最后介绍了遍历大量数据的方式,即foreachforwhile循环。本章的末尾,还以一个较大的游戏示例,展示了本章所学知识在游戏中的应用。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 的相关文章

  • 在 Vulkan 中,图形队列系列与当前队列系列分离是否有益?

    据我所知 队列系列可能支持呈现到屏幕但不支持图形 假设我有一个同时支持图形和呈现的队列系列 以及另一个仅支持呈现的队列系列 我应该为两个进程使用第一个队列系列 还是应该将第一个队列系列委托给图形 将后者委托给呈现 或者这两种方法之间没有明显
  • 使用链表进行堆排序

    我想知道是否有人曾经使用链表进行堆排序 如果他们可以提供代码 我已经能够使用数组进行堆排序 但尝试在链表中进行排序似乎不切实际 而且在你知道的地方很痛苦 我必须为我正在做的项目实现链接列表 任何帮助将不胜感激 我也用C 答案是 你不想在链表
  • 使用 ADAL v3 使用 ClientID 对 Dynamics 365 进行身份验证

    我正在尝试对我们的在线 Dynamics CRM 进行身份验证以使用可用的 API 我能找到的唯一关于执行此操作的官方文档是 https learn microsoft com en us dynamics365 customer enga
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • C# 中一次性对象克隆会导致内存泄漏吗?

    检查这个代码 class someclass IDisposable private Bitmap imageObject public void ImageCrop int X int Y int W int H imageObject
  • 为什么这个 makefile 在“make clean”上执行目标

    这是我当前的 makefile CXX g CXXFLAGS Wall O3 LDFLAGS TARGET testcpp SRCS main cpp object cpp foo cpp OBJS SRCS cpp o DEPS SRCS
  • C# 根据当前日期传递日期时间值

    我正在尝试根据 sql server 中的两个日期获取记录 Select from table where CreatedDate between StartDate and EndDate我通过了5 12 2010 and 5 12 20
  • 来自嵌入图像的 BitmapSource

    我的目标是在 WPF 窗口上重写 OnRender 方法中绘制图像 someImage png 它是嵌入资源 protected override void OnRender System Windows Media DrawingCont
  • 条件类型定义

    如果我有一小段这样的代码 template
  • C# 获取数据表中所有重复行的计数

    我通过运行存储过程来填充数据集 并且从数据集中填充数据表 DataSet RawDataSet DataAccessHelper RunProcedure storedprocedureName this will just return
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • Unity3D - 将 UI 对象移动到屏幕中心,同时保持其父子关系

    我有一个 UI 图像 它的父级是 RectTransform 容器 该容器的父级是 UI 面板 而 UI 面板的父级是 Canvas 我希望能够将此 UI 图像移动到屏幕中心 即画布 同时保留父级层次结构 我的目标是将 UI 图像从中心动画
  • 在 C# 的 WebAPI 中的 ApiController 上使用“传输编码:分块”提供数据

    我需要服务分块传输使用编码数据API控制器 因为我无权访问HttpContext or the Http请求 我有点不知道在哪里写入响应以及在哪里刷新它 设置如下 public class MyController ApiControlle
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 如果将变量设置为等于新对象,旧对象会发生什么?

    假设我们有一个 X 类not有一个超载的operator 功能 class X int n X n 0 X int n n n int main X a 1 an object gets constructed here more code
  • winform c# 中的弹出窗口

    我正在开发一个需要弹出窗口的项目 但问题是我还希望能够通过表单设计器在此弹出窗口中添加文本框等 所以基本上我有一个按钮 当您单击它时 它将打开我在表单设计器中设计的另一个窗口 我一直在谷歌搜索 但还没有找到我需要的东西 所以我希望你们能帮助
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐