Exemple #1
0
 WG_LocationController GetLocationByCoordinates(IntPair coords, List <WG_LocationController> locations)
 {
     for (int i = 0; i < locations.Count; i++)
     {
         WG_LocationController loc = locations[i];
         if (loc.u == coords.u && loc.v == coords.v)
         {
             return(loc);
         }
     }
     return(null);
 }
Exemple #2
0
        public void BuildMesh()
        {
#if UNITY_EDITOR
            //clear generated segments
            navmeshExist = false;
            //create helper object for all sub-generated objects
            GameObject store = new GameObject()
            {
                name = "Temp Store"
            };
            Transform[] allTransforms = gameObject.GetComponentsInChildren <Transform>();
            for (int trIndex = allTransforms.Length - 1; trIndex >= 0; trIndex--)
            {
                GameObject go = allTransforms[trIndex].gameObject;
                //try to get noise primitive component
                //if this component is null, then delete game object
                WG_Primitive_PerlinNoise noiseComponent = go.GetComponent <WG_Primitive_PerlinNoise>();
                WG_Primitive_Paint       paintComponent = go.GetComponent <WG_Primitive_Paint>();
                WG_Painter      painterComponent        = go.GetComponent <WG_Painter>();
                WG_VisualCenter visCenterComponent      = go.GetComponent <WG_VisualCenter>();
                if (go != gameObject && noiseComponent == null && paintComponent == null && painterComponent == null && visCenterComponent == null)
                {
                    if (clearAll)
                    {
                        DestroyImmediate(go);
                    }
                    else
                    {
                        //check is this object contains location controller
                        WG_LocationController locController = go.GetComponent <WG_LocationController>();
                        if (locController != null)
                        {//this is location root object, destoy it
                            DestroyImmediate(go);
                        }
                        else
                        {     //this is not location root, may be walls or ground object
                            if (go.name == groundName || go.name == wallsName || go.name == meshRootName)
                            { //this is generated ground or wall object, destoy it
                                DestroyImmediate(go);
                            }
                            else
                            {//this is sub-placed object, store it
                                if (PrefabUtility.GetOutermostPrefabInstanceRoot(go) == null || PrefabUtility.GetOutermostPrefabInstanceRoot(go) == go)
                                {
                                    go.transform.SetParent(store.transform, true);
                                }
                            }
                        }
                    }
                }
            }
            //fill map for all location segments
            bool[,] map = new bool[(segmenstMaxX - segmentsMinX + 1) * meshSquaresCount + 1, (segmenstMaxY - segmentsMinY + 1) * meshSquaresCount + 1];
            WG_Primitive_BaseNoise[] noises = gameObject.GetComponentsInChildren <WG_Primitive_BaseNoise>();
            float   meshSquareSize          = segmentSize / meshSquaresCount;
            Vector2 bottomLeftCorner        = new Vector2((segmentsMinX - 0.5f) * segmentSize, (segmentsMinY - 0.5f) * segmentSize);
            for (int x = 0; x < map.GetLength(0); x++)
            {
                for (int y = 0; y < map.GetLength(1); y++)
                {
                    Vector2 pos = new Vector2(x * meshSquareSize, y * meshSquareSize) + bottomLeftCorner;
                    map[x, y] = IsPointMountains(pos, noises);
                }
            }

            //next create root for location segments
            GameObject locationsRoot = new GameObject {
                name = meshRootName
            };
            locationsRoot.transform.SetParent(gameObject.transform);
            //create location generator
            WG_SegmentsGenerator         generator = new WG_SegmentsGenerator();
            List <WG_LocationController> locations = generator.GenerateLocationSegments(this, segmentSize, meshSquareSize, meshSquaresCount, segmentsMinX, segmenstMaxX, segmentsMinY, segmenstMaxY, locationsRoot, groundMaterial, mountainsMaterial, wallsMaterial, map, mountainsHeight, !(forceUpdate && buildMesh), navMeshCutVolume, uv2Padding);
#endif

#if UNITY_EDITOR
            //after generation we should place back all stored objects, we will place it inside location root object
            Transform[] storedObjects = store.GetComponentsInChildren <Transform>();
            for (int tfmIndex = 0; tfmIndex < storedObjects.Length; tfmIndex++)
            {
                Transform tfm = storedObjects[tfmIndex];
                if (tfm.gameObject != store)
                {
                    Vector3 position          = tfm.position;
                    IntPair locCoords         = WG_Helper.GetLocationCoordinates(position, segmentSize);
                    WG_LocationController loc = GetLocationByCoordinates(locCoords, locations);
                    if (loc != null)
                    {
                        //rever prefab properties (mesh and material)
                        GameObject prefabMaster  = PrefabUtility.GetOutermostPrefabInstanceRoot(tfm.gameObject);
                        MeshFilter meshComponent = tfm.GetComponent <MeshFilter>();
                        if ((prefabMaster == null && meshComponent != null) || prefabMaster == tfm.gameObject)
                        {
                            Vector3    scale  = tfm.localScale;
                            GameObject source = PrefabUtility.GetCorrespondingObjectFromSource(tfm.gameObject);
                            if (source != null)
                            {
                                PrefabUtility.RevertPrefabInstance(tfm.gameObject, InteractionMode.UserAction);
                            }

                            tfm.localScale = scale;

                            //move object inside location
                            tfm.SetParent(loc.gameObject.transform, true);
                            tfm.position += loc.gameObject.transform.position;
                        }
                    }
                    else
                    {
                        Debug.Log("There is no locations with coordinates " + locCoords.ToString() + ", so skip the object " + tfm.gameObject.name);
                    }
                }
            }
            //delete temp store
            DestroyImmediate(store);
            #endif

            BuildNavmeshOnly();
        }
        void ExportScene(Transform locationRoot)
        {
            WG_Helper.ClearFolder(Application.dataPath + assetLocationSOPath);

            for (int i = 0; i < locationRoot.childCount; i++)
            {
                Transform             loc           = locationRoot.GetChild(i);
                WG_LocationController locController = loc.GetComponent <WG_LocationController>();

                if (locController != null)
                {
                    locController.ExportLocation("Assets" + assetLocationXMLPath, "Assets" + assetLocationSOPath, minimapSize, minimapCamera, minimapCameraHeight, "Assets" + assetMinimapPath);
                }
            }

#if UNITY_EDITOR
            //export navmesh
            WG_TerrainBuilder builderComponent = builder.gameObject.GetComponent <WG_TerrainBuilder>();
            NavMeshData       data             = builderComponent.GetNavmeshData();
            string            navmeshAssetPath = "";
            if (data != null)
            {
                navmeshAssetPath = "navmeshes/" + data.name;
                AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(data)).SetAssetBundleNameAndVariant(navmeshAssetPath, "");
            }
            else
            {
                if (localNavMesh == null)
                {
                    Debug.Log("Navmesh data is null, can't export it.");
                }
                else
                {
                    Debug.Log("Use local version of the navmesh data object.");
                    data             = localNavMesh;
                    navmeshAssetPath = "navmeshes/" + localNavMesh.name;
                    AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(localNavMesh)).SetAssetBundleNameAndVariant(navmeshAssetPath, "");
                }
            }

            //create xml with navmeshlink and starting points
            GlobalLocation globalLocation = new GlobalLocation();
            if (navmeshAssetPath.Length > 0 && data != null)
            {
                globalLocation.navmeshData = new NavmeshData()
                {
                    link = navmeshAssetPath, name = data.name
                };
                if (exportPlayerPositionsInLocations)
                {
                    globalLocation.positions = new List <PositionData>();
                    WG_Position[] positions = WG_Helper.FindObjectsOfTypeAll <WG_Position>().ToArray();// FindObjectsOfType<WG_Position>();
                    for (int i = 0; i < positions.Length; i++)
                    {
                        Vector3 pos = positions[i].gameObject.transform.position;
                        IntPair loc = WG_Helper.GetLocationCoordinates(pos, builderComponent.segmentSize);
                        if (loc.u >= builderComponent.segmentsMinX && loc.u <= builderComponent.segmenstMaxX && loc.v >= builderComponent.segmentsMinY && loc.v <= builderComponent.segmenstMaxY)
                        {
                            globalLocation.positions.Add(new PositionData()
                            {
                                positionX = pos.x, positionY = pos.y, positionZ = pos.z
                            });
                        }
                    }

                    if (globalLocation.positions.Count == 0)
                    {
                        Debug.Log("No start positions on the scene. Add default position (0, 0, 0).");
                        globalLocation.positions.Add(new PositionData()
                        {
                            positionX = 0.0f, positionY = 0.0f, positionZ = 0.0f
                        });
                    }
                }


                globalLocation.bounds = new LocationsBounds()
                {
                    minU = builderComponent.segmentsMinX,
                    maxU = builderComponent.segmenstMaxX,
                    minV = builderComponent.segmentsMinY,
                    maxV = builderComponent.segmenstMaxY
                };

                globalLocation.locationSize = new LocationSize()
                {
                    value = builderComponent.segmentSize
                };

                string globalLocationName      = "global_location";
                string globalLocationAssetPath = "Assets" + assetLocationXMLPath + globalLocationName + ".xml";
                globalLocation.Save(globalLocationAssetPath);
                AssetDatabase.ImportAsset(globalLocationAssetPath, ImportAssetOptions.ForceUpdate);
                AssetImporter.GetAtPath(globalLocationAssetPath).SetAssetBundleNameAndVariant("locations/" + globalLocationName, "");

                //export server data
                SavePlayerPositions(builderComponent);
                SaveCollisionMap(serverPath);
                SaveTowerPositions(builderComponent);

                //also export locations data to SO
                GlobalLocationDataSO globalSO = ScriptableObjectUtility.CreateAsset <GlobalLocationDataSO>("Assets" + assetLocationSOPath, globalLocationName);
                globalSO.minU = builderComponent.segmentsMinX;
                globalSO.maxU = builderComponent.segmenstMaxX;
                globalSO.minV = builderComponent.segmentsMinY;
                globalSO.maxV = builderComponent.segmenstMaxY;

                globalSO.size = builderComponent.segmentSize;

                globalSO.navmeshName = data.name;
                globalSO.navmeshLink = navmeshAssetPath;

                if (exportPlayerPositionsInLocations)
                {
                    globalSO.startPositions = new List <Vector3>();
                    for (int pi = 0; pi < globalLocation.positions.Count; pi++)
                    {
                        globalSO.startPositions.Add(new Vector3(globalLocation.positions[pi].positionX, globalLocation.positions[pi].positionY, globalLocation.positions[pi].positionZ));
                    }
                }

                EditorUtility.SetDirty(globalSO);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                AssetImporter.GetAtPath("Assets" + assetLocationSOPath + globalLocationName + ".asset").SetAssetBundleNameAndVariant("locations_so/" + globalLocationName, "");
            }
#endif
        }