Unity - 2D Navmesh Pathfinding

April 28, 2018 in #Coding #Unity | | | Share on Google+

Berdasarkan dari hasil baca-baca, fitur Navmesh dalam Unity secara default belum bisa digunakan untuk 2D. Berdasarkan pemahaman saya, itu karena proses baking bergantung pada luas objek pada sumbu Z (yang diabaikan di game 2D), serta harus menghadap ke atas ( Vector3.up ). Namun dengan sedikit trik, ada beberapa cara untuk membuatnya.



Cara 1 : Menggunakan Navmesh Surface

Navmesh Surface adalah fitur baru dalam Unity 2017.2 ke atas. Dengan komponen ini, kita bisa membuat agent untuk berjalan di dinding.

Pada gambar di bawah, saya memiliki Plane dengan rotasi X = 90 dan Y = 180, yang telah diberi komponen tersebut. Kemudian untuk agent, adalah GameObject biasa yang telah diberi komponen Navmesh Agent.

Selanjutnya, cara menggerakannya adalah seperti biasa. Misal dalam script berikut melakukan pathfinding ke lokasi yang ditunjukkan oleh mouse.

// Filename : Agent.cs

public class Agent : MonoBehaviour  
{
    public bool UseRotation = false;
    
    private NavMeshAgent   _navMeshAgent;
    private SpriteRenderer _spriteRenderer;
    private Transform      _spriteTransform;
    
    private void Start()
    {
        _navMeshAgent    = GetComponent<NavMeshAgent>();
        _spriteTransform = transform.GetChild(0);
        _spriteRenderer  = GetComponentInChildren<SpriteRenderer>();
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector2 mousePosition     = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            _navMeshAgent.destination = mousePosition;

            if (!UseRotation)
                _spriteRenderer.flipX = mousePosition.< transform.position.x;
        }

        transform.rotation = Quaternion.identity;
    }
}

Untuk obstacle, berikan komponen Navmesh Obstacle dan Box Collider 2D sekaligus. Navmesh Obstacle digunakan agar agent dapat menghindarinya. Sedangkan Box Collider 2D agar objek dengan Rigidbody tidak bisa menembusnya.

Hasilnya :

Drawback

Dalam metode ini, saya belum bisa membuat mengkonversikan rotasi 3D ke 2D berdasarkan velocity-nya. Hal ini terlihat ketika membuat AI yang membutuhkan arah.

Dari gambar di atas, bisa terlihat kalau angle yang dilihat kadang berhasil kadang tidak. Sebenarnya bisa langsung Quaternion.LookRotation() ke ara mouse, tapi akan masih kurang realistis ketika menemui obstacle dan harus berbelok. Kode yang saya pakai adalah seperti berikut :

Vector3 velocity = _navMeshAgent.desiredVelocity;

           
debug.text = velocity.ToString();  
if (velocity != Vector3.zero)  
    _spriteTransform.localEulerAngles = new Vector3(0,0,velocity.* _navMeshAgent.angularSpeed);
 

Yang tau caranya mungkin bisa kasih tau nanti saya update tutorialnya hehe.

Nah karena masih ngebug, lanjut cara 2 yang lebih sederhana.



Cara 2 : Fake 2D

Dalam model ini, game yang kita buat sebenarnya adalah game 3D dengan sudut pandang 2D. Caranya gimana? Ganti mode Camera menjadi ortographic, set posisi Y ke atas, dan rotasi X menjadi 90 derajat.

Kemudian untuk seluruh objek di dalamnya, gunakan GameObject empty dengan rotasi X = 90 dan tambahkan child dengan komponen Sprite Renderer.

Selanjutnya, lakukan pengaturan seperti dengan cara 1. Ingat karena ini sebenarnya adalah game 3D, gunakan collider 3D, bukan 2D.

Hasil akhirnya :



Download Source Code

April 28, 2018 in #Coding #Unity | | | Share on Google+