You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.8 KiB
C#
120 lines
4.8 KiB
C#
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<BranchSway>();
|
|
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<Renderer>();
|
|
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);
|
|
}
|
|
}
|