public void BuildNavMesh(GameObject[] fromObjects = null)
        {
            RemoveData();

            var sources = new List <NavMeshBuildSource>();
            var markups = new List <NavMeshBuildMarkup>();

            var buildSettings = NavMesh.GetSettingsByID(agentTypeID);

            if (fromObjects == null)
            {
                NavMeshBuilder.CollectSources(null, layerMask, useGeometry, defaultArea, markups, sources);
            }
            else
            {
                foreach (var obj in fromObjects)
                {
                    var localSources = new List <NavMeshBuildSource>();
                    NavMeshBuilder.CollectSources(obj.transform, layerMask, useGeometry, defaultArea, markups, localSources);
                    sources.AddRange(localSources);
                }
            }

            var bounds = CalculateWorldBounds(transform, sources);

            navMeshData = NavMeshBuilder.BuildNavMeshData(buildSettings, sources, bounds, Vector3.zero, Quaternion.identity);

            AddData();
        }
Exemple #2
0
    private void OnEnable()
    {
        terrain                    = GetComponent <Terrain>();
        terrain.terrainData        = GenerateTerrain(terrain.terrainData);
        terrain.transform.position = new Vector3(-config.width / 2, 0, -config.depth / 2);

        List <NavMeshBuildSource> buildSources = new List <NavMeshBuildSource>();

        NavMeshBuilder.CollectSources(
            null,
            ~9, // TODO Custom editor so we can select layers
            NavMeshCollectGeometry.RenderMeshes,
            0,
            new List <NavMeshBuildMarkup>(),
            buildSources
            );

        NavMeshData navData = NavMeshBuilder.BuildNavMeshData(
            NavMesh.GetSettingsByID(0),
            buildSources,
            new Bounds(new Vector3(0, 0, 0), new Vector3(config.width, config.height, config.depth)),
            Vector3.zero,
            Quaternion.identity
            );

        if (navData == null)
        {
            Debug.LogError("Failed to create nav mesh data!");
        }
        else
        {
            navMeshDataInstance = NavMesh.AddNavMeshData(navData);
        }
    }
Exemple #3
0
    protected override void OnUpdate()
    {
        var commandBuffer = new EntityCommandBuffer(Allocator.TempJob);
        var chunks        = hybridQuery.CreateArchetypeChunkArray(Allocator.TempJob);

        var entityType       = GetArchetypeChunkEntityType();
        var translationType  = GetArchetypeChunkComponentType <Translation>(true);
        var matrixType       = GetArchetypeChunkComponentType <CellSystem.MatrixComponent>(true);
        var localToWorldType = GetArchetypeChunkComponentType <LocalToWorld>(true);
        var meshType         = GetArchetypeChunkSharedComponentType <RenderMesh>();

        for (int c = 0; c < chunks.Length; c++)
        {
            var chunk = chunks[c];

            var entities               = chunk.GetNativeArray(entityType);
            var translations           = chunk.GetNativeArray(translationType);
            var matrixComponents       = chunk.GetNativeArray(matrixType);
            var localToWorldComponents = chunk.GetNativeArray(localToWorldType);

            for (int e = 0; e < entities.Length; e++)
            {
                Entity entity   = entities[e];
                float3 position = translations[e].Value;
                CellSystem.MatrixComponent matrix = matrixComponents[e];
                float4x4 localToWorld             = localToWorldComponents[e].Value;
                Mesh     mesh = chunk.GetSharedComponentData <RenderMesh>(meshType, entityManager).mesh;

                GameObject sectorGameObject = GameObject.Instantiate(sectorPrefab, position, Quaternion.identity);
                sectorGameObject.GetComponent <MeshCollider>().sharedMesh = mesh;
                NavMeshSurface navMeshComponent = sectorGameObject.GetComponent <NavMeshSurface>();

                NavMeshBuildSettings      settings = NavMesh.GetSettingsByID(0);
                List <NavMeshBuildSource> sources  = CreateNavMeshSource(matrix.width, navMeshComponent, mesh, localToWorld);
                Bounds      bounds = CalculateWorldBounds(sources, position);
                NavMeshData data   = NavMeshBuilder.BuildNavMeshData(settings, sources, bounds, position, Quaternion.identity);

                if (data != null)
                {
                    data.name = sectorGameObject.name;
                    navMeshComponent.RemoveData();
                    navMeshComponent.navMeshData = data;
                    if (navMeshComponent.isActiveAndEnabled)
                    {
                        navMeshComponent.AddData();
                    }
                }

                commandBuffer.AddComponent <Tags.HybridGameObjectCreated>(entity, new Tags.HybridGameObjectCreated());
                commandBuffer.AddSharedComponent <GameObjectComponent>(entity, new GameObjectComponent {
                    gameObject = sectorGameObject
                });
            }
        }

        commandBuffer.Playback(entityManager);
        commandBuffer.Dispose();

        chunks.Dispose();
    }
