[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

        各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是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组件是Unity3DMecanim动画系统所使用的动画组件。这个组件通过Animator Controller来实现对动画的控制。如图是我们今天项目的主角,一个左手持盾,右手持剑的女战士。

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

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

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

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

//基于Mecanim动画系统的三连击效果,眼下最大的问题就是玩家在攻击后无法
//自己主动恢复到Idle状态,须要运行一次攻击才干够回到Idle状态

using UnityEngine;
using System.Collections;

public class SwordGirlScript : MonoBehaviour {

	//Mecanim动画组件
	private Animator mAnimator=null;
	//动画状态信息
	private AnimatorStateInfo mStateInfo;
	//定义状态常量值,前面不要带层名啊,否则无法推断动画状态
	private const string IdleState="Idle";
	private const string Attack1State="Attack1";
	private const string Attack2State="Attack2";
	private const string Attack3State="Attack3";

	//定义玩家连击次数
	private int mHitCount=0;
	
	void Start () 
	{
		//获取动画组件
		mAnimator=GetComponent<Animator>();
		//获取状态信息
		mStateInfo=mAnimator.GetCurrentAnimatorStateInfo(0);
	}

	void Update () 
	{
	    //假设玩家处于攻击状态,且攻击已经完毕,则返回到Idle状态
		if(!mStateInfo.IsName(IdleState) && mStateInfo.normalizedTime>1.0F)
		{
			mAnimator.SetInteger("ActionID",0);
			mHitCount=0;
		}
        //假设按下鼠标左键,则開始攻击
		if(Input.GetMouseButton(0))
		{
	        Attack();
		}
	}

	void Attack()
	{
	   //获取状态信息
	   mStateInfo=mAnimator.GetCurrentAnimatorStateInfo(0);
	   //假设玩家处于Idle状态且攻击次数为0,则玩家依照攻击招式1攻击,否则依照攻击招式2攻击,否则依照攻击招式3攻击
	   if(mStateInfo.IsName(IdleState) && mHitCount==0 && mStateInfo.normalizedTime>0.50F)
	   {
		  mAnimator.SetInteger("ActionID",1);
		  mHitCount=1;
	   }else if(mStateInfo.IsName(Attack1State) && mHitCount==1 && mStateInfo.normalizedTime>0.65F)
	   {
		  mAnimator.SetInteger("ActionID",2);
		  mHitCount=2;
	   }else if(mStateInfo.IsName(Attack2State)&& mHitCount==2 && mStateInfo.normalizedTime>0.70F)
	   {
		  mAnimator.SetInteger("ActionID",3);
	      mHitCount=3;
		}
	}
}

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

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

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

        二、Animation组件篇

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

using UnityEngine;
using System.Collections;
 
public class AttackScripts : MonoBehaviour {

    //当前攻击动画;
    AnimationClip currentClip;
    //动画组件;
    Animation mAnimation;

    //动画状态枚举
    public enum ActionState
    {
        Attack1,
        Attack2,
        Attack3,
        None
    }

    //当前动画状态;
    private ActionState mState = ActionState.None;
     
    //攻击触发
    void AttackTrigger(){
        if (Input.GetMouseButton(0)){
            if (mState != ActionState.Attack1 && mState != ActionState.Attack2 && mState != ActionState.Attack3 ) {
                mState = ActionState.Attack1;
            }else if (mState == ActionState.Attack1 &&  mState != ActionState.Attack2 && mState != ActionState.Attack3 
                && mAnimation[currentClip.name].time > 1.0F){
                mState = ActionState.Attack2;
            }else if (mState == ActionState.Attack2 &&  mState != ActionState.Attack1 && mState != ActionState.Attack3   
                && mAnimation[currentClip.name].time > 1.0F){
                mState = ActionState.Attack2;
            }
        }
    }
     
    //攻击套路
    void Attacks (){
        float delayTime =0.0F;
        switch (mState){
            case ActionState.Attack1:
                delayTime = -0.1F;
                mAnimation.CrossFade("Attack1", 0.15F);
                currentClip = mAnimation["Attack1"].clip;
                break;
                 
            case ActionState.Attack2:
                delayTime = -0.1f;
                mAnimation.CrossFade("Attack2", 0.15F);
                currentClip = mAnimation["Attack2"].clip;
                break;

            case ActionState.Attack3:
                delayTime = -0.1f;
                mAnimation.CrossFade("Attack3", 0.15F);
                currentClip = mAnimation["Attack3"].clip;
                break;
                 
            case ActionState.None:
                break;
        }
         
        //假设攻击动画播放完就切换到Idle状态
        if (mAnimation[currentClip.name].time > (mAnimation[currentClip.name].length +delayTime)){
            mState = ActionState.None;
            currentClip = mAnimation["Idle"].clip;
        }
    }
     
    void Awake(){
        //获取动画组件;
        mAnimation = GetComponent<Animation>();
    }
     
    void Start () {
        if (mAnimation.clip) {
            currentClip = mAnimation.clip;
        } else {
            currentClip = mAnimation["Idle"].clip;
        }
    }
     
    void Update () {
        if (currentClip != null){
            AttackTrigger();
            Attacks();
        }
    }
}

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


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

[Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述


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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118063.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 怎样从数组中删除给定元素_java数组包含某个元素

    怎样从数组中删除给定元素_java数组包含某个元素packageday21;importjava.util.Scanner;//调用Scanner一个简单的文本扫描器importstaticnet.mindview.util.Print.*;importjava.util.Random;publicclassShow{publicstaticvoidmain(String[]args){int[]a={0,1,2,3};for(inti:a).

  • flask部署到nginx_flask部署404

    flask部署到nginx_flask部署404文章目录1.什么是uWSGI?2.uWSGI配置2.1启动一个HTTP服务器2.2并发和监控2.3启动uWSGIweb服务器2.4django中部署uWSGI2.5flask中部署uWSGI2.6web2py中部署uWSGI3.注意事项3.1虚拟环境3.2安全性和可用性4.参考文献1.什么是uWSGI?推荐这个博文uwsgi、wsgi和nginx的区别和关系一个…

  • Unity AssetBundle介绍

    Unity AssetBundle介绍1.什么是AssetBundle?AssetBundle是一种资源压缩包。资源打包AssetBundle有两个好处:减小安装包的大小,资源可以在进入游戏时候,网络下载。 热更资源,方便修复线上资源问题引起的Bug,或新增加游戏内容。AssetBundle分为两种类型:场景AssetBundle&非场景AssetBundle。2.AssetBundle结构2.1As…

  • JavaScript:三目运算符

    JavaScript:三目运算符HELLO大家好!三目运算符是一个非常简单且使用的运算符。是由两个运算符连接的三个操作数据或者表达式条件表达式?表达式1:表达式0当条件表达式为true则选择表达式1,反之false则选择表达式0举个栗子varage=15;console.log(age<18?’未成年’:’成年’);结果为:···本人写博客就是想记录一下自己所学的知识(目前正在学习中),巩固知识加深记忆,也顺便分享一下自己的所学,有什么地方写的不对,希望大家可以多多指出,让我及时改正。如果我分享的

  • 【机器学习】一文读懂正则化与LASSO回归,Ridge回归

    【机器学习】一文读懂正则化与LASSO回归,Ridge回归该文已经收录到专题机器学习进阶之路当中,欢迎大家关注。1.过拟合当样本特征很多,样本数相对较少时,模型容易陷入过拟合。为了缓解过拟合问题,有两种方法:方法一:减少特征数量(人工选择重要特征来保留,会丢弃部分信息)。方法二:正则化(减少特征参数的数量级)。2.正则化(Regularization)正则化是结构风险(损失函数+正则化项)最小化策略的体…

  • app放真机测试_什么软件可以验机安卓手机

    app放真机测试_什么软件可以验机安卓手机本方式测试环境为XCode3.2.3IOS4.0本方法只能把APP放到真机中测试,不能联机调试。 APP写好了之后,关闭XCode,记的要完全关闭哦。找到/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/里的SDKSettings.plist.先修改一下权限。右键GetInfo,不多…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号