各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei。在研究了Unity3D Mecanim动画系统的重定向特性后,今天我们继续来探索Mecanim动画系统很多其它的特性吧。今天博主想和大家分享的是ACT游戏中的三连击效果的实现,因为Unity3D眼下存在Animation和Animator两种类型的动画组件,因此本文将分别讲这两种类型的动画组件的三连击效果的实现,当中Animation组件是Unity3.5以下版本号所使用的动画组件,Animator组件是眼下Unity3D的Mecanim动画系统所使用的动画组件。
  我们首先来了解三连击效果的详细流程,假定角色当前处于Idle状态,此时玩家假设按下攻击键则进入Attack1状态,假设在规定的时间内,玩家继续按下攻击键则进入Attack2状态,否则返回到Idle状态;同理,假设角色处于Attack2状态,假设此时玩家按下攻击键则进入Attack3状态,否则返回Idle状态;当Attack3状态结束后,将返回到Idle状态,等待玩家触发下一次攻击。由此我们能够归纳出三连击的状态变化:
(1)Idle->Attack1->Idle
(2)Idle->Attack1->Attack2->Idle
(3)Idle->Attack1->Attack->Attack3->Idle
       通过状态变化情况我们能够考虑使用两种思路来实现三连击效果。第一种思路是,各状态动画相互独立,通过状态切换来实现总体的动画效果。另外一种思路是,美工人员将各状态动画以序列形式,程序设计人员依据时间来控制动画效果。今天我们主要採用第一种方法,目的是领会游戏设计中的有限状态机思想,将其更好的应用到游戏开发中。好了,以下我们正式開始今天的内容吧!

一、Animator组件篇

Animator组件是Unity3D的Mecanim动画系统所使用的动画组件。这个组件通过Animator Controller来实现对动画的控制。如图是我们今天项目的主角,一个左手持盾,右手持剑的女战士。

我们首先来创建一个Animator Controller并将其命名为SwordGirlController,双击打开Animator窗体,依照我们对状态变化情况的讨论,我们能够非常easy地设计出以下的状态模型:

在这里我们定义一个整型变量ActionID,其默认值为0。当ActionID的值为1时角色由Idle切换到Attack1,当ActionID的值为2时角色由Attack1切换到Attack2,当ActionID为3时角色由Attack2切换到Attack3。全部的指向Idle的连线的切换条件是ActionID的值为0。这样我们就建立了一个动画切换的状态模型。好了,以下我们来编写脚本实现对动画的控制:

  1. //基于Mecanim动画系统的三连击效果,眼下最大的问题就是玩家在攻击后无法
  2. //自己主动恢复到Idle状态,须要运行一次攻击才干够回到Idle状态
  3.  
  4. using UnityEngine;
  5. using System.Collections;
  6.  
  7. public class SwordGirlScript : MonoBehaviour {
  8.  
  9. //Mecanim动画组件
  10. private Animator mAnimator=null;
  11. //动画状态信息
  12. private AnimatorStateInfo mStateInfo;
  13. //定义状态常量值,前面不要带层名啊,否则无法推断动画状态
  14. private const string IdleState="Idle";
  15. private const string Attack1State="Attack1";
  16. private const string Attack2State="Attack2";
  17. private const string Attack3State="Attack3";
  18.  
  19. //定义玩家连击次数
  20. private int mHitCount=0;
  21.  
  22. void Start ()
  23. {
  24. //获取动画组件
  25. mAnimator=GetComponent<Animator>();
  26. //获取状态信息
  27. mStateInfo=mAnimator.GetCurrentAnimatorStateInfo(0);
  28. }
  29.  
  30. void Update ()
  31. {
  32. //假设玩家处于攻击状态,且攻击已经完毕,则返回到Idle状态
  33. if(!mStateInfo.IsName(IdleState) && mStateInfo.normalizedTime>1.0F)
  34. {
  35. mAnimator.SetInteger("ActionID",0);
  36. mHitCount=0;
  37. }
  38. //假设按下鼠标左键,则開始攻击
  39. if(Input.GetMouseButton(0))
  40. {
  41. Attack();
  42. }
  43. }
  44.  
  45. void Attack()
  46. {
  47. //获取状态信息
  48. mStateInfo=mAnimator.GetCurrentAnimatorStateInfo(0);
  49. //假设玩家处于Idle状态且攻击次数为0,则玩家依照攻击招式1攻击,否则依照攻击招式2攻击,否则依照攻击招式3攻击
  50. if(mStateInfo.IsName(IdleState) && mHitCount==0 && mStateInfo.normalizedTime>0.50F)
  51. {
  52. mAnimator.SetInteger("ActionID",1);
  53. mHitCount=1;
  54. }else if(mStateInfo.IsName(Attack1State) && mHitCount==1 && mStateInfo.normalizedTime>0.65F)
  55. {
  56. mAnimator.SetInteger("ActionID",2);
  57. mHitCount=2;
  58. }else if(mStateInfo.IsName(Attack2State)&& mHitCount==2 && mStateInfo.normalizedTime>0.70F)
  59. {
  60. mAnimator.SetInteger("ActionID",3);
  61. mHitCount=3;
  62. }
  63. }
  64. }

