Пример #1
1
        public NavigationEngine(Navmesh navmesh)
        {
            m_Navmesh = navmesh;

            UpdatesThread = new Thread(Updates);
            UpdatesThread.Name = "Navigator-UpdatesThread";
            UpdatesThread.Start();

            Precision = 8;
            GridCellPrecision = 40;
            ExploreCellPrecision = 25;
            PathRandomCoeff = 0;
            PathNodesShiftDist = 5;
            CurrentPosDiffRecalcThreshold = 20;
            UpdatePathInterval = -1;
            EnableAntiStuck = false;
            IsStandingOnPurpose = true;
            MovementFlags = MovementFlag.Walk;            
        }
Пример #2
0
    void OnRenderObject()
    {
        if (!mDebugEnabled)
        {
            return;
        }

        INavmeshData data = NavmeshData;

        if (!mNavmeshData || !data.HasNavmesh)
        {
            mDebugMesh = null;
            return;
        }

        if (mDebugMesh == null || data.Version != mDebugVersion)
        {
            mDebugMesh    = data.GetNavmesh();
            mDebugVersion = data.Version;

            if (mDebugMesh == null)
            {
                return;
            }
        }

        NavDebug.Draw(mDebugMesh, false);
    }
Пример #3
0
        /// <summary>
        /// Reports all edges intersecting specified ray while ISegmentCast.RegisterCollision returns true.
        /// Collisions are reported in order of their distance from rayCast.Origin.
        /// </summary>
        /// <param name="segmentCast">Cast data</param>
        /// <param name="open">NativeList for internal use, is cleared before use</param>
        public static void CastRay <T>(this Navmesh navmesh, T rayCast, NativeList <IntPtr> open) where T : IRayCast
        {
            Assert.IsTrue(rayCast.Distance >= 0, "Ray cast distance should be larger than or equal to zero");
            Assert.IsTrue(math.abs(1 - math.length(rayCast.Direction)) < .001f, "Ray cast direction should be normalized");

            open.Clear();
            var h    = navmesh.Max;
            var dist = math.min(math.max(h.x, h.y) * 4, rayCast.Distance);
            var org  = rayCast.Origin;
            var dest = org + rayCast.Direction * dist;

            if (!navmesh.Contains(dest))
            {
                var d = dest;
                if (!IntersectSegSeg(org, d, -h, new double2(h.x, -h.y), out dest) &&
                    !IntersectSegSeg(org, d, new double2(h.x, -h.y), h, out dest) &&
                    !IntersectSegSeg(org, d, h, new double2(-h.x, h.y), out dest))
                {
                    IntersectSegSeg(org, d, new double2(-h.x, h.y), -h, out dest);
                }
            }

            var segmentCast = new RayCastWrapper <T>(dest, rayCast);

            navmesh.CastSegment(segmentCast, open);
        }
Пример #4
0
 public void Init(Navmesh navMesh, int maxAgent = 100, float maxAgentRaidus = 45f)
 {
     m_MaxAgent       = maxAgent;
     m_MaxAgentRadius = maxAgentRaidus;
     m_NavMesh        = navMesh;
     Init();
 }
Пример #5
0
        protected override void OnUpdate()
        {
            var ecbSource = DotsNavSystemGroup.EcbSource;
            var buffer    = ecbSource.CreateCommandBuffer().AsParallelWriter();

            Entities
            .WithBurst()
            .WithNone <Navmesh>()
            .ForEach((Entity entity, int entityInQueryIndex, in NavmeshComponent data) =>
            {
                var resources = new Navmesh();
                resources.Allocate(data);
                buffer.AddComponent(entityInQueryIndex, entity, resources);
            })
            .ScheduleParallel();

            buffer = ecbSource.CreateCommandBuffer().AsParallelWriter();
            Entities
            .WithBurst()
            .WithNone <NavmeshComponent>()
            .ForEach((Entity entity, int entityInQueryIndex, Navmesh resources) =>
            {
                resources.Dispose();
                buffer.RemoveComponent <Navmesh>(entityInQueryIndex, entity);
            })
            .Schedule();
            ecbSource.AddJobHandleForProducer(Dependency);
        }
Пример #6
0
    void IsCdt(ref Navmesh lct, int constraint = -1, int vertex = -1)
    {
        var e = lct.GetEdgeEnumerator(true);

        while (e.MoveNext())
        {
            if (e.Current->Constrained)
            {
                continue;
            }

            var o = e.Current->Org->Point;
            var d = e.Current->Dest->Point;
            if (Math.Contains(o, lct.Min, lct.Max) && Math.Contains(d, lct.Min, lct.Max))
            {
                var on = e.Current->ONext->Dest->Point;
                var dn = e.Current->DNext->Org->Point;
                if (Math.CircumcircleContains(o, d, on, dn) && Math.Ccw(dn, d, on) && Math.Ccw(on, o, dn))
                {
                    Debug.Log($"delaunay fail, constraint: {constraint}, vertex:{vertex}, from: {o}, to: {d}");
                    throw new Exception();
                }
            }
        }
    }
Пример #7
0
    /// <summary>
    /// Loads a single-tile navigation mesh from the provided data.
    /// </summary>
    /// <param name="buildData">The tile build data.</param>
    /// <param name="buildConfig">The build information. (Optional)</param>
    /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns>
    public NavStatus Load(NavmeshTileBuildData buildData, NavmeshBuildInfo buildConfig)
    {
        if (buildData == null || buildData.IsDisposed)
        {
            return(NavStatus.Failure | NavStatus.InvalidParam);
        }

        Navmesh   navmesh;
        NavStatus status = Navmesh.Create(buildData, out navmesh);

        if ((status & NavStatus.Sucess) == 0)
        {
            return(status);
        }

        mDataPack = navmesh.GetSerializedMesh();

        if (mDataPack == null)
        {
            return(NavStatus.Failure);
        }

        mBuildInfo = buildConfig;

        mVersion++;

        return(NavStatus.Sucess);
    }
Пример #8
0
    /// <summary>
    /// Load a navigation mesh from data created from the <see cref="Navmesh.GetSerializedMesh"/>
    /// method.
    /// </summary>
    /// <param name="serializedMesh">The serialized mesh.</param>
    /// <param name="buildConfig">The build information. (Optional)</param>
    /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns>
    public NavStatus Load(byte[] serializedMesh, NavmeshBuildInfo buildConfig)
    {
        if (serializedMesh == null)
        {
            return(NavStatus.Failure | NavStatus.InvalidParam);
        }

        // This roundabout method is used for validation.

        Navmesh   navmesh;
        NavStatus status = Navmesh.Create(serializedMesh, out navmesh);

        if ((status & NavStatus.Sucess) == 0)
        {
            return(status);
        }

        mDataPack = navmesh.GetSerializedMesh();

        if (mDataPack == null)
        {
            return(NavStatus.Failure);
        }

        mBuildInfo = buildConfig;

        mVersion++;

        return(NavStatus.Sucess);
    }
Пример #9
0
        private void OnSceneGUI(SceneView sceneView)
        {
            if (!(ScriptableObject)mNavmeshData)
            {
                Hide();
                return;
            }

            if (!mNavmeshData.HasNavmesh)
            {
                mDataVersion = -1;
                mNavmesh     = null;
                return;
            }

            if (mNavmesh == null || mNavmeshData.Version != mDataVersion)
            {
                mNavmesh     = mNavmeshData.GetNavmesh();
                mDataVersion = mNavmeshData.Version;

                if (mNavmesh == null)
                {
                    return;
                }
            }

            NavDebug.Draw(mNavmesh, mColorByArea);
        }
Пример #10
0
        /// <summary>
        /// Reports all edges intersecting specified ray while ISegmentCast.RegisterCollision returns true.
        /// Collisions are reported in order of their distance from rayCast.Origin.
        /// </summary>
        /// <param name="segmentCast">Cast data</param>
        /// <param name="allocator">Allocator used to create internal buffers</param>
        public static void CastRay <T>(this Navmesh navmesh, T rayCast, Allocator allocator) where T : IRayCast
        {
            var open = new NativeList <IntPtr>(allocator);

            navmesh.CastRay(rayCast, open);
            open.Dispose();
        }
Пример #11
0
    internal bool SetConfigFromTarget(BuildContext context)
    {
        if (mBuildData.IsValid)
        {
            // Can't do it while in buildable state.
            return(false);
        }

        if (!CanLoadFromTarget(context, false))
        {
            return(false);
        }

        Navmesh navmesh = BuildTarget.GetNavmesh();

        if (navmesh == null)
        {
            context.LogError("Build target does not have an existing navigation mesh. (It lied.)"
                             , this);
            return(false);
        }

        SetConfigFromTargetIntern(navmesh);

        return(true);
    }
Пример #12
0
        public Battle(BattleParams param, Navmesh navmesh, LuaEnv luaEnv)
        {
            this.rid  = param.id;
            this.data = ModelFactory.GetBattleData(Utils.GetIDFromRID(this.rid));

            this._luaEnv        = luaEnv;
            this._context       = new UpdateContext();
            this._entityManager = new EntityManager(this);
            this._buffManager   = new BuffManager(this);
            this._random        = new ConsistentRandom(param.rndSeed);
            this._pathManager   = new NavMeshProxy();
            this._timer0        = new TimeScheduler();
            this._pathManager.Create(navmesh);

            if (!string.IsNullOrEmpty(this.data.script))
            {
                this._script = new Script(this, this._luaEnv, this.data.script);
                this._script.Call(Script.S_ON_BATTLE_INITIALIZED);
            }

            this.CreatePlayers(param);

            foreach (KeyValuePair <string, BattleData.Structure> kv in this.data.structures)
            {
                BattleData.Structure def = this.data.structures[kv.Key];
                this.CreateBio(def.id, def.pos, def.dir, def.team);
            }

            foreach (KeyValuePair <string, BattleData.Neutral> kv in this.data.neutrals)
            {
                BattleData.Neutral def = this.data.neutrals[kv.Key];
                this.CreateBio(def.id, def.pos, def.dir, def.team);
            }
        }
Пример #13
0
        /// <summary>
        /// Reports all edges intersecting specified line segment while ISegmentCast.RegisterCollision returns true.
        /// Collisions are reported in order of their distance from segmentCast.Origin.
        /// </summary>
        /// <param name="segmentCast">Cast data</param>
        /// <param name="allocator">Allocator used to create internal buffers</param>
        public static void CastSegment <T>(this Navmesh navmesh, T segmentCast, Allocator allocator) where T : ISegmentCast
        {
            var open = new NativeList <IntPtr>(allocator);

            navmesh.CastSegment(segmentCast, open);
            open.Dispose();
        }
Пример #14
0
    void TestDisturbances(ref Navmesh lct)
    {
        _disturbances.Clear();

        var e = lct.GetEdgeEnumerator(true);

        while (e.MoveNext())
        {
            if (e.Current->Constrained)
            {
                continue;
            }

            lct.CheckEdgeForDisturbances(e.Current, _disturbances);

            for (int j = 0; j < _disturbances.Length; j++)
            {
                var p = _disturbances[j].Vertex->Point;
                var o = _disturbances[j].Edge->Org->Point;
                var d = _disturbances[j].Edge->Dest->Point;
                Debug.Log($"Edge {o} => {d} disturbed by {p}");
            }

            Assert.IsTrue(_disturbances.Length == 0);
        }
    }
Пример #15
0
    void Awake()
    {
        meshGenerator    = this;
        mesh             = new Mesh();
        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        // Vector3 position = new Vector3(-xSize * width / 2f, 0f, -zSize * length / 2f);
        // meshFilter.transform.Translate(position, Space.World);

        // material.SetFloat("TerraceHeight", terraceHeight);
        material.SetFloat("Height", height);

        // StartCoroutine(IEnumerable CreateShapeCoroutine());
        GenerateLand();
        UpdateMesh();
        meshFilter.mesh         = mesh;
        meshCollider.sharedMesh = mesh;

        navmesh = new Navmesh(vertices, xSize, zSize, width, length);
        // int testVertex = (9 * xSize / 10) * (9 * zSize / 10);
        // Vector3 testVertex = navmesh.findClosestVertex(new Vector3(24.4f, 1f, 24.4f));
        // // Debug.Log("Closest Vertex: " + testVertex.ToString());
        // paths = new Stack<Vector3>[navigators.Length];
        // int index = 0;
        // foreach (Transform navigator in navigators)
        // {
        //     navigator.position = testVertex + transform.position;
        //     paths[index] = navmesh.getSmartPath(testVertex, vertices[0]);
        //     index ++;
        // }
        // path = navmesh.getPath(testVertex, vertices[0]);
    }
Пример #16
0
        public static Pathfinder Create(string filePath)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream      stream    = null;

            if (!File.Exists(filePath))
            {
                return(null);
            }

            try
            {
                stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                NavStatus status = Navmesh.Create((byte[])formatter.Deserialize(stream), out Navmesh navMesh);
                if (status == NavStatus.Sucess)
                {
                    return(new Pathfinder(navMesh));
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            return(null);
        }
Пример #17
0
    private float _elapsedtime;                                 //出現時間

    private void Start()
    {
        _navmesh_obj    = GameObject.Find("Spawner");
        _navmesh        = gameObject.GetComponent <Navmesh>();
        _numberofenemys = 0;
        _elapsedtime    = 0.0f;
    }
Пример #18
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="copy">The group to copy.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned. Otherwise it will be referenced.
 /// </param>
 public NavGroup(NavGroup copy, bool cloneFilter)
 {
     this.mesh    = copy.mesh;
     this.query   = copy.query;
     this.crowd   = copy.crowd;
     this.filter  = (cloneFilter ? copy.filter.Clone() : copy.filter);
     this.extents = copy.extents;
 }
Пример #19
0
        public static CrowdMoveMgr Create(Navmesh navMesh, int maxAgent = 100, float maxAgentRaidus = 45f)
        {
            GameObject   gameObj = new GameObject("CrowdMoveMgr", typeof(CrowdMoveMgr));
            CrowdMoveMgr mgr     = gameObj.GetComponent <CrowdMoveMgr>();

            mgr.Init(navMesh, maxAgent, maxAgentRaidus);
            return(mgr);
        }
Пример #20
0
 public AIMesh()
 {
     navmesh          = null;
     AIMeshVertexData = new List <Vector3>();
     AIMeshIndicsData = new List <AIMeshIndexData>();
     AIMeshVertics    = new List <AIMeshVertex>();
     AIMeshEdges      = new List <AIMeshEdge>();
 }
Пример #21
0
        /// <summary>
        /// Draws a debug visualization of the navigation mesh.
        /// </summary>
        /// <param name="mesh">The mesh to draw.</param>
        /// <param name="colorByArea">
        /// If true, will be colored by polygon area. If false, will be colored by tile index.
        /// </param>
        public static void Draw(Navmesh mesh, bool colorByArea)
        {
            int count = mesh.GetMaxTiles();

            for (int i = 0; i < count; i++)
            {
                Draw(mesh.GetTile(i), null, null, 0, colorByArea ? -1 : i);
            }
        }
Пример #22
0
        /// <summary>
        /// Reports all edges intersecting specified disc while IDiscCast.RegisterCollision returns true.
        /// A NativeQueue and NativeHashSet will be created with the specified allocator, and disposed before returning.
        /// </summary>
        /// <param name="discCast">Cast data</param>
        /// <param name="allocator">Allocator used to create internal buffers</param>
        public static void CastDisc <T>(this Navmesh navmesh, T discCast, Allocator allocator) where T : IDiscCast
        {
            var open   = new NativeList <IntPtr>(allocator);
            var closed = new NativeHashSet <int>(32, allocator);

            navmesh.CastDisc(discCast, open, closed);
            open.Dispose();
            closed.Dispose();
        }
Пример #23
0
        /// <summary>
        /// Draws a debug visualization of the navigation mesh with the closed nodes highlighted.
        /// </summary>
        /// <param name="mesh">The mesh to draw.</param>
        /// <param name="query">The query which provides the list of closed nodes.</param>
        public static void Draw(Navmesh mesh, NavmeshQuery query)
        {
            int count = mesh.GetMaxTiles();

            for (int i = 0; i < count; i++)
            {
                Draw(mesh.GetTile(i), query, null, 0, i);
            }
        }
Пример #24
0
        public void Create(Navmesh navmesh)
        {
            this._navmesh = navmesh;            //一定要保存起来,Navmesh的析构函数会把非托管内存的指针清掉!!
            NavStatus status = NavmeshQuery.Create(navmesh, 2048, out this._query);

            if (status != NavStatus.Sucess)
            {
                LLogger.Error(status);
            }
        }
Пример #25
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="mesh">The navigation mesh used by the query.</param>
 /// <param name="query">A navigation mesh query.</param>
 /// <param name="crowd">A crowd.</param>
 /// <param name="filter">The filter to use with the query.</param>
 /// <param name="extents">The extents to use with the query.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned rather than referenced.
 /// </param>
 public NavGroup(Navmesh mesh, NavmeshQuery query, CrowdManager crowd
                 , NavmeshQueryFilter filter, Vector3 extents
                 , bool cloneFilter)
 {
     this.mesh    = mesh;
     this.query   = query;
     this.crowd   = crowd;
     this.filter  = (cloneFilter ? filter.Clone() : filter);
     this.extents = extents;
 }
Пример #26
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="mesh">The navigation mesh used by the query.</param>
 /// <param name="query">A navigation mesh query.</param>
 /// <param name="crowd">A crowd.</param>
 /// <param name="filter">The filter to use with the query.</param>
 /// <param name="extents">The extents to use with the query.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned rather than referenced.
 /// </param>
 public NavGroup(Navmesh mesh, NavmeshQuery query, CrowdManager crowd
     , NavmeshQueryFilter filter, Vector3 extents
     , bool cloneFilter)
 {
     this.mesh = mesh;
     this.query = query;
     this.crowd = crowd;
     this.filter = (cloneFilter ? filter.Clone() : filter);
     this.extents = extents;
 }
Пример #27
0
 public LctValidator(ref Navmesh navmesh, Allocator allocator)
 {
     _triangles           = new HashSet <int>(1024, allocator);
     _removedTriangles    = new NativeList <int>(1024, allocator);
     _closed              = new HashSet <IntPtr>(1024, allocator);
     _disturbances        = new NativeList <Disturbance>(allocator);
     _unconstrained       = new NativeList <IntPtr>(allocator);
     _clearanceCalculated = new NativeArray <int>(1, allocator);
     _previousTriangles   = default;
     InitTriangles(ref navmesh);
 }
Пример #28
0
    /// <summary>
    /// Generates a human readable report of the mesh data.
    /// </summary>
    /// <returns>A human readable report of the mesh data.</returns>
    public string GetMeshReport()
    {
        if (!HasNavmesh)
        {
            return("No mesh.");
        }

        Navmesh nm = GetNavmesh();

        NavmeshParams nmconfig = nm.GetConfig();

        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        sb.AppendLine("Navigation mesh report for " + name);

        if (mBuildInfo != null)
        {
            sb.AppendLine("Built from scene: " + mBuildInfo.inputScene);
        }

        sb.AppendLine(string.Format("Tiles: {0}, Tile Size: {1:F3}x{2:F3}, Max Polys Per Tile: {3}"
                                    , nmconfig.maxTiles, nmconfig.tileWidth, nmconfig.tileDepth, nmconfig.maxPolysPerTile));

        int polyCount = 0;
        int vertCount = 0;
        int connCount = 0;

        for (int i = 0; i < nmconfig.maxTiles; i++)
        {
            NavmeshTileHeader header = nm.GetTile(i).GetHeader();

            if (header.polyCount == 0)
            {
                continue;
            }

            sb.AppendLine(string.Format(
                              "Tile ({0},{1}): Polygons: {2}, Vertices: {3}, Off-mesh Connections: {4}"
                              , header.tileX, header.tileZ
                              , header.polyCount, header.vertCount
                              , header.connCount));

            polyCount += header.polyCount;
            vertCount += header.vertCount;
            connCount += header.connCount;
        }

        sb.AppendLine(string.Format(
                          "Totals: Polygons: {0}, Vertices: {1}, Off-mesh Connections: {2}"
                          , polyCount, vertCount, connCount));

        return(sb.ToString());
    }
Пример #29
0
        public Pathfinder(Navmesh navMesh)
        {
            _navMesh = navMesh;
            _filter  = new NavmeshQueryFilter();

            if (NavUtil.Failed(NavmeshQuery.Create(_navMesh, 1000, out _query)))
            {
                throw new Exception("NavQuery failed");
            }

            _pathCorridor = new PathCorridor(1000, 1000, _query, _filter);
        }
Пример #30
0
        /// <summary>
        /// Disable the visualization.
        /// </summary>
        public void Hide()
        {
            if (mDelegate != null)
            {
                SceneView.onSceneGUIDelegate -= mDelegate;
                SceneView.RepaintAll();
            }

            mNavmeshData = null;
            mDataVersion = -1;
            mNavmesh     = null;
            mDelegate    = null;
        }
Пример #31
0
        /// <summary>
        /// Draws a debug visualization of the specified navigation mesh tile.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is safe to call on empty tile locations.
        /// </para>
        /// </remarks>
        /// <param name="mesh">The mesh.</param>
        /// <param name="tx">The tile grid x-location.</param>
        /// <param name="tz">The tile grid z-location.</param>
        /// <param name="layer">The tile layer.</param>
        /// <param name="colorByArea">
        /// If true, will be colored by polygon area. If false, will be colored by tile index.
        /// </param>
        public static void Draw(Navmesh mesh, int tx, int tz, int layer, bool colorByArea)
        {
            NavmeshTile tile = mesh.GetTile(tx, tz, layer);

            if (tile == null)
            {
                // No tile at grid location.
                return;
            }

            Draw(tile, null, null, 0
                 , colorByArea ? -1 : tx.GetHashCode() ^ tz.GetHashCode() ^ layer.GetHashCode());
        }
Пример #32
0
        /// <summary>
        /// Draws a debug visualization of the navigation mesh with the specified polygons
        /// highlighted.
        /// </summary>
        /// <param name="mesh">The mesh to draw.</param>
        /// <param name="markPolys">
        /// The references of the polygons that should be highlighted.
        /// </param>
        /// <param name="polyCount">
        /// The number of polygons in the <paramref name="markPolys"/> array.
        /// </param>
        public static void Draw(Navmesh mesh, uint[] markPolys, int polyCount)
        {
            int count = mesh.GetMaxTiles();

            for (int i = 0; i < count; i++)
            {
                Draw(mesh.GetTile(i)
                     , null
                     , markPolys
                     , polyCount
                     , i);
            }
        }
Пример #33
0
    // Use this for initialization
    void Start()
    {
        Rect flappyBoundingRect = SpriteRendererBoundingRect (GameObject.Find ("Flappy").GetComponent<SpriteRenderer> ());
        float flappyWidth = 0.5f * flappyBoundingRect.width;
        float flappyHeight = 0.5f * flappyBoundingRect.height;

        points = new Navmesh();

        float width = Camera.main.pixelWidth;
        float height = Camera.main.pixelHeight;

        for (float x = 0; x < width; x += step) {
            for (float y = 0; y < height; y += step) {
                Vector3 pointPos = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 0));

                // Check at this point, as well as to the left, right, up, down of it to make sure Flappy can fit
                if (!Physics.Raycast(pointPos, Vector3.forward) &&
                    !Physics.Raycast(pointPos + new Vector3(flappyWidth, 0, 0), Vector3.forward) &&
                    !Physics.Raycast (pointPos + new Vector3(-flappyWidth, 0, 0), Vector3.forward) &&
                    !Physics.Raycast (pointPos + new Vector3(0, flappyHeight, 0), Vector3.forward) &&
                    !Physics.Raycast(pointPos + new Vector3(0, -flappyHeight, 0), Vector3.forward))

                    points.Add(Instantiate(point, pointPos + (10 * Vector3.forward), Quaternion.identity) as GameObject);
            }
        }

        Debug.Log ("Total points: " + points.Count);

        float gameUnitInPx = (Camera.main.WorldToScreenPoint(new Vector3(1, 0, 0))
                               - Camera.main.WorldToScreenPoint(new Vector3(0, 0, 0))).x;

        points.gameUnitStep = (step / gameUnitInPx);

        if (this.gameObject.GetComponent<AStar_SpecialSourceAndDest> ()) {
            this.gameObject.GetComponent<AStar_SpecialSourceAndDest> ().UpdateNavmesh ();
        }
    }
        /// <summary>
        /// Disable the visualization.
        /// </summary>
        public void Hide()
        {
            if (mDelegate != null)
            {
                SceneView.onSceneGUIDelegate -= mDelegate;
                SceneView.RepaintAll();
            }

            mNavmeshData = null;
            mDataVersion = -1;
            mNavmesh = null;
            mDelegate = null;
        }
 public void UpdateNavmesh()
 {
     navmesh = GameObject.Find ("NavmeshGenerator").GetComponent<NavmeshSpawner> ().GetNavmesh ();
 }
Пример #36
0
    private void CalculatePath()
    {
        //Debug.Log("Calculating...");

        navmesh = GameObject.Find("NavmeshGenerator").GetComponent<NavmeshSpawner>().GetNavmesh();
        path = new ArrayList();

        // cast rays up, down, left, right and if its longer than it should be, ignore the impact
        float expectedDist = navmesh.gameUnitStep + fudge;

        // Start the calculation by finding the closest node to the player (or GameObject to which we are attached)
        GameObject startPoint = FindClosestNavmeshPointTo(this.gameObject);
        Debug.Log ("Starting from: (" + startPoint.transform.position.x + ", " + startPoint.transform.position.y + ")");

        SearchElement startElement = new SearchElement(startPoint, 0.0f);

        // Then find the closest GameObject to the target
        endPoint = FindClosestNavmeshPointTo(target.gameObject);
        //Debug.Log ("Ending at: (" + endPoint.transform.position.x + ", " + endPoint.transform.position.y + ")");

        // Keep a priority queue of points on the frontier, sorted in increasing order by F = G + H
        // The CompareTo() function of each SearchElement takes into account the H value
        SortedList openSet = new SortedList();
        // Keep a list of NavmeshPoints we have already found in the SPT
        ArrayList closedSet = new ArrayList();

        openSet.Add(startElement, null);

        SearchElement finalSearchElement = null;

        while (openSet.Count > 0) {

            // Dequeue the element in the openSet with the smallest distance
            SearchElement current = openSet.GetKey(0) as SearchElement;

            // Is this what we are looking for?
            if (current.point == endPoint) {
                closedSet.Add(current.point);
                finalSearchElement = current;
                break;

            }

            // Remove this NavmeshPoint from the openSet and add it to the closedSet
            openSet.Remove(current);
            closedSet.Add(current.point);
            current.point.layer = 9;

            //Debug.Log ("Processing point at (" + current.point.transform.position.x
            //           + ", " + current.point.transform.position.y + ")");

            // Get all NavmeshPoints adjacent to this point in the form of SearchElements whose dists are current.dist
            // plus however long the edge from current to the adjacent point is (measured in terms of game space dist)
            ArrayList adj = GetAdjacentPoints(current, expectedDist);

            // Find out if any points adjacent to current are already in the openSet
            // If they are, find out if the distance through the current path is shorter than the distance
            // they are currently at through other paths. If the distance through current is shorter, update the dist
            // to be the dist through current, and update the from field to be current.

            // Note: We do not explicitly handle the heuristic estimate at this time, as it is taken care of for us
            // behind the scenes in the openSet.Add() function by the IComparable interface implemented by SearchElement
            foreach (SearchElement newFrontierElement in adj) {

                bool elementInOpenSet = false;
                bool replaceExistingElement = false;
                SearchElement existingElementIndex = null;

                foreach (SearchElement establishedFrontierElement in openSet.Keys) {
                    if (newFrontierElement.point == establishedFrontierElement.point) {

                        // This NavmeshPoint exists in the openSet
                        elementInOpenSet = true;

                        if (newFrontierElement.dist < establishedFrontierElement.dist) {

                            // The new path is a better path than the current path
                            replaceExistingElement = true;
                            existingElementIndex = establishedFrontierElement;
                        }

                        // Break out of the openSet for-loop; we are done here since we found a match
                        break;
                    }
                }

                if (!elementInOpenSet) {
                    openSet.Add(newFrontierElement, null);
                }
                else if (elementInOpenSet && replaceExistingElement) {
                    openSet.Remove(existingElementIndex);
                    openSet.Add(newFrontierElement, null);
                }

                foreach (SearchElement e in openSet.Keys) {
                    //Debug.Log("(" + e.point.transform.position.x + ", " + e.point.transform.position.y + "): "
                    //          + (e.dist + Vector2.Distance(e.point.transform.position, endPoint.transform.position)).ToString()
                    //          + "   ");
                }
            }

        }

        // We either ran out of elements in the navmesh and should throw an error, or we arrived at the target
        if (finalSearchElement == null) {
            throw new Exception("Target element not found by A* algorithm");
        }
        else {

            // We shouldn't show the close navpoints any longer
            this.gameObject.GetComponent<ShowNearbyNavpoints>().SendMessage("Cleanup");

            // Reconstruct the path that won
            path = new ArrayList();
            pathDist = 0.0f;

            SearchElement pathPoint = finalSearchElement;
            while (pathPoint != null) {
                path.Add(pathPoint.point);
                pathDist += pathPoint.dist;
                pathPoint = (SearchElement)pathPoint.from;
            }

            // Finally, reverse the path, since we added elements to it in reverse order (i.e. starting from target)
            path.Reverse();
            foreach (GameObject navmeshPoint in path) {
                SpriteRenderer sr = navmeshPoint.GetComponent<SpriteRenderer>();
                sr.enabled = true;
                sr.color = Color.red;
            }

            this.gameObject.GetComponent<FollowPath>().StartFollowing(path);

            //Debug.Log ("Final path distance: " + pathDist);

        }
    }
Пример #37
0
 /// <summary>
 /// Draws a debug visualization of the navigation mesh with the closed nodes highlighted.
 /// </summary>
 /// <param name="mesh">The mesh to draw.</param>
 /// <param name="query">The query which provides the list of closed nodes.</param>
 public static void Draw(Navmesh mesh, NavmeshQuery query)
 {
     int count = mesh.GetMaxTiles();
     for (int i = 0; i < count; i++)
     {
         Draw(mesh.GetTile(i), query, null, 0, i);
     }
 }
Пример #38
0
        /// <summary>
        /// Draws a debug visualization of the specified navigation mesh tile.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is safe to call on empty tile locations.
        /// </para>
        /// </remarks>
        /// <param name="mesh">The mesh.</param>
        /// <param name="tx">The tile grid x-location.</param>
        /// <param name="tz">The tile grid z-location.</param>
        /// <param name="layer">The tile layer.</param>
        /// <param name="colorByArea">
        /// If true, will be colored by polygon area. If false, will be colored by tile index.
        /// </param>
        public static void Draw(Navmesh mesh, int tx, int tz, int layer, bool colorByArea)
        {
            NavmeshTile tile = mesh.GetTile(tx, tz, layer);

            if (tile == null)
                // No tile at grid location.
                return;
            
            Draw(tile, null, null, 0
                , colorByArea ? -1 : tx.GetHashCode() ^ tz.GetHashCode() ^ layer.GetHashCode());
        }
Пример #39
0
 /// <summary>
 /// Draws a debug visualization of the navigation mesh with the specified polygons 
 /// highlighted.
 /// </summary>
 /// <param name="mesh">The mesh to draw.</param>
 /// <param name="markPolys">
 /// The references of the polygons that should be highlighted.
 /// </param>
 /// <param name="polyCount">
 /// The number of polygons in the <paramref name="markPolys"/> array.
 /// </param>
 public static void Draw(Navmesh mesh, uint[] markPolys, int polyCount)
 {
     int count = mesh.GetMaxTiles();
     for (int i = 0; i < count; i++)
     {
         Draw(mesh.GetTile(i)
             , null
             , markPolys
             , polyCount
             , i);
     }
 }
Пример #40
0
    void OnRenderObject()
    {
        if (!mDebugEnabled)
            return;

        INavmeshData data = NavmeshData;

        if (!mNavmeshData || !data.HasNavmesh)
        {
            mDebugMesh = null;
            return;
        }

        if (mDebugMesh == null || data.Version != mDebugVersion)
        {
            mDebugMesh = data.GetNavmesh();
            mDebugVersion = data.Version;

            if (mDebugMesh == null)
                return;
        }

        NavDebug.Draw(mDebugMesh, false);
    }
Пример #41
0
        /// <summary>
        /// Draws a debug visualization of a corridor.
        /// </summary>
        /// <param name="mesh">The navigation mesh associated with the corridor.</param>
        /// <param name="corridor">The corridor to draw.</param>
        public static void Draw(Navmesh mesh, PathCorridorData corridor)
        {
            if (corridor.pathCount == 0)
                return;

            DebugDraw.SimpleMaterial.SetPass(0);

            Vector3[] tileVerts = null;

            for (int iPoly = 0; iPoly < corridor.pathCount; iPoly++)
            {
                NavmeshTile tile;
                NavmeshPoly poly;
                mesh.GetTileAndPoly(corridor.path[iPoly], out tile, out poly);

                if (poly.Type == NavmeshPolyType.OffMeshConnection)
                    continue;

                NavmeshTileHeader header = tile.GetHeader();
                if (tileVerts == null
                    || tileVerts.Length < 3 * header.vertCount)
                {
                    // Resize.
                    tileVerts = new Vector3[header.vertCount];
                }

                tile.GetVerts(tileVerts);

                GL.Begin(GL.TRIANGLES);
                GL.Color(polygonOverlayColor);

                int pA = poly.indices[0];
                for (int i = 2; i < poly.vertCount; i++)
                {
                    int pB = poly.indices[i - 1];
                    int pC = poly.indices[i];

                    GL.Vertex(tileVerts[pA]);
                    GL.Vertex(tileVerts[pB]);
                    GL.Vertex(tileVerts[pC]);
                }

                GL.End();

                // Not drawing boundaries since it would obscure other agent
                // debug data.
            }

            Vector3 v = corridor.position;
            DebugDraw.XMarker(v, positionScale, positionColor);
            DebugDraw.Circle(v, positionScale, positionColor);
            DebugDraw.Circle(v, positionScale * 0.5f, positionColor);
            DebugDraw.Circle(v, positionScale * 0.25f, positionColor);

            v = corridor.target;
            DebugDraw.XMarker(v, goalScale, goalColor);
            DebugDraw.Circle(v, goalScale, goalColor);
            DebugDraw.Circle(v, goalScale * 0.5f, goalColor);
            DebugDraw.Circle(v, goalScale * 0.25f, goalColor);
        }