Exemple #4
0
    // Use this for initialization
    void Start()
    {
        // add 20 random big cuboids into the level.
        // The prefab has been tagged as StaticBatchingUtility Navigation in The Navigation editor
        for (int i = 0; i < 20; i++)
        {
            GameObject go = Instantiate(prefab, new Vector3(Random.Range(-25, 25), Random.Range(0, 1), Random.Range(-25, 25)), Quaternion.AngleAxis(Random.Range(-180, 180), Vector3.up));
            go.transform.parent = transform;
        }

        // Use the standard settings from the editor (I think)
        NavMeshBuildSettings settings = NavMesh.GetSettingsByID(0);

        // gather all the physics colliders which are children of this transform (or you can do this by volume)
        List <NavMeshBuildSource> results = new List <NavMeshBuildSource>();

        NavMeshBuilder.CollectSources(transform, 255, NavMeshCollectGeometry.PhysicsColliders, 0, new List <NavMeshBuildMarkup>(), results);

        // make a 100m box around the origin
        Bounds bounds = new Bounds(Vector3.zero, 100 * Vector3.one);

        // Build the actual navmesh
        NavMeshData data = NavMeshBuilder.BuildNavMeshData(settings, results, bounds, Vector3.zero, Quaternion.identity);

        NavMesh.AddNavMeshData(data);
        success = NavMeshBuilder.UpdateNavMeshData(data, settings, results, bounds);
    }
Exemple #5
0
    public void RebuildNavmesh(bool async)
    {
        if (async && buildOperation != null && !buildOperation.isDone)
        {
            return;
        }

        buildOperation = null;

        var totalBounds = new Bounds();

        NavMeshSourceTag2D.Collect(ref buildSources, ref totalBounds);
        var buildSettings       = NavMesh.GetSettingsByID(0);
        var totalBoundsReversed = new Bounds(Plane2DRotationInverse * totalBounds.center, Plane2DRotationInverse * totalBounds.size); // We need to reverse the rotation that's going to be used for baking to get proper bounds
        var buildBounds         = new Bounds(Vector3.zero, Vector3.one * float.MaxValue);                                             //Using enclosing and empty bounds is bugged at the moment - use arbitrarily big one

        if (!data)
        {
            data = NavMeshBuilder.BuildNavMeshData(buildSettings, buildSources, buildBounds, totalBounds.center, Plane2DRotation);
        }
        else
        {
            if (async)
            {
                buildOperation = NavMeshBuilder.UpdateNavMeshDataAsync(data, buildSettings, buildSources, buildBounds);
            }
            else
            {
                NavMeshBuilder.UpdateNavMeshData(data, buildSettings, buildSources, buildBounds);
            }
        }

        dataInstance.Remove();
        dataInstance = NavMesh.AddNavMeshData(data);
    }
Exemple #6
0
        public void BuildNavMesh()
        {
            var sources = CollectSources();

            // Use unscaled bounds - this differs in behaviour from e.g. collider components.
            // But is similar to reflection probe - and since navmesh data has no scaling support - it is the right choice here.
            var sourcesBounds = new Bounds(m_Center, Abs(m_Size));

            if (m_CollectObjects == CollectObjects.All || m_CollectObjects == CollectObjects.Children)
            {
                sourcesBounds = CalculateWorldBounds(sources);
            }

            var data = NavMeshBuilder.BuildNavMeshData(GetBuildSettings(),
                                                       sources, sourcesBounds, transform.position, transform.rotation);

            if (data != null)
            {
                data.name = gameObject.name;
                RemoveData();
                m_NavMeshData = data;
                if (isActiveAndEnabled)
                {
                    AddData();
                }
            }
        }
Exemple #7
0
    NavMeshData InitializeBakeData()
    {
        var emptySources = new List <NavMeshBuildSource>();
        var emptyBounds  = new Bounds();

        return(NavMeshBuilder.BuildNavMeshData(navMeshSurface.GetBuildSettings(), emptySources, emptyBounds,
                                               navMeshSurface.transform.position, navMeshSurface.transform.rotation));
    }
Exemple #8
0
        /// <summary>
        /// Creates the NavMeshData
        /// </summary>
        /// <param name="surface"></param>
        /// <returns></returns>
        private NavMeshData InitializeBakeData()
        {
            List <NavMeshBuildSource> buildSources = new List <NavMeshBuildSource>();
            Bounds bounds = new Bounds(primaryViewer.Transform.position, new Vector3(100f, 50f, 100f));

            NavMeshBuilder.CollectSources(transform, navMeshSurface.layerMask, NavMeshCollectGeometry.PhysicsColliders, 0, new List <NavMeshBuildMarkup>(), buildSources);

            return(NavMeshBuilder.BuildNavMeshData(navMeshSurface.GetBuildSettings(), buildSources, bounds, navMeshSurface.transform.position, navMeshSurface.transform.rotation));
        }
Exemple #9
0
 public void Bake()
 {
     NavMeshBuilder.BuildNavMeshData(
         navMeshSettings.ToBuildSettings(),
         new List <NavMeshBuildSource>(),
         new Bounds(),
         Vector3.zero,
         Quaternion.identity);
 }
Exemple #10
0
 void Build()
 {
     NavMeshData = NavMeshBuilder.BuildNavMeshData(
         NavMesh.GetSettingsByID(0),
         GetBuildSources(NullMask),
         new Bounds(BoundsCenter, BoundsSize),
         Vector3.zero,
         Quaternion.identity);
     AddNavMeshData();
 }
    // creates the navmesh data
    static NavMeshData InitializeBakeData(NavMeshSurface surface)
    {
        var emptySources = new List <NavMeshBuildSource>();
        var emptyBounds  = new Bounds();

        // Debug.Log(surface);
        // Debug.Log(emptySources);
        // Debug.Log(emptyBounds);

        return(NavMeshBuilder.BuildNavMeshData(surface.GetBuildSettings(), emptySources, emptyBounds, surface.transform.position, surface.transform.rotation));
    }
