Unity 2D游戏开发教程之使用脚本实现游戏逻辑

Unity 2D游戏开发教程之使用脚本实现游戏逻辑

使用脚本实现游戏逻辑

通过上一节的操作,我们不仅创建了精灵的动画,还设置了动画的过渡条件,最终使得精灵得以按照我们的意愿,进入我们所指定的动画状态。但是这其中还有一些问题。例如,我们无法使用键盘控制精灵当前要进入的动画状态,而且精灵也只是在原地播放动画而已。但我们希望精灵在进入到PlayerWalkingAnimation状态时,位置应该发生改变。

要解决这些问题,就需要编写脚本。也就是说,要使用脚本来实现动画的播放控制,以及其它一些游戏的逻辑。

精灵动画状态的控制

在Project视图里,新建一个文件夹,命名为Scripts,在此文件夹里新建一个C#脚本,命名为PlayerStateController,然后为此脚本添加下面的代码:

  • 01     using UnityEngine;
  • 02     using System.Collections;
  • 03
  • 04     public class PlayerStateController : MonoBehaviour
  • 05     {
  • 06              //定义游戏人物的状态
  • 07              public enum playerStates
  • 08              {
  • 09                        idle = 0,                                                   //表示空闲
  • 10                        left,                                                           //表示左移
  • 11                        right,                                                                  //表示右移
  • 12              }
  • 13              //定义委托和事件
  • 14              public delegate void playerStateHandler(PlayerStateController.playerStates newState);
  • 15              public static event playerStateHandler onStateChange;
  • 16              void LateUpdate ()
  • 17              {
  • 18                        //获取玩家在键盘上对A、D,或者左、右方向键的输入
  • 19                       float horizontal = Input.GetAxis("Horizontal");
  • 20                       if(horizontal != 0.0f)
  • 21                       {
  • 22                                 //如果按下的是左方向键,则广播左移状态
  • 23                                 if(horizontal < 0.0f)
  • 24                                 {
  • 25                                          if(onStateChange != null)
  • 26                                                   onStateChange(PlayerStateController.playerStates.left);
  • 27                                 }
  • 28                                 //如果按下的是右方向键,则广播右移状态
  • 29                                 else
  • 30                                 {
  • 31                                          if(onStateChange != null)
  • 32                                                   onStateChange(PlayerStateController.playerStates.right);
  • 33                                 }
  • 34                       }
  • 35                       else
  • 36                       {
  • 37                                 //广播空闲状态
  • 38                                 if(onStateChange != null)
  • 39                                          onStateChange(PlayerStateController.playerStates.idle);
  • 40                       }
  • 41              }
  • 42     }

将此脚本赋予Hierarchy视图里的Player对象。对于此脚本,有以下几点需要说明:

  • q   脚本07行,定义了名为playerStates的枚举类型,此类型中定义了精灵的具体状态;
  • q   脚本19行,会获取玩家在键盘上对指定按键的输入。不同的输入值会直接导致精灵进入不同的游戏状态;
  • q   此脚本中定义的是一个可以控制精灵当前所进入动画状态的类,也可以认为是一个管理类型的类,只负责向精灵“发号施令”,具体的实现过程不是这个类要考虑的;

监听精灵当前的动画状态

上一小节里,我们使用脚本,定义了一个用于“发号施令”的类,而本小节将使用脚本定义一个“负责具体执行”的类。

在Project视图里的Scripts文件夹下,新建一个C#脚本,命名为PlayerStateListener,为此脚本添加下面的代码:

  • 01     using UnityEngine;
  • 02     using System.Collections;
  • 03
  • 04     [RequireComponent(typeof(Animator))]
  • 05     public class PlayerStateListener : MonoBehaviour
  • 06     {
  • 07              public float playerWalkSpeed = 3f;                               //表示精灵移动的速度
  • 08              private Animator playerAnimator = null;                      //表示对象上的Animator组件
  • 09              //表示精灵当前的动画状态
  • 10              private PlayerStateController.playerStates currentState = PlayerStateController.playerStates.idle;
  • 11         //对象可用时,加入到订阅者列表中
  • 12              void OnEnable()
  • 13         {
  • 14              PlayerStateController.onStateChange += onStateChange;
  • 15         }
  • 16              //不可用时,从订阅者列表中退出
  • 17         void OnDisable()
  • 18         {
  • 19              PlayerStateController.onStateChange -= onStateChange;
  • 20         }
  • 21              void Start()
  • 22              {
  • 23                        //建立与对象上Animator组件的联系
  • 24                       playerAnimator = GetComponent<Animator>();
  • 25              }
  • 26         void LateUpdate()
  • 27         {
  • 28              onStateCycle();
  • 29         }
  • 30              //用于检测当前所处的动画状态,在不同的状态下将表现出不同的行为
  • 31         void onStateCycle()
  • 32         {
  • 33                        //表示当前对象的大小
  • 34                       Vector3 localScale = transform.localScale;
  • 35                        //判断当前处于何种状态
  • 36                       switch(currentState)
  • 37                       {
  • 38                                 case PlayerStateController.playerStates.idle:
  • 39                                          break;
  • 40                //向左移动
  • 41                                 case PlayerStateController.playerStates.left:
  • 42                                          transform.Translate(
  • 43                                                             new Vector3((playerWalkSpeed * -1.0f) * Time.deltaTime, 0.0f, 0.0f));
  • 44                                          //角色将转向
  • 45                                          if(localScale.x > 0.0f)
  • 46                                          {
  • 47                                                   localScale.x *= -1.0f;
  • 48                                                   transform.localScale  = localScale;
  • 49                                          }
  • 50                                          break;
  • 51                                 //向右移动
  • 52                                 case PlayerStateController.playerStates.right:
  • 53                                          transform.Translate(new Vector3(playerWalkSpeed * Time.deltaTime, 0.0f, 0.0f));
  • 54                                          //角色将转向
  • 55                                          if(localScale.x < 0.0f)
  • 56                                          {
  • 57                                                   localScale.x *= -1.0f;
  • 58                                                   transform.localScale = localScale;
  • 59                                          }
  • 60                                          break;
  • 61                       }
  • 62              }
  • 63
  • 64              //当角色的状态发生改变的时候,调用此函数
  • 65              public void onStateChange(PlayerStateController.playerStates newState)
  • 66              {
  • 67                        //如果状态没有发生变化,则无需改变状态
  • 68                       if(newState == currentState)
  • 69                                 return;
  • 70                        //判断精灵能否由当前的动画状态,直接转换为另一个动画状态
  • 71                       if(!checkForValidStatePair(newState))
  • 72                                 return;
  • 73                        //通过修改Parameter中Walking的值,修改精灵当前的状态
  • 74                       switch(newState)
  • 75                       {
  • 76                                 case PlayerStateController.playerStates.idle:
  • 77                                          playerAnimator.SetBool("Walking", false);
  • 78                                 break;
  • 79                                 case PlayerStateController.playerStates.left:
  • 80                                          playerAnimator.SetBool("Walking", true);
  • 81                                 break;
  • 82                                 case PlayerStateController.playerStates.right:
  • 83                                          playerAnimator.SetBool("Walking", true);
  • 84                                 break;
  • 85                       }
  • 86                        //记录角色当前的状态
  • 87                       currentState = newState;
  • 88              }
  • 89
  • 90              //用于确认当前的动画状态能否直接转换为另一动画状态的函数
  • 91              bool checkForValidStatePair(PlayerStateController.playerStates newState)
  • 92              {
  • 93                       bool returnVal = false;
  • 94                        //比较两种动画状态
  • 95                       switch(currentState)
  • 96                       {
  • 97                                 case PlayerStateController.playerStates.idle:
  • 98                                          returnVal = true;
  • 99                                 break;
  • 100                              case PlayerStateController.playerStates.left:
  • 101                                        returnVal = true;
  • 102                              break;
  • 103                              case PlayerStateController.playerStates.right:
  • 104                                        returnVal = true;
  • 105                              break;
  • 106                     }
  • 107                     return returnVal;
  • 108            }
  • 109  }

将此脚本赋予Hierarchy视图里的Player对象,选中后者,然后在Inspector视图里,找到此脚本组件,发现里面有一个属性Player Walk Speed,如图1-31所示。正如属性名的含义,它可以用于设置精灵的移动速度,并且值越大,精灵的移动速度越快。

图1-31  脚本组件,及其属性

对于此脚本,有以下几点需要说明:

  • q   脚本10行,说明默认情况下,精灵在游戏开始时,所处的是Idle动画状态;
  • q   脚本12、17行定义的方法OnEnable()和OnDisable(),说明只有成为订阅者的对象才会收到动画状态改变的消息;
  • q   脚本31行定义的方法onStateCycle(),可以依据精灵当前所处的动画状态,修改精灵在场景中的位置属性。例如,当精灵进入左移的动画状态时,就向左修改场景里精灵的位置;
  • q   脚本65行定义的方法onStateChange(),用于真正修改精灵当前所处的动画状态,也就是通过设置Parameters中Walking的值,进而完成的精灵动画状态的切换;
  • q   脚本91行定义的方法checkForValidStatePair(),说明动画状态并非可以随意转换,这是为了更加符合逻辑。例如,人可以从“跑”的状态过渡到“跑跳”的状态,但是无法从“走”的状态过渡到“跑跳”的状态。
  • q   脚本中44~49、54~59行的代码应该被关注,因为它使得精灵实现了“转身”。为什么这么说呢?因为没有它们的话,精灵会始终朝向一个方向,读者可以注释掉它们并运行程序查看效果。精灵默认在游戏场景里的位置属性,以及显示效果如图1-32所示。如果修改位置属性里Scale在X属性上的值为原来的负数,游戏场景里的精灵就会“转身”,如图1-33所示。

图1-33  Scene和Inspector视图,精灵面朝左

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

时间: 2024-08-08 22:07:25

Unity 2D游戏开发教程之使用脚本实现游戏逻辑的相关文章

【H5小游戏开发教程】如何限制微信游戏只能在微信端打开?

