标题: Draw lines in Unity GUI [打印本页] 作者: 会飞的鱼 时间: 2012-2-16 14:27 标题: Draw lines in Unity GUI Description
This script allows you to draw a line between two points in the GUI system.
Usage
Render a line in the GUI system by calling DrawLine and passing it a set of Vector2's for point A and point B of the line.
Optionally, you can pass DrawLine a color and width for the line, as well as using a Rect instead of Vector2's. If you do not pass a width, the line will have a width of 1. If you do not pass a color, the line will be rendered with the GUI.contentColor.
Example 1:
// Render a line from the center of the screen to the mouse position
var width = 1.0;
var color = Color.black;
function OnGUI () {
var pointA = Vector2(Screen.width/2, Screen.height/2);
var pointB = Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y);
static function DrawLine(pointA : Vector2, pointB : Vector2, color : Color, width : float) {
// Save the current GUI matrix, since we're going to make changes to it.
var matrix = GUI.matrix;
GUI.matrix = Matrix4x4.identity;
// Generate a single pixel texture if it doesn't exist
if (!lineTex) {
lineTex = Texture2D(1, 1);
lineTex.SetPixel(0, 0, Color.white);
lineTex.Apply();
}
// Store current GUI color, so we can switch it back later,
// and set the GUI color to the color parameter
var savedColor = GUI.color;
GUI.color = color;
// Use Scale to adjust the size of the line.
// We could do this when we draw the texture, but by scaling it here we can use
// non-integer values for the width and length (such as sub 1 pixel widths).
// Note that the pivot point is at +.5 from pointA.y, this is so that the width of the line
// is centered on the origin at pointA.
// Set the rotation for the line.
// The angle was calculated with pointA as the origin.
// For some reason, when used in an Editor window, everything is rotated around the wrong place until some kind of offset is used. The exact value of this was a bit of guesswork - your mileage may vary. Think this is probably a bug in how GUI.matrix is applied.
var offset : Vector2 = new Vector2(0, -20);
// Set the GUI matrix to rotate around a pivot point
// We're doing a 3-stage matrix multiplication since we don't want to rotate around the origin - there's a weird offset bug in the way the GUI is rendered that needs to be worked around
offset += Vector2(0, 0.5); // Compensate for line width
var guiRot : Quaternion = Quaternion.FromToRotation(Vector2.right, pointB-pointA);
var guiRotMat : Matrix4x4 = Matrix4x4.TRS(pointA, guiRot, new Vector3((pointB-pointA).magnitude, width, 1));
var guiTransMat : Matrix4x4 = Matrix4x4.TRS(offset, Quaternion.identity, Vector3.one);
var guiTransMatInv : Matrix4x4 = Matrix4x4.TRS(-offset, Quaternion.identity, Vector3.one);
// If pointB is above pointA, then angle needs to be negative.
if (pointA.y > pointB.y) { angle = -angle; }
// Use ScaleAroundPivot to adjust the size of the line.
// We could do this when we draw the texture, but by scaling it here we can use
// non-integer values for the width and length (such as sub 1 pixel widths).
// Note that the pivot point is at +.5 from pointA.y, this is so that the width of the line
// is centered on the origin at pointA.
GUIUtility.ScaleAroundPivot(new Vector2((pointB - pointA).magnitude, width), new Vector2(pointA.x, pointA.y + 0.5f));
// Set the rotation for the line.
// The angle was calculated with pointA as the origin.
GUIUtility.RotateAroundPivot(angle, pointA);
// Finally, draw the actual line.
// We're really only drawing a 1x1 texture from pointA.
// The matrix operations done with ScaleAroundPivot and RotateAroundPivot will make this
// render with the proper width, length, and angle.
GUI.DrawTexture(new Rect(pointA.x, pointA.y, 1, 1), lineTex);
// We're done. Restore the GUI matrix and GUI color to whatever they were before.