Exemple #12
0
    void Start()
    {
        b = new  Bounds(Map.transform.position, Map.transform.localScale);

        //UnityEditor.AI.NavMeshBuilder.BuildNavMesh();
        NavMeshBuilder.BuildNavMeshData(buildSettings, sources, b, Map.transform.position, Map.transform.rotation);

        Destination = GameObject.FindGameObjectWithTag("Destination");
        StartPos    = GameObject.FindGameObjectWithTag("StartPos");
        Instantiate(ObjectsToPlace[1], StartPos.transform.position, Quaternion.identity);
    }
Exemple #13
0
    public void BuildNavigation()
    {
        var data = NavMeshBuilder.BuildNavMeshData(NavMesh.GetSettingsByID(m_AgentTypeID), GetSource(),
                                                   new Bounds(Vector3.zero, Vector3.one * 100000f), Vector3.zero, Quaternion.identity);

        if (NavMeshData.valid)
        {
            NavMeshData.Remove();
        }

        NavMeshData = NavMesh.AddNavMeshData(data);
    }
Exemple #14
0
    // Use this for initialization
    void Start()
    {
        List <NavMeshBuildMarkup> markups = new List <NavMeshBuildMarkup>();
        List <NavMeshBuildSource> builds  = new List <NavMeshBuildSource>();

        NavMeshBuilder.CollectSources(transform, LayerMask.NameToLayer("Default"), NavMeshCollectGeometry.RenderMeshes, 0, markups, builds);
        NavMeshBuildSettings buildSettings = new NavMeshBuildSettings();
        Bounds localBounds = new Bounds();

        localBounds.size = new Vector3(100f, 100f, 100f);

        NavMeshBuilder.BuildNavMeshData(buildSettings, builds, localBounds, Vector3.zero, Quaternion.identity);
    }
    public void GeanerateNavMeshData()
    {
        List <NavMeshBuildSource> sourceList = new List <NavMeshBuildSource>();
        List <NavMeshBuildMarkup> markups    = new List <NavMeshBuildMarkup>();

        NavMeshBuilder.CollectSources(new Bounds(Vector3.zero, Vector3.one * 1000), 0 | (1 << 9), NavMeshCollectGeometry.RenderMeshes, 0, markups, sourceList);
        NavMeshBuildSettings nmbs = NavMesh.CreateSettings();

        nmbs.agentTypeID = Spawner.nma[0].agentTypeID;
        NavMeshData nmd = NavMeshBuilder.BuildNavMeshData(nmbs, sourceList, new Bounds(transform.position, Vector3.one * 1000), Vector3.zero, Quaternion.identity);

        currentNavMeshs.Add(NavMesh.AddNavMeshData(nmd));
    }
Exemple #16
0
    // create the NavMesh at run time after map is generated
    void bakeNavMesh()
    {
        // lots of BS about the scene that will need editing at some point I'm sure
        Bounds b = new Bounds(mapCenter, mapCenter + new Vector3(0f, 10f, 0f));
        List <NavMeshBuildSource> sources = new List <NavMeshBuildSource>();
        List <NavMeshBuildMarkup> markups = new List <NavMeshBuildMarkup>();

        NavMeshBuilder.CollectSources(b, 0, NavMeshCollectGeometry.RenderMeshes, 0, markups, sources);
        NavMeshBuildSettings settings = NavMesh.CreateSettings();

        // here's the actual important line
        NavMeshBuilder.BuildNavMeshData(settings, sources, b, mapCenter, Quaternion.identity);
    }
Exemple #17
0
    public void generateNavMesh()
    {
        //https://community.gamedev.tv/t/modify-navmesh-dynamically/25849/3
        List <NavMeshBuildSource> buildSources = new List <NavMeshBuildSource>();

        NavMeshBuilder.CollectSources(transform, navMeshLayers, NavMeshCollectGeometry.RenderMeshes, 0, new List <NavMeshBuildMarkup>(), buildSources);

        NavMeshData navData = NavMeshBuilder.BuildNavMeshData(navSettings, buildSources, new Bounds(Vector3.zero, new Vector3(10000, 10000, 10000)), Vector3.down,
                                                              Quaternion.Euler(Vector3.up));

        navMeshDataInstance = NavMesh.AddNavMeshData(navData);
        //Debug.Log(buildSources.Count);
        //Debug.Log("Map Built");
    }
    NavMeshData Build(NavMeshPrefabInstance instance)
    {
        var root    = instance.transform;
        var sources = new List <NavMeshBuildSource>();
        var markups = new List <NavMeshBuildMarkup>();

        UnityEditor.AI.NavMeshBuilder.CollectSourcesInStage(
            root, ~0, NavMeshCollectGeometry.RenderMeshes, 0, markups, instance.gameObject.scene, sources);
        var settings = NavMesh.GetSettingsByID(0);
        var bounds   = new Bounds(Vector3.zero, 1000.0f * Vector3.one);
        var navmesh  = NavMeshBuilder.BuildNavMeshData(settings, sources, bounds, root.position, root.rotation);

        navmesh.name = "Navmesh";
        return(navmesh);
    }
