daily pastebin goal
65%
SHARE
TWEET

Line Drawing in Unity3D!

mvaganov May 30th, 2013 81 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class LineDraw : MonoBehaviour
  6. {
  7.         static LineDraw instance = null;
  8.         float widthStart = 0.1f;
  9.         float widthFinish = 0.1f;
  10.         ShaderOptionEnum shader = ShaderOptionEnum.SelfIlluminDiffuse;
  11.         Color color = Color.red;
  12.        
  13.         string[] shaders = {"Self-Illumin/Diffuse", "Particles/Additive"};//, "VertexLit", "Diffuse"}; 
  14.         public enum ShaderOptionEnum {SelfIlluminDiffuse = 0, ParticlesAdditive};
  15.         //public class LineData{Vector3 a, b; float s, f; ShaderOptionEnum shader; Color c1, c2;}
  16.        
  17.         public void SetWidth_(float widthStart, float widthFinish)
  18.         {
  19.                 this.widthStart = widthStart;
  20.                 this.widthFinish = widthFinish;
  21.         }
  22.         public float GetWidthStart_(){return widthStart;}
  23.         public float GetWidthFinish_(){return widthFinish;}
  24.        
  25.         public void SetShaderOption_(ShaderOptionEnum shader)
  26.         {
  27.                 this.shader = shader;
  28.         }
  29.        
  30.         public void SetColor_(Color color){this.color = color;}
  31.         public Color GetColor_(){return this.color;}
  32.        
  33.         public static void SetShaderOption(ShaderOptionEnum shader){instance.SetShaderOption_(shader);}
  34.         public static Color GetColor(){return instance.GetColor_();}
  35.         public static void SetColor(Color color){instance.SetColor_(color);}
  36.         public static void SetWidth(float widthStart, float widthFinish){instance.SetWidth_(widthStart, widthFinish);}
  37.         public static void SetWidth(float width){instance.SetWidth_(width, width);}
  38.         public static float GetWidthStart(){return instance.GetWidthStart_();}
  39.         public static float GetWidthFinish(){return instance.GetWidthFinish_();}
  40.        
  41.         public static GameObject AddPersistent(Vector3 a, Vector3 b){return instance.AddLine_(a, b, true);}
  42.         public static GameObject AddPersistentCircle(Vector3 center, float radius, Vector3 normal){return instance.AddCircle_(center, radius, normal, 360, 0, 24, true);}
  43.         public static GameObject AddPersistentSpiralPlane(Vector3 center, int size, Vector3 normal){return instance.AddSpiralPlane_(center, size, normal, 24, true);}
  44.         public static GameObject AddPersistentQuaternion(Vector3 p, float radius, Quaternion q){return instance.AddQuaternion_(p, radius, q, 24, true);}
  45.         public static void AddTemporary(Vector3 a, Vector3 b){instance.AddLine_(a, b, false);}
  46.         public static void AddTemporaryCircle(Vector3 center, float radius, Vector3 normal){instance.AddCircle_(center, radius, normal, 360, 0, 24, false);}
  47.  
  48.         List<GameObject> temp = new List<GameObject>();
  49.         List<GameObject> unusedTemp = new List<GameObject>();
  50.        
  51. // MonoBehavior upkeep stuff, including test code -----------------------------
  52.  
  53.         // TEST CODE
  54. //      float t = 0;
  55.         void LateUpdate()
  56.         {
  57.                 for(int i = 0; i < temp.Count; ++i)
  58.                 {
  59.                         temp[i].active = false;
  60.                         unusedTemp.Add(temp[i]);
  61.                 }
  62.                 temp.Clear();
  63.                 // TEST CODE
  64. //              t += Time.deltaTime;
  65. //              if(t >= 360) t-=360;
  66. //              Quaternion q = Quaternion.AngleAxis(t * 360, Vector3.forward);
  67. //              Vector3 v = q * new Vector3(1,0,0);
  68. //              LineDraw.AddTemporary(Vector3.zero, v);
  69.         }
  70.         void Start()
  71.         {
  72.                 if(instance == null)
  73.                         instance = this;
  74.                 // TEST CODE
  75. //              GameObject g = LineDraw.AddPersistent(new Vector3(-1,-1,-2), new Vector3(5,1,-2));
  76. //              Destroy(g, 3);
  77. //              Vector3 v = new Vector3(1,1,1);
  78. //              v.Normalize();
  79. //              LineDraw.AddPersistentSpiralPlane(new Vector3(-2,2,-1), 2, v);
  80. //              Vector3 p = new Vector3(2,-2,-1), n = new Vector3(-1,1,1).normalized;
  81. //              for(int i = 0; i < 5; ++i)
  82. //              {
  83. //                      AddCircle_(p, 1.0f+(0.4f*i), n, 360-(i*15), 0+(i*30), 24, true);
  84. //              }
  85. //              LineDraw.SetColor(Color.white);
  86. //              Quaternion q = transform.rotation;
  87. //              AddPersistentQuaternion(new Vector3(0, -5, 0), .5f, q);
  88. //              LineDraw.SetColor(Color.blue);
  89.         }
  90.  
  91. // THE MEATY CODE -------------------------------------------------------------
  92.         GameObject GetLineGameObject()
  93.         {
  94.                 GameObject go;
  95.                 LineRenderer lineRenderer;
  96.                 if(unusedTemp.Count > 0)
  97.                 {
  98.                         int lastIndex = unusedTemp.Count-1;
  99.                         go = unusedTemp[lastIndex];
  100.                         unusedTemp.RemoveAt(lastIndex);
  101.                         go.active = true;
  102.                         lineRenderer = go.GetComponent<LineRenderer>();
  103.                 }else{
  104.                         go = new GameObject("line");
  105.                         lineRenderer = go.AddComponent<LineRenderer>();
  106.                 }
  107.                 string shaderName = shaders[(int)shader];
  108.                 if(lineRenderer.material.shader.name != shaderName)
  109.                 {
  110.                         UnityEngine.Shader shaderObject = Shader.Find(shaderName);
  111.                         lineRenderer.material = new Material(shaderObject);
  112.                 }
  113.                 lineRenderer.material.color = color;
  114.                 lineRenderer.castShadows = false;
  115.                 lineRenderer.receiveShadows = false;
  116.                 lineRenderer.SetColors(color, color);
  117.                 lineRenderer.SetWidth(widthStart, widthFinish);
  118.                 go.transform.parent = transform;
  119.                 return go;
  120.         }
  121.         public GameObject AddLine_(Vector3 a, Vector3 b, bool persistent)
  122.         {
  123.                 int numPoints = 2;
  124.                 GameObject lineg = GetLineGameObject();
  125.                 LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  126.                 lineRenderer.SetVertexCount(numPoints);
  127.                 lineRenderer.SetPosition(0, a);
  128.                 lineRenderer.SetPosition(1, b);
  129.                 if(!persistent)
  130.                         temp.Add(lineg);
  131.                 return lineg;
  132.         }
  133.         public GameObject AddCircle_(Vector3 p, float r, Vector3 normal, float angle, float startAngle, int pointsPerCircle, bool persistent)
  134.         {
  135.                 float numPointsF = (angle * pointsPerCircle / 360);
  136.                 int numPoints = (int)(numPointsF);
  137.                 float remainder = numPointsF - numPoints;
  138.                 GameObject lineg = GetLineGameObject();
  139.                 LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  140.                 Quaternion q = Quaternion.LookRotation(normal);
  141.                 Vector3 right = GetRightVector(q);
  142.                 lineRenderer.SetVertexCount(numPoints+1 + ((remainder>0?1:0)));
  143.                 lineRenderer.SetPosition(0, p + right * r);
  144.                 for(int i = 0; i < numPoints+1; ++i)
  145.                 {
  146.                         q = Quaternion.AngleAxis(i*360.0f/pointsPerCircle + startAngle, normal);
  147.                         lineRenderer.SetPosition(i, p + q * right * r);
  148.                 }
  149.                 if(remainder > 0)
  150.                 {
  151.                         q = Quaternion.AngleAxis(angle + startAngle, normal);
  152.                         lineRenderer.SetPosition(numPoints+1, p + q * right * r);
  153.                 }
  154.                 if(!persistent)
  155.                         temp.Add(lineg);
  156.                 // TEST CODE
  157. //              Color c = GetColor_();
  158. //                      SetColor_(Color.red);   AddLine_(p, GetRightVector(q) + p,persistent);
  159. //                      SetColor_(Color.green); AddLine_(p, GetUpVector(q) + p,persistent);
  160. //                      SetColor_(Color.blue);  AddLine_(p, GetForwardVector(q) + p,persistent);
  161. //              SetColor_(c);
  162.                 return lineg;
  163.         }
  164.         public GameObject AddQuaternion_(Vector3 p, float r, Quaternion quaternion, int pointsPerCircle, bool persistent)
  165.         {
  166.                 Vector3 axis;
  167.                 float angle;
  168.                 quaternion.ToAngleAxis(out angle, out axis);
  169.                 float s = widthStart, f = widthFinish;
  170.                 SetWidth_(s+f, 0);
  171.                 Vector3 r2 = axis*r*2;
  172.                 GameObject lineg = AddLine_(p-r2, p+r2, persistent);//GetLineGameObject();
  173.                 GameObject curve = AddCircle_(p, r, axis, angle, 0, pointsPerCircle, persistent);
  174.                 curve.transform.parent = lineg.transform;
  175.                 SetWidth_(s, f);
  176.                 if(!persistent)
  177.                 {
  178.                         temp.Add(lineg);
  179.                         temp.Add(curve);
  180.                 }
  181.                 return lineg;
  182.         }
  183.         public GameObject AddSpiralPlane_(Vector3 p, int size, Vector3 normal, int pointsPerCircle, bool persistent)
  184.         {
  185.                 int numPoints = size*pointsPerCircle;
  186.                 GameObject lineg = GetLineGameObject();
  187.                 LineRenderer lineRenderer = lineg.GetComponent<LineRenderer>();
  188.                 Vector3 right = GetRightVector(Quaternion.LookRotation(normal));
  189.                 lineRenderer.SetVertexCount(numPoints);
  190.                 float rad = 0;
  191.                 for(int i = 0; i < numPoints; ++i)
  192.                 {
  193.                         Quaternion q = Quaternion.AngleAxis(i*360.0f/pointsPerCircle, normal);
  194.                         Vector3 delta = q * right * rad;
  195.                         lineRenderer.SetPosition(i, p + (delta * 1));
  196.                         rad += 2f/pointsPerCircle;
  197.                 }                      
  198.                 if(!persistent)
  199.                         temp.Add(lineg);
  200.                 return lineg;
  201.         }
  202.         Vector3 GetForwardVector(Quaternion q)
  203.         {
  204.                 return new Vector3( 2 * (q.x * q.z + q.w * q.y),
  205.                                                 2 * (q.y * q.z - q.w * q.x),
  206.                                                 1 - 2 * (q.x * q.x + q.y * q.y));
  207.         }
  208.         public static Vector3 GetUpVector(Quaternion q)
  209.         {
  210.             return new Vector3( 2 * (q.x * q.y - q.w * q.z),
  211.                             1 - 2 * (q.x * q.x + q.z * q.z),
  212.                             2 * (q.y * q.z + q.w * q.x));
  213.         }
  214.         public static Vector3  GetRightVector(Quaternion q)
  215.         {
  216.             return new Vector3( 1 - 2 * (q.y * q.y + q.z * q.z),
  217.                             2 * (q.x * q.y + q.w * q.z),
  218.                             2 * (q.x * q.z - q.w * q.y));
  219.         }
  220. }
RAW Paste Data
Top