//spawn receptacle/screen <objType> of index [variation] on <targetReceptacle> table object using random seed to pick which spawn coordinate used public bool SpawnExperimentObjAtRandom(string objType, int variation, int seed, SimObjPhysics targetReceptacle, float yRot = 0) { toSpawn = null; bool success = false; //init random state UnityEngine.Random.InitState(seed); if (objType == "screen") { toSpawn = screensToSpawn[variation].GetComponent <SimObjPhysics>(); } if (objType == "receptacle") { toSpawn = receptaclesToSpawn[variation].GetComponent <SimObjPhysics>(); } List <Vector3> spawnCoordinates = new List <Vector3>(); PhysicsRemoteFPSAgentController fpsAgent = agentManager.ReturnPrimaryAgent().GetComponent <PhysicsRemoteFPSAgentController>(); spawnCoordinates = fpsAgent.GetSpawnCoordinatesAboveReceptacle(targetReceptacle); spawnCoordinates.Shuffle_(seed); //instantiate the prefab toSpawn away from every other object SimObjPhysics spawned = GameObject.Instantiate(toSpawn, initialSpawnPosition, Quaternion.identity); Rigidbody rb = spawned.GetComponent <Rigidbody>(); //make sure object doesn't fall until we are done preparing to reposition it on the target receptacle rb.isKinematic = true; //apply rotation to object, default quaternion.identity spawned.transform.Rotate(new Vector3(0, yRot, 0), Space.Self); for (int i = 0; i < spawnCoordinates.Count; i++) { //place object at the given point, this also checks the spawn area to see if its clear //if not clear, it will return false if (fpsAgent.PlaceObjectAtPoint(toSpawn, spawnCoordinates[i])) { //we set success to true, if one of the corners doesn't fit on the table //this will be switched to false and will be returned at the end success = true; //double check if all corners of spawned object's bounding box are //above the targetReceptacle table //note this only accesses the very first receptacle trigger box, so //for EXPERIMENT ROOM TABLES make sure there is only one //receptacle trigger box on the square table List <Vector3> corners = GetCorners(spawned); Contains con = targetReceptacle.ReceptacleTriggerBoxes[0].GetComponent <Contains>(); bool cornerCheck = true; foreach (Vector3 p in corners) { if (!con.CheckIfPointIsAboveReceptacleTriggerBox(p)) { cornerCheck = false; //this position would cause object to fall off table //double back and reset object to try again with another point spawned.transform.position = initialSpawnPosition; break; } } if (!cornerCheck) { success = false; continue; } } //if all corners were succesful, break out of this loop, don't keep trying if (success) { rb.isKinematic = false; //run scene setup to grab reference to object and give it objectId sceneManager.SetupScene(); sceneManager.ResetObjectIdToSimObjPhysics(); break; } } //no objects could be spawned at any of the spawn points //destroy the thing we tried to place on target receptacle if (!success) { Destroy(spawned.transform.gameObject); } return(success); }
//return spawn coordinates above the <receptacleObjectId> that the <objectId> will fit at a given rotation <yRot> //excludes coordinates that would cause object <objectId> to fall off the table public List <Vector3> ReturnValidSpawns(string objType, int variation, SimObjPhysics targetReceptacle, float yRot = 0) { toSpawn = null; if (objType == "screen") { toSpawn = screensToSpawn[variation].GetComponent <SimObjPhysics>(); } if (objType == "receptacle") { toSpawn = receptaclesToSpawn[variation].GetComponent <SimObjPhysics>(); } SimObjPhysics spawned = GameObject.Instantiate(toSpawn, initialSpawnPosition, Quaternion.identity); Rigidbody rb = spawned.GetComponent <Rigidbody>(); //apply rotation to object, default quaternion.identity spawned.transform.Rotate(new Vector3(0, yRot, 0), Space.Self); //generate grid of potential spawn points //GetSpawnCoordinatesAboveReceptacle List <Vector3> spawnCoordinates = new List <Vector3>(); PhysicsRemoteFPSAgentController fpsAgent = agentManager.ReturnPrimaryAgent().GetComponent <PhysicsRemoteFPSAgentController>(); spawnCoordinates = fpsAgent.GetSpawnCoordinatesAboveReceptacle(targetReceptacle); List <Vector3> returnCoordinates = new List <Vector3>(); //try and place object at every spawn coordinate and if it works, add it to the valid coords to return for (int i = 0; i < spawnCoordinates.Count; i++) { //place object at the given point, then check if the corners are ok fpsAgent.PlaceObjectAtPoint(toSpawn, spawnCoordinates[i]); List <Vector3> corners = GetCorners(spawned); Contains con = targetReceptacle.ReceptacleTriggerBoxes[0].GetComponent <Contains>(); bool cornerCheck = true; foreach (Vector3 p in corners) { if (!con.CheckIfPointIsAboveReceptacleTriggerBox(p)) { cornerCheck = false; //this position would cause object to fall off table //double back and reset object to try again with another point spawned.transform.position = initialSpawnPosition; break; } } if (cornerCheck) { returnCoordinates.Add(spawnCoordinates[i]); //all corners were ok, so add it to the points that are valid } spawned.transform.position = initialSpawnPosition; } #if UNITY_EDITOR //debug draw debugCoords = returnCoordinates; #endif Destroy(spawned.transform.gameObject); return(returnCoordinates); }