Exemple #19
0
        public void GenerateNavMesh()
        {
            NavMeshBuildSettings navSettings = new NavMeshBuildSettings();

            navSettings.agentClimb  = NAV_STEP;
            navSettings.agentHeight = NAV_HEIGHT;
            navSettings.agentRadius = NAV_RADIUS;
            navSettings.agentSlope  = NAV_SLOPE;
            NavMeshBuildSource src = new NavMeshBuildSource();

            src.sourceObject = mapRoot;
            src.shape        = NavMeshBuildSourceShape.Mesh;
            List <NavMeshBuildSource> srcs = new List <NavMeshBuildSource>();

            NavMeshBuilder.BuildNavMeshData(navSettings, srcs, new Bounds(), Vector3.zero, Quaternion.identity);
        }
Exemple #20
0
    public static void BuildNavMesh(Transform root, Bounds bounds)
    {
        // Use the standard settings from the editor (I think)
        NavMeshBuildSettings settings = NavMesh.GetSettingsByID(0);

        // gather all the physics colliders which are children of this transform (or you can do this by volume)
        List <NavMeshBuildSource> results = new List <NavMeshBuildSource>();

        NavMeshBuilder.CollectSources(root, 255, NavMeshCollectGeometry.RenderMeshes, 0, new List <NavMeshBuildMarkup>(), results);

        // Build the actual navmesh
        NavMeshData data = NavMeshBuilder.BuildNavMeshData(settings, results, bounds, Vector3.zero, Quaternion.identity);

        instances.Add(NavMesh.AddNavMeshData(data));

        //success = NavMeshBuilder.UpdateNavMeshData(data, settings, results, bounds);
    }
    // Start is called before the first frame update
    void Start()
    {
        mg = GetComponent <MapGenerator>();
        mg.Generate();
        List <NavMeshBuildSource> sourceList = new List <NavMeshBuildSource>();
        List <NavMeshBuildMarkup> markups    = new List <NavMeshBuildMarkup>();

        NavMeshBuilder.CollectSources(new Bounds(Vector3.zero, Vector3.one * 1000), 0 | (1 << 9), NavMeshCollectGeometry.RenderMeshes, 0, markups, sourceList);

        NavMeshData nmd = NavMeshBuilder.BuildNavMeshData(NavMesh.CreateSettings(), sourceList, new Bounds(transform.position, Vector3.one * 1000), Vector3.zero, Quaternion.identity);

        if (!nmd)
        {
            print("OH NO"); return;
        }
        NavMesh.AddNavMeshData(nmd);
    }
Exemple #22
0
    void UpdateNavMesh()
    {
        bakePos = transform.position;
        Vector3 gravityUp = (transform.position - planet.position).normalized;

        dataInstance.Remove();
        Bounds localBound = new Bounds(Vector3.zero, new Vector3(1, 1, 1) * boundSize);// new Bounds(transform.position, boundSize *new Vector3(1, 1, 1));

        bound = new Bounds(transform.position, new Vector3(1, 1, 1) * boundSize);
        NavMeshData navMeshData = NavMeshBuilder.BuildNavMeshData(buildSettings
                                                                  , buildSources
                                                                  , localBound
                                                                  , transform.position
                                                                  , Quaternion.FromToRotation(Vector3.up, gravityUp));

        dataInstance = NavMesh.AddNavMeshData(navMeshData);
    }
Exemple #23
0
    public void GenerateNavMesh()
    {
        if (GetTerrain())
        {
            if (navMesh != null)
            {
                terrain.position -= Vector3.one * 0.5f;
                Bounds bounds = new Bounds
                {
                    min = new Vector3(0, setting.WaterHeight > 0 ? setting.WaterHeight - 2f : setting.WaterHeight, 0),
                    max = new Vector3(setting.MapSideLength, setting.MountainHeight, setting.MapSideLength)
                };
                MeshFilter[] meshFilters = terrain.GetComponentsInChildren <MeshFilter>();
                List <NavMeshBuildSource> meshBuildSources = new List <NavMeshBuildSource>();
                foreach (MeshFilter meshFilter in meshFilters)
                {
                    meshBuildSources.Add(new NavMeshBuildSource()
                    {
                        shape        = NavMeshBuildSourceShape.Mesh,
                        sourceObject = meshFilter.sharedMesh,
                        transform    = meshFilter.transform.localToWorldMatrix,
                    });
                }
                terrain.position += Vector3.one * 0.5f;

                NavMeshBuildSettings settings       = NavMesh.GetSettingsByIndex(0);
                NavMeshData          newNavMeshData = NavMeshBuilder.BuildNavMeshData(settings, meshBuildSources, bounds, bounds.min, Quaternion.identity);
                NavMesh.AddNavMeshData(newNavMeshData);
                newNavMeshData.name = navMesh.name;
                EditorUtility.CopySerialized(newNavMeshData, navMesh);
            }
            else
            {
                print("沒導航設定檔");
            }
        }
    }
Exemple #24
0
    public void GenerateGrid(Vector3 minCorner, Vector3 maxCorner)
    {
        _worldBounds.min = minCorner;
        _worldBounds.max = maxCorner;

        // Find all nav mesh object sources in the scene
        NavMeshBuilder.CollectSources(_worldBounds, _obstacleMask, NavMeshCollectGeometry.PhysicsColliders, 1, _navMeshMarkups, _navMeshBuildSources);
        for (int i = 0; i < _pathFindObjects.Count; ++i)
        {
            _navMeshBuildSources.Add(_pathFindObjects[i].Source);
        }

        // Add a source to represent the 'ground' plane
        // NavMeshBuildSource groundSource = default(NavMeshBuildSource);
        // groundSource.area = 0;
        // groundSource.shape = NavMeshBuildSourceShape.Box;
        // groundSource.size = _worldBounds.size.WithY(0.1f);
        // groundSource.transform = Matrix4x4.identity * Matrix4x4.Translate(_worldBounds.center.WithY(0));
        // _navMeshBuildSources.Add(groundSource);

        // Build settings for default agent
        NavMeshBuildSettings buildSettings = NavMesh.GetSettingsByID(0);

        // Create or update the nav mesh
        if (_navMesh == null)
        {
            _navMesh = NavMeshBuilder.BuildNavMeshData(buildSettings, _navMeshBuildSources, _worldBounds, Vector3.zero, Quaternion.identity);
            NavMesh.AddNavMeshData(_navMesh);
        }
        else
        {
            NavMeshBuilder.UpdateNavMeshData(_navMesh, buildSettings, _navMeshBuildSources, _worldBounds);
        }

        _isBuilt = true;
    }
Exemple #25
0
    //List<NavMeshBuildSource> m_Sources = new List<NavMeshBuildSource>();

    void OnEnable()
    {
        main = this;
        // Construct and add navmesh

        if (meshOrigin == null)
        {
            meshOrigin = transform;
        }

        //Bounds bounds = new Bounds(new Vector3(meshOrigin.position.x, meshOrigin.position.y, meshOrigin.position.y), new Vector3(buildSize.x, buildSize.y, buildSize.y)); // navmesh space bounds
        Bounds bounds = new Bounds(meshOrigin.position, new Vector3(buildSize.x, buildSize.y, buildSize.y));

        NavMeshBuildSettings buildSettings = NavMesh.GetSettingsByID(0);
        float defaultAgentRadius           = buildSettings.agentRadius;

        buildSettings.agentRadius = 0.01f;

        List <NavMeshBuildSource> navSources = PolygonNavmeshObstacle.Collect();

        navSources.Add(generateWalkablePlane());

        //rotation from XY plane to XZ plane
        for (int i = 0; i < navSources.Count; i++)
        {
            Matrix4x4 transformation = navSources[i].transform;

            Vector4 verticalDirection = transformation.GetRow(1);
            transformation.SetRow(1, transformation.GetRow(2));
            transformation.SetRow(2, verticalDirection);

            //these structs are pass by value, apperently?
            NavMeshBuildSource buildSource = navSources[i];
            buildSource.transform = transformation;
            navSources[i]         = buildSource;
        }

        //triangulation breaks and returns vectors with only an x component if we create the navmesh in the XY plane, so we need to do it in the XZ plane then tranform the result.
        m_NavMesh  = NavMeshBuilder.BuildNavMeshData(buildSettings, navSources, bounds, Vector3.zero, Quaternion.identity);//Quaternion.LookRotation(-Vector3.up, Vector3.forward));
        m_Instance = NavMesh.AddNavMeshData(m_NavMesh);

        //calculate reachability

        navSources.Clear();
        buildSettings.agentRadius = defaultAgentRadius - buildSettings.agentRadius;
        //bounds = new Bounds(meshOrigin.position, new Vector3(buildSize.x, buildSize.y, buildSize.y));

        NavMeshTriangulation triangulation = NavMesh.CalculateTriangulation();

        //do de-duping on vertices
        Dictionary <Vector3, int> positionToNewIndex = new Dictionary <Vector3, int>();

        for (int i = 0; i < triangulation.vertices.Length; i++)
        {
            Vector3 vertexPosition = Quantize(triangulation.vertices[i], vectorPrecision); //round to one decimal place
            if (!positionToNewIndex.ContainsKey(vertexPosition))
            {
                positionToNewIndex[vertexPosition] = positionToNewIndex.Count;
            }
        }

        Vector3[] deDupedVertices = new Vector3[positionToNewIndex.Count];
        foreach (KeyValuePair <Vector3, int> vertexEntry in positionToNewIndex)
        {
            deDupedVertices[vertexEntry.Value] = vertexEntry.Key;
        }
        int[] triangleIndices = new int[triangulation.indices.Length];
        for (int i = 0; i < triangulation.indices.Length; i++)
        {
            Vector3 vertexPosition = Quantize(triangulation.vertices[triangulation.indices[i]], vectorPrecision);
            triangleIndices[i] = positionToNewIndex[vertexPosition];
        }

        HashSet <int> reachableVertices;

        navSources.Add(generateReachableArea(deDupedVertices, triangleIndices, out reachableVertices));

        if (includeUnreachableAreas)
        {
            navSources.Add(generateUnreachableArea(deDupedVertices, triangleIndices, reachableVertices));
        }

        //rotation from XZ plane to XY plane
        for (int i = 0; i < navSources.Count; i++)
        {
            Matrix4x4 transformation = navSources[i].transform;

            Vector4 verticalDirection = transformation.GetRow(1);
            transformation.SetRow(1, transformation.GetRow(2));
            transformation.SetRow(2, verticalDirection);

            //these structs are pass by value, apperently?
            NavMeshBuildSource buildSource = navSources[i];
            buildSource.transform = transformation;
            navSources[i]         = buildSource;
        }

        m_Instance.Remove();
        m_NavMesh = NavMeshBuilder.BuildNavMeshData(buildSettings, navSources, bounds, Vector3.zero, Quaternion.LookRotation(-Vector3.up, Vector3.forward));
        //replace the old navmesh with the new one

        ///*
        m_Instance = NavMesh.AddNavMeshData(m_NavMesh);
        //*/
    }
