文档章节

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

大学霸
 大学霸
发布于 2015/09/02 15:25
字数 1814
阅读 887
收藏 0

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                        //获取玩家在键盘上对AD,或者左、右方向键的输入

  • 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                        //通过修改ParameterWalking的值,修改精灵当前的状态

  • 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   脚本1217行定义的方法OnEnable()OnDisable(),说明只有成为订阅者的对象才会收到动画状态改变的消息;

  • q   脚本31行定义的方法onStateCycle(),可以依据精灵当前所处的动画状态,修改精灵在场景中的位置属性。例如,当精灵进入左移的动画状态时,就向左修改场景里精灵的位置;

  • q   脚本65行定义的方法onStateChange(),用于真正修改精灵当前所处的动画状态,也就是通过设置ParametersWalking的值,进而完成的精灵动画状态的切换;

  • q   脚本91行定义的方法checkForValidStatePair(),说明动画状态并非可以随意转换,这是为了更加符合逻辑。例如,人可以从“跑”的状态过渡到“跑跳”的状态,但是无法从“走”的状态过渡到“跑跳”的状态。

  • q   脚本中44~4954~59行的代码应该被关注,因为它使得精灵实现了“转身”。为什么这么说呢?因为没有它们的话,精灵会始终朝向一个方向,读者可以注释掉它们并运行程序查看效果。精灵默认在游戏场景里的位置属性,以及显示效果如图1-32所示。如果修改位置属性里ScaleX属性上的值为原来的负数,游戏场景里的精灵就会“转身”,如图1-33所示。

1-33  SceneInspector视图,精灵面朝左

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


© 著作权归作者所有

大学霸
粉丝 270
博文 908
码字总数 557321
作品 0
东城
程序员
私信 提问
C#开发Unity游戏教程之游戏对象的行为逻辑方法

C#开发Unity游戏教程之游戏对象的行为逻辑方法 游戏对象的行为逻辑——方法 方法(method),读者在第1章新建脚本时就见过了,而且在第2章对脚本做整体上的介绍时也介绍过,那么上一章呢,尽...

大学霸
2015/07/08
913
0
Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏

Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏 即使是现在,很多初学游戏开发的同学,在谈到Unity的时候,依然会认为Unity只能用于制作3D游戏的。实际上,Unity在2013年发布4.3版本的时...

大学霸
2014/10/17
1K
0
【Unity】Unity地形入门问题集锦

版权声明:非技术文章禁止转载,如有需要请私信作者。技术类文章欢迎转载,转载请注明出处: http://blog.csdn.net/ztf312/ https://blog.csdn.net/ztf312/article/details/89632314 =======...

CS青雀
04/28
0
0
Unity网络多玩家游戏开发教程第1章Unity自带网络功能

Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持。但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说...

大学霸
2014/10/30
1K
1
对于质疑.Net语言的那些人,我只能告诉你们,你们不懂.... ...

最近这些年我一直用c#开发,因为C#和.Net的非常棒的软件开发语言和平台,我感觉C#正是我想要的语言,用它既能开发上层东西,也能开发底层代码,更重要的是,用它开发unity3d游戏,已是将来的...

八一戒
2013/06/08
26K
56

没有更多内容

加载失败,请刷新页面

加载更多

深入理解表单脚本系列第二篇——表单字段

本文转载于:专业的前端网站➜深入理解表单脚本系列第二篇——表单字段 前面的话   表单字段又叫表单元素,表示表单所包含控件,如<input>、<select>等。本文将详细介绍表单字段的内容 访问...

前端老手
11分钟前
1
0
前端技术之:常用webpack插件

1、html-webpack-plugin Simplifies creation of HTML files to serve your webpack bundles. 主页地址: https://github.com/jantimon/html-webpack-plugin 安装方法: npm i --save-dev h......

popgis
16分钟前
4
0
IT兄弟连 HTML5教程 HTML5表单 多样的输入类型1

HTML5拥有多个新的表单输入类型,这些新特性提供了更好的输入控制和验证。并不是所有的主浏览器都支持新的input类型,不过我们可以在所有的主浏览器中使用它们,即使不被支持,仍然可以显示为...

老码农的一亩三分地
17分钟前
2
0
规则引擎

解决问题 版本迭代速度更不上业务变化,但是若多个业务同时变化,除了为每个业务设计专属配置项也不利于操作。就想服务接口单纯化,将复杂多变的业务逻辑交给规则引擎,让用户在web端或cs端自...

无极之岚
54分钟前
7
0
OSChina 周三乱弹 —— 欢迎你来做产品经理

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :10多次劲歌金曲获奖,更多叱咤歌坛排名,黎明才应该是四大天王之首,只可惜拍的电影太少。单曲循环一个多月的歌,力荐 《无名份的...

小小编辑
今天
601
10

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部