public void OnSceneGUI()
{
Event e = Event.current;
//draw a grid at the lowest available levels for the map
Map m = (Map)target;
EditorUtility.SetSelectedWireframeHidden(m.GetComponent<MeshRenderer>(), true);
Vector2 sz = m.size;
float s = m.sideLength;
Vector3 pos = m.transform.position;
float h = m.tileHeight;
if(tiles == null) {
tiles = new List<TileBounds>();
}
Vector3 here = pos + new Vector3(-s/2, -h, -s/2);
Vector3[] basePlane = new Vector3[]{
here+new Vector3(-0.1f,-0.1f,-0.1f),
here+new Vector3(-0.1f,-0.1f,s*sz.y+0.2f),
here+new Vector3(s*sz.x+0.2f,-0.1f,s*sz.y+0.2f),
here+new Vector3(s*sz.x+0.2f,-0.1f,-0.1f)
};
Handles.DrawSolidRectangleWithOutline(basePlane,
Color.clear,
Color.black);
Vector2 mpos = e.mousePosition;
Ray ray = HandleUtility.GUIPointToWorldRay(mpos);
int closestIdx = -1;
float closestDistance = Mathf.Infinity;
Vector3 collisionPoint = Vector3.zero;
Neighbors collidedFace = Neighbors.None;
bool dimsChanged =
sz != lastSize ||
s != lastSideLength ||
pos != lastPos ||
h != lastH;
if(editMode == EditMode.AddRemove) {
int neededBoxes = (int)(sz.x*sz.y);
if(dimsChanged ||
editModeChanged ||
tiles.Count <= neededBoxes) {
for(int i = 0; i < neededBoxes; i++) {
SetupAddRemoveTileBounds(new TileBounds(), i);
}
}
for(int i = 0; i < neededBoxes; i++) {
TileBounds b = tiles[i];
if(b.center == Vector3.zero && b.size == Vector3.zero) {
continue;
}
float distance;
if(b.IntersectRay(ray, out distance) && distance < closestDistance) {
closestDistance = distance;
closestIdx = i;
//find the ray's collision point (ray.origin+ray.direction*closestDistance),
collisionPoint = ray.origin+ray.direction*closestDistance;
//now translate it to the box position by subtracting the box's center (may need to subtract `new Vector3(0, -h/2, 0)`) as well
collidedFace = CollidedFaceAt(collisionPoint, b);
}
int y = i/(int)m.size.x;
int x = i-(y*(int)m.size.x);
int z = editZ;
if(m.HasTileAt(x,y,z)) {
//skip drawing, but you can still opt-click to delete
} else {
DrawWireBounds(b.center, b.size, Color.magenta);
}
}
if(closestIdx != -1) {
TileBounds closest = tiles[closestIdx];
DrawWireBounds(closest.center, closest.size, Color.green);
}
} else if(editMode == EditMode.Reshape || editMode == EditMode.Paint) {
int neededBoxes = (int)(sz.x*sz.y);
if(dimsChanged ||
editModeChanged ||
tiles.Count <= neededBoxes) {
for(int i = 0; i < neededBoxes; i++) {
SetupPaintTileBounds(new TileBounds(), i);
}
}
for(int i = 0; i < neededBoxes; i++) {
TileBounds b = tiles[i];
if(b.center == Vector3.zero && b.size == Vector3.zero) {
continue;
}
float distance;
if(b.IntersectRay(ray, out distance) && distance < closestDistance) {
closestDistance = distance;
closestIdx = i;
//find the ray's collision point (ray.origin+ray.direction*closestDistance),
collisionPoint = ray.origin+ray.direction*closestDistance;
}
DrawWireBounds(b.center, b.size, Color.white);
}
if(closestIdx != -1) {
TileBounds closest = tiles[closestIdx];
//decide what face it's on by comparing its x,y,z against the bounding box's minima and maxima
collidedFace = CollidedFaceAt(collisionPoint, closest);
DrawWireBounds(closest.center, closest.size, Color.green, collidedFace);
}
}
int controlID = GUIUtility.GetControlID(FocusType.Passive);
if(e.type == EventType.mouseUp) {
draggingInMap = false;
}
if(e.type == EventType.mouseDown || (e.type == EventType.mouseDrag && draggingInMap)) {
if(editMode == EditMode.AddRemove || editMode == EditMode.Reshape) {
if(closestIdx != -1) {
if(e.alt && e.shift) {
AdjustIsoHeightAt(closestIdx, collidedFace, collisionPoint, -1);
draggingInMap = false;
} else if(e.shift) {
AdjustIsoHeightAt(closestIdx, collidedFace, collisionPoint, 1);
draggingInMap = false;
} else if(editMode == EditMode.AddRemove) {
if(e.alt) {
RemoveIsoTileAt(closestIdx);
draggingInMap = true;
} else {
AddOrStampIsoTileAt(closestIdx);
draggingInMap = true;
}
} else if(editMode == EditMode.Reshape) {
if(e.alt) {
RemoveOffsetsAt(closestIdx);
draggingInMap = true;
} else {
StampOffsetsAt(closestIdx);
draggingInMap = true;
}
}
e.Use();
}
} else if(editMode == EditMode.Paint) {
if(collidedFace != Neighbors.None) {
SetTileSpecAt(closestIdx, collidedFace);
draggingInMap = true;
e.Use();
}
}
} else if(e.type == EventType.layout) {
HandleUtility.AddDefaultControl(controlID);
} else if(e.type == EventType.mouseMove) {
e.Use();
} else if(e.type == EventType.KeyDown) {
int nextZ = editZ;
if(e.keyCode == KeyCode.UpArrow) {
if(editZ < 20-1) { nextZ++; }
e.Use();
} else if(e.keyCode == KeyCode.DownArrow) {
if(editZ > 0) { nextZ--; }
e.Use();
}
if(nextZ != editZ) {
//RegisterUndo(target, "Map Height Selection");
editZ = nextZ;
}
}
lastSize = sz;
lastSideLength = s;
lastPos = pos;
lastH = h;
editModeChanged = false;
this.Repaint();
}