-
-
Save solsnare/e5d9a9970497bb039d7e834db4410732 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Pathfinding; | |
using Pathfinding.Util; | |
using UnityEngine; | |
public class RoomData : MonoBehaviour | |
{ | |
public Color mapColor; | |
public TextAsset AStarCache; | |
public Vector3 startingPosition; | |
public Vector3 startingRotation; | |
private static bool _roomsMerged = false; | |
void Start() | |
{ | |
//yield return new WaitForSeconds(5.0f); | |
if (AStarCache == null) return; | |
AstarPath.active.data.DeserializeGraphsAdditive(AStarCache.bytes); | |
Matrix4x4 graphMatrix = Matrix4x4.identity; | |
graphMatrix *= Matrix4x4.Translate(transform.position); | |
graphMatrix *= Matrix4x4.Rotate(transform.rotation); | |
graphMatrix *= Matrix4x4.Translate(-transform.position); | |
graphMatrix *= Matrix4x4.Translate(transform.position - startingPosition); | |
var graphs = AstarPath.active.graphs; | |
int pointGraphIndex = graphs.Length - 1; | |
int recastGraphIndex = graphs.Length - 2; | |
if (graphs[recastGraphIndex] is RecastGraph) | |
{ | |
Debug.Log("Moving a recast graph!"); | |
var g = graphs[recastGraphIndex] as RecastGraph; | |
g.RelocateNodes(graphMatrix); | |
} | |
if (graphs[pointGraphIndex] is PointGraph) | |
{ | |
Debug.Log("Moving a point graph!"); | |
var g = graphs[pointGraphIndex] as PointGraph; | |
g.RelocateNodes(graphMatrix); | |
g.Scan(); | |
g.RebuildNodeLookup(); | |
g.RebuildConnectionDistanceLookup(); | |
g.ConnectNodes(); | |
} | |
} | |
private RecastGraph masterGraph; | |
static List<RecastGraph> recasts; | |
void LateUpdate() | |
{ | |
if (!_roomsMerged) | |
{ | |
_roomsMerged = true; | |
masterGraph = AstarPath.active.data.AddGraph(typeof(RecastGraph)) as RecastGraph; //This will be the main graph with all merged stuff. | |
Debug.Log($"MASTER GRAPH tileXCount {masterGraph.tileXCount} tileZCount {masterGraph.tileZCount}"); | |
Bounds b = new Bounds(); | |
bool boundsEmpty = true; | |
float minCellSize = Mathf.Infinity; | |
recasts = new List<RecastGraph>(); | |
for (int i = 0; i < AstarPath.active.data.graphs.Length - 1; i++) //The final graph will be ours, that's why we do -1. | |
{ | |
if (AstarPath.active.data.graphs[i] is RecastGraph) | |
{ | |
var g = AstarPath.active.data.graphs[i] as RecastGraph; | |
Debug.Log($"Graph {i} tileXCount {g.tileXCount} tileZCount {g.tileZCount}"); | |
var bounds = g.GetTileBounds(new IntRect(0, 0, g.tileXCount-1, g.tileZCount-1)); | |
if (boundsEmpty) | |
{ | |
b = bounds; | |
boundsEmpty = false; | |
} | |
else | |
{ | |
b.Encapsulate(bounds); | |
} | |
if (g.cellSize < minCellSize) | |
{ | |
minCellSize = g.cellSize; | |
} | |
recasts.Add(g); | |
} | |
} | |
masterGraph.cellSize = minCellSize; | |
Debug.Log("DRAWNG RED LINE"); | |
Debug.DrawLine(b.center - b.extents,b.center+b.extents,Color.red,100.0f); | |
//Based on the calculated bounds, let's calculate how many tiles we need to fill that | |
// Voxel grid size | |
int totalVoxelWidth = (int)(b.size.x / masterGraph.cellSize + 0.5f); | |
int totalVoxelDepth = (int)(b.size.z / masterGraph.cellSize + 0.5f); | |
int tileSizeX; | |
int tileSizeZ; | |
if (!masterGraph.useTiles) | |
{ | |
tileSizeX = totalVoxelWidth; | |
tileSizeZ = totalVoxelDepth; | |
} | |
else | |
{ | |
tileSizeX = masterGraph.editorTileSize; | |
tileSizeZ = masterGraph.editorTileSize; | |
} | |
// Number of tiles | |
int tileXCount = (totalVoxelWidth + tileSizeX - 1) / tileSizeX; | |
int tileZCount = (totalVoxelDepth + tileSizeZ - 1) / tileSizeZ; | |
if (tileXCount * tileZCount > NavmeshBase.TileIndexMask + 1) | |
{ | |
throw new System.Exception("Too many tiles (" + (tileXCount * tileZCount) + ") maximum is " + (NavmeshBase.TileIndexMask + 1) + | |
"\nTry disabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* inspector."); | |
} | |
//Based on this, let's make the master graph big enough to contain all these. | |
masterGraph.tileXCount = tileXCount; | |
masterGraph.tileZCount = tileZCount; | |
Debug.Log($"CREATING GRAPH WITH X {tileXCount} Z {tileZCount}"); | |
//Initialize the tile array: | |
masterGraph.InitializeTiles(); | |
masterGraph.FillWithEmptyTiles(); | |
Bounds nb = masterGraph.GetTileBounds(new IntRect(0, 0, masterGraph.tileXCount-1, masterGraph.tileZCount-1)); | |
Debug.DrawLine(nb.center - nb.extents, nb.center + nb.extents, Color.yellow, 100); | |
//Debug.DrawLine(b.center - b.extents, b.center + b.extents, Color.green, 100); | |
//The issue here is that the graph is the right size, but it's not aligned properly. | |
//To align this properly, we need to shift it's current bounds to the calculated world bounds. | |
Vector3 boundDiff = b.center - nb.center; | |
Matrix4x4 graphMatrix = Matrix4x4.identity; | |
//Vector3 tileOffset = new Vector3(masterGraph.tileSizeX, 0, masterGraph.tileSizeZ); | |
//tileOffset = masterGraph.transform.Transform(tileOffset); | |
//Vector3 tileOffset = new Vector3(1.25f, 0, 1.25f); | |
Vector3 tileOffset = new Vector3(0, (nb.size.y - b.size.y)/2,0); | |
//Vector3 tileOffset = new Vector3(0, 0, 0); | |
graphMatrix *= Matrix4x4.Translate(boundDiff + tileOffset); | |
//graphMatrix *= Matrix4x4.Rotate(Quaternion.Euler(0, 90, 0)); | |
masterGraph.RelocateNodes(graphMatrix); | |
//masterGraph.transform = recasts[0].transform; | |
//graph.RelocateNodes(recasts[1].transform); | |
Bounds nb2 = masterGraph.GetTileBounds(new IntRect(0, 0, masterGraph.tileXCount-1, masterGraph.tileZCount-1)); | |
Debug.DrawLine(nb2.center - nb2.extents, nb2.center + nb2.extents, Color.magenta, 100); | |
Debug.Log("MASTER BOUNDS: " + nb2); | |
//---------------------------------- | |
//Now we have a graph that is the right size, and placement | |
//We need to loop through all the recast graphs again, and place their tile data into this larger tilemap | |
//-------------------------------- | |
//Bounds topLeftTile = recasts[2].GetTileBounds(0, 0, 1, 1); | |
//Bounds bottomRightTile = recasts[2].GetTileBounds(recasts[0].tileXCount - 2, recasts[0].tileZCount - 2, 1, 1); | |
//Debug.DrawLine(topLeftTile.center - topLeftTile.extents, topLeftTile.center + topLeftTile.extents, Color.green, 100); | |
//Debug.DrawLine(bottomRightTile.center - bottomRightTile.extents, bottomRightTile.center + bottomRightTile.extents, Color.magenta, 100); | |
TriangleMeshNode.SetNavmeshHolder(AstarPath.active.data.GetGraphIndex(masterGraph), masterGraph); | |
Debug.Log($"TILE SIZE MASTER {masterGraph.TileWorldSizeX} AND GRAPH: {recasts[0].TileWorldSizeX}"); | |
Debug.Log($"World Size {masterGraph.TileWorldSizeX} Tile Count {masterGraph.tileXCount} Tile Size {masterGraph.tileSizeX} Editor Size {masterGraph.editorTileSize}"); | |
AstarPath.active.AddWorkItem((context) => | |
{ | |
masterGraph.StartBatchTileUpdate(); | |
foreach (RecastGraph rg in recasts) | |
{ | |
for (int x = 0; x < rg.tileXCount; x++) | |
{ | |
for (int z = 0; z < rg.tileZCount; z++) | |
{ | |
//Given that the main graph bounds are aligned properly now | |
//We need to convert the tile position from it's space to masterGraphs space. | |
//To do this we want to convert this tile from local into world first. | |
var tile = rg.GetTile(x, z); | |
var tileB = rg.GetTileBounds(x, z, 1, 1); | |
//Bounds is in world space, so we can use that to convert into master graph local space. | |
var masterTileLoc = masterGraph.GetTileCoordinates(tileB.center); | |
//If this is not out of bounds | |
if (masterTileLoc.x >= 0 && masterTileLoc.x < masterGraph.tileXCount && masterTileLoc.y >= 0 && | |
masterTileLoc.y < masterGraph.tileZCount) | |
{ | |
} | |
else continue; | |
//var masterTileB = masterGraph.GetTileBounds(masterTileLoc.x,masterTileLoc.y,1,1); | |
//Debug.DrawLine(masterTileB.center - masterTileB.extents, masterTileB.center + masterTileB.extents, Color.white, 100); | |
//Debug.Log($"Replacing X:{masterTileLoc.x} Z:{masterTileLoc.y}"); | |
Int3[] verts = new Int3[tile.vertsInGraphSpace.Length]; | |
tile.vertsInGraphSpace.CopyTo(verts,0); | |
Matrix4x4 trans = Matrix4x4.identity; | |
trans *= Matrix4x4.Scale(Vector3.one * 0.1f); | |
GraphTransform newGraphTrans = new GraphTransform(trans); | |
//newGraphTrans.Transform(verts); | |
int xSize = (int)(masterGraph.TileWorldSizeX * 1000); | |
int zSize = (int)(masterGraph.TileWorldSizeZ * 1000); | |
for (int i = 0; i < verts.Length; i++) | |
{ | |
verts[i].x -= (xSize * x); | |
verts[i].z -= (zSize * z); | |
} | |
//Let's replace the info. | |
masterGraph.ReplaceTile(masterTileLoc.x, masterTileLoc.y, verts, tile.tris); | |
//There is a problem with the vertices looking like they're scaled up by 3 or 4 times? | |
//Not only that but the vertices are kinda far apart, doesn't make cohesive tiles, it's weird. | |
//tile.vertsInGraphSpace | |
} | |
} | |
} | |
masterGraph.EndBatchTileUpdate(); | |
}); | |
//Clean up all the old graphs. | |
foreach (RecastGraph r in recasts) | |
{ | |
AstarPath.active.data.RemoveGraph(r); | |
} | |
} | |
} | |
void OnDrawGizmos() | |
{ | |
return; | |
if (!_roomsMerged) return; | |
Gizmos.color = Color.blue; | |
if (_roomsMerged && masterGraph != null) | |
{ | |
for (int x = 0; x < masterGraph.tileXCount; x++) | |
{ | |
for (int z = 0; z < masterGraph.tileZCount; z++) | |
{ | |
var b = masterGraph.GetTileBounds(x, z, 1, 1); | |
Gizmos.DrawWireCube(b.center, b.size); | |
} | |
} | |
} | |
//Size of tile b 2.6 in worldspace. | |
return; | |
Bounds totalB = new Bounds(); | |
bool firstBound = true; | |
Gizmos.color = Color.yellow; | |
if (_roomsMerged && masterGraph != null) | |
{ | |
for (int x = 0; x < recasts[0].tileXCount; x++) | |
{ | |
for (int z = 0; z < recasts[0].tileZCount; z++) | |
{ | |
var b = recasts[0].GetTileBounds(x, z, 1, 1); | |
Gizmos.DrawWireCube(b.center, b.size); | |
if (firstBound) | |
{ | |
totalB = b; | |
firstBound = false; | |
} | |
else totalB.Encapsulate(b); | |
} | |
} | |
} | |
Gizmos.color = Color.cyan; | |
var bounds = recasts[0].GetTileBounds(new IntRect(0, 0, recasts[0].tileXCount - 1, recasts[0].tileZCount - 1)); | |
Gizmos.DrawWireCube(totalB.center, totalB.size); | |
} | |
[ContextMenu("Set Starting Position")] | |
void SetStartingPosition() | |
{ | |
startingPosition = transform.position; | |
startingRotation = transform.rotation.eulerAngles; | |
} | |
void OnDestroy() | |
{ | |
_roomsMerged = false; | |
recasts = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment