using System.Collections; using UnityEngine; public class tree : MonoBehaviour { public GameObject branchPrefab; public int maxDepth = 4; public float branchAngle = 45f; public float scaleReduction = 0.6f; public float initialLength = 5f; public int branchesPerLevel = 4; [Header("Artistic Settings")] public Color trunkColor = new Color(0.4f, 0.2f, 0f); // 나무 몸통 (갈색) public Color leafColor = new Color(1f, 0.4f, 0.6f); // 가지 끝부분 (핑크/벚꽃 느낌) [Range(0f, 1f)] public float lengthRandomness = 0.2f; // 길이 랜덤 (0~1) [Range(0f, 45f)] public float angleRandomness = 20f; // 휘어짐 극대화를 위한 각도 랜덤 [Header("Animation & Wind")] public float growthDelay = 0.1f; // 가지 생성 대기 시간 (애니메이션 효과) [Range(0f, 5f)] public float windStrength = 1.5f; // 바람의 세기 private GameObject branchContainer; void Start() { // Hierarchy 창을 깔끔하게 유지하기 위한 컨테이너 생성 branchContainer = new GameObject("TreeContainer"); branchContainer.transform.position = transform.position; StartCoroutine(CreateBranchRoutine(transform.position, transform.rotation, initialLength, 0, branchContainer.transform)); } IEnumerator CreateBranchRoutine(Vector3 pos, Quaternion rot, float length, int depth, Transform parentTransform) { if (depth >= maxDepth) yield break; // 런타임에서 자라나는 모습을 보여주기 위한 대기 시간 yield return new WaitForSeconds(growthDelay); // 바람에 흔들릴 때 관절이 끊어지지 않도록, 가지 시작점(pos)에 가상의 피벗(Pivot)을 생성 GameObject pivot = new GameObject("Pivot_Depth_" + depth); pivot.transform.position = pos; pivot.transform.rotation = rot; pivot.transform.parent = parentTransform; // 흔들림(Sway) 스크립트 추가 BranchSway sway = pivot.AddComponent(); sway.Init(depth, windStrength); // 중앙 피벗 큐브를 위한 중심 위치 계산 Vector3 centerPos = pos + rot * (Vector3.up * length * 0.5f); // 나뭇가지를 생성하고 부모를 생성한 피벗으로 설정 GameObject branch = Instantiate(branchPrefab, centerPos, rot); branch.transform.parent = pivot.transform; // 아티스틱: 깊이에 따라 색상 자연스럽게 섞기 (Lerp) Renderer rnd = branch.GetComponentInChildren(); if (rnd != null) { float colorT = maxDepth > 1 ? (float)depth / (maxDepth - 1) : 1f; rnd.material.color = Color.Lerp(trunkColor, leafColor, colorT); } // 동적 크기 조절: 깊이에 따라 두께가 얇아짐 float thickness = 0.15f * (maxDepth - depth); branch.transform.localScale = new Vector3(thickness, length, thickness); // 가지의 끝 지점 계산 Vector3 endPoint = pos + rot * (Vector3.up * length); // 길이 및 각도 세팅 float randomizedLengthMultiplier = Random.Range(1f - lengthRandomness, 1f + lengthRandomness); float nextLength = length * scaleReduction * randomizedLengthMultiplier; float angleStep = 360f / branchesPerLevel; for (int i = 0; i < branchesPerLevel; i++) { float randTilt = Random.Range(-angleRandomness, angleRandomness); float randSpin = Random.Range(-angleRandomness, angleRandomness); Quaternion tilt = Quaternion.Euler(branchAngle + randTilt, 0, 0); Quaternion spin = Quaternion.Euler(0, (i * angleStep) + (depth * 25f) + randSpin, 0); Quaternion finalRot = rot * spin * tilt; // 다음 가지 생성 코루틴 실행 StartCoroutine(CreateBranchRoutine(endPoint, finalRot, nextLength, depth + 1, pivot.transform)); } } } // 바람에 흔들리는 효과를 담당하는 컴포넌트 public class BranchSway : MonoBehaviour { private Quaternion initialLocalRotation; private float speed = 1f; private float amount = 2f; private float offset; public void Init(int depth, float windStrength) { initialLocalRotation = transform.localRotation; offset = Random.Range(0f, 100f); speed = 1f + Random.Range(0f, 0.5f); // 끝가지일수록, 그리고 windStrength가 강할수록 더 많이 흔들림. 잘 보이도록 수치를 키움 amount = 2.5f * (depth + 1) * windStrength; } void Update() { // 시간에 따라 부드럽게 흔들리도록 사인 곡선 적용 float angleX = Mathf.Sin(Time.time * speed + offset) * amount; float angleZ = Mathf.Cos(Time.time * speed * 0.8f + offset) * amount; transform.localRotation = initialLocalRotation * Quaternion.Euler(angleX, 0, angleZ); } }