zoukankan      html  css  js  c++  java
  • 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人!

  • 相关阅读:
    Android JNI 使用的数据结构JNINativeMethod详解 .
    datatable的部分问题处理(动态定义列头,给某行添加事件,初始显示空数据)
    关于boostrap的modal隐藏问题(前端框架)
    三丰云服务器的基本使用(端口)
    Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
    云服务器内,nginx安装部署,Xshell,Xftp安装
    免费云服务器的申请(三丰云)
    vue的组件化运用(数据在两个组件互传,小问题总结)
    vue的表单编辑删除,保存取消功能
    datatable动态列处理,重绘表格(敲黑板,划重点!!!我肝了一天半才彻底弄懂这个东西,TAT)
  • 原文地址:https://www.cnblogs.com/daxueba-ITdaren/p/4778721.html
Copyright © 2011-2022 走看看