1
votes

I'm confronted with a problem with the implementation of enemies. Firstly, I'm following this tutorial. I have a gameobject for enemy with box collider and basically all I need.

Here is my script :

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

[SerializeField]
private float rotationSpeed = 180; // In degrees per second

[SerializeField]
private float movementSpeed = 1f; // In units per second

[SerializeField]
private float meshRadius = 1f; // In units

private IEnumerator turnTowardsPlayerCoroutine;
private IEnumerator moveTowardsPlayerCoroutine;

void OnTriggerEnter(Collider collider)
{
    if (collider.gameObject.tag == "Player")
    {
        float playerDistance = Vector3.Distance(collider.transform.position, transform.position);

        // Ignore trigger events from the inner colliders
        if (playerDistance >= 2f * meshRadius)
        {
            turnTowardsPlayerCoroutine = TurnTowardsPlayer(collider.transform);
            moveTowardsPlayerCoroutine = MoveTowardsPlayer(collider.transform);
            StartCoroutine(turnTowardsPlayerCoroutine);
            StartCoroutine(moveTowardsPlayerCoroutine);
        }
    }
}

void OnTriggerExit(Collider collider)
{
    if (collider.tag == "Player")
    {
        float playerDistance = Vector3.Distance(collider.transform.position, transform.position);

        // Ignore trigger events from the inner colliders
        if (playerDistance >= 2f * meshRadius)
        {
            StopCoroutine(turnTowardsPlayerCoroutine);
            StopCoroutine(moveTowardsPlayerCoroutine);
        }
    }
}

private IEnumerator TurnTowardsPlayer(Transform player)
{
    while (true)
    {
        Quaternion targetRotation = Quaternion.LookRotation(player.position - transform.position, Vector3.up);
        targetRotation.x = 0f;
        targetRotation.z = 0f;

        transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
        yield return 0;
    }
}

private IEnumerator MoveTowardsPlayer(Transform player)
{
    while (true)
    {
        Vector3 playerDirection = transform.position - player.position;
        playerDirection.y = 0;
        playerDirection = playerDirection.normalized;

        Vector3 deltaMovement = playerDirection * movementSpeed * Time.deltaTime;

        int layermask = LayerMask.GetMask("Environment");
        Vector3 movingTowards = transform.position - playerDirection*meshRadius + (new Vector3(0f, 0.1f, 0f));
        if (Physics.Raycast(movingTowards, Vector3.down, 0.25f, layermask))
        {
            transform.position -= deltaMovement;
        }

        yield return 0;
    }
}
}

The result is, when I enter in the zone where enemy must attack me, the enemy rotated towards me, but he didn't move. Did I forget something or did something go wrong?

2
Have you tried to debug this code? Is coroutine running? Is Physics.Raycast successful? - Adrian Krupa
After debug, the coroutine is running but the Physics.Raycast isn't successful ... - PokeRwOw
What is the purpose of this Raycast? - Adrian Krupa
This raycast tells us if the enemy is about to walk off the edge of a platform. If the raycast hits something, that means we won't walk off the edge, so it's okay to continue moving. But if my player enter in the area where enemy must follow him, the coroutine is called 2 times... - PokeRwOw
I think that recast is too short. It checks only 0.25f which may be too low. - Adrian Krupa

2 Answers

1
votes

I have been through that tutorial a couple times, and the script is correct as it is. What appears to be missing is the layer. Be sure the "Environment" layer exists and is assigned it to the environment objects.

The easiest way to add the "Environment" layer to the necessary objects would be to select each of the objects in the hierarchy that should be in the "Environment" layer and then changing the layer in the inspector.

0
votes

Well if Physics raycast is unsuccessful that can mean just one of the following things:

-layermask settings are wrong (it ignores specifically layered objects and it doesn't hit anything)

-You are sending it in wrong direction

-Shooting distance is too small, the thing is that in the tutorial you are watching it might work with that value, but you probably have differently scaled your level. Try putting it to something much larger (100, 1000).