Vector3 MoveablePosition(Coord coord, Vector3 currentPosition) { Vector3 p = maze.GetGroundPosition(coord); switch (tileSurfaceChoice) { case TileSurfaceChoice.Center: break; case TileSurfaceChoice.Random: { Vector3 extents = maze.tileSize / 2; extents.y = 0; Vector3 r = new Vector3(Random.NextFloat(-1, 1) * extents.x, 0, extents.z * Random.NextFloat(-1, 1)); // raycasting hits something early quite often, resulting in very high points. not sure what is going on there. r.y = maze.tileSize.y; if (Physics.Raycast(p + r, Vector3.down, out RaycastHit rh, maze.tileSize.y * 2, ~pathingIgnores, QueryTriggerInteraction.Ignore)) { p = rh.point; } } break; case TileSurfaceChoice.Closest: { Vector3 extents = maze.tileSize / 2; extents.y = 0; extents.z -= follower.CharacterRadius * 2; extents.x -= follower.CharacterRadius * 2; float fDot = Vector3.Dot(Vector3.forward, currentPosition - (p + Vector3.forward * extents.z)); float bDot = Vector3.Dot(Vector3.back, currentPosition - (p + Vector3.back * extents.z)); float lDot = Vector3.Dot(Vector3.left, currentPosition - (p + Vector3.left * extents.x)); float rDot = Vector3.Dot(Vector3.right, currentPosition - (p + Vector3.right * extents.x)); Vector3 inner = currentPosition; if (fDot > 0) { inner.z = p.z + extents.z; } if (bDot > 0) { inner.z = p.z - extents.z; } if (rDot > 0) { inner.x = p.x + extents.x; } if (lDot > 0) { inner.x = p.x - extents.x; } inner.y = p.y + maze.tileSize.y; if (Physics.Raycast(inner, Vector3.down, out RaycastHit rh, maze.tileSize.y * 2, ~pathingIgnores, QueryTriggerInteraction.Ignore)) { p = rh.point; } } break; } return(p + Vector3.up * follower.CharacterHeight); }
public bool RandomVisibleNode(out Coord c, Coord currentNode) { Coord size = Map.GetSize(); c = new Coord(Random.Next(size.X), Random.Next(size.Y)); if (vision[c]) { return(true); } return(false); }
public bool RandomNeighborNode(out Coord c, Coord currentNode) { c = currentNode; List <int> edges = GetEdges(c); if (edges.Count > 0) { c = NextNode(c, edges[Random.Next(edges.Count)]); return(true); } return(false); }
void Update() { if (visionParticle != null) { if (characterMover.JumpButtonTimed > 0 && !visionParticle.isPlaying) { visionParticle.Play(); } else if (characterMover.JumpButtonTimed == 0 && visionParticle.isPlaying) { visionParticle.Stop(); } } Coord mapSize = maze.Map.GetSize(); if (mapAstar == null) { mapAstar = new Map2dAStar(() => canJump, maze, discovery.vision, _t, prefab_debug_astar); } mapAstar.UpdateMapSize(); Vector3 p = _t.position; Coord here = maze.GetCoord(p); if (follower.waypoints.Count > 0) { Coord there = maze.GetCoord(follower.waypoints[0].positon); if (here == there) { follower.NotifyWayPointReached(); } } List <Coord> moves = mapAstar.Moves(here, canJump); if (textOutput != null) { UiText.SetText(textOutput, here.ToString() + ":" + (p - maze.transform.position) + " " + moves.JoinToString(", ")); } if (useVisionParticle && visionParticle) { timer -= Time.deltaTime; if (timer <= 0) { mapSize.ForEach(co => { if (discovery.vision[co]) { Vector3 po = maze.GetPosition(co); po.y = _t.position.y; visionParticle.transform.position = po; visionParticle.Emit(1); } }); timer = .5f; } } switch (aiBehavior) { case AiBehavior.RandomLocalEdges: if (!characterMover.IsAutoMoving()) { Coord c = moves[Random.Next(moves.Count)]; characterMover.SetAutoMovePosition(MoveablePosition(c, p)); } break; case AiBehavior.RandomInVision: if (mapAstar.goal == here) { if (mapAstar.RandomVisibleNode(out Coord there, here)) { //Debug.Log("startover #"); //Debug.Log("goal " + there+ " "+astar.IsFinished()); } else { mapAstar.RandomNeighborNode(out there, here); } mapAstar.Start(here, there); } else { // iterate astar algorithm if (!mapAstar.IsFinished()) { mapAstar.Update(); } else if (mapAstar.BestPath == null) { //Debug.Log("f" + astar.IsFinished() + " " + astar.BestPath); mapAstar.Start(here, here); //Debug.Log("startover could not find path"); } if (mapAstar.BestPath != null) { if (mapAstar.BestPath != currentBestPath) { currentBestPath = mapAstar.BestPath; List <Coord> nodes = new List <Coord>(); Coord c = mapAstar.start; nodes.Add(c); for (int i = currentBestPath.Count - 1; i >= 0; --i) { c = mapAstar.NextNode(c, currentBestPath[i]); nodes.Add(c); } //Debug.Log(currentBestPath.JoinToString(", ")); indexOnBestPath = nodes.IndexOf(here); if (indexOnBestPath < 0) { mapAstar.Start(here, mapAstar.goal); //Debug.Log("startover new better path"); } Vector3 pos = p; follower.ClearWaypoints(); for (int i = 0; i < currentBestPath.Count; ++i) { pos = MoveablePosition(nodes[i + 1], pos); //pos.y += follower.CharacterHeight; //Show.Log(i + " " + nodes.Count + " " + currentBestPath.Count + " " + (currentBestPath.Count - i - 1)); MazeAStar.EdgeMoveType moveType = MazeAStar.GetEdgeMoveType(currentBestPath[currentBestPath.Count - i - 1]); switch (moveType) { case MazeAStar.EdgeMoveType.Walk: follower.AddWaypoint(pos, false); break; case MazeAStar.EdgeMoveType.Fall: follower.AddWaypoint(pos, false, 0, true); break; case MazeAStar.EdgeMoveType.Jump: follower.AddWaypoint(pos, false, characterMover.jump.fullPressDuration); break; } } follower.SetCurrentTarget(pos); follower.UpdateLine(); follower.doPrediction = true; } else { if (!characterMover.IsAutoMoving() && follower.waypoints.Count == 0) { mapAstar.Start(here, here); //Debug.Log("startover new level?"); } } } } break; } }