unityでL-Systemの最後
3Dの木っぽいものができたのでいったん終了。
- メディア: ペーパーバック
- この商品を含むブログを見る
思っていたよりもコードが少ない。
自然に見せるためにはもう一工夫必要で、恐らく時間がかかりそう。
Parse関数のswitchかかっこ悪い。
using UnityEngine; using System.Collections; using System.Collections.Generic; public class LSystem : MonoBehaviour { GameObject m_Root = null; const float FORWARD_DISTANCE = 2.0f; class Pointer { public Vector3 pos = Vector3.zero; public Quaternion rot = Quaternion.identity; } //string m_InitialString = "F"; //string m_InitialString = "F-F-F-F"; //string m_InitialString = "B"; string m_InitialString = "X"; string m_CurrentString = ""; Dictionary<string, string> m_RuleTable = null; Pointer m_Pointer = null; int m_Index = 0; float m_Angle = 90; Stack<Pointer> m_Stack = null; void Awake () { m_Pointer = new Pointer(); m_Stack = new Stack<Pointer>(); m_Pointer.pos = Vector3.zero; m_Pointer.rot = Quaternion.identity; m_Root = new GameObject("Tree"); m_Root.transform.position = Vector3.zero; m_Root.transform.rotation = Quaternion.identity; m_Angle = 27.5f; m_RuleTable = new Dictionary<string, string>(); //m_RuleTable.Add("F", "FFF-FF-F-F+F+FF-F-FFF"); //m_RuleTable.Add("F", "F+F-F-F+F"); m_RuleTable.Add("F", "FF"); m_RuleTable.Add("-", "-"); m_RuleTable.Add("+", "+"); m_RuleTable.Add("A", "B+A+B"); m_RuleTable.Add("B", "A-B-A"); m_RuleTable.Add("X", "F[+<*X]F[->*X]+<*X"); m_RuleTable.Add("Y", "FX-Y"); m_RuleTable.Add("[", "["); m_RuleTable.Add("]", "]"); m_RuleTable.Add(">", ">"); m_RuleTable.Add("<", "<"); m_RuleTable.Add("*", "*"); m_RuleTable.Add("/", "/"); string cmd = m_InitialString; for(int i = 0; i < 6; ++i) { m_CurrentString = ""; foreach(char s in cmd) { m_CurrentString += m_RuleTable[s.ToString()]; } cmd = m_CurrentString; } } void Build (string command) { foreach(char s in command) { ParseCommand(s); } } void ParseCommand(char s) { switch(s) { case 'F': case 'A': case 'B': GameObject go = GameObject.Instantiate(Resources.Load("Branch")) as GameObject; go.name = "Branch"+m_Index; go.transform.position = m_Pointer.pos; go.transform.rotation = m_Pointer.rot; go.transform.parent = m_Root.transform; Vector3 n = m_Pointer.rot*(FORWARD_DISTANCE*Vector3.up) + m_Pointer.pos; m_Pointer.pos = n; break; case 'X': case 'Y': break; case '-': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(m_Angle, Vector3.left); break; case '+': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(-m_Angle, Vector3.left); break; case '[': Pointer push = new Pointer(); push.pos = m_Pointer.pos; push.rot = m_Pointer.rot; m_Stack.Push(push); break; case ']': if(m_Stack.Count > 0) { Pointer pop = m_Stack.Pop(); m_Pointer.pos = pop.pos; m_Pointer.rot = pop.rot; } break; case '>': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(m_Angle, Vector3.forward); break; case '<': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(-m_Angle, Vector3.forward); break; case '*': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(m_Angle, Vector3.up); break; case '/': m_Pointer.rot = m_Pointer.rot * Quaternion.AngleAxis(-m_Angle, Vector3.up); break; } m_Index++; } // Use this for initialization void Start () { Build(m_CurrentString); } // Update is called once per frame void Update () { } }