//TODO: why is this called try place ground if you can specify the anchor type?
    /// <summary>
    /// Tries to place object on the ground.
    /// </summary>
    /// <returns><c>true</c>, if location to spawn object is found, <c>false</c> otherwise.</returns>
    /// <param name="bounds">Bounds.</param>
    /// <param name="anchorType">Anchor type, can be Ground, Ceiling, or Wall.</param>
    /// <param name="finalX">x coord where object should spawn.</param>
    /// <param name="finalY">y coord where object should spawn.</param>
    /// <param name="modScale">Modified scale.</param>
    /// <seealso cref="PrefabDatabase.GetSceneScale">modScale is retrieved via this method.</seealso>
    /// <param name="whichPlane">Which height plane the object should spawn on.</param>
    ///
    private bool TryPlaceGroundObject(Bounds bounds, float modScale, GeneratablePrefab.AttachAnchor anchorType, out int finalX, out int finalY, out HeightPlane whichPlane)
    {
        finalX = 0;
        finalY = 0;
        whichPlane = null;

        /*
        modScale = 1.0f;
        if (shouldUseStandardizedSize)
        {
            modScale = Mathf.Min(
                standardizedSize.x / bounds.extents.x,
                standardizedSize.y / bounds.extents.y,
                standardizedSize.z / bounds.extents.z);
        }
        */

        Bounds testBounds = new Bounds(bounds.center, modScale * 2f * bounds.extents);
        int boundsWidth = Mathf.CeilToInt(2 * testBounds.extents.x / gridDim);
        int boundsLength = Mathf.CeilToInt(2 * testBounds.extents.z / gridDim);
        float boundsHeight = testBounds.extents.y;

        List<int> randomPlanesOrder = new List<int>();
        int randomOrderValue = _rand.Next(0, int.MaxValue);

        for(int i = 0; i < _allHeightPlanes.Count; ++i)
            randomPlanesOrder.Insert(randomOrderValue % (randomPlanesOrder.Count + 1), i);
        if (_forceStackObject)
            randomPlanesOrder.Remove(0);

        bool foundValid = false;
        foreach(int planeNum in randomPlanesOrder)
        {
            HeightPlane curHeightPlane = _allHeightPlanes[planeNum];
            // Make sure we aren't hitting the ceiling
            if (boundsHeight >= curHeightPlane.planeHeight || curHeightPlane.cornerPos.y + boundsHeight >= _curRoomHeight)
                continue;
            // Only get grid squares which are valid to place on.
            List<GridInfo> validValues = curHeightPlane.myGridSpots.FindAll((GridInfo info)=>{return info.rightSquares >= (boundsWidth-1) && info.downSquares > (boundsLength-1) && !info.inUse;});
            while(validValues.Count > 0 && !foundValid)
            {
                int randIndex = _rand.Next(0, validValues.Count);
                GridInfo testInfo = validValues[randIndex];
                validValues.RemoveAt(randIndex);
                if (curHeightPlane.TestGrid(testInfo, boundsWidth, boundsLength))
                {
                    Vector3 centerPos = curHeightPlane.cornerPos + new Vector3(gridDim * (testInfo.x + (0.5f * boundsWidth)), 0.1f+boundsHeight, gridDim * (testInfo.y + (0.5f * boundsLength)));
                    if (anchorType == GeneratablePrefab.AttachAnchor.Ceiling)
                        centerPos.y = _roomCornerPos.y + _curRoomHeight - (0.1f+boundsHeight);
                    if (Physics.CheckBox(centerPos, testBounds.extents))
                    {
                        // Found another object here, let the plane know that there's something above messing with some of the squares
                        string debugText = "";
                        Collider[] hitObjs = Physics.OverlapBox(centerPos, testBounds.extents);
                        HashSet<string> hitObjNames = new HashSet<string>();
                        foreach(Collider col in hitObjs)
                        {
                            if (col.attachedRigidbody != null)
                                hitObjNames.Add(col.attachedRigidbody.name);
                            else
                                hitObjNames.Add(col.gameObject.name );
                            curHeightPlane.RestrictBounds(col.bounds);
                        }
                        foreach(string hitName in hitObjNames)
                            debugText += hitName + ", ";
                        if (showProcGenDebug)
                            Debug.LogFormat("Unexpected objects: ({0}) at ({1},{2}) on plane {3} with test {5} ext: {4}", debugText, testInfo.x, testInfo.y, curHeightPlane.name, testBounds.extents, centerPos);
                    }
                    else
                    {
        //                        Debug.LogFormat("Selecting ({0},{1}) which has ({2},{3}) to place ({4},{5})", testInfo.x, testInfo.y, testInfo.rightSquares, testInfo.downSquares, boundsWidth, boundsLength);
                        finalX = testInfo.x;
                        finalY = testInfo.y;
                        whichPlane = curHeightPlane;
                        foundValid = true;
                        return foundValid;
                    }
                }
            }
        }

        return foundValid;
    }
    public void SavePrefabInformation(GeneratablePrefab prefab, bool shouldRecomputePrefabInformation, bool replaceOld = true)
    {
        const string resPrefix = "Resources/";
        string assetPath = AssetDatabase.GetAssetPath(prefab);
        if (string.IsNullOrEmpty(assetPath))
            return;
        string newFileName = assetPath.Substring(assetPath.LastIndexOf(resPrefix) + resPrefix.Length);
        newFileName = newFileName.Substring(0, newFileName.LastIndexOf("."));
        int replaceIndex = -1;
        if (replaceOld)
        {
            replaceIndex = availablePrefabs.FindIndex( (PrefabDatabase.PrefabInfo testInfo)=>{
                return testInfo.fileName == newFileName;
            });
            if (replaceIndex >= 0)
                availablePrefabs.RemoveAt(replaceIndex);
        }

        if (prefab.shouldUse)
        {
            if (shouldRecomputePrefabInformation)
                prefab.ProcessPrefab();
            PrefabDatabase.PrefabInfo newInfo = new PrefabDatabase.PrefabInfo();
            newInfo.fileName = newFileName;
            newInfo.complexity = prefab.myComplexity;
            newInfo.bounds = prefab.myBounds;
            newInfo.isLight = prefab.isLight;
            newInfo.anchorType = prefab.attachMethod;
            foreach(GeneratablePrefab.StackableInfo stackRegion in prefab.stackableAreas)
                newInfo.stackableAreas.Add(stackRegion);
            if (replaceIndex < 0)
                availablePrefabs.Add(newInfo);
            else
                availablePrefabs.Insert(replaceIndex, newInfo);
        }
        EditorUtility.SetDirty(this);
    }
Пример #3
0
    public void SavePrefabInformation(GeneratablePrefab prefab, string assetPath, bool shouldRecomputePrefabInformation, bool replaceOld = true)
    {
        /*
         * Saves the prefab information in "prefabs" property of PrefabDatabase prefab.
         */
        string newFileName = "";
        if (assetPath == null) {
            const string resPrefix = "Resources/";
            assetPath = AssetDatabase.GetAssetPath (prefab);
            if (string.IsNullOrEmpty (assetPath))
                return;
            newFileName = assetPath.Substring (assetPath.LastIndexOf (resPrefix) + resPrefix.Length);
            newFileName = newFileName.Substring (0, newFileName.LastIndexOf ("."));
        } else {
            if (!(assetPath.ToLowerInvariant ().Contains ("http://"))) {
                const string resPrefix = BUNDLES_SUBPATH;
                string currentPath = Directory.GetCurrentDirectory ();
                newFileName = Path.Combine (currentPath, assetPath);
            } else {
                newFileName = assetPath;
            }
        }
        int replaceIndex = -1;
        if (replaceOld) {
            replaceIndex = prefabs.FindIndex ((PrefabInfo testInfo) => {
                return testInfo.fileName == newFileName;
            });
            if (replaceIndex >= 0)
                prefabs.RemoveAt (replaceIndex);
        }

        if (prefab.shouldUse) {

            if (shouldRecomputePrefabInformation)
                prefab.ProcessPrefab ();
            PrefabInfo newInfo = new PrefabInfo ();
            newInfo.fileName = newFileName;
            newInfo.complexity = prefab.myComplexity;
            newInfo.bounds = prefab.myBounds;
            newInfo.isLight = prefab.isLight;
            newInfo.anchorType = prefab.attachMethod;
            foreach (GeneratablePrefab.StackableInfo stackRegion in prefab.stackableAreas)
                newInfo.stackableAreas.Add (stackRegion);
            if (replaceIndex < 0)
                prefabs.Add (newInfo);
            else
                prefabs.Insert (replaceIndex, newInfo);
        }
        EditorUtility.SetDirty (this);
    }