在这行里接触的时间多了,就会发现很多有意思的东西. 比如,很多微信小游戏会限制只能在微信端打开,有木有? 有这样的, 也有这样的, 妈蛋,不能用PC访问,这游戏就没法扒呀..... 其实涛舅舅告诉你,这两种都可以扒 而且是用PC! 但是今天,我不教你扒皮 我要教你的是,怎么让你的微信游戏也能限制PC打不开 很想学吧  准备开始! 1.第一种不提了,因为人家是设置了微信授权登录,从微信那里就拦截住了,只能用微信访问,你可能弄不了这么高级的微信授权这块,如果你真能弄,这一讲你也不用听了,因为你已经能

Unity 2D游戏开发教程之精灵的死亡和重生

Unity 2D游戏开发教程之精灵的死亡和重生 精灵的死亡和重生 目前为止,游戏项目里的精灵只有Idle和Walking这两种状态.也就是说,无论精灵在游戏里做什么,它都不会进入其它的状态,如死亡.于是我们发现游戏里的精灵,即使是跳入“万丈深渊”,也依然存活,显然这种游戏逻辑无法让人接受.因此,本节就来说明为精灵添加死亡和重生这两种状态的方法,并使用脚本实现这两种状态的逻辑.具体的实现步骤如下: (1)在Hierarchy视图里,新建一个Empty对象,并命名为Death Trigger,设置其

Unity 2D游戏开发教程之游戏中精灵的跳跃状态

Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却无法从低的地面移动到高的地面,因为当前的游戏精灵只能左右移动,即left和right.为了解决这个问题,本节就来为精灵添加跳跃状态.   图2-14  精灵从一个地面移动到另一个地面 (1)如果要为精灵添加跳跃状态,即jump,就不得不再引入其它状态: q   landing:用于表示精灵接触到地面

Unity 2D游戏开发教程之摄像头追踪功能

Unity 2D游戏开发教程之摄像头追踪功能 上一章,我们创建了一个简单的2D游戏.此游戏中的精灵有3个状态:idle.left和right.这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以及游戏逻辑的想象空间.看来有必要让精灵拥有更多的状态,而这就是本章要讲解的主要内容. 摄像头追踪功能 游戏里的精灵可以在游戏场景中任意移动,这没什么问题,可是这就导致了一个问题,就是精灵可能移动到我们的视野之外,或者说游戏视图之外.为了解决这个问题,很多游戏都采用了"摄像头追踪"的方法,使

Unity 2D游戏开发教程之游戏精灵的开火状态

Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 "开火"就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌人,而精灵最好具备开火的能力,否则会被敌人轻易干掉!具体的实现方法是: (1)导入一个表示子弹的图片到Unity,本示例中选用的子弹图片,名为PlayerBullet,如图2-23所示. 图2-23  导入到游戏项目的表示子弹的图片 (2)拖动此图片到Scene视图,即可在当前的游戏场景中

Unity 2D游戏开发教程之为游戏场景添加多个地面

Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面.具体的操作方法是: (1)在Project视图里,新建一个文件夹,命名为Prefabs.然后将Hierarchy视图里的Platform对象,拖动到Prefabs文件夹中,如此一来就可以生成一个同名的预置资源,如图2-11所示. 图2-11  通过拖动对象到Project视图的方式,新建预置资源 (

Unity网络多玩家游戏开发教程第1章Unity自带网络功能

Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持.但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说到的Unity Networking API.这些API是借助于组件NetworkView发挥作用的,而它可以简化开发者大量的网络功能编码任务.本文选自<Unity网络多玩家游戏开发教程(大学霸内部资料)> NetworkView组件 在Unity中,NetworkView组件用于处理游戏在网络上

【Unity3D游戏开发】—— 太空大战打飞机游戏详解

大家好我是Kaven,今天给大家带来的是一个Unity3D的打飞机的小项目.俗话说"眼看千变,不如手过一边",学了差不多两星期Unity3D了,是时候找个小项目练练手了.于是就翻出了cocos2d-x的一个例子,模仿着写了一个飞机大战的游戏,虽然有一些功能没有实现,但总体上是完成了.闲话少说,下面开始吧. 由于这个用的是Unity3d自带的原生的2D插件native 2d,所以创建项目时左下角选择2d. 这个小游戏我分了三个场景,菜单场景,游戏场景,结束场景.由于菜单场景与结束场景都比

C#游戏开发快速入门 2.1 构建游戏场景

C#游戏开发快速入门 2.1  构建游戏场景 如果已经计划好了要编写什么样的游戏,在打开Unity以后,要做的第一件事情就是构建游戏场景(Scene).游戏场景就是玩家游戏时,在游戏视图中看到的一切,包括游戏背景.游戏角色.阳光等等,这些所有可视的元素在Unity中,被统称为游戏对象(GameObject).本节就先来学习游戏场景的构建. 2.1.1  新建游戏场景 就像是创建游戏就需要要新建游戏项目一样,构建游戏场景也是需要新建游戏场景的.只不过,Unity在开发者新建游戏项目的时候,已经默认