daily pastebin goal
68%
SHARE
TWEET

Lines.cs

mvaganov Jul 15th, 2014 (edited) 491 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3.  
  4. // author: mvaganov@hotmail.com
  5. // license: Copyfree, public domain. This is free code! Great artists, steal this code!
  6. // latest version at: https://pastebin.com/raw/8m69iTut -- added MakeBox (2018/03/02)
  7. namespace NS {
  8. public class Lines : MonoBehaviour {
  9.     [Tooltip("Used to draw lines. Ideally a white Sprites/Default shader.")]
  10.     public Material lineMaterial;
  11.     public bool autoParentLinesToGlobalObject = true;
  12.  
  13.     /// <summary>The singleton instance.</summary>
  14.     static Lines instance;
  15.     public static Lines Instance() {
  16.         if(instance == null) {
  17.             instance = FindComponentInstance<Lines>();
  18.         }
  19.         return instance;
  20.     }
  21.     public static T FindComponentInstance<T>() where T : Component {
  22.         T instance = null;
  23.         if((instance = FindObjectOfType(typeof(T)) as T) == null) {
  24.             GameObject g = new GameObject("<" + typeof(T).Name + ">");
  25.             instance = g.AddComponent<T>();
  26.         }
  27.         return instance;
  28.     }
  29.  
  30.     void Start() {
  31.         if (instance != null && instance != this) {
  32.             Debug.LogWarning ("<Lines> should be a singleton. Deleting extra");
  33.             Destroy (this);
  34.         }
  35.     }
  36.  
  37.     /// <summary>
  38.     /// Make the specified Line.
  39.     /// example usage:
  40.     /// <para><code>
  41.     /// /* GameObject forwardLine should be a member variable */
  42.     /// Lines.Make (ref forwardLine, transform.position,
  43.     ///             transform.position + transform.forward, Color.blue, 0.1f, 0);
  44.     /// //This makes a long thin triangle, pointing forward.
  45.     /// </code></para>
  46.     /// </summary>
  47.     /// <param name="lineObject">GameObject host of the LineRenderer</param>
  48.     /// <param name="start">Start, an absolute world-space coordinate</param>
  49.     /// <param name="end">End, an absolute world-space coordinate</param>
  50.     /// <param name="startSize">How wide the line is at the start</param>
  51.     /// <param name="endSize">How wide the line is at the end</param>
  52.     public static LineRenderer Make(ref GameObject lineObject, Vector3 start, Vector3 end,
  53.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f) {
  54.         if (lineObject == null) { lineObject = new GameObject(); }
  55.         if (Instance().autoParentLinesToGlobalObject) { lineObject.transform.SetParent (instance.transform); }
  56.         LineRenderer lr = lineObject.GetComponent<LineRenderer>();
  57.         if(lr == null) { lr = lineObject.AddComponent<LineRenderer>(); }
  58.         lr.startWidth = startSize;
  59.         lr.endWidth = endSize;
  60.         lr.positionCount = 2;
  61.         lr.SetPosition(0, start); lr.SetPosition(1, end);
  62.         SetColor(lr, color);
  63.         return lr;
  64.     }
  65.  
  66.     /// <summary>Make the specified Line from a list of points</summary>
  67.     /// <returns>The LineRenderer hosting the line</returns>
  68.     /// <param name="lineObject">GameObject host of the LineRenderer</param>
  69.     /// <param name="color">Color of the line</param>
  70.     /// <param name="points">List of absolute world-space coordinates</param>
  71.     /// <param name="pointCount">Number of the points used points list</param>
  72.     /// <param name="startSize">How wide the line is at the start</param>
  73.     /// <param name="endSize">How wide the line is at the end</param>
  74.     public static LineRenderer Make(ref GameObject lineObject, Vector3[] points, int pointCount,
  75.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f) {
  76.         if (lineObject == null) { lineObject = new GameObject(); }
  77.         if (Instance().autoParentLinesToGlobalObject) { lineObject.transform.SetParent (instance.transform); }
  78.         LineRenderer lr = lineObject.GetComponent<LineRenderer>();
  79.         if(lr == null) { lr = lineObject.AddComponent<LineRenderer>(); }
  80.         lr.startWidth = startSize;
  81.         lr.endWidth = endSize;
  82.         lr.positionCount = pointCount;
  83.         for(int i = 0; i < pointCount; ++i) { lr.SetPosition(i, points[i]); }
  84.         SetColor(lr, color);
  85.         return lr;
  86.     }
  87.  
  88.     public static Material FindShaderMaterial(string shadername){
  89.         Shader s = Shader.Find(shadername);
  90.         if(s == null) {
  91.             throw new System.Exception("Missing shader: " + shadername
  92.                 + ". Please make sure it is in the \"Resources\" folder, "
  93.                 + "or used by at least one other object. Or, create an "
  94.                 + " object with Lines, and assign the material manually");
  95.         }
  96.         return new Material(s);
  97.     }
  98.  
  99.     public static void SetColor(LineRenderer lr, Color color) {
  100.         Material mat = Instance().lineMaterial;
  101.         if(mat == null) {
  102.             const string colorShaderName = "Sprites/Default";//"Unlit/Color";
  103.             mat = FindShaderMaterial(colorShaderName);
  104.             Instance ().lineMaterial = mat;
  105.         }
  106.         if(lr.material == null || lr.material.name != mat.name) { lr.material = mat; }
  107.         lr.material.color = color;
  108.     }
  109.  
  110.     /// <summary>Write 2D arc in 3D space, into given Vector3 array</summary>
  111.     /// <param name="points">Will host the list of coordinates</param>
  112.     /// <param name="pointCount">How many vertices to make &gt; 1</param>
  113.     /// <param name="normal">The surface-normal of the arc's plane</param>
  114.     /// <param name="firstPoint">Arc start, rotate about Vector3.zero</param>
  115.     /// <param name="angle">2D angle. Tip: Vector3.Angle(v1, v2)</param>
  116.     /// <param name="offset">How to translate the arc</param>
  117.     public static void WriteArc(ref Vector3[] points, int pointCount,
  118.         Vector3 normal, Vector3 firstPoint, float angle = 360, Vector3 offset = default(Vector3), int startIndex = 0) {
  119.         if(points == null) { points = new Vector3[pointCount]; }
  120.         points[startIndex] = firstPoint;
  121.         Quaternion q = Quaternion.AngleAxis(angle / (pointCount - 1), normal);
  122.         for(int i = startIndex+1; i < startIndex+pointCount; ++i) { points[i] = q * points[i - 1]; }
  123.         if(offset != Vector3.zero)
  124.             for(int i = startIndex; i < startIndex+pointCount; ++i) { points[i] += offset; }
  125.     }
  126.  
  127.     /// <summary>
  128.     /// Make the specified arc line in 3D space. Example usage: <para><code>
  129.     /// /* GameObject turnArc should be a member variable */
  130.     /// Lines.MakeArc(ref turnArc, Vector3.Angle(transform.forward, direction),
  131.     ///     10, Vector3.Cross(transform.forward, direction),
  132.     ///     transform.forward, transform.position, Color.green, 0.1f, 0);
  133.     /// // makes a curve showing the turn from transform.forward to direction
  134.     /// </code></para>
  135.     /// </summary>
  136.     /// <returns>The LineRenderer hosting the line</returns>
  137.     /// <param name="lineObject">GameObject host of the LineRenderer</param>
  138.     /// <param name="color">Color of the line</param>
  139.     /// <param name="center">Center of arc</param>
  140.     /// <param name="normal">surface-normal of arc's plane</param>
  141.     /// <param name="firstPoint">Arc start, rotate about Vector3.zero</param>
  142.     /// <param name="angle">2D angle. Tip: Vector3.Angle(v1, v2)</param>
  143.     /// <param name="pointCount">How many vertices to make &gt; 1</param>
  144.     /// <param name="startSize">How wide the line is at the start</param>
  145.     /// <param name="endSize">How wide the line is at the end</param>
  146.     public static LineRenderer MakeArc(ref GameObject lineObj,
  147.         float angle, int pointCount, Vector3 normal, Vector3 firstPoint,
  148.         Vector3 center = default(Vector3), Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f) {
  149.         Vector3[] points = null;
  150.         WriteArc(ref points, pointCount, normal, firstPoint, angle, center);
  151.         return Make(ref lineObj, points, pointCount, color, startSize, endSize);
  152.     }
  153.  
  154.     public static LineRenderer MakeLineOnSphere(ref GameObject lineObj, Vector3 sphereCenter, Vector3 start, Vector3 end,
  155.         Color color=default(Color), float startSize=0.125f, float endSize=0.125f, int pointCount = 24) {
  156.         Vector3[] points = null;
  157.         WriteArcOnSphere(ref points, pointCount, sphereCenter, start, end);
  158.         return Make(ref lineObj, points, pointCount, color, startSize, endSize);
  159.     }
  160.     public static void WriteArcOnSphere(ref Vector3[] points, int pointCount, Vector3 sphereCenter, Vector3 start, Vector3 end) {
  161.         Vector3 axis;
  162.         if(start == -end) {
  163.             axis = (start != Vector3.up && end != Vector3.up)? Vector3.up : Vector3.right;
  164.         } else {
  165.             axis = Vector3.Cross(start, end).normalized;
  166.         }
  167.         Vector3 a = start - sphereCenter, b = end - sphereCenter;
  168.         float arad = a.magnitude, brad = b.magnitude;
  169.         a /= arad; b /= brad;
  170.         float angle = Vector3.Angle(a,b);
  171.         WriteArc(ref points, pointCount, axis, a, angle, Vector3.zero);
  172.         float raddelta = brad-arad;
  173.         for(int i=0; i < points.Length; ++i) {
  174.             points[i] = points[i] * ((i * raddelta / points.Length) + arad);
  175.             points[i] += sphereCenter;
  176.         }
  177.     }
  178.  
  179.     /// <summary>Makes a circle with a 3D line</summary>
  180.     /// <returns>The LineRenderer hosting the line</returns>
  181.     /// <param name="lineObj">GameObject host of the LineRenderer</param>
  182.     /// <param name="color">Color of the line</param>
  183.     /// <param name="center">Absolute world-space 3D coordinate</param>
  184.     /// <param name="normal">Which way the circle is facing</param>
  185.     /// <param name="radius"></param>
  186.     /// <param name="linesize">The width of the line</param>
  187.     public static LineRenderer MakeCircle(ref GameObject lineObj,
  188.         Vector3 center, Vector3 normal, Color color = default(Color), float radius = 1, float linesize = 0.125f) {
  189.         Vector3 crossDir = (normal != Vector3.up) ? Vector3.up : Vector3.forward;
  190.         Vector3 r = Vector3.Cross(normal, crossDir).normalized;
  191.         LineRenderer lr = Lines.MakeArc(ref lineObj, 360, 24, normal, r * radius, center, color,
  192.             linesize, linesize);
  193.         lr.loop = true;
  194.         return lr;
  195.     }
  196.     /// <summary>As MakeCircle, but using an assured GameObject</summary>
  197.     public static LineRenderer MakeCircle_With(GameObject lineObj,
  198.         Vector3 center, Vector3 normal, Color color = default(Color), float radius = 1, float linesize = 0.125f) {
  199.         return MakeCircle (ref lineObj, center, normal, color, radius, linesize);
  200.     }
  201.  
  202.     /// <returns>a line renderer in the shape of a sphere made of 3 circles, for the x.y.z axis</returns>
  203.     /// <param name="lineObj">Line object.</param>
  204.     /// <param name="radius">Radius.</param>
  205.     /// <param name="center">Center.</param>
  206.     /// <param name="color">Color.</param>
  207.     /// <param name="linesize">Linesize.</param>
  208.     public static LineRenderer MakeSphere(ref GameObject lineObj, float radius = 1,
  209.         Vector3 center = default(Vector3), Color color = default(Color), float linesize = 0.125f) {
  210.         Vector3[] circles = new Vector3[24 * 3];
  211.         Lines.WriteArc (ref circles, 24, Vector3.forward, Vector3.up, 360, center, 24*0);
  212.         Lines.WriteArc (ref circles, 24, Vector3.right,   Vector3.up, 360, center, 24*1);
  213.         Lines.WriteArc (ref circles, 24, Vector3.up, Vector3.forward, 360, center, 24*2);
  214.         if (radius != 1) { for (int i = 0; i < circles.Length; ++i) { circles [i] *= radius; } }
  215.         return Lines.Make (ref lineObj, circles, circles.Length, color, linesize, linesize);
  216.     }
  217.     public static LineRenderer MakeBox(ref GameObject lineObj, Vector3 center,
  218.         Vector3 size, Quaternion rotation, Color color = default(Color), float linesize = 0.125f) {
  219.         Vector3 u = Vector3.up / 2 * size.y;
  220.         Vector3 r = Vector3.right / 2 * size.x;
  221.         Vector3 f = Vector3.forward / 2 * size.z;
  222.         Vector3[] line = new Vector3[] {
  223.             f+u-r,
  224.             -f+u-r,
  225.             -f-u-r,
  226.             -f-u+r,
  227.             -f+u+r,
  228.             f+u+r,
  229.             f-u+r,
  230.             f-u-r,
  231.             f+u-r,
  232.             f+u+r,
  233.             f-u+r,
  234.             -f-u+r,
  235.             -f+u+r,
  236.             -f+u-r,
  237.             -f-u-r,
  238.             f-u-r
  239.         };
  240.         for (int i = 0; i < line.Length; ++i) { line [i] = rotation * line [i] + center; }
  241.         return Make (ref lineObj, line, line.Length, color, linesize, linesize);
  242.     }
  243.     private static Vector3[] thumbtack_points_base = null;
  244.     /// <summary>Draws a "thumbtack", which shows a visualization for direction and orientation</summary>
  245.     /// <returns>The LineRenderer hosting the thumbtack line. The LineRenderer's transform can be adjusted!</returns>
  246.     /// <param name="lineObj">Line object.</param>
  247.     /// <param name="c">C: color</param>
  248.     /// <param name="size">Size: radius of the thumbtack</param>
  249.     /// <param name="lineWidth">Line width.</param>
  250.     public static LineRenderer MakeThumbtack(ref GameObject lineObj, Color c = default(Color), float size = 1, float lineWidth = 0.1f) {
  251.         const float epsilon = 1/1024.0f;
  252.         if(thumbtack_points_base == null) {
  253.             Vector3 pstn = Vector3.zero, fwrd = Vector3.forward * size, rght = Vector3.right * size, up__ = Vector3.up;
  254.             float startAngle = (360.0f / 4) - (360.0f / 32);
  255.             Vector3 v = Quaternion.AngleAxis(startAngle, up__) * fwrd;
  256.             Lines.WriteArc(ref thumbtack_points_base, 32, up__, v, 360, pstn);
  257.             Vector3 tip = pstn + fwrd * Mathf.Sqrt(2);
  258.             thumbtack_points_base[0] = thumbtack_points_base[thumbtack_points_base.Length - 1];
  259.             int m = (32 * 5 / 8) + 1;
  260.             thumbtack_points_base[m++] = thumbtack_points_base[m] + (tip - thumbtack_points_base[m]) * (1 - epsilon);
  261.             thumbtack_points_base[m++] = tip;
  262.             int n = (32 * 7 / 8) + 1;
  263.             while(n < 32) { thumbtack_points_base[m++] = thumbtack_points_base[n++]; }
  264.             Vector3 side = pstn + rght;
  265.             thumbtack_points_base[m++] = thumbtack_points_base[m] + (side - thumbtack_points_base[m]) * (1 - epsilon);
  266.             thumbtack_points_base[m++] = pstn + rght;
  267.             thumbtack_points_base[m++] = pstn + rght * epsilon;
  268.             thumbtack_points_base[m++] = pstn;
  269.             thumbtack_points_base[m++] = pstn + up__ * size * (1 - epsilon);
  270.             thumbtack_points_base[m++] = pstn + up__ * size;
  271.         }
  272.         LineRenderer lr = Lines.Make(ref lineObj, thumbtack_points_base, thumbtack_points_base.Length, c, lineWidth, lineWidth);
  273.         lr.useWorldSpace = false;
  274.         return lr;
  275.     }
  276.  
  277.     /// <summary>Draws a "thumbtack", which shows a visualization for direction and orientation</summary>
  278.     /// <returns>The LineRenderer hosting the thumbtack line</returns>
  279.     /// <param name="lineObj">Line object.</param>
  280.     /// <param name="t">t: the transform to attach the thumbtack visualisation to</param>
  281.     /// <param name="c">C: color</param>
  282.     /// <param name="size">Size: radius of the thumbtack</param>
  283.     /// <param name="lineWidth">Line width.</param>
  284.     public static LineRenderer SetThumbtack(ref GameObject lineObj, Transform t, Color c = default(Color), float size = 1, float lineWidth = 0.125f) {
  285.         LineRenderer line_ = MakeThumbtack (ref lineObj, c, size, lineWidth);
  286.         line_.transform.SetParent (t);
  287.         line_.transform.localPosition = Vector3.zero;
  288.         line_.transform.localRotation = Quaternion.identity;
  289.         return line_;
  290.     }
  291.  
  292.     public static Vector3 GetForwardVector(Quaternion q) {
  293.         return new Vector3 (2 * (q.x * q.z + q.w * q.y),
  294.             2 * (q.y * q.z + q.w * q.x),
  295.             1-2*(q.x * q.x + q.y * q.y));
  296.     }
  297.     public static Vector3 GetUpVector(Quaternion q) {
  298.         return new Vector3 (2 * (q.x * q.y + q.w * q.z),
  299.             1-2*(q.x * q.x + q.z * q.z),
  300.             2 * (q.y * q.z + q.w * q.x));
  301.     }
  302.     public static Vector3 GetRightVector(Quaternion q) {
  303.         return new Vector3 (1-2*(q.y * q.y + q.z * q.z),
  304.             2 * (q.x * q.y + q.w * q.z),
  305.             2 * (q.x * q.z + q.w * q.y));
  306.     }
  307.  
  308.     /// <example>CreateSpiralSphere(transform.position, 0.5f, transform.up, transform.forward, 16, 8);</example>
  309.     /// <summary>creates a line spiraled onto a sphere</summary>
  310.     /// <param name="center"></param>
  311.     /// <param name="radius"></param>
  312.     /// <param name="axis">example: Vector3.up</param>
  313.     /// <param name="axisFace">example: Vector3.right</param>
  314.     /// <param name="sides"></param>
  315.     /// <param name="rotations"></param>
  316.     /// <returns></returns>
  317.     public static Vector3[] CreateSpiralSphere(Vector3 center = default(Vector3), float radius = 1,
  318.         Vector3 axis = default(Vector3), Vector3 axisFace = default(Vector3), float sides = 12, float rotations = 6) {
  319.         List<Vector3> points = new List<Vector3>(); // List instead of Array because sides and rotations are floats!
  320.         if(axis == Vector3.zero) { axis=Vector3.up; }
  321.         if(axisFace == Vector3.zero) { axisFace=Vector3.right; }
  322.         if (sides != 0 && rotations != 0) {
  323.             float iter = 0;
  324.             float increment = 1f / (rotations * sides);
  325.             points.Add(center + axis * radius);
  326.             do {
  327.                 iter += increment;
  328.                 Quaternion faceTurn = Quaternion.AngleAxis(iter * 360 * rotations, axis);
  329.                 Vector3 newFace = faceTurn * axisFace;
  330.                 Quaternion q = Quaternion.LookRotation(newFace);
  331.                 Vector3 right = GetUpVector(q);
  332.                 Vector3 r = right * radius;
  333.                 q = Quaternion.AngleAxis(iter * 180, newFace);
  334.                 Vector3 newPoint = center + q * r;
  335.                 points.Add(newPoint);
  336.             }
  337.             while (iter < 1);
  338.         }
  339.         return points.ToArray();
  340.     }
  341.  
  342.     /// <returns>a line renderer in the shape of a spiraling sphere, spiraling about the Vector3.up axis</returns>
  343.     /// <param name="lineObj">Line object.</param>
  344.     /// <param name="radius">Radius.</param>
  345.     /// <param name="center">Center.</param>
  346.     /// <param name="color">Color.</param>
  347.     /// <param name="linesize">Linesize.</param>
  348.     public static LineRenderer MakeSpiralSphere(ref GameObject lineObj, float radius = 1,
  349.         Vector3 center = default(Vector3), Color color = default(Color), float linesize = 0.125f) {
  350.         Vector3[] verts = CreateSpiralSphere (center, radius, Vector3.up, Vector3.right, 24, 3);
  351.         return Make (ref lineObj, verts, verts.Length, color, linesize, linesize);
  352.     }
  353.  
  354.     public const float ARROWSIZE = 3;
  355.     public static LineRenderer MakeArrow(ref GameObject lineObject, Vector3 start, Vector3 end,
  356.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE) {
  357.         return MakeArrow(ref lineObject, new Vector3[] { start, end }, 2, color, startSize, endSize, arrowHeadSize);
  358.     }
  359.     public static LineRenderer MakeArrowBothEnds(ref GameObject lineObject, Vector3 start, Vector3 end,
  360.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE) {
  361.         return MakeArrowBothEnds(ref lineObject, new Vector3[] { start, end }, 2, color, startSize, endSize, arrowHeadSize);
  362.     }
  363.     public static LineRenderer MakeArrow(ref GameObject lineObject, Vector3[] points, int pointCount,
  364.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE, Keyframe[] lineKeyFrames = null) {
  365.         float arrowSize = endSize*arrowHeadSize;
  366.         int lastGoodIndex = 0;
  367.         Vector3 arrowheadBase = Vector3.zero, arrowheadWidest = Vector3.zero, delta, dir = Vector3.zero;
  368.         float dist = 0, backtracked = 0, extraFromLastGoodIndex = 0;
  369.         for(int i = points.Length-1; i>0; --i) {
  370.             float d = Vector3.Distance(points[i], points[i-1]);
  371.             dist += d;
  372.             backtracked += d;
  373.             if(backtracked >= arrowSize && dir == Vector3.zero) {
  374.                 lastGoodIndex = i-1;
  375.                 delta = points[i] - points[i-1];
  376.                 dir = delta.normalized;
  377.                 extraFromLastGoodIndex = backtracked - arrowSize;
  378.                 arrowheadBase = points[lastGoodIndex] + dir * extraFromLastGoodIndex;
  379.             }
  380.         }
  381.         if(dist <= arrowSize) { return Make(ref lineObject, points[0], points[points.Length-1], color, arrowSize, 0); }
  382.         delta = points[points.Length-1] - arrowheadBase;
  383.         dir = delta.normalized;
  384.         const float factionalArrowheadExpanseDelta = 1.0f/512;
  385.         arrowheadWidest = arrowheadBase + dir * (dist*factionalArrowheadExpanseDelta);
  386.         Vector3[] line = new Vector3[lastGoodIndex+4];
  387.         for(int i = 0; i<=lastGoodIndex; i++) {
  388.             line[i] = points[i];
  389.         }
  390.         line[lastGoodIndex+3] = points[points.Length-1];
  391.         line[lastGoodIndex+2] = arrowheadWidest;
  392.         line[lastGoodIndex+1] = arrowheadBase;
  393.         LineRenderer lr;
  394.         Keyframe[] keyframes;
  395.         float arrowHeadBaseStart = 1 - arrowSize/dist;
  396.         float arrowHeadBaseWidest = 1 - (arrowSize/dist-factionalArrowheadExpanseDelta);
  397.         if(lineKeyFrames == null) {
  398.             keyframes= new Keyframe[] {
  399.                 new Keyframe(0, startSize), new Keyframe(arrowHeadBaseStart, endSize),
  400.                 new Keyframe(arrowHeadBaseWidest, arrowSize), new Keyframe(1, 0)
  401.             };
  402.         } else {
  403.             // count how many there are after arrowHeadBaseStart.
  404.             float t = 0;
  405.             int validCount = lineKeyFrames.Length;
  406.             for(int i = 0; i < lineKeyFrames.Length; ++i) {
  407.                 t = lineKeyFrames[i].time;
  408.                 if(t > arrowHeadBaseStart) { validCount = i; break; }
  409.             }
  410.             // those are irrelivant now. they'll be replaced by the 3 extra points
  411.             keyframes = new Keyframe[validCount+3];
  412.             for(int i=0;i<validCount; ++i) { keyframes[i] = lineKeyFrames[i]; }
  413.             keyframes[validCount+0] = new Keyframe(arrowHeadBaseStart, endSize);
  414.             keyframes[validCount+1] = new Keyframe(arrowHeadBaseWidest, arrowSize);
  415.             keyframes[validCount+2] = new Keyframe(1, 0);
  416.         }
  417.         lr = Make(ref lineObject, line, line.Length, color, startSize, endSize);
  418.         lr.widthCurve = new AnimationCurve(keyframes);
  419.         return lr;
  420.     }
  421.     public static LineRenderer MakeArrowBothEnds(ref GameObject lineObject, Vector3[] points, int pointCount,
  422.         Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE) {
  423.         LineRenderer lr = MakeArrow(ref lineObject, points, pointCount, color, startSize, endSize, arrowHeadSize, null);
  424.         ReverseLineInternal(ref lr);
  425.         Vector3[] p = new Vector3[lr.positionCount];
  426.         lr.GetPositions(p);
  427.         lr = MakeArrow(ref lineObject, p, p.Length, color, endSize, startSize, arrowHeadSize, lr.widthCurve.keys);
  428.         ReverseLineInternal(ref lr);
  429.         return lr;
  430.     }
  431.     public static LineRenderer ReverseLineInternal(ref LineRenderer lr) {
  432.         Vector3[] p = new Vector3[lr.positionCount];
  433.         lr.GetPositions(p);
  434.         System.Array.Reverse(p);
  435.         lr.SetPositions(p);
  436.         if(lr.widthCurve != null && lr.widthCurve.length > 1) {
  437.             Keyframe[] kf = new Keyframe[lr.widthCurve.keys.Length];
  438.             Keyframe[] okf = lr.widthCurve.keys;
  439.             for(int i = 0; i<kf.Length; ++i) { kf[i]=okf[i]; }
  440.             System.Array.Reverse(kf);
  441.             for(int i = 0; i<kf.Length; ++i) { kf[i].time = 1-kf[i].time; }
  442.             lr.widthCurve = new AnimationCurve(kf);
  443.         }
  444.         return lr;
  445.     }
  446.  
  447.     public static LineRenderer MakeArcArrow(ref GameObject lineObj,
  448.         float angle, int pointCount, Vector3 arcPlaneNormal = default(Vector3), Vector3 firstPoint = default(Vector3),
  449.         Vector3 center = default(Vector3), Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE) {
  450.         if(arcPlaneNormal == default(Vector3)) { arcPlaneNormal = Vector3.up; }
  451.         if(center == default(Vector3) && firstPoint == default(Vector3)) { firstPoint = Vector3.right; }
  452.         Vector3[] points = null;
  453.         WriteArc(ref points, pointCount, arcPlaneNormal, firstPoint, angle, center);
  454.         return MakeArrow(ref lineObj, points, pointCount, color, startSize, endSize, arrowHeadSize);
  455.     }
  456.  
  457.     public static LineRenderer MakeArcArrowBothEnds(ref GameObject lineObj,
  458.         float angle, int pointCount, Vector3 arcPlaneNormal = default(Vector3), Vector3 firstPoint = default(Vector3),
  459.         Vector3 center = default(Vector3), Color color = default(Color), float startSize = 0.125f, float endSize = 0.125f, float arrowHeadSize = ARROWSIZE) {
  460.         LineRenderer lr = MakeArcArrow(ref lineObj, angle, pointCount, arcPlaneNormal, firstPoint, center, color, startSize, endSize, arrowHeadSize);
  461.         ReverseLineInternal(ref lr);
  462.         Vector3[] p = new Vector3[lr.positionCount];
  463.         lr.GetPositions(p);
  464.         lr = MakeArrow(ref lineObj, p, p.Length, color, endSize, startSize, arrowHeadSize, lr.widthCurve.keys);
  465.         ReverseLineInternal(ref lr);
  466.         return lr;
  467.     }
  468.  
  469.     public static void MakeQuaternion(ref GameObject axisObj, ref GameObject angleObj, Quaternion quaternion,
  470.         Vector3 position=default(Vector3), Color color=default(Color), Quaternion orientation=default(Quaternion),
  471.         int arcPoints = 24, float lineSize = 0.125f, float arrowHeadSize = ARROWSIZE,
  472.         Vector3 startPoint=default(Vector3)) {
  473.         if (orientation == default(Quaternion)) { orientation = Quaternion.identity; }
  474.         float angle;
  475.         Vector3 axis;
  476.         quaternion.ToAngleAxis (out angle, out axis);
  477.         MakeQuaternion (ref axisObj, ref angleObj, axis, angle,
  478.             position, color, orientation, arcPoints, lineSize, arrowHeadSize, startPoint);
  479.     }
  480.     public static void MakeQuaternion(ref GameObject axisObj, ref GameObject angleObj, Vector3 axis, float angle,
  481.         Vector3 position=default(Vector3), Color color=default(Color), Quaternion orientation=default(Quaternion),
  482.         int arcPoints = 24, float lineSize = 0.125f, float arrowHeadSize = ARROWSIZE, Vector3 startPoint=default(Vector3)) {
  483.         if (startPoint == default(Vector3)) {
  484.             float a = Vector3.Angle (axis, Vector3.up);
  485.             if (a < 45 || a > 315) { // if the quaternion axis is too vertical
  486.                 startPoint = Vector3.forward; // start from forward
  487.             } else {
  488.                 startPoint = Vector3.up; // otherwise start from top
  489.             }
  490.             startPoint = orientation * startPoint;
  491.             // find the closest point to the starPoint on the arc-circle
  492.             Vector3 forwardVector = Vector3.Cross(axis, startPoint);
  493.             forwardVector.Normalize ();
  494.             Vector3 turnedStartPoint = Vector3.Cross (forwardVector, axis);
  495.             turnedStartPoint.Normalize ();
  496.             startPoint = turnedStartPoint;
  497.             angle *= -1;
  498.         }
  499.         while (angle > 180) { angle -= 360; }
  500.         while (angle < -180) { angle += 360; }
  501.         Vector3 axisRotated = orientation * axis;
  502.         Lines.MakeArrow (ref axisObj, position - axisRotated/2, position + axisRotated/2, color, lineSize, lineSize, arrowHeadSize);
  503.         Lines.MakeArcArrow (ref angleObj, angle, arcPoints, axisRotated, startPoint, position, color, lineSize, lineSize, arrowHeadSize);
  504.     }
  505. }
  506. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top