Пример #42
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="copy">The group to copy.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned. Otherwise it will be referenced.
 /// </param>
 public NavGroup(NavGroup copy, bool cloneFilter)
 {
     this.mesh = copy.mesh;
     this.query = copy.query;
     this.crowd = copy.crowd;
     this.filter = (cloneFilter ? copy.filter.Clone() : copy.filter);
     this.extents = copy.extents;
 }
Пример #43
0
 /// <summary>
 /// Returns the 3D centroids of the provided navigation mesh polygons.
 /// </summary>
 /// <remarks>
 /// <para>
 /// If a polygon does not exist within the mesh, its associated centroid will not 
 /// be altered.  So some centroid data will be invalid if  <paramref name="polyCount"/> 
 /// is not equal to the result count.
 /// </para>
 /// </remarks>
 /// <param name="mesh">The navigation mesh containing the polygons.</param>
 /// <param name="polyRefs">The references of the polygons.</param>
 /// <param name="polyCount">The number of polygons.</param>
 /// <param name="centroids">
 /// The centroids for the polygons. [Length: >= polyCount] (Out)
 /// </param>
 /// <returns>The actual number of polygons found within the mesh. </returns>
 public static int GetCentroids(Navmesh mesh
     , uint[] polyRefs
     , int polyCount
     , Vector3[] centroids)
 {
     int resultCount = 0;
     int count = mesh.GetMaxTiles();
     for (int i = 0; i < count; i++)
     {
         resultCount += GetCentroids(mesh.GetTile(i)
             , polyRefs
             , polyCount
             , centroids);
         if (resultCount == polyRefs.Length)
             break;
     }
     return resultCount;
 }
Пример #44
0
 public void AttachToNavmesh(Navmesh nav_mesh)
 {
     Navmesh = nav_mesh;
     Navmesh.Navigator.AddListener(this);
 }
Пример #45
0
 /// <summary>
 /// Draws a debug visualization of the navigation mesh.
 /// </summary>
 /// <param name="mesh">The mesh to draw.</param>
 /// <param name="colorByArea">
 /// If true, will be colored by polygon area. If false, will be colored by tile index.
 /// </param>
 public static void Draw(Navmesh mesh, bool colorByArea)
 {
     int count = mesh.GetMaxTiles();
     for (int i = 0; i < count; i++)
     {
         Draw(mesh.GetTile(i), null, null, 0, colorByArea ? -1 : i);
     }
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="navmesh">The navigation mesh used by the agents.
 /// </param>
 public CrowdAgentDebug(Navmesh navmesh) 
 {
     this.navmesh = navmesh;
 }
        private void OnSceneGUI(SceneView sceneView)
        {
            if (!(ScriptableObject)mNavmeshData)
            {
                Hide();
                return;
            }

            if (!mNavmeshData.HasNavmesh)
            {
                mDataVersion = -1;
                mNavmesh = null;
                return;
            }

            if (mNavmesh == null || mNavmeshData.Version != mDataVersion)
            {
                mNavmesh = mNavmeshData.GetNavmesh();
                mDataVersion = mNavmeshData.Version;

                if (mNavmesh == null)
                    return;
            }

            NavDebug.Draw(mNavmesh, mColorByArea);
        }