Пример #1
0
    //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);
    }
Пример #2
0
    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
        }
    }
Пример #3
0
    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]);
    }
Пример #4
0
    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;
    }
Пример #6
0
 public bool haveTypeInventory(SimObjType objectType)
 {
     foreach (SimObj so in inventory.Values)
     {
         if (so.Type == objectType)
         {
             return(true);
         }
     }
     return(false);
 }
Пример #7
0
    //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);
    }
Пример #8
0
    public bool HasSpecificType(SimObjType check)
    {
        bool result = false;

        foreach (SimObjType sot in SpecificTypes)
        {
            if (sot == check)
            {
                result = true;
            }
        }

        return(result);
    }
Пример #9
0
    //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);
    }
Пример #10
0
    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
    }
Пример #11
0
    //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;
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #13
0
        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);
        }