3.5 游戏界面

上一节已经介绍了所有菜单界面的开发过程,本节将要介绍的游戏界面是本游戏开发的中心场景,其他的场景都是为此场景服务的,游戏场景的开发对于此游戏的可玩性有至关重要的作用。在本节中,将对此界面的开发进行进一步的介绍。

3.5.1 游戏关卡场景制作

搭建游戏界面场景的步骤比较繁琐,由于篇幅的限制这里不能很详细地介绍每一个细节,因此要求读者对Unity的基础知识有一定的了解。接下来以游戏关卡一为例,对游戏界面的开发步骤进行具体的介绍。

(1)新建场景。选择“File”→“New Scene”,然后选择“File”→“Save Scene”选项(或者Ctrl+S),在保存对话框中输入场景名“GameScene”,如图3-48所示。

▲图3-48 新建场景

(2)创建定向光源。选择“GameObject”→“Create Other”→“Directional Light”后会自动创建一个定向光源,如图3-49所示。调整定向光源位置,如图3-50所示。

▲图3-49 创建定向光源

▲图3-50 定向光源位置摆放

(3)导入迷宫模型。将迷宫模型拖入游戏场景,并为其贴图,如图3-51所示。调整其位置、姿态、大小,如图3-52所示。

▲图3-51 为迷宫贴图

▲图3-52 摆放迷宫位置

(4)小球和木箱的制作。在前面的章节已经详细介绍,这里不再赘述,将小球命名为“Ball1”,置于迷宫中,调整位置、姿态、大小,如图3-53所示。将木箱集体放入“Boxs”组中,置于迷宫的通道中,调整位置、姿态、大小,如图3-54所示。

▲图3-53 小球的大小和摆放

▲图3-54 木箱的大小和摆放

(5)创建胜利的平面。选择“GameObject”→“Create Other”→“Plane”选项,并命名为“PlaneTrigger”,如 图3-55所示。然后调整平面位置、姿态和大小,置于“GameOneFloor”游戏对象内。由于该平面用于触发游戏界面判定,所以需要勾选游戏对象属性中“Is Trigger”后的单选框,其各项参数如图3-56所示。

▲图3-55 创建平面

▲图3-56 平面参数

(6)创建地板的平面。选择“GameObject”→“Create Other”→“Plane”选项,命名为“BallFallTrigger”,然后调整平面位置、姿态和大小,并为其贴图,置于“GameOneFloor”游戏对象下方。由于该平面用于触发游戏界面判定,所以需要勾选游戏对象属性中“Is Trigger”后的单选框,其各项参数如图3-57所示。

(7)添加盒子碰撞器。为木箱和迷宫的墙添加盒子碰撞器。首先选中“Boxs”组中的所有Cube游戏对象,和“GameOneFloor”地板中的“Box002”—“Box030”和“Box031”—“Box032”游戏对象,然后选择“Component”→“Physics”→“Box Collider”,具体情况如图3-58所示。

▲图3-57 地板平面

(8)添加刚体。首先选中“Ball1”对象和“Boxs”组中的所有Cube游戏对象,以及“GameOneFloor”地板中的“Box002”—“Box030”和“Box031”—“Box032”游戏对象,然后选择“Component”→“Physics”→“Rigidbody”选项,具体情况如图3-59所示。

▲图3-58 添加盒子碰撞器

▲图3-59 添加刚体

(9)关卡二制作的简要讲解。由于其他关卡和关卡一制作类似,就不再赘述。关卡二的特点在于本关导入了一些装饰模型,如图3-60所示,这3棵树木模型的位置大小如图3-61、图3-62、图3-63所示。在本关卡中,还有匀速旋转的木条作为路障,该木条的匀速旋转将后续进行细致讲解。

▲图3-60 树木模型

▲图3-61 树木模型大小位置1

▲图3-62 树木模型大小位置2

▲图3-63 树木模型大小位置3

(10)关卡3制作的简要讲解。关卡3的特点在于本关导入了铅笔的装饰模型,这两个铅笔模型的位置大小如图3-64、图3-65所示。本关卡是封闭型的迷宫,小球掉入缝隙也会导致游戏失败,所以玩家需要借助木箱的铺垫,才能顺利到达终点。

▲图3-64 铅笔模型大小位置1

▲图3-65 铅笔模型大小位置2

(11)关卡4制作的简要讲解。关卡四的特点在于本关是两个迷宫相连的形式,小球必须通过两个迷宫相连的轨道,才能顺利到达目的地,如图3-66所示。

▲图3-66 关卡四的轨道

3.5.2 多视角的制作与切换

上一小节已经介绍了游戏界面的搭建过程,本小节将向读者介绍多视角的制作与切换。本游戏中主要有两个摄像机,游戏运行时,摄像机根据玩家切换视角的情况只有一个处于激活状态。具体的开发步骤如下。

(1)制作主摄像机。调整主摄像机“Main Camera”摄像机到适当位置,并设置“Field of View”属性值为60,去掉属性查看器中对象名称前单选框中的对勾,如图3-67所示。

▲图3-67 制作主摄像机

(2)制作第一人称摄像机。首先选择“GameObject”→“Create Other”→“Camera”新建一个摄像机对象,命名为“FirstCamera”。然后调整摄像机到适当位置,可调整“Field of View”属性值为60,如图3-68所示。

▲图3-68 制作第一人称摄像机

(3)编写第一人称摄像机挂载脚本。该脚本主要负责绘制游戏关卡的界面,包括游戏关卡的返回按钮,切换镜头按钮和移动第一人称摄像机位置的方向按钮。具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的GameLayer.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class GameLayer : MonoBehaviour {
      4         public GameObject[] cameras;                              //摄像机列表
      5         public GUIStyle[] buttonStyleOfGameLayer;                 //按钮样式
      6         public static int curCam = 0;                             //当前摄像机编号
      7         void Start () {}
      8         void OnGUI(){
      9               if (GUI.Button(new Rect(90*Screen.width/100,1*Screen.height/100,
      10                    9*Screen.width/100,16*Screen.height/100), "",
      11                    buttonStyleOfGameLayer[ConstOfMenu.GAME_BACK])) { //绘制返回按钮
      12                    Application.LoadLevel("GamesMenu");           //返回选择关卡界面
      13              }
      14              if (GUI.Button(new Rect(11*Screen.width/100,65*Screen.height/100,
      15                    9*Screen.width/100,16*Screen.height/100), "",
      16                    buttonStyleOfGameLayer[ConstOfMenu.ANGLE_OF_VIEW])) {//绘制切换相机按钮
      17                    ChangeCam(1);                                  //切换至1号摄像机
      18              }
      19              if (GUI.Button(new Rect(11*Screen.width/100,47*Screen.height/100,
      20                    9*Screen.width/100,16*Screen.height/100), "",
      21                    buttonStyleOfGameLayer[ConstOfMenu.UP_BUTTON])) { //绘制向上按钮
      22                    cameras[curCam].transform.Translate(new Vector3(0, 30* Time.deltaTime,0));
      23              }
      24              if (GUI.Button(new Rect(11*Screen.width/100,83*Screen.height/100,
      25                    9*Screen.width/100,16*Screen.height/100), "",
      26                    buttonStyleOfGameLayer[ConstOfMenu.DOWN_BUTTON])) {//绘制向下按钮
      27                    cameras[curCam].transform.Translate(new Vector3(0,-30*Time.deltaTime,0));
      28              }
      29              if (GUI.Button(new Rect(1*Screen.width/100,65*Screen.height/100,
      30                    9*Screen.width/100,16*Screen.height/100), "",
      31                    buttonStyleOfGameLayer[ConstOfMenu.LEFT_BUTTON])) {//绘制向左按钮
      32                    cameras[curCam].transform.Translate(new Vector3(-30* Time.deltaTime,0,0));
      33              }
      34              if (GUI.Button(new Rect(21*Screen.width/100,65*Screen.height/100,
      35                    9*Screen.width/100,16*Screen.height/100), "",
      36                    buttonStyleOfGameLayer[ConstOfMenu.RIGHT_BUTTON])) { //绘制向右按钮
      37                    cameras[curCam].transform.Translate(new Vector3(30 * Time.deltaTime,0,0));
      38         }}
      39         void Update() {
      40              if(Input.GetKeyDown(KeyCode.Escape)){               //如果按下返回键
      41                    Application.LoadLevel("GamesMenu");           //返回选择关卡界面
      42         }}
      43         public void ChangeCam(int index){                        //切换摄像机方法
      44              cameras[curCam].SetActive(false);                   //设置当前摄像机不可用
      45              cameras[index].SetActive(true);                     //启用相应摄像机
      46   }}