这样我们就能够实现ACT游戏中的三连击效果了,我们一起来看看终于的效果吧!

博主在实际測试的过程中发现角色在运行一次攻击后无法自己主动恢复到Idle状态,除非玩家继续按下攻击键,博主眼下并没有找到解决的办法,假设各位朋友知道详细原因的话,一定要告诉博主啊,哈哈。

二、Animation组件篇

我们知道Mecanim动画系统是通过状态机来实现对动画的控制的,而在3.5版本号曾经的Unity3D所採用的动画系统呢,依照博主的理解,事实上就是一种无状态的动画,我们只能通过动画片段的名称来决定播放某一个动画片段或者在一个确定的时间内进行动画的切换。因此,假设我们希望使用Animation组件来实现三连击效果的话,就必须在该组件的基础上实现一个状态机的结构。依据開始讨论的结果,我们知道整个三连击过程中有四个状态Attack1、Attack2、Attack3、Idle,由此我们能够定义一个动画状态的枚举类型ActionState。接下来我们就能够依据这个状态值来切换攻击动画,实现三连击的效果,我们一起来看脚本:

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class AttackScripts : MonoBehaviour {
  5.  
  6. //当前攻击动画;
  7. AnimationClip currentClip;
  8. //动画组件;
  9. Animation mAnimation;
  10.  
  11. //动画状态枚举
  12. public enum ActionState
  13. {
  14. Attack1,
  15. Attack2,
  16. Attack3
  17. None
  18. }
  19.  
  20. //当前动画状态;
  21. private ActionState mState = ActionState.None;
  22.  
  23. //攻击触发
  24. void AttackTrigger(){
  25. if (Input.GetMouseButton(0)){
  26. if (mState != ActionState.Attack1 && mState != ActionState.Attack2 && mState != ActionState.Attack3 ) {
  27. mState = ActionState.Attack1;
  28. }else if (mState == ActionState.Attack1 && mState != ActionState.Attack2 && mState != ActionState.Attack3
  29. && mAnimation[currentClip.name].time > 1.0F){
  30. mState = ActionState.Attack2;
  31. }else if (mState == ActionState.Attack2 && mState != ActionState.Attack1 && mState != ActionState.Attack3
  32. && mAnimation[currentClip.name].time > 1.0F){
  33. mState = ActionState.Attack2;
  34. }
  35. }
  36. }
  37.  
  38. //攻击套路
  39. void Attacks (){
  40. float delayTime =0.0F;
  41. switch (mState){
  42. case ActionState.Attack1:
  43. delayTime = -0.1F;
  44. mAnimation.CrossFade("Attack1", 0.15F);
  45. currentClip = mAnimation["Attack1"].clip;
  46. break;
  47.  
  48. case ActionState.Attack2:
  49. delayTime = -0.1f;
  50. mAnimation.CrossFade("Attack2", 0.15F);
  51. currentClip = mAnimation["Attack2"].clip;
  52. break;
  53.  
  54. case ActionState.Attack3:
  55. delayTime = -0.1f;
  56. mAnimation.CrossFade("Attack3", 0.15F);
  57. currentClip = mAnimation["Attack3"].clip;
  58. break;
  59.  
  60. case ActionState.None:
  61. break;
  62. }
  63.  
  64. //假设攻击动画播放完就切换到Idle状态
  65. if (mAnimation[currentClip.name].time > (mAnimation[currentClip.name].length +delayTime)){
  66. mState = ActionState.None;
  67. currentClip = mAnimation["Idle"].clip;
  68. }
  69. }
  70.  
  71. void Awake(){
  72. //获取动画组件;
  73. mAnimation = GetComponent<Animation>();
  74. }
  75.  
  76. void Start () {
  77. if (mAnimation.clip) {
  78. currentClip = mAnimation.clip;
  79. } else {
  80. currentClip = mAnimation["Idle"].clip;
  81. }
  82. }
  83.  
  84. void Update () {
  85. if (currentClip != null){
  86. AttackTrigger();
  87. Attacks();
  88. }
  89. }
  90. }

这里的连击效果并没有设置打断,即全部的动画一次性播放完毕。假设我们在Mecanim动画系统中只保留第三种情形,那么它实现的效果是一样的,这一点希望大家注意。好了,今天的内容就是这样了,感谢大家关注我的博客,希望大家能够喜欢。

每日箴言:无论当下的我们有没有人爱,我们都要努力做一个可爱的人。不埋怨谁,不嘲笑谁,也不羡慕谁,做自己的梦,走自己的路。

喜欢我的博客请记住我的名字:秦元培,我博客地址是blog.csdn.net/qinyuanpei。
转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/38023199

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述的更多相关文章

  1. [整理]Unity3D游戏开发之Lua

    原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...

  2. [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读

    ---------------------------------------------------------------------------------------------------- ...

  3. [Unity3D]Unity3D游戏开发之从Unity3D到Eclipse

    ---------------------------------------------------------------------------------------------------- ...

  4. [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)

    ---------------------------------------------------------------------------------------------------- ...

  5. Cocos2d-x 3.x游戏开发之旅

    Cocos2d-x 3.x游戏开发之旅 钟迪龙 著   ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x ...

  6. 【转载】浅谈游戏开发之2D手游工具

    浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android  程序设计: 其它  编程语言:   引擎/SDK ...

  7. Cocos2d—X游戏开发之CCToggle(菜单标签切换)CCControlSwitch(开关切换)

    Cocos2d—X游戏开发之CCToggle(菜单标签切换) 首先继承子CCMenu,是菜单标签中的一种.‘ class CC_DLL CCMenuItemToggle : public CCMenu ...

  8. iOS游戏开发之UIDynamic

    iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ...

  9. [Unity3D]Unity3D游戏开发之Unity与Android交互调用研究

    各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei.在前一篇文章中,我们研究了Android平台上Unity3D的手势操作并在之前的基础 ...

随机推荐

  1. 使用POI创建Excel文件下载

    POIExcelUtils.java: package com.saicfc.pmpf.internal.manage.utils; import java.io.File; import java. ...

  2. Java面试题精选(三) JSP/Servlet Java面试逻辑题

    --   JSP/Servlet  Java面试逻辑题   --     很显然,Servlet/JSP的WEB前端动态制作的重要性比HTML/CSS/JS的价值高很多,但我们都知道他们都是建立在HT ...

  3. 基于visual Studio2013解决面试题之0802数字最多元素

     题目

  4. 使用gradle打包jar包

    近期用android studio来做android开发的IDE,它是使用gradle来构建的,于是開始学习gradle. 如今有一个项目,里面有一个android-library的模块.我想在做re ...

  5. 【环境配置】配置sdk

    1. 安装和配置 (1) 下载sdk 官方下载地址http://developer.android.com/sdk/index.html 这里以android-sdk_r12-linux_x86.tg ...

  6. python3语法小记(二)列表 和 元组

    列表(list): 列表就像一个线性容器,但是比C++的 lis t扩展多得多 列表里的元素可以是相同类型,也可以包含各种类型,比如列表里嵌套另一个列表 >>> L1 = [1,2, ...

  7. C++学习之路—const用法总结

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) C++为什么要引入const?它允许你指定一个语 ...

  8. Java描述语言、国家和地理的类——Locale

    Locale类代表一个特定的地理.语言和国家环境.一个Locale的实例对象本身不会验证它代表的语言和国家地区信息是否正确,只是向一些对国家和语言.地理等比较敏感的类提供国家地区语言信息,这些类有Da ...

  9. 《Linux命令行与shell脚本编程大全》 第十八章 学习笔记

    第十八章:初识sed和gawk 文本处理 sed编辑器 sed编辑器可以基于输入到命令行的或是存储在命令文本文件中的命令来处理数据流中的数据. 它每次读取一行,用提供的编辑器命令匹配数据.按命令中指定 ...

  10. HEVC码率控制浅析——HM代码阅读之四

    继续分析第一篇提到的compressSlice中对LCU的RC参数初始化: #if RATE_CONTROL_LAMBDA_DOMAIN Double oldLambda = m_pcRdCost-& ...