Moving around obstacles

Hello!

So currently I’m working on a project. I have batalions of soldiers attacking a castle, but I’d like to be able to click on a point and have the battalion move there. I already have such a system in place, but it doesn’t take into account other batalions in its path. A picture is worth a thousand words, so here’s a sketch of my idea: 2908298--214387--UnityMoveIdea1.png

So my question is, how could I have intelligent movement that would understand how to move around obstacles? In fact, there could even be more than one obstacle to move around!

Currently, this is the code I’m using to move the battalion. It finds the point location, moves horizontally then vertically:

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

public class BatalionController : MonoBehaviour {

    private bool AllowMoveToPoint;
    public bool AllowRotation;
    public Transform PointTransform;
    public Vector3 PointLocation;
    public Vector3 Difference;
    public GameObject Arrows;
    public bool MovingX;
    public bool MovingZ;
    //original values
    public float OrigDiffX;
    public float OrigDiffZ;
    public float MoveSpeed;
    public float RotationSpeed;
    public float distCovered;
    public float fracJourney;
    public float journeyLength;
    private float TimeLeft;
    private float startTime;
    private float MathfT;
    // Use this for initialization
    void Start () {
   
    }

    // Update is called once per frame
    void Update ()
    {
        if (AllowMoveToPoint == true)
        {
       
        }

        if (AllowRotation == true)
        {
            CalcDifference();
            MoveInStraightLines();
        }
    }

    public void StartMoveToPoint(Vector3 Location)
    {
        startTime = Time.time;
        PointLocation = Location;
        journeyLength = Vector3.Distance(transform.position, PointLocation);
        CalcDifference();
        MovingX = true;
        OrigDiffX = Difference.x;
        OrigDiffZ = Difference.z;
        AllowRotation = true;
        Arrows.SetActive(false);
    }

    void CalcDifference()
    {
        Difference = transform.position - PointLocation;
    }

    void MoveInStraightLines()
    {
        //move X first
        if (MovingX == true)
        {
            if (Difference.x <= 0)
            {
                //if negative and original was negative, move right
                if (OrigDiffX <= 0)
                {
                    transform.Translate(Vector3.right * MoveSpeed * Time.deltaTime);
                }

                else
                {
                    //starting to overshoot, so stop moving X
                    MovingX = false;
                }
            }

            if (Difference.x >= 0)
            {
                //if positive and original was positive, move left
                if (OrigDiffX >= 0)
                {
                    transform.Translate(Vector3.left * MoveSpeed * Time.deltaTime);
                }
                else
                {
                    //starting to overshoot, so stop moving X
                    MovingX = false;
                }
            }
        }

        //move Y
        if (MovingX == false)
        {
            if (Difference.z <= 0)
            {
                //if negative and original was negative, move forward
                if (OrigDiffZ <= 0)
                {
                    transform.Translate(Vector3.forward * MoveSpeed * Time.deltaTime);
                }

                else
                {
                    //starting to overshoot, so stop moving Z
                    MovingZ = false;
                    AllowRotation = false;
                }
            }

            if (Difference.z >= 0)
            {
                //if positive and original was positive, move left
                if (OrigDiffZ >= 0)
                {
                    transform.Translate(Vector3.back * MoveSpeed * Time.deltaTime);
                }
                else
                {
                    //starting to overshoot, so stop moving X
                    MovingZ = false;
                    AllowRotation = false;
                }
            }
        }
    }
}

So my path of motion with that code (if I’d add a way to detect obstacles) would look like this:

Would I have to make my batalions grid-based so they would be places on grids on the map? I’ve looked into Unity’s NavMesh system, but it seems to require paths to be pre-baked. How would you achieve something like this?

Thank you for sharing any of your ideas, please let me know if I wasn’t descriptive enough.

You could use a NavMesh if you use the Carve option of NavMesh Obstacle, but it might get expensive - https://docs.unity3d.com/Manual/class-NavMeshObstacle.html

I’ll have to look into that. Do you think it’s too expensive for mobile?

Use NavMesh navigation. It’s easy to use. I recommend you to watch tutorials on unity website (Learn game development w/ Unity | Courses & tutorials in game design, VR, AR, & Real-time 3D | Unity Learn) (it will take you about 30 minutes to watch them all, but you will have better understanding). It’s not to expensive for mobile.

Advices for after you finished tutorials:
If obstacles are static, use NavMesh Obstacle components on them. NavMesh Agenst will avoid them.
For moving batalions to avoid eachother, set different priority value under their NavMesh Agent components.

EDIT: Sorry, I haven’t seen what you wrote at the end:

““Would I have to make my batalions grid-based so they would be places on grids on the map? I’ve looked into Unity’s NavMesh system, but it seems to require paths to be pre-baked. How would you achieve something like this?””

Paths are not pre-baked, walkable area is pre-baked. Paths are then calculated at runtime. They can be even recalculated, if an obstacle comes in a way.

Regards, L

1 Like