第4行~第6行声明了游戏第一人称视角界面的按钮样式、摄像机列表,以及当前摄像机索引。在这里,将第一人称视角的摄像机和俯视摄像机分别编为0号和1号,方便操控。

第10行~第42行绘制了游戏第一人称视角界面的五个按钮,分别为返回选择关卡按钮,切换视角按钮,和上、下、左、右4个方向移动当前摄像机的四个按钮,以及按下按钮的处理方法。

第43行~第45行表示当用户在游戏界面按下返回键,则加载选择关卡界面。同时介绍了切换摄像机的方法“ChangeCam”,在该方法中设置当前摄像机不可用,然后启用另一个摄像机,以达到切换视角的目的。

(4)游戏第一人称界面脚本的变量赋值。在这里,摄像机列表的Size输入2,包括两个摄像机互相切换。按钮的Size输入6,共有六个按钮需要赋予相应贴图。详细如图3-69所示。

▲图3-69 游戏第一人称界面脚本变量赋值

(5)编写俯视摄像机挂载脚本。该摄像机能俯看整个迷宫地图,但是在该视角下,不能拖动木箱。具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的LookAllGameLayer.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class LookAllGameLayer : MonoBehaviour {
      4         public GameObject[] cameras;                              //摄像机列表
      5         public GUIStyle[] buttonStyleOfLookAllGameLayer;          //按钮样式
      6         public static int curCam = 1;                             //当前摄像机编号
      7         void Start () {}
      8         void Update () {}
      9         void OnGUI(){
      10              if (GUI.Button(new Rect(91*Screen.width/100,1*Screen.height/100,
      11                    9*Screen.width/100,16*Screen.height/100), "", //绘制返回按钮
      12                    buttonStyleOfLookAllGameLayer[ConstOfMenu.GAME_BACK])){
      13                    Application.LoadLevel("GamesMenu");           //返回选择关卡界面
      14              }
      15              if (GUI.Button(new Rect(81*Screen.width/100,1*Screen.height/100,
      16                    9*Screen.width/100,16*Screen.height/100), "", //绘制切换视角按钮
      17                    buttonStyleOfLookAllGameLayer[ConstOfMenu.ANGLE_OF_VIEW])) {
      18                    ChangeCam(0);                                  //切换摄像机
      19         }}
      20         public void ChangeCam(int index) {                       //切换摄像机方法
      21              cameras[curCam].SetActive(false);                   //设置当前摄像机不可用
      22              cameras[index].SetActive(true);                     //启用相应摄像机
      23   }}

第4行~第6行声明了游戏俯视视角界面的按钮样式、摄像机列表,以及当前摄像机索引。在这里,将第一人称视角的摄像机和俯视摄像机分别编为0号和1号,方便操控。

第9行~第18行绘制了返回按钮,当用户单击该按钮的时候,加载游戏选择关卡界面。同时绘制了切换视角按钮,当用户单击该按钮的时候,从俯视角切换到第一人称视角。

第20行~第22行介绍了切换摄像机的方法。在该方法中,将当前俯视视角的摄像机设置为不可用,同时激活第一人称视角的摄像机。

(6)游戏俯视界面脚本的变量赋值。在这里,摄像机列表的Size输入2,包括两个摄像机互相切换。按钮的Size输入2,共有两个按钮需要赋予相应贴图。详细如图3-70所示。

▲图3-70 游戏俯视界面脚本变量赋值

3.5.3 游戏关卡脚本的编写

上一小节已经介绍了游戏场景和游戏多视角的制作过程,本小节将向读者介绍游戏界面绘制和功能完善的相关脚本。每个脚本负责游戏关卡不同的功能部分,详细的编写介绍如下。

(1)编写重力小球脚本。该脚本主要负责四个游戏关卡中的小球如何随着用户终端倾斜而改变移动方向和速度,在4个关卡中,“Ball1”、“Ball2”、“Ball3”以及“Ball4”4个游戏对象都分别挂载了该脚本,具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的BallMove.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class BallMove : MonoBehaviour {
      4         public float speed = 10.0f;                               //初始化速度
      5         private Vector3 dir = Vector3.zero;                       //声明方向向量
      6         void Update() {
      7               dir.x=Input.acceleration.x;                          //获取X轴加速度
      8               dir.z=Input.acceleration.y;                          //获取Y轴加速度
      9               this.rigidbody.AddForce(dir.x*speed,0,dir.z*speed); //移动小球
      10   }}

说明

由于小球根据重力在迷宫平面上移动,因此将初始速度定为10.0f,同时声明X,Y两个方向向量。根据手机倾斜度,判断小球重力加速度,然后调整小球位置。

(2)四个关卡中小球的初始位置以及大小分别如图3-71、图3-72、图3-73和图3-74所示。玩家需要根据整体地图的路线,来选择哪一条路最快最顺利到达终点。

▲图3-71 关卡一小球位置大小

▲图3-72 关卡二小球位置大小

▲图3-73 关卡三小球位置大小

▲图3-74 关卡四小球位置大小

(3)编写拖曳木箱脚本。该脚本主要负责在游戏迷宫中当作阻碍的木箱能被用户用手指拖曳移动,四个关卡中的所有木箱游戏对象都分别挂载了该脚本,具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的DragObject.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class DragObject : MonoBehaviour {
      4         private Vector3 screenPosition;                           //声明屏幕坐标
      5         private Vector3 position;                                 //声明游戏空间坐标
      6         private Vector3 tempPosition;                             //声明变换坐标
      7         void OnMouseDown() {
      8               screenPosition=Camera.main.WorldToScreenPoint (transform.position);
      9               position=transform .position -Camera.main.ScreenToWorldPoint (
      10                    new Vector3 (Input.mousePosition.x,           //变换坐标
      11              Input.mousePosition.y ,screenPosition.z));          //用户单击坐标
      12              StartCoroutine (ChangePosition());                  //改变位置
      13         }
      14         IEnumerator ChangePosition () {
      15              while (Input .GetMouseButton(0)){                   //根据用户触碰目标点
      16                   tempPosition = Camera.main.ScreenToWorldPoint(
      17                       new Vector3 (Input.mousePosition.x,Input.mousePosition.y ,screen
                                Position.z));
      18                   transform.position = tempPosition + position ; //改变木箱位置
      19                   yield return null;
      20   }}}

第4地~第12行声明了所需的3个坐标位置,由于用户触碰在手机上的点需要转换为游戏空间中的坐标点,才能使木箱根据手指的移动而移动,在“OnMouseDown”方法中,便根据转换坐标系,调用“ChangePosition”改变位置方法。

第14行~第19行介绍了“ChangePosition”改变位置方法,在该方法中,根据手指的移动位置,将木箱变换到指定位置,这样便实现了木箱被拖曳的功能。

(4)下面介绍迷宫笑脸终点触发游戏结果脚本。该脚本主要负责当小球顺利通过迷宫,滚动到该处的时候,触发游戏胜利结果,具体代码如下。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的PlaneTrigger.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class PlaneTrigger : MonoBehaviour {
      4         void OnTriggerEnter(Collider other){                      //触发结果方法
      5               if(other.transform.name == "Ball1")    {            //若小球为Ball1
      6                     Application.LoadLevel("GameWin");             //加载游戏胜利场景
      7                     ConstOfMenu.GAMEONE_INDEX=1;                  //设置该索引为1
      8               }
      9               else if(other.transform.name == "Ball2"){           //若小球为Ball2
      10                    Application.LoadLevel("GameWin");             //加载游戏胜利场景
      11                    ConstOfMenu.GAMEONE_INDEX=2;                  //设置该索引为2
      12              }
      13              else if(other.transform.name == "Ball3"){           //若小球为Ball3
      14                    Application.LoadLevel("GameWin");             //加载游戏胜利场景
      15                    ConstOfMenu.GAMEONE_INDEX=3;                  //设置该索引为3
      16              }
      17              else if(other.transform.name == "Ball4"){           //若小球为Ball4
      18                    Application.LoadLevel("GameWin");             //加载游戏胜利场景
      19                    ConstOfMenu.GAMEONE_INDEX=4;                  //设置该索引为4
      20   }}}

第4行~第20行为小球触发结果方法,当小球滚动到指定笑脸位置,表示该关游戏胜利。由于每个关卡顺利通过后,会显示游戏胜利界面,在该界面会有“重玩”和“继续”的按钮,所以需要判断当前通过的是哪关,这里为四个关卡的4个小球命名不同,便解决了这个问题。

第5行~第19行表示,当到达终点的小球为“Ball1”时,表示玩家将顺利通过第一关,所以加载游戏胜利场景的同时会将索引“GAMEONE_INDEX”置为1。同样地,其他游戏关卡也会因为不同的小球将索引置为不同数字,方便游戏结果界面使用该索引。

(5)游戏终点笑脸。4个关卡的终点笑脸有不同的贴图素材,要根据每一关的主题风格,选择合适的笑脸贴图。游戏关卡1的笑脸位置大小在前面的章节已经详细介绍过,这里不再赘述。游戏关卡2、关卡3和关卡4的笑脸大小、位置和贴图效果如图3-75、图3-76和图3-77所示。

▲图3-75 关卡2笑脸终点位置大小

▲图3-76 关卡3笑脸终点位置大小

▲图3-77 关卡4笑脸终点位置大小

(6)编写小球掉落触发结果脚本。该脚本主要负责当小球从迷宫掉落出来落在地板上时,就要触发游戏失败结果,具体代码如下。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的BallFallTrigger.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class BallFallTrigger : MonoBehaviour{
      4         void OnTriggerEnter(Collider other) {
      5               if(other.transform.name == "Ball1") {               //若小球索引为Ball1
      6                     Application.LoadLevel("GameLose");            //加载游戏失败界面
      7                     ConstOfMenu.GAMEONE_INDEX=1;                  //将索引值设为1
      8               }
      9               else if(other.transform.name == "Ball2"){           //若小球索引为Ball2
      10                    Application.LoadLevel("GameLose");            //加载失败界面
      11                    ConstOfMenu.GAMEONE_INDEX=2;                  //将索引值设为2
      12              }
      13              else if(other.transform.name == "Ball3") {          //若小球索引为Ball3
      14                    Application.LoadLevel("GameLose");            //加载失败界面
      15                    ConstOfMenu.GAMEONE_INDEX=3;                  //将索引值设为3
      16              }
      17              else if(other.transform.name == "Ball4"){           //若小球索引为Ball4
      18                    Application.LoadLevel("GameLose");            //加载失败界面
      19                    ConstOfMenu.GAMEONE_INDEX=4;                  //将索引值设为4
      20   }}}

第4行~第20行为小球触发结果方法,当小球滚落到地板上,表示该关游戏失败。由于每个关卡失败后,会显示游戏失败界面,在该界面会有“重玩”的按钮,所以需要判断当前失败的是哪关,这里为4个关卡的4个小球命名不同,便解决了这个问题。

第5行~第19行表示,当掉落的小球为“Ball1”时,表示玩家将第一关失败,所以加载游戏失败场景的同时会将索引“GAMEONE_INDEX”置为1。同样地,其他游戏关卡也会因为不同的小球将索引置为不同数字,方便游戏结果界面使用该索引。

(7)编写木块匀速旋转脚本。该脚本主要负责在游戏关卡2中,设计一块匀速旋转的木块,用于阻碍小球顺利通过迷宫,具体代码如下。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的CubRotation.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class CubRotation : MonoBehaviour {
      4         public GameObject cub;                                    //声明游戏对象
      5         void Start () {}
      6         void Update () {
      7               cub.transform.Rotate(0,0,30 * Time.deltaTime);      //匀速绕z轴旋转
      8    }}

说明

首先声明了游戏对象cub木条,然后通过Rotate变换,匀速绕着z轴旋转,形成了木条在迷宫地板上匀速旋转的效果。

(8)游戏关卡2的木条,为了配合该关卡的绿地主题,该木条也被贴上树干的素材贴图,该木条在绿地上大小位置效果如图3-78所示。

▲图3-78 关卡2匀速旋转木条

(9)编写机械圆盘匀速旋转脚本。该脚本主要负责在游戏关卡4中,设计一块匀速旋转的机械圆盘,用于阻碍小球顺利通过迷宫,具体代码如下。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的Cub2Rotation.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class Cub2Rotation : MonoBehaviour {
      4         public GameObject cub;                                    //声明游戏对象
      5         void Start () {}
      6         void Update () {
      7               cub.transform.Rotate(0,0, 40 * Time.deltaTime);     //绕Z轴匀速旋转
      8    }}

说明

首先声明了游戏对象cub,然后通过Rotate变换,匀速绕着z轴旋转,形成了机械圆盘在迷宫地板上匀速旋转的效果。

(10)游戏关卡4的圆盘,为了配合该关卡的绿地主题,该圆盘也被贴上树干的素材贴图,该圆盘在绿地上大小位置效果如图3-79所示。

▲图3-79 关卡4匀速旋转圆盘

3.5.4 游戏结果场景

上一小节已经介绍了游戏场景的相关设计开发,本小节将向读者介绍关于游戏结果场景的相关开发。游戏结果场景分为胜利场景和失败场景,详细开发过程如下。

(1)编写游戏胜利场景脚本。在游戏胜利场景中有3个按钮,分别为“重玩”、“继续”和“返回”,当游戏胜利的时候,用户可以选择“继续”玩下一关。具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的GameWinLayer.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class GameWinLayer : MonoBehaviour {
      4         public Texture backgroundOfWinLayer;                      //菜单界面背景图片
      5         public GUIStyle[] buttonStyleOfWinLayer;                 //菜单界面按钮图样式
      6         void Start () {}
      7         void OnGUI(){
      8               GUI.DrawTexture(new Rect(0,0,1*Screen.width,1*Screen.height),
      9                   backgroundOfWinLayer);                           //绘制背景图片
      10              if (GUI.Button(new Rect(68*Screen.width/100,0*Screen.height/100,
      11                  21*Screen.width/100,32*Screen.height/100), "",  //绘制界面按钮
      12                  buttonStyleOfWinLayer[ConstOfMenu.GAMERESULT_BACK_BUTTON])) {
      13                            Application.LoadLevel("GamesMenu");   //返回选择关卡界面
      14              }
      15              if (GUI.Button(new Rect(45*Screen.width/100,21*Screen.height/100,
      16                    18*Screen.width/100,40*Screen.height/100), "",//绘制重玩按钮
      17                    buttonStyleOfWinLayer[ConstOfMenu.GAMERESULT_REPEAT_BUTTON])){
      18                    if(ConstOfMenu.GAMEONE_INDEX==1){             //若当前为关卡1
      19                         Application.LoadLevel("GameOne");        //则重新加载关卡1场景
      20                    }
      21                    else if(ConstOfMenu.GAMEONE_INDEX==2){        //若当前为关卡2
      22                          Application.LoadLevel("GameTwo");       //则重新加载关卡2场景
      23                    }
      24                    else if(ConstOfMenu.GAMEONE_INDEX==3){        //若当前为关卡3
      25                          Application.LoadLevel("GameThree");     //则重新加载关卡3场景
      26                    }
      27                    else if(ConstOfMenu.GAMEONE_INDEX==4){        //若当前为关卡4
      28                         Application.LoadLevel("GameFour");       //则重新加载关卡4场景
      29              }}
      30              if (GUI.Button(new Rect(74*Screen.width/100,66*Screen.height/100,
      31                    14*Screen.width/100,31*Screen.height/100), "", //绘制下一关按钮
      32                    buttonStyleOfWinLayer[ConstOfMenu.GAMERESULT_NEXT_BUTTON])){
      33                    if(ConstOfMenu.GAMEONE_INDEX==1){             //若当前为关卡1
      34                         Application.LoadLevel("GameTwo");        //则加载下一关关卡2
      35                    }
      36                    else if(ConstOfMenu.GAMEONE_INDEX==2){        //若当前为关卡2
      37                          Application.LoadLevel("GameThree");     //则加载下一关关卡3
      38                    }
      39                    else if(ConstOfMenu.GAMEONE_INDEX==3){        //若当前为关卡3
      40                          Application.LoadLevel("GameFour");      //则加载下一关关卡4
      41                    }
      42                    else if(ConstOfMenu.GAMEONE_INDEX==4){        //若当前为关卡4
      43                          Application.LoadLevel("GameOne");       //则重新加载关卡1
      44   }}}}

第4行~第9行主要声明了菜单界面背景图片素材,声明了菜单界面按钮图样式。同时绘制了菜单界面需要的背景图片。

第10行~第14行主要负责绘制游戏胜利界面的返回按钮,当用户单击该按钮的时候,游戏会从胜利界面切换到选择关卡界面。

第15行~第28行主要负责绘制“重玩”按钮,根据“GAMEONE_INDEX”索引的数值,若数值为1,则当用户选择重玩按钮的时候,重新加载游戏关卡1。若数值为2,重玩关卡加载关卡2,以此类推。

第30行~第43行主要负责绘制“继续”按钮,当用户单击该按钮的时候,游戏根据“GAMEONE_INDEX”索引值,来判断下一关为关卡几。若索引值为1,则下一关为关卡2,便加载游戏关卡2,以此类推。

(2)游戏胜利脚本挂载和变量赋值。该场景中存在一个“Main Camera”摄像机,将游戏胜利脚本挂载在该摄像机上,变量赋值如图3-80所示,场景最终呈现效果如图3-81所示。

▲图3-80 游戏胜利脚本变量赋值

▲图3-81 游戏胜利场景

(3)游戏失败场景。在游戏失败场景中有两个按钮,分别为“重玩”和“返回”。当游戏失败的时候,用户可以选择“重玩”来重新玩本关。具体代码如下所示。

代码位置:见随书光盘中源代码/第03章/PlayBox/Assets/Scripts/GameScript目录下的GameLoseLayer.cs。

      1    using UnityEngine;
      2    using System.Collections;
      3    public class GameLoseLayer : MonoBehaviour {
      4         public Texture backgroundOfLoseLayer;                     //菜单界面背景图片
      5         public GUIStyle[] buttonStyleOfLoseLayer;                //菜单界面按钮图样式
      6         void Start () {}
      7         void OnGUI(){
      8               GUI.DrawTexture(new Rect(0,0,1*Screen.width,
      9                   1*Screen.height), backgroundOfLoseLayer);       //绘制背景图片
      10              if (GUI.Button(new Rect(68*Screen.width/100,0*Screen.height/100,
      11                    21*Screen.width/100,32*Screen.height/100), "",    //绘制界面按钮
      12                    buttonStyleOfLoseLayer[ConstOfMenu.GAMERESULT_BACK_BUTTON])) {
      13                         Application.LoadLevel("GamesMenu");      //返回选择关卡界面
      14              }
      15              if (GUI.Button(new Rect(45*Screen.width/100,21*Screen.height/100,
      16                    18*Screen.width/100,40*Screen.height/100), "",//绘制重玩按钮
      17                    buttonStyleOfLoseLayer[ConstOfMenu.GAMERESULT_REPEAT_BUTTON])){
      18                          if(ConstOfMenu.GAMEONE_INDEX==1) {      //若当前关卡为1
      19                                 Application.LoadLevel("GameOne");//则重新加载关卡1
      20                    }
      21                    else if(ConstOfMenu.GAMEONE_INDEX==2) {       //若当前关卡为2
      22                          Application.LoadLevel("GameTwo");       //则重新加载关卡2
      23                    }
      24                    else if(ConstOfMenu.GAMEONE_INDEX==3) {       //若当前关卡为3
      25                          Application.LoadLevel("GameThree");     //则重新加载关卡3
      26                    }
      27                    else if(ConstOfMenu.GAMEONE_INDEX==4) {       //则重新加载关卡4
      28                          Application.LoadLevel("GameFour");      //则重新加载关卡4
      29   }}}}

第4行~第9行主要声明了菜单界面背景图片素材,声明了菜单界面按钮图样式。同时绘制了菜单界面需要的背景图片。

第10行~第13行主要负责绘制游戏失败界面的返回按钮,当用户单击该按钮的时候,游戏会从胜界面切换到选择关卡界面。

第15行~第28行主要负责绘制了“重玩”按钮,根据“GAMEONE_INDEX”索引的数值,若数值为1,则当用户选择重玩按钮的时候,重新加载游戏关卡1。若数值为2,重玩关卡加载关卡2,以此类推。

(4)游戏失败脚本挂载和变量赋值。该场景中存在一个“Main Camera”摄像机,将游戏失败脚本挂载在该摄像机上,变量赋值如图3-82所示,场景最终呈现效果如图3-83所示。

▲图3-82 游戏失败脚本变量赋值

▲图3-83 游戏失败场景