Exemple #26
0
        public void LoadMap(IMapData mapData, bool generateNavMesh)
        {
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter == null)
            {
                throw new Exception("MeshFilter on map not found.");
            }

            if (meshFilter.mesh == null)
            {
                meshFilter.mesh = new Mesh();
            }

            var fowMeshFilter = FogOfWar.GetComponent <MeshFilter>();

            if (fowMeshFilter.mesh == null)
            {
                fowMeshFilter.mesh = new Mesh();
            }

            var fowVertices = new List <Vector3>();
            var mapVertices = new List <Vector3>();
            var mapUVs      = new List <Vector2>();
            var fowUVs      = new List <Vector2>();
            var i           = 0;
            var mapIndices  = new int[(mapData.Width - 1) * (mapData.Length - 1) * 4];

            for (int x = 0; x < mapData.Width; x++)
            {
                for (int y = 0; y < mapData.Length; y++)
                {
                    fowVertices.Add(GameUtils.GetPosition(new Vector2(x, y), mapData));
                    mapVertices.Add(GameUtils.GetPosition(new Vector2(x, y), mapData));
                    mapUVs.Add(new Vector2(x, y) / 4);
                    fowUVs.Add(new Vector2((float)x / mapData.Width, (float)y / mapData.Length));

                    if (y == mapData.Length - 1 || x == mapData.Width - 1)
                    {
                        continue;
                    }

                    mapIndices[i++] = x * mapData.Length + y;
                    mapIndices[i++] = x * mapData.Length + y + 1;
                    mapIndices[i++] = (x + 1) * mapData.Length + y + 1;
                    mapIndices[i++] = (x + 1) * mapData.Length + y;
                }
            }

            ApplyMesh(meshFilter, mapVertices, mapIndices, mapUVs);
            ApplyMesh(fowMeshFilter, fowVertices, mapIndices, fowUVs);

            var mapCollider = GetComponent <MeshCollider>();

            if (mapCollider != null)
            {
                mapCollider.sharedMesh = meshFilter.mesh;
            }

            var fowCollider = FogOfWar.GetComponent <MeshCollider>();

            if (fowCollider != null)
            {
                fowCollider.sharedMesh = fowMeshFilter.mesh;
            }

            gameObject.isStatic = true;

            for (int x = 0; x < mapData.Width; x++)
            {
                for (int y = 0; y < mapData.Length; y++)
                {
                    var        pos  = GameUtils.GetPosition(new Vector2(x + 0.5f, y + 0.5f), mapData);
                    GameObject inst = null;
                    switch (mapData.GetMapObjectAt(x, y))
                    {
                    case MapObject.Tree:
                        inst = Instantiate(TreePrefab);
                        break;

                    case MapObject.Crystal:
                        inst = Instantiate(CrystalPrefab);
                        break;
                    }

                    if (inst == null)
                    {
                        continue;
                    }

                    inst.transform.parent        = ObjectsContainer.transform;
                    inst.transform.localPosition = pos;
                }
            }

            if (generateNavMesh)
            {
                var settings = NavMesh.CreateSettings();
                settings.agentTypeID = AgentTypeID;
                settings.agentRadius = 0;
                settings.agentSlope  = 60;

                var source = new NavMeshBuildSource();
                source.shape        = NavMeshBuildSourceShape.Mesh;
                source.sourceObject = meshFilter.mesh;
                source.transform    = transform.localToWorldMatrix;

                var navMeshData = NavMeshBuilder.BuildNavMeshData(settings, new List <NavMeshBuildSource> {
                    source
                }, new Bounds(new Vector3((float)mapData.Width / 2, 0, (float)mapData.Length / 2), new Vector3(mapData.Width, 2, mapData.Length)), transform.position, transform.rotation);

                NavMesh.RemoveAllNavMeshData();
                NavMesh.AddNavMeshData(navMeshData);
            }
            mMapData = mapData;
            FogOfWarTexture.width                  = mapData.Width;
            FogOfWarTexture.height                 = mapData.Length;
            FogOfWarCamera.orthographicSize        = Mathf.Max(mapData.Width - 1, mapData.Length - 1) / 2f;
            FogOfWarCamera.transform.localPosition = new Vector3((mapData.Width - 1) / 2f, 10, (mapData.Length - 1) / 2f);
        }
Exemple #27
0
    void Start()
    {
        Mesh mesh = GetComponent <MeshFilter>().mesh;

        for (int x = 0; x < halfWidth * 2; x++)
        {
            for (int z = 0; z < halfHeight * 2; z++)
            {
                int xx = x - halfWidth;
                int zz = z - halfHeight;
                if (Random.Range(0, 18) < 1)
                {
                    pushWall(xx, zz);
                }
                else
                {
                    pushFloor(xx, zz);
                    if (Random.Range(0, 20) < 1)
                    {
                        addTree(xx, zz);
                    }
                    else if (Random.Range(0, 25) < 1)
                    {
                        addRock(xx, zz);
                    }
                }
            }
        }

        Vector3[] vertArray = newVerts.ToArray();
        int[]     triArray  = newTris.ToArray();

        // this NavMeshBuildSettings is copy pasted from some place

        NavMeshBuildSettings bs = new NavMeshBuildSettings()
        {
            agentClimb    = 10f,
            agentHeight   = 1.0f,
            agentRadius   = 0.3f,
            agentSlope    = 25.0f,
            agentTypeID   = 0,
            minRegionArea = 0.1f,
            tileSize      = 5,
            voxelSize     = 0.005f /*whatever, doesnt matter for quad source*/
        };

        mesh.Clear();

        mesh.vertices  = vertArray;
        mesh.triangles = triArray;

        mesh.RecalculateNormals();
        mesh.RecalculateTangents();
        mesh.RecalculateBounds();

        // this next part is also copy pasted from some place

        var sources = new List <NavMeshBuildSource>()
        {
            new NavMeshBuildSource()
            {
                area         = 0,
                component    = null /*a sprite?*/,
                shape        = NavMeshBuildSourceShape.Mesh,
                size         = new Vector3(7.2f, 4.8f),
                sourceObject = mesh /*mesh*/,
                transform    = Matrix4x4.identity /*already in world coordinates*/
            }
        };

        var data = NavMeshBuilder.BuildNavMeshData(bs, sources, mesh.bounds, Vector3.zero, Quaternion.identity);
        var res  = UnityEngine.AI.NavMesh.AddNavMeshData(data);

        var triangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();//no areas, vertices or triangles

        if (unitObject != null)
        {
            Instantiate(unitObject, new Vector3(0, 0, 0), Quaternion.identity);
        }

        GetComponent <MeshCollider>().sharedMesh = mesh;
    }
Exemple #28
0
    public void GenerateLevel(int level)
    {
        int         assetsToUse = level % levels.Count;
        LevelAssets assets      = levels[assetsToUse];

        currentLevel = new LevelData()
        {
            levelNumber = level,
            levelName   = assets.displayName,
            assets      = assets,
            bossName    = "Fred",
            enemies     = new List <Transform>(),
        };


        int[,] wallTypes = new int[levelSize, levelSize];
        List <NavMeshBuildSource> src = new List <NavMeshBuildSource>();

        // Start with cave carving
        for (int i = 0; i < levelSize; i++)
        {
            for (int k = 0; k < levelSize; k++)
            {
                int dX = i - levelSize / 2;
                int dZ = k - levelSize / 2;

                float caveRadius = Mathf.Sqrt(dX * dX + dZ * dZ) / levelSize + Mathf.PerlinNoise(i * 0.0913f, k * 0.07498f);
                if (caveRadius > assets.caveness)
                {
                    wallTypes[i, k] = WALL_TYPE_ROCK;
                }
            }
        }

        // Then build the route
        int x = levelSize / 2;
        int z = levelSize / 2;

        BuildRoom(x, z, wallTypes, assets.roomBudget, assets.hallwayLength, assets.minRoomSize, assets.maxRoomSize);

        // Place boundaries
        for (int i = 0; i < levelSize; i++)
        {
            wallTypes[i, 0]             = WALL_TYPE_BEDROCK;
            wallTypes[i, levelSize - 1] = WALL_TYPE_BEDROCK;
            wallTypes[0, i]             = WALL_TYPE_BEDROCK;
            wallTypes[levelSize - 1, i] = WALL_TYPE_BEDROCK;

            if (Random.Range(0f, 1f) > 0.5f)
            {
                wallTypes[i, 1] = WALL_TYPE_BEDROCK;
                wallTypes[levelSize - 1 - i, levelSize - 2] = WALL_TYPE_BEDROCK;
                wallTypes[1, levelSize - 1 - i]             = WALL_TYPE_BEDROCK;
                wallTypes[levelSize - 2, i] = WALL_TYPE_BEDROCK;
            }
        }

        walls = new Transform[levelSize, levelSize];
        for (int i = 0; i < levelSize; i++)
        {
            for (int k = 0; k < levelSize; k++)
            {
                switch (wallTypes[i, k])
                {
                case WALL_TYPE_ROCK:
                {
                    walls[i, k] = Instantiate(assets.rockPrefab, new Vector3(i, -1f, k), Quaternion.identity, transform);
                    break;
                }

                case WALL_TYPE_WALL:
                {
                    walls[i, k] = Instantiate(assets.wallPrefab, new Vector3(i, -1f, k), Quaternion.identity, transform);
                    break;
                }

                case WALL_TYPE_BEDROCK:
                {
                    walls[i, k] = Instantiate(assets.bedrockPrefab, new Vector3(i, -1f, k), Quaternion.identity, transform);

                    break;
                }
                }

                if (walls[i, k] != null)
                {
                    MeshFilter mesh = walls[i, k].GetComponentInChildren <MeshFilter>();
                    src.Add(new NavMeshBuildSource()
                    {
                        area         = 0,
                        shape        = NavMeshBuildSourceShape.Mesh,
                        sourceObject = mesh.sharedMesh,
                        transform    = mesh.transform.localToWorldMatrix,
                    });
                }
            }
        }

        floor = Instantiate(assets.floorPrefab, transform);
        foreach (MeshFilter mf in floor.GetComponentsInChildren <MeshFilter>())
        {
            src.Add(new NavMeshBuildSource()
            {
                area         = 0,
                shape        = NavMeshBuildSourceShape.Mesh,
                sourceObject = mf.sharedMesh,
                transform    = mf.transform.localToWorldMatrix,
            });
        }

        // Place player spawn pos - start at outer edge and work inwards
        Vector2Int spawnPoint = Vector2Int.zero;
        float      radius     = levelSize / 2f;

        while (spawnPoint == Vector2Int.zero && radius >= 0.0f)
        {
            float      angle   = Random.Range(0, Mathf.PI * 2f);
            Vector2    pos     = new Vector2(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle));
            Vector2Int gridPos = new Vector2Int(Mathf.RoundToInt(pos.x), Mathf.RoundToInt(pos.y));
            if (gridPos.x > 0 && gridPos.x < levelSize - 1 && gridPos.y > 0 && gridPos.y < levelSize - 1)
            {
                if (wallTypes[gridPos.x, gridPos.y] == WALL_TYPE_EMPTY)
                {
                    spawnPoint = gridPos;
                }
            }

            radius -= 1.0f;
        }

        if (spawnPoint == Vector2Int.zero)
        {
            Debug.LogError("Failed to find spawn point");
            spawnPoint = new Vector2Int(levelSize / 2, levelSize / 2);
        }

        Player.inst.GetComponent <CharacterController>().enabled = false;
        Player.inst.transform.position = new Vector3(spawnPoint.x, 0.0f, spawnPoint.y);
        Player.inst.GetComponent <CharacterController>().enabled = true;
        Camera.main.transform.parent.position = Player.inst.transform.position;


        // Place enemies
        float totalWeight = 0.0f;

        foreach (LevelAssets.SpawnData spawn in assets.regularSpawns)
        {
            totalWeight += spawn.spawnWeight;
        }
        for (int i = 0; i < assets.numToSpawn; i++)
        {
            float pick  = Random.Range(0.0f, totalWeight);
            int   index = 0;

            do
            {
                if (pick <= assets.regularSpawns[index].spawnWeight)
                {
                    Spawn(assets.regularSpawns[index], wallTypes, spawnPoint);
                }

                pick -= assets.regularSpawns[index].spawnWeight;
                index++;
            }while (pick >= 0.0f && index < assets.regularSpawns.Count);
        }

        // Place an exit hole / boss spawn
        Dictionary <Vector2Int, int> connected = new Dictionary <Vector2Int, int>();

        connected.Add(spawnPoint, 0);
        int furthestExplored = Explore(connected, spawnPoint, wallTypes, 0);

        // Go a good distance from the player
        int        target    = furthestExplored * 3 / 4;
        Vector2Int targetPos = Vector2Int.zero;

        foreach (var kvp in connected)
        {
            if (kvp.Value >= target)
            {
                targetPos = kvp.Key;
                break;
            }
        }

        Transform hole = Instantiate(assets.holePrefab, new Vector3(targetPos.x + 0.5f, 0, targetPos.y + 0.5f), Quaternion.identity, transform);

        currentLevel.enemies.Add(hole);
        UI.inst.Announce($"Level {level + 1} - {assets.displayName}");

        if (assets.spawnBoss)
        {
            Spawn(assets.bossData, wallTypes, spawnPoint, forceSpawn: true);
            currentLevel.bossName = LootGenerator.inst.GetBossName(assets.bossData.name, level / 3);
            UI.inst.Announce($@"Level {level + 1} - {assets.displayName}");
            currentLevel.boss = currentLevel.enemies[currentLevel.enemies.Count - 1];

            hole.gameObject.SetActive(false);
            currentLevel.boss.GetComponent <Creature>().setActiveOnDeath = hole.gameObject;
        }
        else
        {
        }

        UI.inst.SetLevelNameText($"Level {level + 1} - {assets.displayName}");

        RenderSettings.fogDensity = 0.2f + 0.01f * level;

        NavMeshBuildSettings settings = NavMesh.GetSettingsByIndex(0);
        NavMeshData          data     = NavMeshBuilder.BuildNavMeshData(settings, src, new Bounds(Vector3.one * (levelSize / 2f) + Vector3.down, Vector3.one * levelSize), Vector3.zero, Quaternion.identity);

        NavMesh.RemoveAllNavMeshData();
        NavMesh.AddNavMeshData(data);
    }
 public NavMeshData BuildNavigation(Transform root)
 {
     return(NavMeshBuilder.BuildNavMeshData(NavMesh.GetSettingsByID(m_AgentTypeID), GetSource(root),
                                            new Bounds(Vector3.zero, Vector3.one * 100000f), Vector3.zero, Quaternion.identity));
 }