GL 라인 사용 :
GL API를 사용하여 선을 그리는 것이 좋습니다 . 화면에서 선 두께는 항상 1px이며 변경할 수있는 옵션이 없습니다. 그림자도 없습니다.
GL 메소드 호출은 즉시 실행되므로 카메라가 이미 렌더링 된 후에 호출해야합니다.
스크립트를 카메라에 연결하고 Camera.OnPostRender ()를 사용 하면 게임 창에서 렌더링하는 데 적합합니다. 편집기에 표시하려면 MonoBehaviour.OnDrawGizmos ()를 사용할 수 있습니다 .
GL API로 선을 그리는 기본 코드는 다음과 같습니다.
public Material lineMat = new Material("Shader \"Lines/Colored Blended\" {" + "SubShader { Pass { " + " Blend SrcAlpha OneMinusSrcAlpha " + " ZWrite Off Cull Off Fog { Mode Off } " + " BindChannels {" + " Bind \"vertex\", vertex Bind \"color\", color }" + "} } }");
void OnPostRender() {
GL.Begin(GL.LINES);
lineMat.SetPass(0);
GL.Color(new Color(0f, 0f, 0f, 1f));
GL.Vertex3(0f, 0f, 0f);
GL.Vertex3(1f, 1f, 1f);
GL.End();
}
다음은 주어진 모든 포인트를 메인 포인트에 연결하는 전체 스크립트입니다. 코드 주석에 올바르게 설정하기위한 지침과 진행 상황에 대한 지침이 있습니다.
연결선의 색상을 변경하는 데 문제가있는 경우 등의 정점 색상을 고려한 선 재질에 셰이더를 사용해야합니다 Unlit/Color
.
using UnityEngine;
using System.Collections;
// Put this script on a Camera
public class DrawLines : MonoBehaviour {
// Fill/drag these in from the editor
// Choose the Unlit/Color shader in the Material Settings
// You can change that color, to change the color of the connecting lines
public Material lineMat;
public GameObject mainPoint;
public GameObject[] points;
// Connect all of the `points` to the `mainPoint`
void DrawConnectingLines() {
if(mainPoint && points.Length > 0) {
// Loop through each point to connect to the mainPoint
foreach(GameObject point in points) {
Vector3 mainPointPos = mainPoint.transform.position;
Vector3 pointPos = point.transform.position;
GL.Begin(GL.LINES);
lineMat.SetPass(0);
GL.Color(new Color(lineMat.color.r, lineMat.color.g, lineMat.color.b, lineMat.color.a));
GL.Vertex3(mainPointPos.x, mainPointPos.y, mainPointPos.z);
GL.Vertex3(pointPos.x, pointPos.y, pointPos.z);
GL.End();
}
}
}
// To show the lines in the game window whne it is running
void OnPostRender() {
DrawConnectingLines();
}
// To show the lines in the editor
void OnDrawGizmos() {
DrawConnectingLines();
}
}
그림자에 대한 추가 참고 : 나는 지오메트리 셰이더가 그림자를 만들하지만 GL 호출 즉시 실행하기 때문에, 그들은 정상적인 렌더링 파이프 라인에없는 및 사용 탐구 AutoLight.cginc
및 Lighting.cginc
픽업되지 않습니다 ShadowCaster
패스를.
그림자와 반지름이있는 선
선 두께를 변경하고 사실적인 그림자를 원할 경우. 원통 메쉬를 사용하여 높이를 조정하십시오.
다음은 각 점을 메인 점에 연결하기 위해 실린더를 만드는 스크립트입니다. 빈 게임 오브젝트에 놓고 매개 변수를 채우십시오. 추가 연결 개체를 모두 보유합니다.
using UnityEngine;
using System.Collections;
public class ConnectPointsWithCylinderMesh : MonoBehaviour {
// Material used for the connecting lines
public Material lineMat;
public float radius = 0.05f;
// Connect all of the `points` to the `mainPoint`
public GameObject mainPoint;
public GameObject[] points;
// Fill in this with the default Unity Cylinder mesh
// We will account for the cylinder pivot/origin being in the middle.
public Mesh cylinderMesh;
GameObject[] ringGameObjects;
// Use this for initialization
void Start () {
this.ringGameObjects = new GameObject[points.Length];
//this.connectingRings = new ProceduralRing[points.Length];
for(int i = 0; i < points.Length; i++) {
// Make a gameobject that we will put the ring on
// And then put it as a child on the gameobject that has this Command and Control script
this.ringGameObjects[i] = new GameObject();
this.ringGameObjects[i].name = "Connecting ring #" + i;
this.ringGameObjects[i].transform.parent = this.gameObject.transform;
// We make a offset gameobject to counteract the default cylindermesh pivot/origin being in the middle
GameObject ringOffsetCylinderMeshObject = new GameObject();
ringOffsetCylinderMeshObject.transform.parent = this.ringGameObjects[i].transform;
// Offset the cylinder so that the pivot/origin is at the bottom in relation to the outer ring gameobject.
ringOffsetCylinderMeshObject.transform.localPosition = new Vector3(0f, 1f, 0f);
// Set the radius
ringOffsetCylinderMeshObject.transform.localScale = new Vector3(radius, 1f, radius);
// Create the the Mesh and renderer to show the connecting ring
MeshFilter ringMesh = ringOffsetCylinderMeshObject.AddComponent<MeshFilter>();
ringMesh.mesh = this.cylinderMesh;
MeshRenderer ringRenderer = ringOffsetCylinderMeshObject.AddComponent<MeshRenderer>();
ringRenderer.material = lineMat;
}
}
// Update is called once per frame
void Update () {
for(int i = 0; i < points.Length; i++) {
// Move the ring to the point
this.ringGameObjects[i].transform.position = this.points[i].transform.position;
// Match the scale to the distance
float cylinderDistance = 0.5f*Vector3.Distance(this.points[i].transform.position, this.mainPoint.transform.position);
this.ringGameObjects[i].transform.localScale = new Vector3(this.ringGameObjects[i].transform.localScale.x, cylinderDistance, this.ringGameObjects[i].transform.localScale.z);
// Make the cylinder look at the main point.
// Since the cylinder is pointing up(y) and the forward is z, we need to offset by 90 degrees.
this.ringGameObjects[i].transform.LookAt(this.mainPoint.transform, Vector3.up);
this.ringGameObjects[i].transform.rotation *= Quaternion.Euler(90, 0, 0);
}
}
}