首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >(统一C#) NPC不在草丛和其他地形上移动

(统一C#) NPC不在草丛和其他地形上移动
EN

Stack Overflow用户
提问于 2020-03-12 09:33:40
回答 1查看 1.1K关注 0票数 2

我已经创建了一个全国人民代表大会,它跟随着主要参与者。当玩家在NPC的某一范围内时,NPC应该根据玩家和NPC之间的距离进行步行、奔跑和攻击。NPC有一个动画,盒对撞机,Nav网格代理,敌人动画和敌人控制器脚本附加。设置为下面是

我的问题是,如果在地形上有某种草或蕨类植物,NPC就不会追逐玩家。

NPC被设置为使用Nav网格剂运行所有类型的地形,而且烘焙设置与图像中的地形相似。有关这个问题的视频可以在这里上看到。

敌方控制员的代码(尽管我怀疑这是问题所在)如下:

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public enum EnemyState
{
    PATROL,
    CHASE,
    ATTACK
}

public class EnemyController : MonoBehaviour
{

    private EnemyAnimator enemy_Anim;
    private NavMeshAgent navAgent;

    private EnemyState enemy_State;

    public float walk_Speed = 0.5f;
    public float run_Speed = 4f;

    public float chase_Distance = 7f;
    private float current_Chase_Distance;
    public float attack_Distance = 1.8f;
    public float chase_After_Attack_Distance = 2f;

    public float patrol_Radius_Min = 20f, patrol_Radius_Max = 60f;
    public float patrol_For_This_Time = 15f;
    private float patrol_Timer;

    public float wait_Before_Attack = 2f;
    private float attack_Timer;

    private Transform target;

   public GameObject attack_Point;

    //private EnemyAudio enemy_Audio;

    void Awake()
    {
        enemy_Anim = GetComponent<EnemyAnimator>();
        navAgent = GetComponent<NavMeshAgent>();

        target = GameObject.FindWithTag(Tags.PLAYER_TAG).transform;

      //  enemy_Audio = GetComponentInChildren<EnemyAudio>();

    }

    // Use this for initialization
    void Start()
    {

        enemy_State = EnemyState.PATROL;

        patrol_Timer = patrol_For_This_Time;

        // when the enemy first gets to the player
        // attack right away
        attack_Timer = wait_Before_Attack;

        // memorize the value of chase distance
        // so that we can put it back
        current_Chase_Distance = chase_Distance;

    }

    // Update is called once per frame
    void Update()
    {

        if (enemy_State == EnemyState.PATROL)
        {
            Patrol();
        }

        if (enemy_State == EnemyState.CHASE)
        {
            Chase();
        }

        if (enemy_State == EnemyState.ATTACK)
        {
            Attack();
        }

    }

    void Patrol()
    {

        // tell nav agent that he can move
        navAgent.isStopped = false;
        navAgent.speed = walk_Speed;

        // add to the patrol timer
        patrol_Timer += Time.deltaTime;

        if (patrol_Timer > patrol_For_This_Time)
        {

            SetNewRandomDestination();

            patrol_Timer = 0f;

        }

        if (navAgent.velocity.sqrMagnitude > 0)
        {

            enemy_Anim.Walk(true);

        }
        else
        {

            enemy_Anim.Walk(false);

        }

        // test the distance between the player and the enemy
        if (Vector3.Distance(transform.position, target.position) <= chase_Distance)
        {

            enemy_Anim.Walk(false);

            enemy_State = EnemyState.CHASE;

            // play spotted audio
         //   enemy_Audio.Play_ScreamSound();

        }


    } // patrol

    void Chase()
    {

        // enable the agent to move again
        navAgent.isStopped = false;
        navAgent.speed = run_Speed;

        // set the player's position as the destination
        // because we are chasing(running towards) the player
        navAgent.SetDestination(target.position);

        if (navAgent.velocity.sqrMagnitude > 0)
        {

            enemy_Anim.Run(true);

        }
        else
        {

            enemy_Anim.Run(false);

        }

        // if the distance between enemy and player is less than attack distance
        if (Vector3.Distance(transform.position, target.position) <= attack_Distance)
        {

            // stop the animations
            enemy_Anim.Run(false);
            enemy_Anim.Walk(false);
            enemy_State = EnemyState.ATTACK;

            // reset the chase distance to previous
            if (chase_Distance != current_Chase_Distance)
            {
                chase_Distance = current_Chase_Distance;
            }

        }
        else if (Vector3.Distance(transform.position, target.position) > chase_Distance)
        {
            // player run away from enemy

            // stop running
            enemy_Anim.Run(false);

            enemy_State = EnemyState.PATROL;

            // reset the patrol timer so that the function
            // can calculate the new patrol destination right away
            patrol_Timer = patrol_For_This_Time;

            // reset the chase distance to previous
            if (chase_Distance != current_Chase_Distance)
            {
                chase_Distance = current_Chase_Distance;
            }


        } // else

    } // chase

    void Attack()
    {

        navAgent.velocity = Vector3.zero;
        navAgent.isStopped = true;

        attack_Timer += Time.deltaTime;

        if (attack_Timer > wait_Before_Attack)
        {

            enemy_Anim.Attack();

            attack_Timer = 0f;

            // play attack sound
        //    enemy_Audio.Play_AttackSound();

        }

        if (Vector3.Distance(transform.position, target.position) > attack_Distance + chase_After_Attack_Distance)
        {

            enemy_State = EnemyState.CHASE;

        }


    } // attack

    void SetNewRandomDestination()
    {

        float rand_Radius = Random.Range(patrol_Radius_Min, patrol_Radius_Max);

        Vector3 randDir = Random.insideUnitSphere * rand_Radius;
        randDir += transform.position;

        NavMeshHit navHit;

        NavMesh.SamplePosition(randDir, out navHit, rand_Radius, -1);

        navAgent.SetDestination(navHit.position);

    }

    void Turn_On_AttackPoint()
    {
        attack_Point.SetActive(true);
    }

    void Turn_Off_AttackPoint()
    {
        if (attack_Point.activeInHierarchy)
        {
            attack_Point.SetActive(false);
        }
    }

    public EnemyState Enemy_State
    {
        get; set;
    }

} // class

如果有人能帮忙解决这个问题,我会非常感激的!

编辑:我忘了添加草设置,如下所示。正如你所看到的,没有对撞机。

我正在挖掘更多,显然唯一可步行的区域如下(不是整个地图)

我该怎么调整呢?

EN

回答 1

Stack Overflow用户

发布于 2021-03-22 15:14:15

以下是我所做的事:

  1. 用我所需要的各种草和树木来描绘地形。
  2. 把所有画好的草和树都撤下来。
  3. 将导航网格(Navmesh)烘焙到地形上。
  4. 把所有画好的草和树都重做一遍。
  5. 轰隆隆!工作完成了。:)

为什么草不能行走?

  • 草被漆成树,因此在烘焙过程中被雕刻成树。

技巧:,你必须画草和所有需要的树,然后你必须取消所有的草为树特殊的油漆。在此之后,烘焙地形,并取消过程(按CTRL + Z几次),直到你看到草重新油漆。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60651145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档