Hello, forum-goers,
I’m creating a free and extensive Star Wars flight simulator, similar to X-Wing Alliance or X-Wing Vs. TIE Fighter. I’m trying to make yellow targeting brackets that always frame the object using GUI, like in this mockup here.
I’ve figured out that essentially I need to calculate the ship’s bounding box, get the eight vertices of it, use WorldToScreenPoint to convert them to screen points, and then build a rect out of that using MinMaxRect. I wrote the code below, but no matter what the brackets always end up all over the place or off the screen:
Utility.js
static function Get2dBounds (t : Transform) : Rect {
var b = GetCombinedBounds (t);
var points = new Array ();
points.Add (t.position + Vector3(b.extents.x, b.extents.y, b.extents.z));
points.Add (t.position + Vector3(-b.extents.x, b.extents.y, b.extents.z));
points.Add (t.position + Vector3(b.extents.x, -b.extents.y, b.extents.z));
points.Add (t.position + Vector3(b.extents.x, b.extents.y, -b.extents.z));
points.Add (t.position + Vector3(-b.extents.x, -b.extents.y, b.extents.z));
points.Add (t.position + Vector3(b.extents.x, -b.extents.y, -b.extents.z));
points.Add (t.position + Vector3(-b.extents.x, b.extents.y, -b.extents.z));
points.Add (t.position + Vector3(-b.extents.x, -b.extents.y, -b.extents.z));
var left = Screen.width;
var up = Screen.height;
var right = 0;
var down = 0;
for (var p : Vector3 in points){
var pPos = Camera.main.WorldToScreenPoint (p);
pPos.y = Screen.height - pPos.y;
if (pPos.x < left)
left = p.x;
if (pPos.x > right)
right = p.x;
if (pPos.y < down)
down = p.y;
if (pPos.y > up)
up = p.y;
}
var rect : Rect;
rect.x = left;
rect.y = up;
rect.width = right - left;
rect.height = up - down;
rect = Rect.MinMaxRect(left, up, right, down);
return rect;
}
static function GetCombinedBounds (t : Transform) : Bounds {
var bArray = new Array ();
for (var r : MeshRenderer in t.GetComponentsInChildren (MeshRenderer)){
bArray.Add (r.bounds);
}
var b3d = Bounds (t.position, Vector3.zero);
for (var bSub : Bounds in bArray){
b3d.Encapsulate (bSub);
}
return b3d;
}
var tex : Texture2D;
function OnGUI () {
var rect = Utility.Get2dBounds (target);
GUI.DrawTexture(rect, tex);
}
This doesn’t seem like a very necessary thing, but my testers have agreed that it greatly increases the aesthetic appeal.
Any help would be much appreciated; this seems like something that should be a fairly common thing for games to need. I can’t just take general concepts for an answer though, I really do need to know the specifics since that’s what I’m missing.