//searches for a SimObj item under a receptacle by ID //this does not TAKE the item, it just searches for it public static bool FindItemFromReceptacleByType(SimObjType itemType, Receptacle r, out SimObj item) { item = null; //make sure we're not doing something insane if (r == null) { Debug.LogError("Receptacle was null, not searching for item"); return(false); } if (itemType == SimObjType.Undefined) { Debug.LogError("Can't search for type UNDEFINED, not searching for item"); return(false); } SimObj checkItem = null; for (int i = 0; i < r.Pivots.Length; i++) { if (r.Pivots [i].childCount > 0) { checkItem = r.Pivots [i].GetChild(0).GetComponent <SimObj> (); if (checkItem != null && checkItem.Type == itemType) { //if the item under the pivot is a SimObj of the right type //we've found what we're after item = checkItem; return(true); } } } //couldn't find it! return(false); }
public System.Collections.Generic.IEnumerator <SimObjPhysics> GetValidReceptaclesForSimObj( SimObjPhysics simObj, List <SimObjPhysics> receptaclesInScene ) { SimObjType goObjType = simObj.ObjType; bool typeFoundInDictionary = ReceptacleRestrictions.PlacementRestrictions.ContainsKey(goObjType); if (typeFoundInDictionary) { List <SimObjType> typesOfObjectsPrefabIsAllowedToSpawnIn = new List <SimObjType>(ReceptacleRestrictions.PlacementRestrictions[goObjType]); // remove from list if receptacle isn't in this scene // compare to receptacles that exist in scene, get the ones that are the same foreach (SimObjPhysics receptacleSop in receptaclesInScene) { // don't random spawn in objects that are pickupable to prevent Egg spawning in Plate with the plate spawned in Cabinet.... if (receptacleSop.PrimaryProperty != SimObjPrimaryProperty.CanPickup) { if (typesOfObjectsPrefabIsAllowedToSpawnIn.Contains(receptacleSop.ObjType)) { yield return(receptacleSop); } } } } else { // not found in dictionary! #if UNITY_EDITOR Debug.Log(simObj.ObjectID + "'s Type is not in the ReceptacleRestrictions dictionary!"); #endif } }
public GameObject GetGameObject(string objectType, bool randomize, int variation) { List <GameObject> candidates = new List <GameObject>(); SimObjType target = (SimObjType)Enum.Parse(typeof(SimObjType), objectType); // Debug.Log(target); foreach (GameObject go in prefabsToLaunch) { // Debug.Log(go.GetComponent<SimObjPhysics>().Type); // does a prefab of objectType exist in the current array of prefabs to spawn? if (go.GetComponent <SimObjPhysics>().Type == target) { candidates.Add(go); } } // Figure out which variation to use, if no variation use first candidate found if (randomize) { variation = UnityEngine.Random.Range(1, candidates.Count); } if (variation != 0) { variation -= 1; } return(candidates[variation]); }
public bool SetObjectToggles(ObjectToggle[] objectToggles) { bool shouldFail = false; if (objectToggles != null && objectToggles.Length > 0) { // Perform object toggle state sets. SimObjPhysics[] simObjs = GameObject.FindObjectsOfType(typeof(SimObjPhysics)) as SimObjPhysics[]; Dictionary <SimObjType, bool> toggles = new Dictionary <SimObjType, bool>(); foreach (ObjectToggle objectToggle in objectToggles) { SimObjType objType = (SimObjType)System.Enum.Parse(typeof(SimObjType), objectToggle.objectType); toggles[objType] = objectToggle.isOn; } PhysicsRemoteFPSAgentController fpsController = GameObject.Find("FPSController").GetComponent <PhysicsRemoteFPSAgentController>(); foreach (SimObjPhysics sop in simObjs) { if (toggles.ContainsKey(sop.ObjType)) { bool success = fpsController.ToggleObject(sop, toggles[sop.ObjType], true); if (!success) { shouldFail = true; } } } } return(!shouldFail); }
public void Setup(SimObjType type, SimObjPrimaryProperty primaryProperty, SimObjSecondaryProperty[] secondaryProperties, string tag, int layer) { // SimObjPhysics sop = gameObject.GetComponent<SimObjPhysics>(); // sop.Type = type; // sop.PrimaryProperty = primaryProperty; // sop.SecondaryProperties = secondaryProperties; // sop.gameObject.tag = tag; // sop.layer = layer; }
public bool haveTypeInventory(SimObjType objectType) { foreach (SimObj so in inventory.Values) { if (so.Type == objectType) { return(true); } } return(false); }
//call PlaceObject for all points in the passed in ReceptacleSpawnPoint list //The ReceptacleSpawnPoint list should be sorted based on what we are doing. If placing from the agent's hand, the list //should be sorted by distance to agent so the closest points are checked first. If used for Random Initial Spawn, it should //be randomized so that the random spawn is... random public bool PlaceObjectReceptacle(List <ReceptacleSpawnPoint> rsps, SimObjPhysics sop, bool PlaceStationary, int maxPlacementAttempts, int degreeIncrement, bool AlwaysPlaceUpright, Dictionary <SimObjType, int> minFreePerReceptacleType) { if (rsps == null) { #if UNITY_EDITOR Debug.Log("Null list of points to check, please pass in populated list of <ReceptacleSpawnPoint>?"); #endif return(false); //uh, there was nothing in the List for some reason, so failed to spawn } if (rsps.Count == 0) { return(false); } List <ReceptacleSpawnPoint> goodRsps = new List <ReceptacleSpawnPoint>(); foreach (ReceptacleSpawnPoint p in rsps) { if (!p.ParentSimObjPhys.GetComponent <SimObjPhysics>().DoesThisObjectHaveThisSecondaryProperty (SimObjSecondaryProperty.ObjectSpecificReceptacle)) { goodRsps.Add(p); } } // Make a seed that is pseudo-random (different for different objects even in the same area) but also reproducible. //int seed = rsps.Count + goodRsps.Count + sop.UniqueID.GetHashCode(); int tries = 0; foreach (ReceptacleSpawnPoint p in goodRsps) { SimObjType parentType = p.ParentSimObjPhys.ObjType; if (minFreePerReceptacleType != null && minFreePerReceptacleType.ContainsKey(parentType) && goodRsps.Count < minFreePerReceptacleType[parentType]) { return(false); } //if this is an Object Specific Receptacle, stop this check right now! I mean it! //Placing objects in/on an Object Specific Receptacle uses different logic to place the //object at the Attachemnet point rather than in the spawn area, so stop this right now! if (PlaceObject(sop, p, PlaceStationary, degreeIncrement, AlwaysPlaceUpright)) { //found a place to spawn! neato, return success return(true); } tries += 1; if (maxPlacementAttempts > 0 && tries > maxPlacementAttempts) { break; } } //couldn't find valid places to spawn return(false); }
public bool HasSpecificType(SimObjType check) { bool result = false; foreach (SimObjType sot in SpecificTypes) { if (sot == check) { result = true; } } return(result); }
//use action.randomseed for seed, use action.forceVisible for if objects shoudld ONLY spawn outside and not inside anything // //set forceVisible to true for if you want objects to only spawn in immediately visible receptacles. // public bool RandomSpawnRequiredSceneObjects(ServerAction action) // { // return RandomSpawnRequiredSceneObjects(action.randomSeed, action.forceVisible, action.numPlacementAttempts, action.placeStationary, action.numDuplicatesOfType, action.excludedReceptacles); // } //place each object in the array of objects that should appear in this scene randomly in valid receptacles //seed- random seed used to pick locations //SpawnOnlyOutside - set to true to use only receptacles that are open innately (ie: tables, countertops, sinks) and not ones that require actions to open (drawer, cabinet etc.) //maxPlacementAttempts - the max number of times an object will attempt to be placed in within a receptacle //StaticPlacement - set to true if objects should be placed so they don't roll around after being repositioned //numDuplicatesOfType - used to duplicate the first instance of an object type found in a scene //excludedReceptacles - public bool RandomSpawnRequiredSceneObjects( int seed, bool SpawnOnlyOutside, int maxPlacementAttempts, bool StaticPlacement, ObjectTypeCount[] numDuplicatesOfType, List <SimObjType> excludedReceptacles ) { #if UNITY_EDITOR var Masterwatch = System.Diagnostics.Stopwatch.StartNew(); #endif if (RequiredObjects.Count == 0) { #if UNITY_EDITOR Debug.Log("No objects in Required Objects array, please add them in editor"); #endif return(false); } //initialize Unity's random with seed UnityEngine.Random.InitState(seed); List <SimObjType> TypesOfObjectsPrefabIsAllowedToSpawnIn = new List <SimObjType>(); Dictionary <SimObjType, List <SimObjPhysics> > AllowedToSpawnInAndExistsInScene = new Dictionary <SimObjType, List <SimObjPhysics> >(); int HowManyCouldntSpawn = RequiredObjects.Count; //if we already spawned objects, lets just move them around if (SpawnedObjects.Count > 0) { HowManyCouldntSpawn = SpawnedObjects.Count; Dictionary <SimObjType, List <SimObjPhysics> > typeToObjectList = new Dictionary <SimObjType, List <SimObjPhysics> >(); Dictionary <SimObjType, int> requestedNumDuplicatesOfType = new Dictionary <SimObjType, int>(); //List<SimObjType> listOfExcludedReceptacles = new List<SimObjType>(); HashSet <GameObject> originalObjects = new HashSet <GameObject>(SpawnedObjects); if (numDuplicatesOfType == null) { numDuplicatesOfType = new ObjectTypeCount[0]; } foreach (ObjectTypeCount repeatCount in numDuplicatesOfType) { SimObjType objType = (SimObjType)System.Enum.Parse(typeof(SimObjType), repeatCount.objectType); requestedNumDuplicatesOfType[objType] = repeatCount.count; } //now lets go through all pickupable sim objects that are in the current scene foreach (GameObject go in SpawnedObjects) { SimObjPhysics sop = null; sop = go.GetComponent <SimObjPhysics>(); //add object types in the current scene to the typeToObjectList if not already on it if (!typeToObjectList.ContainsKey(sop.ObjType)) { typeToObjectList[sop.ObjType] = new List <SimObjPhysics>(); } //Add this sim object to the list if the sim object's type matches the key in typeToObjectList if (!requestedNumDuplicatesOfType.ContainsKey(sop.ObjType) || (typeToObjectList[sop.ObjType].Count < requestedNumDuplicatesOfType[sop.ObjType])) { typeToObjectList[sop.ObjType].Add(sop); } } //keep track of the sim objects we are making duplicates of List <GameObject> simObjectDuplicates = new List <GameObject>(); //keep track of the sim objects that have not been duplicated List <GameObject> unduplicatedSimObjects = new List <GameObject>(); //ok now lets go through each object type in the dictionary foreach (SimObjType sopType in typeToObjectList.Keys) { //we found a matching SimObjType and the requested count of duplicates is bigger than how many of that //object are currently in the scene if (requestedNumDuplicatesOfType.ContainsKey(sopType) && requestedNumDuplicatesOfType[sopType] > typeToObjectList[sopType].Count) { foreach (SimObjPhysics sop in typeToObjectList[sopType]) { simObjectDuplicates.Add(sop.gameObject); } int numExtra = requestedNumDuplicatesOfType[sopType] - typeToObjectList[sopType].Count; //let's instantiate the duplicates now for (int j = 0; j < numExtra; j++) { // Add a copy of the item to try and match the requested number of duplicates SimObjPhysics sop = typeToObjectList[sopType][UnityEngine.Random.Range(0, typeToObjectList[sopType].Count - 1)]; SimObjPhysics copy = Instantiate(sop); copy.name += "_random_copy_" + j; copy.ObjectID = sop.ObjectID + "_copy_" + j; copy.objectID = copy.ObjectID; simObjectDuplicates.Add(copy.gameObject); } } //this object is not one that needs duplicates, so just add it to the unduplicatedSimObjects list else { foreach (SimObjPhysics sop in typeToObjectList[sopType]) { unduplicatedSimObjects.Add(sop.gameObject); } } } unduplicatedSimObjects.Shuffle_(seed); simObjectDuplicates.AddRange(unduplicatedSimObjects); List <SimObjPhysics> ReceptaclesInScene = new List <SimObjPhysics>(); ReceptaclesInScene = GatherAllReceptaclesInScene(); //ok now simObjectDuplicates should have all the game objects, duplicated and unduplicated foreach (GameObject go in simObjectDuplicates) { AllowedToSpawnInAndExistsInScene = new Dictionary <SimObjType, List <SimObjPhysics> >(); SimObjType goObjType = go.GetComponent <SimObjPhysics>().ObjType; bool typefoundindictionary = ReceptacleRestrictions.PlacementRestrictions.ContainsKey(goObjType); if (typefoundindictionary) { TypesOfObjectsPrefabIsAllowedToSpawnIn = new List <SimObjType>(ReceptacleRestrictions.PlacementRestrictions[goObjType]); //remove from list if receptacle isn't in this scene //compare to receptacles that exist in scene, get the ones that are the same foreach (SimObjPhysics sop in ReceptaclesInScene) { // don't random spawn in objects that are pickupable to prevent Egg spawning in Plate with the plate spawned in Cabinet.... bool allowed = false; if (sop.PrimaryProperty != SimObjPrimaryProperty.CanPickup) { if (SpawnOnlyOutside) { if (ReceptacleRestrictions.SpawnOnlyOutsideReceptacles.Contains(sop.ObjType) && TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) { allowed = true; } } else if (TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) { allowed = true; } } if (allowed) { if (!AllowedToSpawnInAndExistsInScene.ContainsKey(sop.ObjType)) { AllowedToSpawnInAndExistsInScene[sop.ObjType] = new List <SimObjPhysics>(); } AllowedToSpawnInAndExistsInScene[sop.ObjType].Add(sop); } } } //not found in dictionary! else { #if UNITY_EDITOR Debug.Log(go.name + "'s Type is not in the ReceptacleRestrictions dictionary!"); #endif break; } // Now we have an updated list of receptacles in the scene that are also in the list // of valid receptacles for this given game object "go" that we are currently checking this loop if (AllowedToSpawnInAndExistsInScene.Count > 0) { InstantiatePrefabTest spawner = gameObject.GetComponent <InstantiatePrefabTest>(); List <ReceptacleSpawnPoint> targetReceptacleSpawnPoints; bool spawned = false; foreach (SimObjPhysics sop in ShuffleSimObjPhysicsDictList(AllowedToSpawnInAndExistsInScene, seed)) { //if the receptacle, sop, is in the list of receptacles to exclude, skip over it and try the other Receptacles if (excludedReceptacles.Contains(sop.Type)) { continue; } //check if the target Receptacle is an ObjectSpecificReceptacle //if so, if this game object is compatible with the ObjectSpecific restrictions, place it! //this is specifically for things like spawning a mug inside a coffee maker if (sop.DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty.ObjectSpecificReceptacle)) { ObjectSpecificReceptacle osr = sop.GetComponent <ObjectSpecificReceptacle>(); if (osr.HasSpecificType(go.GetComponent <SimObjPhysics>().ObjType)) { //in the random spawn function, we need this additional check because there isn't a chance for //the physics update loop to fully update osr.isFull() correctly, which can cause multiple objects //to be placed on the same spot (ie: 2 pots on the same burner) if (osr.attachPoint.transform.childCount > 0) { break; } //perform additional checks if this is a Stove Burner! if (sop.GetComponent <SimObjPhysics>().Type == SimObjType.StoveBurner) { if (StoveTopCheckSpawnArea(go.GetComponent <SimObjPhysics>(), osr.attachPoint.transform.position, osr.attachPoint.transform.rotation, false) == true) { //print("moving object now"); go.transform.position = osr.attachPoint.position; go.transform.SetParent(osr.attachPoint.transform); go.transform.localRotation = Quaternion.identity; go.GetComponent <Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Discrete; go.GetComponent <Rigidbody>().isKinematic = true; HowManyCouldntSpawn--; spawned = true; break; } } //for everything else (coffee maker, toilet paper holder, etc) just place it if there is nothing attached else { go.transform.position = osr.attachPoint.position; go.transform.SetParent(osr.attachPoint.transform); go.transform.localRotation = Quaternion.identity; Rigidbody rb = go.GetComponent <Rigidbody>(); rb.collisionDetectionMode = CollisionDetectionMode.Discrete; rb.isKinematic = true; HowManyCouldntSpawn--; spawned = true; break; } } } targetReceptacleSpawnPoints = sop.ReturnMySpawnPoints(false); //first shuffle the list so it's raaaandom targetReceptacleSpawnPoints.Shuffle_(seed); if (spawner.PlaceObjectReceptacle(targetReceptacleSpawnPoints, go.GetComponent <SimObjPhysics>(), StaticPlacement, maxPlacementAttempts, 90, true)) { HowManyCouldntSpawn--; spawned = true; break; } } if (!spawned) { #if UNITY_EDITOR Debug.Log(go.name + " could not be spawned."); #endif //go.GetComponent<SimpleSimObj>().IsDisabled = true; if (!originalObjects.Contains(go)) { go.SetActive(false); Destroy(go); } } } } } else { ///XXX: add exception in at some point throw new NotImplementedException(); } #if UNITY_EDITOR if (HowManyCouldntSpawn > 0) { Debug.Log(HowManyCouldntSpawn + " object(s) could not be spawned into the scene!"); } Masterwatch.Stop(); var elapsed = Masterwatch.ElapsedMilliseconds; print("total time: " + elapsed); #endif SetupScene(); return(true); }
protected virtual void OnEnable() { if (SceneManager.Current == null) { return; } //reset this in case one of our scripts was interrupted isAnimating = false; //store this beacause we'll be parenting / unparenting objects rapidly //and the floating point math can get wonky real quick startupScale = transform.lossyScale; //the receptacle script is guaranteed to run before sim obj //so it's safe to get our colliders here - we won't accidentally //grab colliders of nested objects receptacle = gameObject.GetComponent <Receptacle> (); animator = gameObject.GetComponent <Animator> (); rearrangeable = gameObject.GetComponent <Rearrangeable> (); colliders = gameObject.GetComponentsInChildren <Collider> (); //if the manip type isn't inventory, use the presence of the rearrangeable component to determine type switch (Manipulation) { case SimObjManipType.Inventory: break; case SimObjManipType.Static: case SimObjManipType.StaticNoPlacement: Manipulation = (rearrangeable != null) ? SimObjManipType.Rearrangeable : Manipulation; break; } #if UNITY_EDITOR if (Type == SimObjType.Undefined) { //check our prefab just in case the enum has gotten disconnected GameObject prefabParent = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(gameObject) as GameObject; if (prefabParent != null) { SimObj ps = prefabParent.GetComponent <SimObj> (); if (ps != null) { Type = ps.Type; } } } if (!Application.isPlaying) { foreach (Collider c in colliders) { c.gameObject.layer = SimUtil.RaycastVisibleLayer; } //if we're type static, set our renderers to static so navmeshes generate correctly MeshRenderer [] renderers = gameObject.GetComponentsInChildren <MeshRenderer> (); foreach (MeshRenderer mr in renderers) { switch (Manipulation) { case SimObjManipType.Static: mr.gameObject.isStatic = true; UnityEditor.GameObjectUtility.SetNavMeshArea(mr.gameObject, PlacementManager.NavmeshShelfArea); UnityEditor.GameObjectUtility.SetStaticEditorFlags(mr.gameObject, UnityEditor.StaticEditorFlags.NavigationStatic | UnityEditor.StaticEditorFlags.BatchingStatic); break; case SimObjManipType.StaticNoPlacement: mr.gameObject.isStatic = true; UnityEditor.GameObjectUtility.SetNavMeshArea(mr.gameObject, PlacementManager.NavemeshNoneArea); UnityEditor.GameObjectUtility.SetStaticEditorFlags(mr.gameObject, UnityEditor.StaticEditorFlags.NavigationStatic | UnityEditor.StaticEditorFlags.BatchingStatic); break; default: mr.gameObject.isStatic = false; UnityEditor.GameObjectUtility.SetNavMeshArea(mr.gameObject, PlacementManager.NavemeshNoneArea); UnityEditor.GameObjectUtility.SetStaticEditorFlags(mr.gameObject, 0); break; } } } #endif Rigidbody rb = GetComponent <Rigidbody> (); if (rb == null) { rb = gameObject.AddComponent <Rigidbody> (); } if (SceneManager.Current.LocalPhysicsMode == ScenePhysicsMode.Dynamic) { switch (Manipulation) { case SimObjManipType.Static: case SimObjManipType.StaticNoPlacement: rb.isKinematic = true; break; default: rb.isKinematic = false; break; } } else { rb.isKinematic = true; } RecalculatePoints(); if (Application.isPlaying) { if (startupTransform == null) { switch (Manipulation) { case SimObjManipType.Inventory: //if we can enter inventory //create a transform that stores our startup position startupTransform = new GameObject(name + "_Startup").transform; startupTransform.position = transform.position; startupTransform.rotation = transform.rotation; startupTransform.localScale = transform.localScale; startupTransform.parent = SceneManager.Current.ObjectsParent; startupTransform.SetAsLastSibling(); break; default: break; } } //make sure we're visible gameObject.layer = SimUtil.RaycastVisibleLayer; //force-update our colliders visibleToRaycasts = false; VisibleToRaycasts = true; } #if UNITY_EDITOR CheckForErrors(); #endif }
//place each object in the array of objects that should appear in this scene randomly in valid receptacles //a seed of 0 is the default positions placed by hand(?) public bool RandomSpawnRequiredSceneObjects( int seed, bool SpawnOnlyOutside, int maxPlacementAttempts, bool StaticPlacement, ObjectTypeCount[] numRepeats, ObjectTypeCount[] emptyReceptacleSpots ) { #if UNITY_EDITOR var Masterwatch = System.Diagnostics.Stopwatch.StartNew(); #endif if (RequiredObjects.Count == 0) { #if UNITY_EDITOR Debug.Log("No objects in Required Objects array, please add them in editor"); #endif return(false); } UnityEngine.Random.InitState(seed); List <SimObjType> TypesOfObjectsPrefabIsAllowedToSpawnIn = new List <SimObjType>(); Dictionary <SimObjType, List <SimObjPhysics> > AllowedToSpawnInAndExistsInScene = new Dictionary <SimObjType, List <SimObjPhysics> >(); int HowManyCouldntSpawn = RequiredObjects.Count; // GameObject topLevelObject = GameObject.Find("Objects"); // PhysicsRemoteFPSAgentController controller = GameObject.FindObjectsOfType<PhysicsRemoteFPSAgentController>()[0]; // foreach (GameObject go in SpawnedObjects) { // go.SetActive(true); // SimObjPhysics sop = go.GetComponent<SimObjPhysics>(); // sop.transform.parent = topLevelObject.transform; // sop.transform.position = new Vector3(0.0f, controller.sceneBounds.min.y - 10f, 0.0f); // go.GetComponent<Rigidbody>().isKinematic = true; // } //if we already spawned objects, lets just move them around if (SpawnedObjects.Count > 0) { HowManyCouldntSpawn = SpawnedObjects.Count; //for each object in RequiredObjects, start a list of what objects it's allowed //to spawn in by checking the PlacementRestrictions dictionary Dictionary <SimObjType, List <SimObjPhysics> > typeToObjectList = new Dictionary <SimObjType, List <SimObjPhysics> >(); List <GameObject> simObjectCopies = new List <GameObject>(); List <GameObject> unduplicatedSimObjects = new List <GameObject>(); Dictionary <SimObjType, int> requestedNumRepeats = new Dictionary <SimObjType, int>(); Dictionary <SimObjType, int> minFreePerReceptacleType = new Dictionary <SimObjType, int>(); HashSet <GameObject> originalObjects = new HashSet <GameObject>(SpawnedObjects); if (numRepeats == null) { numRepeats = new ObjectTypeCount[0]; } foreach (ObjectTypeCount repeatCount in numRepeats) { SimObjType objType = (SimObjType)System.Enum.Parse(typeof(SimObjType), repeatCount.objectType); requestedNumRepeats[objType] = repeatCount.count; } if (emptyReceptacleSpots == null) { emptyReceptacleSpots = new ObjectTypeCount[0]; } foreach (ObjectTypeCount emptyReceptacleSpot in emptyReceptacleSpots) { SimObjType objType = (SimObjType)System.Enum.Parse(typeof(SimObjType), emptyReceptacleSpot.objectType); minFreePerReceptacleType[objType] = emptyReceptacleSpot.count; } foreach (GameObject go in SpawnedObjects) { SimObjPhysics gop = null; gop = go.GetComponent <SimObjPhysics>(); if (!typeToObjectList.ContainsKey(gop.ObjType)) { typeToObjectList[gop.ObjType] = new List <SimObjPhysics>(); } if (!requestedNumRepeats.ContainsKey(gop.ObjType) || (typeToObjectList[gop.ObjType].Count < requestedNumRepeats[gop.ObjType])) { typeToObjectList[gop.ObjType].Add(gop); } } foreach (SimObjType sopType in typeToObjectList.Keys) { if (requestedNumRepeats.ContainsKey(sopType) && requestedNumRepeats[sopType] > typeToObjectList[sopType].Count) { foreach (SimObjPhysics gop in typeToObjectList[sopType]) { simObjectCopies.Add(gop.gameObject); } int numExtra = requestedNumRepeats[sopType] - typeToObjectList[sopType].Count; for (int j = 0; j < numExtra; j++) { // Add a copy of the item. SimObjPhysics gop = typeToObjectList[sopType][UnityEngine.Random.Range(0, typeToObjectList[sopType].Count - 1)]; SimObjPhysics copy = Instantiate(gop); copy.name += "_random_copy_" + j; copy.UniqueID = gop.UniqueID + "_copy_" + j; copy.uniqueID = copy.UniqueID; //Randomizer randomizer = (copy.gameObject.GetComponentInChildren<Randomizer>() as Randomizer); //randomizer.Randomize(rnd.Next(0, 2147483647)); simObjectCopies.Add(copy.gameObject); } } else { foreach (SimObjPhysics gop in typeToObjectList[sopType]) { unduplicatedSimObjects.Add(gop.gameObject); } } } unduplicatedSimObjects.Shuffle_(); simObjectCopies.AddRange(unduplicatedSimObjects); foreach (GameObject go in simObjectCopies) { AllowedToSpawnInAndExistsInScene = new Dictionary <SimObjType, List <SimObjPhysics> >(); SimObjType goObjType = go.GetComponent <SimObjPhysics>().ObjType; bool typefoundindictionary = ReceptacleRestrictions.PlacementRestrictions.ContainsKey(goObjType); if (typefoundindictionary) { TypesOfObjectsPrefabIsAllowedToSpawnIn = new List <SimObjType>(ReceptacleRestrictions.PlacementRestrictions[goObjType]); //remove from list if receptacle isn't in this scene //compare to receptacles that exist in scene, get the ones that are the same // Todo: make a copy of receptacles and remove the ones where things can't be placed. Then clean up the placement code. foreach (SimObjPhysics sop in ReceptaclesInScene) { // don't random spawn in objects that are pickupable to prevent Egg spawning in Plate with the plate spawned in Cabinet.... bool allowed = false; if (sop.PrimaryProperty != SimObjPrimaryProperty.CanPickup) { if (SpawnOnlyOutside) { if (ReceptacleRestrictions.SpawnOnlyOutsideReceptacles.Contains(sop.ObjType) && TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) { allowed = true; } } else if (TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) { allowed = true; } } if (allowed) { if (!AllowedToSpawnInAndExistsInScene.ContainsKey(sop.ObjType)) { AllowedToSpawnInAndExistsInScene[sop.ObjType] = new List <SimObjPhysics>(); } AllowedToSpawnInAndExistsInScene[sop.ObjType].Add(sop); } } } //not found in dictionary! else { #if UNITY_EDITOR Debug.Log(go.name + "'s Type is not in the ReceptacleRestrictions dictionary!"); #endif break; } // Now we have an updated list of receptacles in the scene that are also in the list // of valid receptacles for this given game object "go" that we are currently checking this loop if (AllowedToSpawnInAndExistsInScene.Count > 0) { //SimObjPhysics targetReceptacle; InstantiatePrefabTest spawner = gameObject.GetComponent <InstantiatePrefabTest>(); List <ReceptacleSpawnPoint> targetReceptacleSpawnPoints; //each sop here is a valid receptacle bool spawned = false; foreach (SimObjPhysics sop in ShuffleSimObjPhysicsDictList(AllowedToSpawnInAndExistsInScene)) { //targetReceptacle = sop; //check if the target Receptacle is an ObjectSpecificReceptacle //if so, if this game object is compatible with the ObjectSpecific restrictions, place it! //this is specifically for things like spawning a mug inside a coffee maker if (sop.DoesThisObjectHaveThisSecondaryProperty(SimObjSecondaryProperty.ObjectSpecificReceptacle)) { ObjectSpecificReceptacle osr = sop.GetComponent <ObjectSpecificReceptacle>(); if (osr.HasSpecificType(go.GetComponent <SimObjPhysics>().ObjType)) { //in the random spawn function, we need this additional check because there isn't a chance for //the physics update loop to fully update osr.isFull() correctly, which can cause multiple objects //to be placed on the same spot (ie: 2 pots on the same burner) if (osr.attachPoint.transform.childCount > 0) { break; } //perform additional checks if this is a Stove Burner! if (sop.GetComponent <SimObjPhysics>().Type == SimObjType.StoveBurner) { if (StoveTopCheckSpawnArea(go.GetComponent <SimObjPhysics>(), osr.attachPoint.transform.position, osr.attachPoint.transform.rotation, false) == true) { //print("moving object now"); go.transform.position = osr.attachPoint.position; go.transform.SetParent(osr.attachPoint.transform); go.transform.localRotation = Quaternion.identity; go.GetComponent <Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Discrete; go.GetComponent <Rigidbody>().isKinematic = true; HowManyCouldntSpawn--; spawned = true; // print(go.transform.name + " was spawned in " + sop.transform.name); // #if UNITY_EDITOR // //Debug.Log(go.name + " succesfully placed in " +sop.UniqueID); // #endif break; } } //for everything else (coffee maker, toilet paper holder, etc) just place it if there is nothing attached else { go.transform.position = osr.attachPoint.position; go.transform.SetParent(osr.attachPoint.transform); go.transform.localRotation = Quaternion.identity; Rigidbody rb = go.GetComponent <Rigidbody>(); rb.collisionDetectionMode = CollisionDetectionMode.Discrete; rb.isKinematic = true; HowManyCouldntSpawn--; spawned = true; break; } } } targetReceptacleSpawnPoints = sop.ReturnMySpawnPoints(false); //first shuffle the list so it's raaaandom targetReceptacleSpawnPoints.Shuffle_(); //try to spawn it, and if it succeeds great! if not uhhh... #if UNITY_EDITOR // var watch = System.Diagnostics.Stopwatch.StartNew(); #endif if (spawner.PlaceObjectReceptacle(targetReceptacleSpawnPoints, go.GetComponent <SimObjPhysics>(), StaticPlacement, maxPlacementAttempts, 90, true, minFreePerReceptacleType)) //we spawn them stationary so things don't fall off of ledges { HowManyCouldntSpawn--; spawned = true; #if UNITY_EDITOR // watch.Stop(); // var y = watch.ElapsedMilliseconds; //print( "SUCCESFULLY placing " + go.transform.name+ " in " + sop.transform.name); #endif break; } #if UNITY_EDITOR // watch.Stop(); // var elapsedMs = watch.ElapsedMilliseconds; // print("time for trying, but FAILING, to place " + go.transform.name + " in " + sop.transform.name + ": " + elapsedMs + " ms"); #endif } if (!spawned) { #if UNITY_EDITOR Debug.Log(go.name + " could not be spawned."); #endif //go.GetComponent<SimpleSimObj>().IsDisabled = true; if (!originalObjects.Contains(go)) { go.SetActive(false); Destroy(go); } } } } } else { throw new NotImplementedException(); } // Debug code to see where every object is spawning // string s = ""; // foreach (GameObject sop in SpawnedObjects) { // s += sop.name + ": " + sop.transform.parent.gameObject.name + ",\t"; // } // Debug.Log(s); ///////////////KEEP THIS DEPRECATED STUFF - In case we want to spawn in objects that don't currently exist in the scene, that logic is below//////////////// // //we have not spawned objects, so instantiate them here first // else // { // //for each object in RequiredObjects, start a list of what objects it's allowed // //to spawn in by checking the PlacementRestrictions dictionary // foreach(GameObject go in RequiredObjects) // { // TypesOfObjectsPrefabIsAllowedToSpawnIn.Clear(); // AllowedToSpawnInAndExistsInScene.Clear(); // SimObjType goObjType = go.GetComponent<SimObjPhysics>().ObjType; // bool typefoundindictionary = ReceptacleRestrictions.PlacementRestrictions.ContainsKey(goObjType); // if(typefoundindictionary) // { // TypesOfObjectsPrefabIsAllowedToSpawnIn = new List<SimObjType>(ReceptacleRestrictions.PlacementRestrictions[goObjType]); // //remove from list if receptacle isn't in this scene // //compare to receptacles that exist in scene, get the ones that are the same // foreach(SimObjPhysics sop in ReceptaclesInScene) // { // if(SpawnOnlyOutside) // { // if(ReceptacleRestrictions.SpawnOnlyOutsideReceptacles.Contains(sop.ObjType) && TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) // { // AllowedToSpawnInAndExistsInScene.Add(sop); // } // } // else if(TypesOfObjectsPrefabIsAllowedToSpawnIn.Contains(sop.ObjType)) // { // //updated list of valid receptacles in scene // AllowedToSpawnInAndExistsInScene.Add(sop); // } // } // } // else // { // #if UNITY_EDITOR // Debug.Log(go.name +"'s Type is not in the ReceptacleRestrictions dictionary!"); // #endif // break; // } // // // //now we have an updated list of SimObjPhys of receptacles in the scene that are also in the list // // // //of valid receptacles for this given game object "go" that we are currently checking this loop // if(AllowedToSpawnInAndExistsInScene.Count > 0) // { // SimObjPhysics targetReceptacle; // InstantiatePrefabTest spawner = gameObject.GetComponent<InstantiatePrefabTest>(); // List<ReceptacleSpawnPoint> targetReceptacleSpawnPoints; // //RAAANDOM! // ShuffleSimObjPhysicsList(AllowedToSpawnInAndExistsInScene); // //bool diditspawn = false; // GameObject temp = Instantiate(go, new Vector3(0, 100, 0), Quaternion.identity); // temp.transform.name = go.name; // //print("create object"); // //GameObject temp = PrefabUtility.InstantiatePrefab(go as GameObject) as GameObject; // temp.GetComponent<Rigidbody>().isKinematic = true; // //spawn it waaaay outside of the scene and then we will try and move it in a moment here, hold your horses // temp.transform.position = new Vector3(0, 100, 0);//GameObject.Find("FPSController").GetComponent<PhysicsRemoteFPSAgentController>().AgentHandLocation(); // foreach(SimObjPhysics sop in AllowedToSpawnInAndExistsInScene) // { // targetReceptacle = sop; // targetReceptacleSpawnPoints = targetReceptacle.ReturnMySpawnPoints(false); // //first shuffle the list so it's raaaandom // ShuffleReceptacleSpawnPointList(targetReceptacleSpawnPoints); // //try to spawn it, and if it succeeds great! if not uhhh... // #if UNITY_EDITOR // var watch = System.Diagnostics.Stopwatch.StartNew(); // #endif // if(spawner.PlaceObjectReceptacle(targetReceptacleSpawnPoints, temp.GetComponent<SimObjPhysics>(), true, maxcount, 360, true)) //we spawn them stationary so things don't fall off of ledges // { // //Debug.Log(go.name + " succesfully spawned"); // //diditspawn = true; // HowManyCouldntSpawn--; // SpawnedObjects.Add(temp); // break; // } // #if UNITY_EDITOR // watch.Stop(); // var elapsedMs = watch.ElapsedMilliseconds; // print("time for PlacfeObject: " + elapsedMs); // #endif // } // } // } // } //we can use this to report back any failed spawns if we want that info at some point ? #if UNITY_EDITOR if (HowManyCouldntSpawn > 0) { Debug.Log(HowManyCouldntSpawn + " object(s) could not be spawned into the scene!"); } Masterwatch.Stop(); var elapsed = Masterwatch.ElapsedMilliseconds; print("total time: " + elapsed); #endif //Debug.Log("Iteration through Required Objects finished"); SetupScene(); return(true); }
public void RandomInitialize(ServerAction response) { this.excludeObjectIds = response.excludeObjectIds; System.Random rnd = new System.Random(response.randomSeed); SimObj[] simObjects = GameObject.FindObjectsOfType(typeof(SimObj)) as SimObj[]; int pickupableCount = 0; for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; if (IsPickupable(so)) { pickupableCount++; SimUtil.TakeItem(so); } if (IsOpenable(so) && response.randomizeOpen) { if (rnd.NextDouble() < 0.5) { openSimObj(so); } else { closeSimObj(so); } } } //shuffle objects for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; int randomIndex = rnd.Next(i, simObjects.Length); simObjects [i] = simObjects [randomIndex]; simObjects [randomIndex] = so; } Dictionary <SimObjType, HashSet <SimObjType> > receptacleObjects = new Dictionary <SimObjType, HashSet <SimObjType> > (); foreach (ReceptacleObjectList rol in response.receptacleObjects) { HashSet <SimObjType> objectTypes = new HashSet <SimObjType> (); SimObjType receptacleType = (SimObjType)Enum.Parse(typeof(SimObjType), rol.receptacleObjectType); foreach (string itemObjectType in rol.itemObjectTypes) { objectTypes.Add((SimObjType)Enum.Parse(typeof(SimObjType), itemObjectType)); } receptacleObjects.Add(receptacleType, objectTypes); } bool[] consumedObjects = new bool[simObjects.Length]; int randomTries = 0; HashSet <SimObjType> seenObjTypes = new HashSet <SimObjType> (); while (pickupableCount > 0) { if (randomTries > 5) { Debug.Log("Pickupable count still at, but couldn't place all objects: " + pickupableCount); break; } randomTries++; foreach (SimObj so in simObjects) { if (so.IsReceptacle && !excludeObject(so)) { int totalRandomObjects = rnd.Next(1, so.Receptacle.Pivots.Length + 1); for (int i = 0; i < totalRandomObjects; i++) { for (int j = 0; j < simObjects.Length; j++) { if (Array.Exists(response.excludeReceptacleObjectPairs, e => e.objectId == simObjects [j].UniqueID && e.receptacleObjectId == so.UniqueID)) { Debug.Log("skipping object id receptacle id pair, " + simObjects [j].UniqueID + " " + so.UniqueID); continue; } if (!consumedObjects[j] && IsPickupable(simObjects[j]) && receptacleObjects[so.Type].Contains(simObjects[j].Type) && (!response.uniquePickupableObjectTypes || !seenObjTypes.Contains(simObjects[j].Type)) && SimUtil.AddItemToReceptacle(simObjects [j], so.Receptacle)) { consumedObjects [j] = true; seenObjTypes.Add(simObjects [j].Type); pickupableCount--; break; } } } } } } }
public void RandomInitialize(ServerAction response) { bool success = true; this.excludeObjectIds = response.excludeObjectIds; Dictionary <SimObjType, HashSet <SimObjType> > receptacleObjects = new Dictionary <SimObjType, HashSet <SimObjType> > (); HashSet <SimObjType> pickupable = new HashSet <SimObjType> (); foreach (ReceptacleObjectList rol in response.receptacleObjects) { HashSet <SimObjType> objectTypes = new HashSet <SimObjType> (); SimObjType receptacleType = (SimObjType)Enum.Parse(typeof(SimObjType), rol.receptacleObjectType); foreach (string itemObjectType in rol.itemObjectTypes) { objectTypes.Add((SimObjType)Enum.Parse(typeof(SimObjType), itemObjectType)); pickupable.Add((SimObjType)Enum.Parse(typeof(SimObjType), itemObjectType)); } receptacleObjects.Add(receptacleType, objectTypes); } Debug.Log("random seed:Z " + response.randomSeed); System.Random rnd = new System.Random(response.randomSeed); SimObj[] simObjects = GameObject.FindObjectsOfType(typeof(SimObj)) as SimObj[]; // Sorting to ensure that our randomization is deterministic when using a seed // without sorting, there is no guarantee how the objects will get returned from from FindObjectsOfType // so the shuffle becomes non-deterministic Array.Sort(simObjects, delegate(SimObj a, SimObj b) { return(a.UniqueID.CompareTo(b.UniqueID)); }); int pickupableCount = 0; for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; if (IsPickupable(so)) { pickupableCount++; SimUtil.TakeItem(so); } if (IsOpenable(so) && response.randomizeOpen) { if (rnd.NextDouble() < 0.5) { openSimObj(so); } else { closeSimObj(so); } } } //shuffle objects rnd = new System.Random(response.randomSeed); for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; int randomIndex = rnd.Next(i, simObjects.Length); simObjects [i] = simObjects [randomIndex]; simObjects [randomIndex] = so; } rnd = new System.Random(response.randomSeed); List <SimObj> simObjectsFiltered = new List <SimObj> (); for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; if (IsPickupable(so) && pickupable.Contains(so.Type)) { double val = rnd.NextDouble(); if (val > response.removeProb) { // Keep the item int numRepeats = 1; if (response.maxNumRepeats > 1) { numRepeats = rnd.Next(1, response.maxNumRepeats); } for (int j = 0; j < numRepeats; j++) { // Add a copy of the item. SimObj copy = Instantiate(so); copy.name += "" + j; copy.UniqueID = so.UniqueID + "_copy_" + j; simObjectsFiltered.Add(copy); } } else { pickupableCount--; } } else { simObjectsFiltered.Add(simObjects [i]); } } simObjects = simObjectsFiltered.ToArray(); int randomTries = 0; HashSet <SimObjType> seenObjTypes = new HashSet <SimObjType> (); rnd = new System.Random(response.randomSeed); while (pickupableCount > 0) { if (randomTries > 5) { Debug.Log("Pickupable count still at, but couldn't place all objects: " + pickupableCount); success = false; break; } randomTries++; int[] randomOrder = new int[simObjects.Length]; for (int rr = simObjects.Length - 1; rr >= 0; rr--) { int randomLoc = simObjects.Length - 1 - rnd.Next(0, (simObjects.Length - rr)); randomOrder [rr] = randomOrder [randomLoc]; randomOrder [randomLoc] = rr; } for (int ss = 0; ss < simObjects.Length; ss++) { int j = randomOrder [ss]; foreach (SimObj so in simObjects) { if (so.IsReceptacle && !excludeObject(so)) { if (response.excludeReceptacleObjectPairs != null && Array.Exists(response.excludeReceptacleObjectPairs, e => e.objectId == simObjects [j].UniqueID && e.receptacleObjectId == so.UniqueID)) { //Debug.Log ("skipping object id receptacle id pair, " + simObjects [j].UniqueID + " " + so.UniqueID); continue; } if (IsPickupable(simObjects [j]) && receptacleObjects.ContainsKey(so.Type) && receptacleObjects [so.Type].Contains(simObjects [j].Type) && (!response.uniquePickupableObjectTypes || !seenObjTypes.Contains(simObjects [j].Type)) && SimUtil.AddItemToReceptacle(simObjects [j], so.Receptacle)) { //Debug.Log ("Put " + simObjects [j].Type + " " + simObjects[j].name + " in " + so.Type); seenObjTypes.Add(simObjects [j].Type); pickupableCount--; break; } } } } } if (response.randomizeObjectAppearance) { // Use a random texture for each object individually. rnd = new System.Random(response.randomSeed); for (int i = 0; i < simObjects.Length; i++) { SimObj so = simObjects [i]; if (so.gameObject.activeSelf) { Randomizer randomizer = (so.gameObject.GetComponentInChildren <Randomizer> () as Randomizer); if (randomizer != null) { randomizer.Randomize(rnd.Next(0, 2147483647)); } } } } if (imageSynthesis != null) { imageSynthesis.OnSceneChange(); } actionFinished(success); }