Sử dụng GL Lines:
Tôi sẽ khuyên bạn nên sử dụng API GL để vẽ các đường. Độ dày của dòng sẽ luôn là 1px trên màn hình và không có tùy chọn để thay đổi nó. Cũng sẽ không có bóng.
Các cuộc gọi phương thức GL được thực hiện ngay lập tức, do đó bạn cần đảm bảo gọi chúng sau khi máy ảnh đã được kết xuất.
Đính kèm tập lệnh vào máy ảnh và sử dụng Camera.OnPostRender () hoạt động tốt để hiển thị trong cửa sổ trò chơi. Để làm cho chúng hiển thị trong trình chỉnh sửa, bạn có thể sử dụng MonoBehaviour.OnDrawGizmos () .
Đây là mã vạch để vẽ một dòng với API GL:
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();
}
Dưới đây là một kịch bản đầy đủ gắn tất cả các điểm đã cho vào điểm chính. Có một số hướng dẫn trong các ý kiến của mã để thiết lập đúng và về những gì đang xảy ra.
Nếu bạn gặp vấn đề khi thay đổi màu của các đường kết nối, hãy đảm bảo sử dụng trình đổ bóng trên vật liệu đường có tính đến màu đỉnh như 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();
}
}
Lưu ý thêm về bóng: Tôi đã khám phá bằng cách sử dụng trình tạo bóng hình học để tạo bóng nhưng vì các cuộc gọi GL chạy ngay lập tức, chúng không nằm trong đường dẫn kết xuất thông thường AutoLight.cginc
và Lighting.cginc
sẽ không nhận ShadowCaster
đường chuyền.
Dòng có bóng và bán kính
Nếu bạn cần thay đổi độ dày của dòng và muốn có bóng thực tế. Chỉ cần sử dụng một lưới xi lanh và quy mô chiều cao.
Dưới đây là một kịch bản sẽ tạo ra một hình trụ để kết nối mỗi điểm với điểm chính. Đặt nó trên một đối tượng trò chơi trống và điền vào các tham số. Nó sẽ giữ tất cả các đối tượng kết nối thêm.
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);
}
}
}