首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么让敌人在弹药用完后拿起壁橱里的武器?

我怎么让敌人在弹药用完后拿起壁橱里的武器?
EN

Stack Overflow用户
提问于 2022-10-29 18:10:29
回答 1查看 29关注 0票数 0

我试图创造一个“聪明”的敌人,如果它没有弹药,并且如果它的所有武器都耗尽了弹药,那就换一个武器,找到最近的武器并更换武器。

到目前为止,我有一个敌人可以巡逻,在射程内找到玩家,追逐和攻击玩家。

以下是代码:

代码语言:javascript
复制
public class EnemyControler : MonoBehaviour
{

    [Header("Attack")]
    [SerializeField] float shootingDistance =10.0f;
    [SerializeField] float shootDelay = 3.5f;
    [Range(0,1.0f)][SerializeField] float shootingAccuracy =0.5f;
    [SerializeField] int shootDamage =5;
    [SerializeField] int ammo = 1;

    [Header("User Interface")]
    public Transform canvasTr;
    public Slider Healthbar;

    [Header("Health/Damage/Death")]
    public float MaxHealth;
    public float Damage;
    public float AttackRange;
    public int deathCounter;


    public Transform ammoObject;
    private NavMeshAgent navAgent;
    private Collider enemycollider;
    private Transform PlayerTr;
    private Animator EnemyAnim;


    float Health;
    bool showingHealthBar, alive;
    bool isPatrolling =false;
    bool isInShootingRange =false;
    bool canResumeIdleState =true;
    bool isPreparingToShoot=false;
    bool isDead =false;
    bool isAlerted =false;
    float shootTimer = Mathf.Infinity;
    AIPatrolBehavior aIPatrolBehavior = null;
    
    void Start()
    {
        Health = MaxHealth;
        canvasTr.gameObject.SetActive(false);
        navAgent = GetComponent<NavMeshAgent>();
        EnemyAnim = GetComponent<Animator>();
        enemycollider = GetComponent<Collider>();
        PlayerTr = GameObject.FindGameObjectWithTag("Player").transform;
        aIPatrolBehavior = GetComponent<AIPatrolBehavior>();
        alive = true;
        ammo = 100;
        StartCoroutine(Idle());
        // are you sure you want to randomly change MaxHealth after settting health = maxHealth?
        //the slider gets weirdly bugged
        //   MaxHealth = Random.Range(50, 200); 


        Healthbar.maxValue = MaxHealth; // set the max value to MaxHelth
    }

    private void Update() 
    {   
        if(isDead)return;

        if(Vector3.Distance(PlayerTr.transform.position, transform.position) > 20 && !isAlerted
        || PlayerTr.GetComponent<PlayerController>().HealthBar.value <= 0.0f){
            StopAllCoroutines();
            GetComponent<AIPatrolBehavior>().enabled =true;
            return;
        }
        if(Vector3.Distance(PlayerTr.transform.position, transform.position) < 20 && isAlerted) isAlerted=false;
        isInShootingRange = DistanceToPlayer() < shootingDistance &&
         DistanceToPlayer() > AttackRange - 0.5f && 
         PlayerTr.GetComponent<PlayerController>().HealthBar.value > 0;




        if(isInShootingRange)
        {
            if(canResumeIdleState){
                StopAllCoroutines();
                canResumeIdleState=false;
            }
            ProcessShooting();
        }  else{

            if(!canResumeIdleState){
                isPreparingToShoot =false;
                StartCoroutine(Idle());
                canResumeIdleState =true;
                navAgent.enabled =true;
            }
        }
    }

    private void ProcessShooting()
    {
        if(!isPreparingToShoot) shootTimer +=Time.deltaTime;
        navAgent.enabled =false;
        transform.LookAt(PlayerTr);
        float randomProbability =Random.Range(0,1.0f);
        if(shootTimer > shootDelay){
            ShootAtPlayer();
        }
        EnemyAnim.SetFloat("MovmentSpeed", 0, 0.3f, Time.deltaTime);
    }

