ใช้สาย GL:
ฉันอยากจะแนะนำให้ใช้GL API สำหรับการวาดเส้น ความหนาของเส้นจะอยู่ที่ 1px บนหน้าจอเสมอและไม่มีตัวเลือกให้เปลี่ยน จะไม่มีเงาอีกด้วย
การเรียกใช้เมธอด GL จะดำเนินการทันทีดังนั้นคุณต้องแน่ใจว่าได้ทำการโทรหลังจากที่กล้องแสดงผลไปแล้ว
การแนบสคริปต์เข้ากับกล้องและใช้CameraOnPostRender ()ทำงานได้ดีสำหรับการแสดงผลในหน้าต่างเกม เพื่อให้พวกเขาแสดงให้เห็นในการแก้ไขคุณสามารถใช้MonoBehaviour.OnDrawGizmos ()
นี่คือรหัส barebones เพื่อวาดเส้นด้วย 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();
}
นี่คือสคริปต์เต็มรูปแบบที่แนบจุดที่กำหนดทั้งหมดไปยังจุดหลัก มีคำแนะนำในการแสดงความคิดเห็นของรหัสเพื่อให้มันถูกต้องและเกี่ยวกับสิ่งที่เกิดขึ้น
หากคุณกำลังมีปัญหาในการเปลี่ยนสีของเส้นเชื่อมต่อให้แน่ใจว่าจะใช้ Shader 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);
}
}
}