NPC enemy teleporting to player

So as you might know from other threads I’ve posted on the forum, I’m working on an FPS game, and am having difficulties. I want the NPC enemies to walk towards the player when the player is in between two CheckSpheres. The problem is that the NPCs teleport to the player. I don’t know exactly how to fix this, so I’m asking for some help.

Here"s my kinda confusing code. Sorry:

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

public class Enemy : MonoBehaviour
{
    float health = 75f;
    float viewRange = 60f;
    float weaponRange = 35f;
    float turnSpeed = -75f;
    float moveSpeed = 10f;

    int weaponDamage = 10;
    float fireRate = 1f;
    float lastFiredAt = -999f;

    public bool seesPlayer;

    [SerializeField] Rigidbody lightEnemyRB;
    [SerializeField] Rigidbody playerRb;

    public LayerMask playerLayer;

    public Transform playerTransform;

    private void Start()
    {
        seesPlayer = false;   
    }

    void Update()
    {
        if (health <= 0)
        {
            Die();
        }

        LookForPlayer();
    }

    public void TakeDamage(float damageRecieved)
    {
        health -= damageRecieved;
    }

    void Die()
    {
        //play death animation, then get deleted from mammories
        Destroy(gameObject);
    }

    void LookForPlayer()
    {
        var step = turnSpeed * Time.deltaTime;
        if(Physics.CheckSphere(transform.position, viewRange, playerLayer))
        {
            if (Physics.CheckSphere(transform.position, weaponRange, playerLayer))
            {
                transform.rotation = Quaternion.RotateTowards(transform.rotation, playerTransform.rotation, step);
                //Use pathfinding to close distance between enemy and player to weaponRange
                RaycastHit hit;
                if (Time.time > lastFiredAt + fireRate && Physics.Raycast(transform.position, transform.forward, out hit, weaponRange))
                {
                    PlayerController player = hit.transform.GetComponent<PlayerController>();
                    if (player != null)
                    {
                        seesPlayer = true;
                        turnSpeed = -35f;
                        ShootAtPlayer();
                    }
                    else
                    {
                        seesPlayer = false;
                        turnSpeed = -75f;
                    }
                }
            }
            else
            {
                //Enemy is teleporting to player. Dn't have the energy to fix it Rn, but you WILL do it later (8/23/2020)
                lightEnemyRB.MovePosition(playerTransform.position - transform.position);
            }
        }
    }

    void ShootAtPlayer()
    {
        lastFiredAt = Time.time;
        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.forward, out hit, weaponRange) && seesPlayer)
        {
            PlayerController player = hit.transform.GetComponent<PlayerController>();
            if (player != null)
            {
                Debug.Log("Enemy Pew Pew!");
                player.TakeDamage(weaponDamage);
            }
        }
    }
}

P.S. it’s rigidbody-based, but you probably knew that just by looking at it

It might be line 81: I think you’re moving the entire delta distance to the player.

Instead, calculate a small offset towards the player and add it to the enemy position.

// delta of position from enemy to player (take player, subtract enemy)
var delta = playerTransform.position - lightEnemyRB.transform.position;

float speed = 10.0f; // enemy approach speed

// how much to move this frame, based on heading towards player
var step = delta.normalized * speed * Time.deltaTime;

// where enemy was
var pos = lightEnemyRB.transform.position;

// new pos
pos += step;

// assign back thru the RB MovePosition to let physics happen
lightEnemyRB.MovePosition(pos);
1 Like

Works great! Thanks!!

1 Like