    private void ShootAtPlayer(){
        if(isPreparingToShoot)return;
        EnemyAnim.SetBool("PrepareAttack", false);
        shootTimer =0.0f;
        isPreparingToShoot = true;
        EnemyAnim.SetTrigger("shoot");
    }

    public void ShootPlayerAnimationEvent(){
        Debug.Log("Player got shot");
        float randomAccuracy = Random.Range(0, 1.0f);
        bool willHitTarget = randomAccuracy > 1.0f - shootingAccuracy;
        if(willHitTarget && DistanceToPlayer() < shootingDistance){
            PlayerTr.GetComponent<PlayerController>().DoDamage(shootDamage,true);
        }
        GetComponentInChildren<AIWeapon>().UseWeapon();
        isPreparingToShoot =false;
    }

    IEnumerator Idle()
    {        
        EnemyAnim.SetBool("PrepareAttack", false);

        yield return new WaitUntil(() => Vector3.Distance(PlayerTr.transform.position, transform.position) < 20 || isAlerted);
        StartCoroutine(RunToTarget());
    }
    IEnumerator RunToTarget()
    {
        aIPatrolBehavior.enabled =false;

        if(navAgent.isOnNavMesh) { // save from error apperng
            navAgent.isStopped = false;
        }

        EnemyAnim.SetTrigger("Attack");
        while (Vector3.Distance(PlayerTr.transform.position, transform.position) > AttackRange - 0.5f)
        {
            if(navAgent.isOnNavMesh) { // save from error apperng
                navAgent.SetDestination(PlayerTr.position);
            }
            
        //    navAgent.SetDestination(PlayerTr.position);
            EnemyAnim.SetFloat("MovmentSpeed", 1, 0.3f, Time.deltaTime);
            yield return null;
        }
        StartCoroutine(Attack());
    }
    IEnumerator Attack()
    {
        EnemyAnim.SetBool("PrepareAttack", true);
        navAgent.isStopped = true;
        while (Vector3.Distance(PlayerTr.position, transform.position) < AttackRange)
        {
            EnemyAnim.SetTrigger("Attack");
            float t = 0.5f;
            while (t > 0)
            {
                Vector3 rotation = Vector3.RotateTowards(transform.forward, PlayerTr.position - transform.position, 5f * Time.deltaTime, 1f);
                transform.forward = rotation;
                t -= Time.deltaTime;
                yield return null;
            }
            yield return null;
        }
        EnemyAnim.SetBool("PrepareAttack", false);
        StartCoroutine(RunToTarget());
    }

   


    float DistanceToPlayer(){
        return Vector3.Distance(transform.position,PlayerTr.position);
    }

    public void DoDamage(float damage)
    {
        Alert();
        if (!showingHealthBar)
        {
            showingHealthBar = true;
            StartCoroutine(ShowHealthBar());
        }
        Health -= damage;
        Debug.Log("Health: " + Health + " of: " + MaxHealth);
        Healthbar.value = Health;
        if (Health <= 0)
        {
            StopAllCoroutines();
            if(navAgent.isOnNavMesh) { // save from error apperng
                navAgent.isStopped = true;
            }
            if (alive)
            {
                alive = true; // does this make sense?
                StartCoroutine(Death());
            }
        }
    }

我曾尝试通过谷歌搜索,以找到任何教程,但没有成功。有人有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-29 19:53:00

如果在地图上放置的武器是固定的,你可以让敌人停止巡逻或追逐玩家,当他的弹药== 0被布尔值控制时,你可以使用MoveTowrds()武器。你可以用某种方法来计算敌人的位置和阵列上所有武器之间的距离,然后它向最近的方向飞去。你将使用一系列的向量来存储武器的位置。现在轮到你试试了。

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

https://stackoverflow.com/questions/74247677

复制
相关文章

相似问题

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