【Unity3D】3D模型的自动寻路与Animation连击

在《【Unity3D】3D模型的使用——FBX的使用与Animation设置》(点击打开链接)曾经说明了,在Unity3D中使用3D模型,本文将进一步地说明如何用这个3D模型配合《【Unity3D】自动寻路》(点击打开链接)做出游戏主角的移动效果,同时进一步地实现连击。

本文使用的是:http://download.csdn.net/detail/yongh701/9867149中一个英雄模型。

将制作出如下的效果:


点击左键可以自由行走,行走的时候,不会碰到障碍物,然后点击右键可以进行连击,最多可以达到三连击。

制作过程如下:

一、场景布置

1、导入了英雄模型之后,可以看到fighter char采用传统的Animation而并非新型的Animator来实现英雄的动画,我们需要对Animation的一些基本属性进行设置,比如Animation设置为Stand,也就是默认是播放Stand这个动画,之后Size设置为5,输入按回车之后,用Stand、run、punch1~3分别填充Element0~5,意思英雄包含这5个动作。


2、之后场景布置如下:


3、与《【Unity3D】自动寻路》(点击打开链接)同理,保存当前的场景为Hero,对于Cube、Plane这些障碍体设置Navigation Static,然后点击烘培Bake,让Unity3D完成自动寻路的计算。


之后对主角fighter char添加一个Nav Mesh Agent组件,同时设置其半径radius为2,高度Height为8,主要看到绿色的导航圆柱体,能够完全覆盖主角,避免出现穿墙、入墙等现象。


二、脚本编写

对于英雄赋予如下的脚本Hero.cs:

using UnityEngine;
using System.Collections;

public class Hero : MonoBehaviour
{

    public GameObject plane;//地板
    private NavMeshAgent navMeshAgent;//自动寻路,必须要的导航体
    private int attack_combo;//连击数
    private bool is_Move, is_Attack;//是否在移动、攻击的flag

    void Start()//初始化是一个站着的状态
    {
        navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent  
        attack_combo = 0;//连击数为0
        is_Move = false;//不在移动
        is_Attack = false;//不在攻击
    }

    void Update()
    {

        if (is_Move && navMeshAgent.remainingDistance < 0.01)//如果在移动中,而且离终点的距离不多于0.01
        {
            is_Move = false;//则设置为不移动状态
        }

        if (Input.GetMouseButtonDown(0))//鼠标左键点下    
        {
            animation.Play("run");//开始你的移动
            Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);//住摄像机向鼠标位置发射射线   
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))//射线检验   
            {
                if (mHit.collider.gameObject == plane)
                {
                    navMeshAgent.SetDestination(mHit.point);//mHit.point就是射线和plane的相交点,实为碰撞点   
                    is_Move = true;//设置为移动状态
                }
            }
        }

        if (Input.GetMouseButtonDown(1))//鼠标右键点下  
        {
            navMeshAgent.Stop();//停止移动
            is_Move = false;
            if (attack_combo < 3)//如果连击数没到达上限,则开始连击
            {
                attack_combo++;
            }
            animation.Play("punch" + attack_combo);//进行相应阶段的连击
        }

        /*判断是否正处于攻击状态中,主要是判断是否将连击动画播放完毕*/
        bool is_Attack = false;
        string[] attack_animation_name = { "punch1", "punch2", "punch3" };
        for (int i = 0; i < attack_animation_name.Length; i++)
        {
            if (animation.IsPlaying(attack_animation_name[i]))
            {
                is_Attack = true;
                break;
            }
        }
        //如果是则不用进行任何操作,让它继续将连击动画播放完毕,如果不是,也就是连击动画播放完毕。
        if (!is_Attack)
        {
            attack_combo = 0;//连击数清0
        }

        if (!is_Attack && !is_Move)
        {//如果现在不是在攻击或者移动,则播放站立动画
            animation.Play("Stand");
        }

    }

}
并且指明这里的public GameObject plane就是Plane,则大功告成:

这个程序的关键主要就是这个脚本,主要难点和重点就是:一个,解决自动寻路的状态判定问题,另一个,连击实现的问题。

1、解决自动寻路的状态,虽然判断对象是否到达终点很简单if (navMeshAgent.remainingDistance < 0.01){}甚至if (navMeshAgent.hasPath){}都行,但这个判断并执行,一定要放在鼠标点下左键,让主角寻路之前,反正update()里面的代码是不停被执行的。放在之后有个很严重的问题,在你鼠标点击左键之后,系统会认为主角已经开始跑,但是要跑的路径还未来得及生成,就开始判断是否还有路径没跑完,判断是否离终点有剩余距离,就认为由于路径没生成,就没有寻路路径和离终点没有距离了。所以这个判断一定要放在开始自动寻路之前,否则会直接播放Stand动画,出现主角站着飘B到重点的行为。

2、连击问题,我认为应该这样:用户点击右键,只需要增加连击数,之后再根据连击数播放动画就好,无须像其它人,在点击右键之后的处理动作写一大堆东西。之后,对于连击数的清零,主要还是需要判断 主角的攻击动作是否完成。判断是否处于攻击状态,只能判断它是否处于播放攻击状态了。

这里设置private bool is_Move, is_Attack;//是否在移动、攻击的flag,其主要的意图在最后,if (!is_Attack && !is_Move) //如果现在不是在攻击或者移动,则播放站立动画。如果没有这句,主角完成一系列的动画,不会自动的回复到初始的Stand动画里面的。

这里是Animation连击,也就是指明如何对Unity3D中带有传统动画系统的FBX模型实现连接,所以不能像采用新型动画系统Animator的FBX模型,用AnimatorStateInfo animatorInfo;在配合animatorInfo.normalizedTime > 某百分比,来实现动画是否完成的判断,只能用传统的IsPlaying来搞了。

我认为网上盛传的Animator已经取代Animation完全是扯谈,个人在网上转来一圈,发现收集到的3D模型素材都还是用Animation的。当然如果你是新做的模型,当然要求美工使用Animator,毕竟Animator的方法与类更多,可以更好进行控制。

万万没想到这不足70行代码,居然弄了我一天了,之前玩kof玩combo玩得high翻天,万万没想到实现起来的逻辑居然这么难理解!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值