unity3d 如何根据字符串的结尾示例化一个对象?(这是针对L系统)

vmjh9lq9  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(141)

我正在研究这个L系统,我把它设置成这样:
private const string axiom = "X";
private string currentString = string.Empty;
我正在调用一个名为Generate的方法。

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循环和switch语句遍历字符串,生成树:

foreach (char c in currentString) { 
            switch(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 + 4) % currentString.Length] == 'F' && currentString[(c + 5) % currentString.Length] == 'X')
                    {
                         treeSegment = Instantiate(leaf);
                        Debug.Log("LEAF!");
                    }
                    else{
                         treeSegment = Instantiate(branch);
                    }
                    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");
            }
        }

我的教程,这是基于关闭检查的位置,以放置树枝和树叶,像这样:

for (int i = 0; i < currentString.Length; i++) 
{
    switch (currentString[i]) 
    { 
        case 'F':
             initialPosition = transform.position; 
             transform.Translate(Vector3.up * 2 * length);

             GameObject fLine = currentString[(i + 1) % currentString.Length] == 'X' || currentString[(i + 3) % currentString.Length] == 'F' && currentString[(i + 4) % currentString.Length] == 'X' ? Instantiate(leaf) : Instantiate(branch);

我不知道这里发生了什么,我不明白为什么他要把看似随机的数字相加,然后用模数。
任何帮助都将不胜感激。

xxls0lw8

xxls0lw81#

在原来的一个你是访问下一个字符!像一个前瞻与回绕

currentString[(i + 1) % currentString.Length]

基本上转到下一个索引,但是如果索引达到currentString.Length,则由于%,它被绕回,并且再次变为0
例如,假设字符串如下所示

0 1 2 3 4 5
A B C D E F
      |
      | current index = 3

那么(i + 4) % length就意味着7 % 6 = 1

0 1 2 3 4 5
A B C D E F
  |
  | new index after shifting 4 with wrap around = 1

所以整条线

GameObject fLine = currentString[(i + 1) % currentString.Length] == 'X' || currentString[(i + 3) % currentString.Length] == 'F' && currentString[(i + 4) % currentString.Length] == 'X' ? Instantiate(leaf) : Instantiate(branch);

基本上就是

  • (当前字符是F)-从switch
  • 中频
  • 下一个字符是X
  • 右边的字符3(带回绕)是F
  • AND之后的字符是X
  • 然后
  • 示例化(叶)
  • 其他
  • 示例化(分支);
    但是

在代码中执行的操作

currentString[(c + 1) % currentString.Length]

BUTc是一个字符的实际,例如A == 65。在原始字符串中使用它作为索引完全没有意义!

=〉你想坚持一个for循环,以便得到字符的实际当前索引

相关问题