简体   繁体   中英

Have an enemy follow the player in Unity3D

I made a script to have an enemy to follow the player, after the player collided with the ground.

I'm facing a problem that is that the enemy walks to the start point and not to the player.

it would be cool if someone could help me with that :)

Transform tr_Player;
float f_RotSpeed = 3.0f, f_MoveSpeed = 3.0f;

public int gegnerLeben;
Rigidbody m_Rigidbody2;
Vector3 m_YAxis2;

public int leben;
public GameObject Player;
public GameObject verfolgen;
public GameObject MinenGener;

void Start()
{

    tr_Player = Player.transform;

    m_Rigidbody2 = GetComponent<Rigidbody>();
    m_YAxis2 = new Vector3(0, 5, 0);

}


public void GegnerFreez()
{
    m_Rigidbody2.constraints = RigidbodyConstraints.FreezePosition;
}

void Update()
{
    if (Player.GetComponent<SpielerScript>().MineBetreten == true)
    {
        MinenGener.transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(tr_Player.position - transform.position), f_RotSpeed * Time.deltaTime);
        MinenGener.transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
    }


    if (gegnerLeben < 1)
    {
        Destroy(Player.GetComponent<SpielerScript>().MinenGegner);
    }
}

A few points here:

Don't use GetComponent in Update over and over again.

Rather make your field of type

public SpielerScript Player;

and drag the player in via the Inspector. This does two things

  • Check if the object even has a SpielerScript attached and only allow drop then
  • Already stores the reference to SpielerScript so no need of using GetComponent

Also the m_Rigidbody2 could already be referenced via the Inspector by making it

[SerializeField] Rigidbody m_Rigidbody2;

Then Quaternion.Slerp is a linear interpolation between rotations on a given factor between 0 and 1 . It makes no sense to use a factor multiplied by Time.deltaTime here since what you get will be something like 3 * 0.017 (for 60 f/s) which results in an interpolation factor of around 0.051 so very close to 0 so your enemy simply changes its rotation extremely slow!

Rather use a fix value like eg 0.5 in order to every frame set it to the middle between the two rotations or 0.25 in order to make it slower.

After a bit cleaning and refactoring your code could look like eg

[Header("References")]
[SerializeField] private PlayerScript Player;
[SerializeField] private Rigidbody m_Rigidbody2;
[SerializeField] private Transform MinenGener;

public GameObject verfolgen;

[Header("Settings")]
[SerializeField] [Range(0,1)] private float f_RotFactor = 0.5f
[SerializeField] private float f_MoveSpeed = 3.0f;

[Header("Runtime Values")]
public int leben;
public int gegnerLeben;

private Transform tr_Player;
private Vector3 m_YAxis2 = new Vector3(0, 5, 0);

private void Start()
{
    tr_Player = Player.transform;

    // only do as fallback if not referenced via the Inspector to save resources
    if(!m_Rigidbody2) m_Rigidbody2 = GetComponent<Rigidbody>();
}

public void GegnerFreez()
{
    m_Rigidbody2.constraints = RigidbodyConstraints.FreezePosition;
}

void Update()
{
    if (Player.MineBetreten)
    {
        MinenGener.transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(tr_Player.position - transform.position), f_RotFactor);
        MinenGener.transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
    }

    if (gegnerLeben < 1)
    {
        Destroy(Player.MinenGegner);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM