[英]How do I replace Line Renderers with meshes or prefabs/Instantiate meshes or prefabs on top of Line Renderers?
我正在使用 L 系統生成樹,我的算法運行良好。 我這樣做是為了讓我正在處理的 L-System 將自己顯示為線渲染器。 完整代碼如下:
public class TransformInfo{
public Vector3 position;
public Quaternion rotation;
}
public class LSystemScript : MonoBehaviour{
[SerializeField] private float iterations;
[SerializeField] private GameObject branch;
[SerializeField] private GameObject leaf;
[SerializeField] private float length;
[SerializeField] private float angle ;
[SerializeField] private float rotationAngle;
[SerializeField] private GameObject treeMesh;
private const string axiom = "X";
private Stack<TransformInfo> transformStack;
private Dictionary<char, string> rules;
private string currentString = string.Empty;
void Start(){
transformStack = new Stack<TransformInfo>();
angle = UnityEngine.Random.Range(10, 60);
iterations = UnityEngine.Random.Range(3, 5);
rotationAngle = UnityEngine.Random.Range(0, 90);
length = UnityEngine.Random.Range(0.01f, 0.1f);
rules = new Dictionary<char, string> {
{ 'X',"[F-[[X]+X]+F[+FX]-X]" },
//{ 'X', "[FX[+F[-FX]FX][-F-FXFX]]" }, //This generates interesting shrubs
{ 'F',"FF"}
};
Generate();
//ReplaceWithMesh();
}
private void ReplaceWithMesh(){
GameObject[] gos = GameObject.FindGameObjectsWithTag("Tree");
foreach (GameObject g in gos) {
Quaternion gq = g.transform.rotation;
Instantiate(treeMesh, new Vector3(g.transform.position.x, g.transform.position.y, g.transform.position.z), gq);
}
}
private void Generate() {
currentString = axiom;
StringBuilder sb = new StringBuilder();
for(int i=0; i < iterations; i++) {
//loop through current string and create a new string based on the rules
foreach (char c in currentString){
sb.Append(rules.ContainsKey(c) ? rules[c] : c.ToString());
}
//Set currentString to the new string we just generated.
currentString = sb.ToString();
sb = new StringBuilder();
}
//foreach (char c in currentString)
for (int c = 0; c < currentString.Length; c++){
switch(currentString[c])
{
case 'F':
//Draw a straight line
Vector3 initialPosition = transform.position;
transform.Translate(Vector3.up * length);
GameObject treeSegment;
if (currentString[(c + 1) % currentString.Length] == 'X' ||
currentString[(c + 3) % currentString.Length] == 'F' && currentString[(c + 4) % currentString.Length] == 'X')
{
treeSegment = Instantiate(leaf);
}
else{
treeSegment = Instantiate(branch);
transform.Rotate(0, rotationAngle, 0);
}
treeSegment.GetComponent<LineRenderer>().SetPosition(0, initialPosition);
treeSegment.GetComponent<LineRenderer>().SetPosition(1, transform.position);
break;
case 'X':
//does nothing, generate more Fs
break;
case '+':
//Rotates clockwise
transform.Rotate(Vector3.back * angle);
break;
case '-':
//Rotates counter-clockwise
transform.Rotate(Vector3.forward * angle);
break;
case '[':
//Save current transform info
transformStack.Push(new TransformInfo(){
position = transform.position,
rotation = transform.rotation
});
break;
case ']':
//Return to our previously saved transform info
TransformInfo ti = transformStack.Pop();
transform.position = ti.position;
transform.rotation = ti.rotation;
break;
default:
throw new InvalidOperationException("Invalid L-tree operation");
}
}
}
}
下一步是用網格/預制件替換線渲染器。 但是我嘗試過的一切似乎都沒有用。
我嘗試簡單地用網格替換線渲染器,以及標記線預制件,並使用它們的標簽來獲取它們的位置和旋轉並在它們的位置實例化預制件。 但這似乎也不起作用。
我注意到的第一件事是迭代是一個浮點數。 這不是錯誤,但您可能應該將其設置為 integer,除非您在其他地方使用它。
所以如果你想從一堆線創建一個網格,那可能比你想象的更難。 最直接的解決方案是將每個點都轉換為格點,然后進行一些移動立方體惡作劇,但我不建議這樣做。
如果您想簡單地實例化一個新的游戲對象,就像您的 function 目前所做的那樣,使用 Instantiate 是 go 的正確方法。 我不明白你為什么使用new Vector3(g.transform.position.x, g.transform.position.y, g.transform.position.z)
而不是g.transform.position
,但這不應該導致任何問題。
如果您想像我說的那樣創建游戲對象的副本,您的問題可能與 TreeMesh 預制件或類似的東西有關。
希望我能幫上忙,對不起,如果我不能,我也是新手。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.