【问题标题】:Using Unity: Scripting Enemy AI - Follow Player使用 Unity:编写 Enemy AI 脚本 - 跟随玩家
【发布时间】:2020-03-20 04:54:46
【问题描述】:

我试图让我的敌人在范围内跟随我的玩家,否则敌人会在游荡。我对 C-Sharp 很陌生,所以一直在拼凑其他教程代码。

目前敌人在我设置的触发盒对撞机之间来回游荡。当玩家在范围内时敌人会切换状态为跟随,但是如果玩家在敌人的左侧,敌人只会向玩家移动,如果我在敌人的右侧,它会卡住直到我超出范围,然后继续漫游。跟随时敌人也不会翻转面对敌人。

任何帮助将不胜感激。

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

public enum EnemyState
   {
      Wander,   
      Follow,
      Die,
   };


public class EnemyController : MonoBehaviour
   {
     GameObject player;    
     public EnemyState currState = EnemyState.Wander; 
     public Transform target;
     Rigidbody2D myRigidbody;

     public float range = 2f;    
     public float moveSpeed = 2f;



void Start()
{
    player = GameObject.FindGameObjectWithTag("Player");
    myRigidbody = GetComponent<Rigidbody2D>();
    target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}

void Update()
{

    switch (currState)
    {
        case (EnemyState.Wander):
            Wander();
            break;
        case (EnemyState.Follow):
            Follow();
            break;
        case (EnemyState.Die):
           // Die();
            break;
    }    

    if(IsPlayerInRange(range) && currState != EnemyState.Die)
    {
        currState = EnemyState.Follow;
    }
    else if(!IsPlayerInRange(range)&& currState != EnemyState.Die)
    {
        currState = EnemyState.Wander;
    }
}

private bool IsPlayerInRange(float range)
{
    return Vector3.Distance(transform.position, player.transform.position) <= range;
}

bool isFacingRight()
{
    return transform.localScale.x > 0;
}

void Wander()
{
    {
        if (isFacingRight())
        {
            myRigidbody.velocity = new Vector2(moveSpeed, 0f);
        }
        else
        {
            myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
        }
    }

}

void OnTriggerExit2D(Collider2D collision) //this is to flip the sprite when it reaches the end of its path - a box 2d collider trigger
{
    transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), 1f);

}

void Follow()
{
    if (isFacingRight())
    {
        myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
        transform.position = Vector2.MoveTowards(transform.position, new Vector2(target.position.x, transform.position.y), moveSpeed * Time.deltaTime);

    }
   /* else //this seems to have no effect on the code
    {
        myRigidbody.velocity = new Vector2(moveSpeed, 0f);
        transform.position = Vector2.MoveTowards(transform.position, new Vector2(target.position.x, transform.position.y), -moveSpeed * Time.deltaTime);
    }*/

}

}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    好的,我发现了自己的问题,这是工作脚本:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public enum EnemyState
    {
      Wander,
      Follow,
      Die,
    };
    
    public class EnemyController : MonoBehaviour
    {
      GameObject player;
      public EnemyState currState = EnemyState.Wander;
    
      public Transform target;
    
      Rigidbody2D myRigidbody;
    
      public float range = 2f;
      public float moveSpeed = 2f;
    
    
    
    
    
    
    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        myRigidbody = GetComponent<Rigidbody2D>();
        target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
    
    
    
    }
    
    // Update is called once per frame
    void Update()
    {
    
        switch (currState)
        {
            case (EnemyState.Wander):
                Wander();
                break;
            case (EnemyState.Follow):
                Follow();
                break;
            case (EnemyState.Die):
               // Die();
                break;
        }    
    
        if(IsPlayerInRange(range) && currState != EnemyState.Die)
        {
            currState = EnemyState.Follow;
        }
        else if(!IsPlayerInRange(range)&& currState != EnemyState.Die)
        {
            currState = EnemyState.Wander;
        }
    }
    
    private bool IsPlayerInRange(float range)
    {
        return Vector3.Distance(transform.position, player.transform.position) <= range;
    }
    
    bool isFacingRight()
    {
        return transform.localScale.x > 0;
    }
    
    void Wander()
    {
        {
            if (isFacingRight())
            {
                myRigidbody.velocity = new Vector2(moveSpeed, 0f);
            }
            else
            {
                myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
            }
        }
    
    
    }
    
    void OnTriggerExit2D(Collider2D collision)
    {
        transform.localScale = new Vector2(-(Mathf.Sign(myRigidbody.velocity.x)), 1f);
    
    }
    
    
    void Follow()
    {
    
        if (transform.position.x > target.position.x)
        {
            //target is left
            transform.localScale = new Vector2(-1, 1);
            myRigidbody.velocity = new Vector2(-moveSpeed, 0f);
            transform.position = Vector2.MoveTowards(transform.position, new Vector2(target.position.x, transform.position.y), moveSpeed * Time.deltaTime);
        }
        else if (transform.position.x < target.position.x)
        {
            //target is right
            transform.localScale = new Vector2(1, 1);
            myRigidbody.velocity = new Vector2(moveSpeed, 0f);
            transform.position = Vector2.MoveTowards(transform.position, new Vector2(target.position.x, transform.position.y), moveSpeed * Time.deltaTime);
        }
    
    }
    

    }

    【讨论】:

    • 好的,所以这被拒绝了......它按照我在 Unity 中需要的方式工作。但是,我对编码完全是个菜鸟,并且正在自学。 7 个月前我什至不知道 C-Sharp 是什么。我可以从中学习的有用的 cmets 将不胜感激。如果我的不知识在这里犯了一些礼仪错误,我很抱歉。希望 Stack Overflow 也能成为我学习的地方!无论如何,感谢您的帮助...
    • 刚刚遇到这个问题,代码有效——在我看来,这才是最重要的 :) 干得好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多