Nikita Khustochka
Nikita Khustochka

Reputation: 3

How to make obstacle avoidance in a 2.5d Unity game?

I am making a 2.5d game in Unity. The ground on the Scene is made with a Rectangular Tilemap. The ground itself is on the same level in Z. There are elevations that are implemented using OrderInLayer and colliders. In fact, there are 3 levels of elevation on the scene (marked with numbers on the picture). Each level consists of zones with colliders (so that from the lower level you can not step on the upper level) and without colliders (for example, so that the player can pass behind the rocks). Transition between levels occurs when passing the ladder (L on the picture), on which there is a collider, so the orderInLayer and layer of the entity changes. In LayerCollisionMatrix everything is configured so that an entity does not interact with colliders on its own level, but interacts with colliders on other levels My LayerCollisionMask My Scene

I want to add enemies that will follow the player and avoid obstacles. How can I do this? By using NavMesh? With my own implementation of alogrithm or with some third party libraries? How do I implement this?

I tried using an embedded NavMesh with the NavMeshPlus add-on. I created three objects with a NavMeshSurface on each, configured included layers and baked them. It turned out that the NavMeshSurfaces intersect on the stairs. Automatically, the enemy would just get stuck on the stairs. The built-in NavMeshLink didn't help (I just couldn't set its width). So I wrote my own implementation of NavMeshLink. But it didn't really help, because the enemy still prefers to get stuck in the wall than to go through the stairs Enemy get stuck My NavMesh

My NavMeshLink:

public class ElevationEntry : MonoBehaviour
{
    [SerializeField] private int newOrderInLayer;
    [SerializeField] private int newLayer;
    [SerializeField] private GameObject endPos;
    private void OnTriggerEnter2D(Collider2D collision)
    {
        var stalkingMovement = collision.gameObject.GetComponent<StalkingMovement>();
        if(stalkingMovement != null) stalkingMovement.SetObjectToGoToPosition(endPos.transform.position);
        collision.gameObject.layer = newLayer;
        collision.gameObject.GetComponent<SpriteRenderer>().sortingOrder = newOrderInLayer;
    }
}
public void SetObjectToGoToPosition(Vector2 pos)
    {
        _navMeshAgent.enabled = false;
        isMovingByAI = false;
        moveToPos = pos;
    }
private void MoveToPosition(Vector2 position)
    {
        var pos = Vector2.MoveTowards(transform.position, position, speed * Time.fixedDeltaTime);
        _rigidbody2D.MovePosition(pos);
        if(Vector2.Distance(transform.position, position) < 0.01)
        {
            _navMeshAgent.enabled = true;
            isMovingByAI = true;
        }
    }

I tried using the A* Pathfinding Project. I created 3 grid graphs and customized them by layers. The enemy didn't want to just move between the graphs. The built-in Link and Link2 didn't help. I did not write my own implementation of Link, but I think that the situation will be similar to NavMesh

Upvotes: 0

Views: 57

Answers (1)

Blue Horizon
Blue Horizon

Reputation: 1

I am not an expert, but maybe you can use navmesh, and make a variable called target that enemy follows, when player goes to another level, the enemy's target becomes the closest stair to their location, and when they have reached it and gone to the player level, their target can be rechanged to player? Since you have multiple levels, you might need to track which level player is on and which level enemy is on.

Upvotes: 0

Related Questions