1

I have a script to instantiate a gameobject when the agent reaches its position, when instantiated it will randomly choose any of those 2, then 3, etc... this gameobjects belong to a parent (I use the random with childcount and getChild), however my agent won't move to the instances, just the original one. I've tried using it's position and it's localPosition and none of them works, actually if I use the local position it won't even do the set destination to the original one. I can't guess if its a navmesh problem or if there is an error with my scripting. I can add some images so if anyone can help me.

Script part:

if (plant_gameobject_father.transform.childCount != 0)
    {
        chosen_child = Random.Range(0, plant_gameobject_father.transform.childCount - 1);
        plant_target = plant_gameobject_father.transform.GetChild(chosen_child);
        Debug.Log(plant_target.transform.position);
        agent_.SetDestination(plant_target.position);
        Debug.Log(agent_.pathStatus);
    }

Video Sample: Navmesh working just on the original gameobject

EDIT: When using agent.remainingDistance to check how it's doing it: right after assigning the destination the remaining distance is 0, and when it "arrives" to the target it's remaining distance it's bigger than it should (I have a coroutine using yield return wait until agent.remainingDistance < 3.5f) and still it thinks it has reached destination.

I will upload full script for context understanding(it's a long one)

Could it be that the distances are too big? Mi terrain is larger that 2000 units in lenght.

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

public class insect_IA : MonoBehaviour
{
    public ciclo_dia_noche info_horas;                                            //Programado para que haga 3 ciclos de actividad al dia y inactividad de noche.

    public GameObject plant_type_small;
    public GameObject plant_type_medium;
    public GameObject plant_type_big;
    Transform plant_target;
    GameObject plant_gameobject_father;
    public GameObject colmena;
    public int objetivo_diario_recoleccion;

    public int segundos_recoleccion_polen;
    public int segundos_depositado_polen;

    public int plant_selector;
    public NavMeshAgent agent_;

    int selector_accion;

    public bool wander_is_happening;
    public GameObject colmena_wander_childs;
    public Transform wander_target;

    public int is_performing_routine_insect;
    public bool its_a_new_day;

    public birth_controller puedo_reproducir;

    public Collider tree_spawner1, tree_spawner2, tree_spawner3, selected_collider;
    public Vector3 bounds_max, bounds_min;
    public int random_number;
    public float spawn_point_x, spawnpoint_z, spawnpoint_y;
    public Vector3 spawn_point_tree;
    public GameObject tree_big_prefab, tree_med_prefab, tree_peq_prefab;

    public int chosen_child;


    // Start is called before the first frame update
    void Start()
    {
        
    }

    private void Awake()
    {
        info_horas = GameObject.Find("Directional_Light").GetComponent<ciclo_dia_noche>();
        plant_type_big = GameObject.Find("PLANTAS_GRAND");
        plant_type_medium = GameObject.Find("PLANTAS_MED");
        plant_type_small = GameObject.Find("PLANTAS_PEQ");
        colmena = GameObject.Find("colmena");
        puedo_reproducir = GameObject.Find("birth_controlator").GetComponent<birth_controller>();
        tree_spawner1 = GameObject.Find("spawn_area1").GetComponent<Collider>();
        tree_spawner2 = GameObject.Find("spawn_area2").GetComponent<Collider>();
        tree_spawner3 = GameObject.Find("spawn_area3").GetComponent<Collider>();

        tree_big_prefab = GameObject.Find("PLANTAS_GRAND/planta_grand");
        tree_med_prefab = GameObject.Find("PLANTAS_MED/planta_med");
        tree_peq_prefab = GameObject.Find("PLANTAS_PEQ/planta_peq");

        agent_ = GetComponent<NavMeshAgent>();
        colmena_wander_childs = colmena;
        selector_accion = 0;
        segundos_recoleccion_polen = 5;
        segundos_depositado_polen = 5;
        objetivo_diario_recoleccion = 3;
        is_performing_routine_insect = 0;
        its_a_new_day = true;
        random_number = -1;
    }

    // Update is called once per frame
    void Update()
    {
        if ((puedo_reproducir.plant_big_type.transform.childCount < puedo_reproducir.max_plant_big || puedo_reproducir.plant_med_type.transform.childCount < puedo_reproducir.max_plant_med || puedo_reproducir.plant_peq_type.transform.childCount < puedo_reproducir.max_plant_peq) && info_horas.segundos_globales < info_horas.duracion_dia)
        {
            insect_state();
        }


        if (wander_is_happening == false && puedo_reproducir.plant_big_type.transform.childCount > puedo_reproducir.max_plant_big && puedo_reproducir.plant_med_type.transform.childCount > puedo_reproducir.max_plant_med && puedo_reproducir.plant_peq_type.transform.childCount > puedo_reproducir.max_plant_peq)
        {
            wander_is_happening = true;
            is_performing_routine_insect = 4;
            StartCoroutine("regular_wander");
        }


    }

    public void insect_state()
    {
        if (selector_accion == 0)
        {
            //Debug.Log("buscar padre arbol");
            is_performing_routine_insect = 1;
            selector_accion = -1;
            cojo_un_padre_arbol();
            selector_accion = 1;
        }
        if (selector_accion == 1)
        {
            //Debug.Log("elegir destino");
            selector_accion = -2;
            elijo_destino();
            selector_accion = 2;
        }
        if (selector_accion == 2)
        {
            //Debug.Log("esperar a que llegue");
            selector_accion = -3;
            check_path();

        }
        if (selector_accion == 3)
        {
            //Debug.Log("cogiendo polen");
            is_performing_routine_insect = 2;
            StartCoroutine("cogiendo_polen");
        }
        if (selector_accion == 4)
        {
            //Debug.Log("de vuelta a la colmena");
            selector_accion = -5;
            volver_colmena();
            check_path();

        }
        if (selector_accion == 5)
        {
            //Debug.Log("guardo polen");
            is_performing_routine_insect = 3;
            StartCoroutine("guardando_polen");
        }
        if (selector_accion == 6)
        {
            //Debug.Log("reinicio insecto");
            is_performing_routine_insect = 4;
            StartCoroutine("esperar_proxima_recoleccion");
        }
    }

    public void cojo_un_padre_arbol()
    {
        if (puedo_reproducir.plant_big_type.transform.childCount < puedo_reproducir.max_plant_big)
        {
            plant_selector = 2;
        }
        else if (puedo_reproducir.plant_med_type.transform.childCount < puedo_reproducir.max_plant_med)
        {
            plant_selector = 1;
        }
        else if (puedo_reproducir.plant_peq_type.transform.childCount < puedo_reproducir.max_plant_peq)
        {
            plant_selector = 0;
        }


        if (plant_selector == 0)
        {
            plant_gameobject_father = plant_type_small;
        }
        if (plant_selector == 1)
        {
            plant_gameobject_father = plant_type_medium;
        }
        if (plant_selector == 2)
        {
            plant_gameobject_father = plant_type_big;
        }
        //Debug.Log("padre elegido:" + plant_gameobject_father);
    }

    public void elijo_destino()
    {
        if (plant_gameobject_father.transform.childCount != 0)
        {
            chosen_child = Random.Range(0, plant_gameobject_father.transform.childCount - 1);
            plant_target = plant_gameobject_father.transform.GetChild(chosen_child);
            Debug.Log(plant_target.transform.position);
            agent_.SetDestination(plant_target.position);
            Debug.Log(agent_.pathStatus);
            
        }
        else if(plant_gameobject_father.transform.childCount == 0)
        {
            wander_is_happening = true;
            is_performing_routine_insect = 4;
            StartCoroutine("regular_wander");
        }
        
        //Debug.Log(this.transform.position);
        //Debug.Log("planta seleccionada: " + plant_target);
        //Debug.Log(agent_.remainingDistance);

    }

    public void check_path()
    {
        StartCoroutine("esperar_destino");

    }

    public void volver_colmena()
    {
        agent_.SetDestination(colmena.transform.position);
        create_plant();
    }

    public IEnumerator cogiendo_polen()
    {
        selector_accion = -4;
        yield return new WaitForSeconds(segundos_recoleccion_polen);
        selector_accion = 4;
    }

    public IEnumerator guardando_polen()
    {
        selector_accion = -6;
        yield return new WaitForSeconds(segundos_depositado_polen);
        selector_accion = 6;
    }

    public IEnumerator esperar_destino()
    {
        if (plant_target.tag == "planta_peq")
        {
            //Debug.Log(agent_.remainingDistance);
            yield return new WaitUntil(() => agent_.remainingDistance < 1.7f);
            //Debug.Log(agent_.remainingDistance);
            agent_.isStopped = true;
            agent_.ResetPath();
            if (selector_accion == -3)
            {
                selector_accion = 3;
            }
            if (selector_accion == -5)
            {
                selector_accion = 5;
            }
        }
        if (plant_target.tag == "planta_med")
        {
            //Debug.Log(agent_.remainingDistance);
            yield return new WaitUntil(() => agent_.remainingDistance < 3.0f);
            //Debug.Log(agent_.remainingDistance);
            agent_.isStopped = true;
            agent_.ResetPath();
            if (selector_accion == -3)
            {
                selector_accion = 3;
            }
            if (selector_accion == -5)
            {
                selector_accion = 5;
            }
        }
        if (plant_target.tag == "planta_grand")
        {
            Debug.Log(agent_.remainingDistance);
            yield return new WaitUntil(() => agent_.remainingDistance < 3.5f);
            Debug.Log(agent_.remainingDistance);
            agent_.isStopped = true;
            agent_.ResetPath();
            if (selector_accion == -3)
            {
                selector_accion = 3;
            }
            if (selector_accion == -5)
            {
                selector_accion = 5;
            }
        }
    }


    public IEnumerator esperar_proxima_recoleccion()
    {
        selector_accion = -7;
        yield return new WaitForSeconds(1);
        selector_accion = 0;
    }

    public IEnumerator regular_wander()
    {
        wander_target = colmena_wander_childs.transform.GetChild(Random.Range(0, colmena_wander_childs.transform.childCount - 1));
        agent_.SetDestination(wander_target.position);
        yield return new WaitUntil(() => agent_.remainingDistance < 0.1f);
        agent_.isStopped = true;
        agent_.ResetPath();
        yield return new WaitForSeconds(5);
        wander_is_happening = false;
    }


    public void create_plant()
    {
        //Debug.Log("entro a crear una planta");
        random_number = Random.Range(0, 3);

        if (random_number == 0)
        {
            selected_collider = tree_spawner1;
            
        }
        if (random_number == 1)
        {
            selected_collider = tree_spawner2;
            
        }
        if (random_number == 2)
        {
            selected_collider = tree_spawner3;
            
        }

        bounds_max = selected_collider.bounds.max;
        bounds_min = selected_collider.bounds.min;
        spawn_point_x = Random.Range(bounds_min.x, bounds_max.x);
        spawnpoint_z = Random.Range(bounds_min.z, bounds_max.z);
        spawnpoint_y = bounds_max.y;
        spawn_point_tree = new Vector3(spawn_point_x, spawnpoint_y, spawnpoint_z);
        if (plant_target.tag == "planta_peq")
        {
            Instantiate(tree_peq_prefab, spawn_point_tree, Quaternion.identity, plant_type_big.transform);
        }
        if (plant_target.tag == "planta_med")
        {
            Instantiate(tree_med_prefab, spawn_point_tree, Quaternion.identity, plant_type_medium.transform);
        }
        if (plant_target.tag == "planta_grand")
        {
            Instantiate(tree_big_prefab, spawn_point_tree, Quaternion.identity, plant_type_big.transform);
        }
        Debug.Log(puedo_reproducir.plant_big_type.transform.childCount);
    }
}

´´´´


Fanre5
  • 31
  • 2
  • Do you want all the colored objects to move on the navmesh on target of your selected object on video? – KiynL May 19 '22 at 10:06
  • @KiynL Sorry for not explaining, ignore all objects except for the sphere(agent) and the green capsule. The sphere must go to the green capsule and then return to the cube. This green capsule is instantiated each time the sphere returns to the cube so in the next "cycle" it can choose to go to the original object or the new instantiated one. But if it chooses the clone it won't move despite getting pathComplete Status and continuing the script as if it has reached it. – Fanre5 May 19 '22 at 10:13
  • It'd be useful to see the full script, we're currently missing a lot of context on when this logic is called and what the rest of the flow looks like. – Alex Leest May 19 '22 at 11:47
  • @AlexLeest Just uploaded the full script, some variables are declared in spanish though. – Fanre5 May 19 '22 at 11:59

1 Answers1

0

There's a lot going on in your script. I'm going to put some calculated guesses here on what might help.

Your birth_controller object seems to have a separate list of all the small/medium/big plants. Are you 100% sure these reference the same as the ones in your Insect_IA object?

You are also using a lot of logic that seems very framerate dependant. Your update function itself calls insect_state() which functions as a state machine that runs through one step per frame, one frame at a time. At the same time, you start coroutines that work alongside that during all that. selector_accion is edited in both insect_state and a lot of those coroutines. Are you sure you're not deadlocking yourself out of certain values of selector_accion which are necessary for the navmesh to work?

Also: Random.Range(int minInclusive, int maxExclusive) is, for the int overload, EXCLUSIVE on the upper bound, so you can remove the -1 from plant_gameobject_father.transform.childCount - 1.

EDIT: As discussed in the comments and in edits to the original post, the scale of your scene might be causing issues as well. If your navmesh agent cannot physically get as close as your yield WaitUntil statements are waiting for, that's probably deadlocking your logic.

Alex Leest
  • 76
  • 7
  • The state machine works in a way so that it can't enter in any ifs until the current if is finished(that's why I change "selector_accion" to a negative number at the start of each if) so despite being in update it will just change state when the previous is done. Coroutines are called in those ifs and it wont change the value of "selector_accion" until they are finished so there are no problems on coroutines working at the same time as the state machine changes states. And yes, the birht controller stores the max number of instances I want to get. – Fanre5 May 19 '22 at 12:51
  • The only problem I can see is probably that the set destination is called once and it wont get called again until the check_path is done calculating the remaining distance(which is 0 because it's wrong somehow). Also I've been invetigating and maybe the problem could be that the destination for the agent is too far for it to be able to calculate the path and just decides to finish that path and store it as "pathcomplete" despite not moving at all. My terrain is aprox 2000 units in lenght, and I cannot scale it down for some reason – Fanre5 May 19 '22 at 12:56
  • That's quite large. I'd say logging the remaining distance, seeing what happens when the agent gets as close as possible (which might not be <3.5f due to colliders keeping the two objects away from eachother) and adjusting the minimum distance in those coroutines to something more applicable might help. You should look into scaling all your models down. A large scene like this is generally bad for performance and is more likely to cause issues like this. – Alex Leest May 19 '22 at 13:04
  • Ok I'm almost sure that the problem is the objects just being too far away, I tried moving some destination targets while executing the game(pausing and so) and trying to move them far or near and it works perfectly as long as the target is not too far away. The solution I can think of is either scaling up all my "animals" to match the terrain size or create a new terrain. Because I cannot scale my terrain for whatever reason. – Fanre5 May 19 '22 at 13:57
  • Edit: This might not be a permanent solution but I discovered that overriding the tile size to be as big as possible and overriding the voxel size actually increase the "range" of the agent to be able to path correctly to it's target. This is not perfect but it may do the trick – Fanre5 May 19 '22 at 15:33