Unity - A计划(永久有效期) 扫二维码继续学习 二维码时效为半小时

(197评价)
价格: 4431.00元
stealth秘密行动机器人巡逻位置和动画匹配问题
不知道叫啥发起了问答2018-04-01
1
回复
606
浏览

SIKI老师你好,我在设置机器人巡逻的时候,如果加入了不让导航系统控制位置和旋转的代码

navAgent.updateRotation = false;
navAgent.updatePosition = false;

机器人走路与动画匹配但无法到目的地,只能走一半;如果不加入这个代码,可以到目的地但走路与动画不匹配。

 

我也在群里面问了,有小伙伴给了如下代码让我添加在update里面:

navAgent.nextPosition = transform.position;

但是运行起来勉强与动画匹配,却非常容易卡墙角,这又是什么原理呢?

谢谢老师。blush

下面是EnemyAnimation的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyAniamation : MonoBehaviour {

    private NavMeshAgent navAgent;
    private Animator anim;

    public float speedDampTime = 0.3f;
    public float angleSpeedDampTime = 0.3f;

    private Enemy sight;
    // Use this for initialization
    void Start()
    {
        navAgent = GetComponent<NavMeshAgent>();
        anim = GetComponent<Animator>();
        sight=GetComponent<Enemy>();
    }

    // Update is called once per frame
    void Update()
    {
        if (navAgent.desiredVelocity == Vector3.zero)
        {
            anim.SetFloat("Speed", 0, speedDampTime, Time.deltaTime);
            anim.SetFloat("AngleSpeed", 0, angleSpeedDampTime, Time.deltaTime);
        }
        else
        {
            float angle = Vector3.Angle(transform.forward, navAgent.desiredVelocity);
            float angleRad = 0f;
            if (angle > 90)
            {
                anim.SetFloat("Speed", 0, speedDampTime, Time.deltaTime);
            }
            else
            {
                Vector3 projection = Vector3.Project(navAgent.desiredVelocity,transform.forward);
                anim.SetFloat("Speed", projection.magnitude, speedDampTime, Time.deltaTime);
                
            }
            angleRad = angle * Mathf.Deg2Rad;
            Vector3 crossRes = Vector3.Cross(transform.forward, navAgent.desiredVelocity);
            if (crossRes.y < 0)
            {
                angleRad = -angleRad;
            }
            anim.SetFloat("AngleSpeed", angleRad, angleSpeedDampTime, Time.deltaTime);
            
        }
        anim.SetBool("PlayerInSight", sight.playerInSight);
    }
    
}

下面是EnemyMoveAI的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyMove : MonoBehaviour {

    public Transform[] wayPoint;
    private int index = 0;

    private float patrolTime = 3f;
    private float patrolTimer = 0;
    private float chaseTime = 3f;
    private float chaseTimer = 0;

    private NavMeshAgent navAgent;
    private Animator anim;

    private Enemy sight;
    private PlayerHealth health;
    // Use this for initialization
    void Start()
    {
        navAgent = GetComponent<NavMeshAgent>();
        navAgent.destination = wayPoint[index].position;
        navAgent.updatePosition = false;
        navAgent.updateRotation = false;
        anim=GetComponent<Animator>();
        sight=GetComponent<Enemy>();
        health=GameObject.FindGameObjectWithTag(Tags.player).GetComponent<PlayerHealth>();
    }

    // Update is called once per frame
    void Update()
    {
        //navAgent.nextPosition = transform.position;
        if (sight.playerInSight&&health.hp>0)
        {
            Shooting();
        }
        else if (sight.alermPosition!=Vector3.zero&&health.hp>0)
        {
            //追捕
            
            //navAgent.destination =sight.alermPosition;
            Chasing();
        }
        else
        {
            Patrolling();
           
        }
        
    }
    private void Patrolling()
    {
        navAgent.isStopped = false;
        navAgent.destination = wayPoint[index].position;
        navAgent.speed = 3f;
        navAgent.updateRotation = false;
        navAgent.updatePosition = false;
        if (navAgent.remainingDistance < 0.5f)
        {
            patrolTimer += Time.deltaTime;
            if (patrolTimer > patrolTime)
            {
                
                index++;
                index %= 4;
                navAgent.destination = wayPoint[index].position;
                navAgent.updateRotation = false;
                navAgent.updatePosition = false;
                patrolTimer = 0;
            }
        }
    }
    public void Chasing()
    {
        navAgent.isStopped = false;
        navAgent.destination = sight.alermPosition;
        navAgent.speed = 6f;
        //navAgent.updateRotation = false;
        //navAgent.updatePosition = false;
        if (navAgent.remainingDistance < 2f)
        {
           
            chaseTimer += Time.deltaTime;
            if (chaseTimer > chaseTime)
            {
                sight.alermPosition = Vector3.zero;
                GameController._instance.LastPosition = Vector3.zero;
                GameController._instance.alermOn = false;
                chaseTimer = 0;
            }
        }
        
    }
    private void Shooting()
    {
        navAgent.isStopped = true;
    }
}

所有回复
  • siki 2018-04-01

    首先是在使用导航系统在控制移动的时候,navAgent.nextPosition = transform.position; 

    这个是必须要加的(版本变更),而且是要每帧执行的

    如果容易卡墙角的话,先找到原因是不是转弯过慢还是其他动画导致的

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
发表回复
你还没有登录,请先 登录或 注册!