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人!
Unity 2D游戏开发教程之使用脚本实现游戏逻辑相关推荐
- Unity 2D游戏开发教程之摄像头追踪功能
Unity 2D游戏开发教程之摄像头追踪功能 上一章,我们创建了一个简单的2D游戏.此游戏中的精灵有3个状态:idle.left和right.这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- Unity 2D游戏开发教程之精灵的死亡和重生
Unity 2D游戏开发教程之精灵的死亡和重生 精灵的死亡和重生 目前为止,游戏项目里的精灵只有Idle和Walking这两种状态.也就是说,无论精灵在游戏里做什么,它都不会进入其它的状态,如死亡.于 ...
- Unity 2D游戏开发教程之为游戏场景添加多个地面
Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面. ...
- unity 2d 游戏开发教程(2d战棋)
unity 2d 游戏开发教程(2d战棋) 类似的游戏有:火焰纹章,梦幻模拟战 先上效果 源码领取方式:私信发送 2D战棋资料领取 这是 unity3d 战棋游戏开发 专题的内容拓展 这个专题完整的讲 ...
- Unity网络多玩家游戏开发教程(上册)
Unity网络多玩家游戏开发教程(上册) 试读文档下载地址:http://pan.baidu.com/s/1jGwwxam Unity作为强大的游戏开发平台,为网络游戏的的开发提供大量的组件和API. ...
- Unity网络多玩家游戏开发教程第1章Unity自带网络功能
Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持.但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说 ...
- 微信小游戏开发教程-2D游戏原理讲解
微信小游戏开发教程-2D游戏原理讲解 原理 为了更加形象的描述,这里先上一张图: 背景 a. 首先,我们看到背景好像是一张无限长的图片在向下移动.实际则不然,这是一张顶部和底部刚好重叠的图片.这是一种 ...
- 2D平台类游戏开发教程(翻译)
这是一篇实现2D平台类游戏的技术指导文章,原文地址:http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-pla ...
最新文章
- python和c语言的对比_类C语言与Python负数除法求值间的差异
- 对手机支付安全机制的思考
- 互联网日报 | 6月12日 星期六 | BOSS直聘正式登陆纳斯达克;腾讯回应“试点强制6点下班”;数据安全法9月1日起实施...
- HTML5开发和web前端开发的区别与联系?
- linux中查找find命令的程序文件,如何使用find命令在Linux中查找文件
- Https如何做到通信安全
- win7开机动画_分享win7开机画面修改方法
- 秒跳转html代码,5秒定时跳转指定网页源码
- aop日志 android,ASM实现Android APK的AOP日志统计
- RCP中设置view和editor的tilte字体
- Java生成二维码,Spring Boot整合ZXing实现二维码生成,支持自定义二维码
- char *那些事儿
- 电流互感器的一些计算
- python_爬虫 01 爬虫前奏
- 你见过几次四大天王同台啊
- 复制excel或word中图片不失真
- 经济法基础——第六章第三节综合、与增值税联系较为密切的税种
- 施耐德电气ComPacT NSX塑壳断路器收获肯定彰显实力
- 网优谷带你盘一盘重构IT基础架构的“七种武器”!
- python发红包最佳手气王_给自己发了两亿个红包后,我找到了手气最佳的秘密
热门文章
- Android Studio打包~安卓打包踩坑及总结
- 让pip使用国内镜像,解决下载速度慢的问题
- Json返回时间中出现乱码问题的两种解决方法
- [c#]解决方案:需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
- 解决Windows10下无法对docker容器进行端口访问(端口映射的问题)
- 为解决Thymeleaf数字格式化问题而想到的几种方案
- Android 解决不同进程发送KeyEvent 的问题
- Ubuntu死机解决方法汇总
- 在objective-c / cocoa中抛出异常
- python全栈开发 * 22 面向对象 知识点汇总 * 180703