0
\$\begingroup\$

I'm trying to generate a number of prefabs in a scene where that scene will have procedurally-generated terrain objects. I have tagged each of the terrain objects with Environment to try and make trigger detection a bit easier.

The issue I'm facing is that the prefabs I'm attempting to spawn don't have their trigger detection run until after my script runs, and I'm wondering if there is a better way to do this. Basically, what is happening is that my prefabs are spawning inside of environmental objects and I want to either move them or regenerate them.

Here's what I'm trying so far:

  1. Instantiate scene (tagging environmental objects with Environment - right now this is manual to prove out the prefab placement but will later become fully automated).

This is what the scene currently looks like - it is basically going to be an extension of the Unity ROS example:

Unity Screenshot

Eventually the objects placed in the scene (tagged Environment) will be procedurally generated.

  1. Prefab controller script will attempt to randomly place 100 objects within the bounds of the scene. Currently I'm trying to have the prefab script handle its own destruction and have the main controller check to see if the prefab was destroyed - however that information isn't available until later. What I tried before was to add an OnTriggerEnter function within the prefab to set a flag that was publicly-accessible, but had the same issue with timing.
public class WaypointGenerator : MonoBehaviour
{
    public List<GameObject> locations;

    void Start()
    {
        for (int i = 0; i < 100; i++)
        {
            GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Prefabs/BaseWaypoint.prefab");
            
            // instantiate prefab
            var prefabInstance = Object.Instantiate(prefab, GenerateLocation(), Quaternion.identity);
            var prefabScriptInstance = prefabInstance.GetComponent<WaypointController>();

            locations.Add(prefabInstance);

            // previous attempt - check if collision flag is true
            // if (prefabScriptInstance.IsColliding())
            // {
            //   Destroy(prefabInstance);
            //   print("spawned inside object");
            // }
        }

        for (int i = 0; i < locations.Count; i++)
        {
          // here i was thinking to check which prefabs were missing and regenerate
          if (locations[i].name.Contains("Missing Prefab"))
            print("oops");
        }
    }

This is what my prefab script looks like. Right now the prefab itself is an empty gameObject with a BoxCollider with trigger checked.

public class WaypointController : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Environment") {
            print("Spawned inside environment - destroying.");
            Destroy(transform.root.gameObject);
        }
    }
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

The answer here for me was pretty simple, so this might not fit for everyone. I just generate a new position from the child (WaypointController) script if OnTriggerEnter is called appropriately. Then the object takes care of itself rather than the main controller.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .