728x90
반응형
유니티에서 플레이어 주변을 회전하는 무기나 오브젝트를 어떻게 구현하는지에 대해 알아보겠습니다.
흔히 뱀파이어 서바이버(Vampire Survivors)와 같은 게임에서 볼 수 있는 시스템을 만드는 기초가 될 수 있습니다.
1. 구현 목표 및 미리 보기
우리가 만들고자 하는 것은 다음과 같은 기능을 가진 스크립트입니다:
- 지속적인 회전: 오브젝트 자체가 특정 속도로 계속 회전합니다.
- 자식 오브젝트 배치: 회전하는 오브젝트를 부모로 삼아, 여러 개의 자식 오브젝트(무기)를 원형으로 균등하게 배치합니다.
2. C# 스크립트 분석
using UnityEngine;
public class Weapon : MonoBehaviour
{
// [공개 변수] 유니티 에디터에서 설정 가능
public GameObject prefab; // 회전하는 무기/오브젝트의 프리헵
public int count; // 배치할 무기/오브젝트의 개수
public float speed; // 오브젝트의 회전 속도
// 매 프레임마다 호출됨
void Update()
{
// Z축을 기준으로 'speed * Time.deltaTime'만큼 회전합니다.
// Time.deltaTime을 곱하여 프레임 속도와 상관없이 일정한 속도로 회전하게 만듭니다.
transform.Rotate(0, 0, speed * Time.deltaTime);
}
// 오브젝트들을 배치하고 위치를 업데이트하는 함수
void Batch()
{
for (int i = 0; i < count; i++)
{
Transform bullet;
if (i < transform.childCount)
{
bullet = transform.GetChild(i); // 기존에 생성된 자식 오브젝트 재사용 (최적화)
}
else
{
bullet = Instantiate(prefab).transform; // 새 자식 오브젝트 생성
bullet.parent = transform; // 현재 오브젝트를 부모로 설정
}
// 위치 및 회전 초기화
// 부모를 기준으로 로컬 위치를 원점(0,0,0)으로, 로컬 회전을 기본값으로 리셋합니다.
bullet.localPosition = Vector3.zero;
bullet.localRotation = Quaternion.identity;
// 회전 및 위치 적용 (원형 배치)
// 1. 회전 계산: 'count' 개수만큼 360도를 균등하게 나눕니다.
Vector3 rotVec = Vector3.forward * 360 * i / count;
// 2. 오브젝트를 계산된 각도만큼 회전시킵니다.
bullet.Rotate(rotVec);
// 3. 오브젝트의 '위' 방향(local up)으로 1.5f만큼 이동시킵니다.
// 이렇게 하면 부모의 중앙에서 'rotVec' 각도로 1.5f 떨어진 위치에 배치됩니다.
bullet.Translate(bullet.up * 1.5f, Space.World);
// 참고: 'Space.World' 대신 'Space.Self'를 사용하면 더 자연스러운 무기 배치를 할 수도 있습니다.
}
}
}
3. 스크립트 주요 기능 설명
A. 회전 구현 (Update 함수)
void Update()
{
transform.Rotate(0, 0, speed * Time.deltaTime);
}
transform.Rotate(x, y, z)는 현재 오브젝트를 주어진 축을 기준으로 회전시키는 함수입니다.- 우리는 Z축(0, 0, 1)을 기준으로
speed에 비례하여 회전시킵니다. Time.deltaTime을 곱해줌으로써 게임이 어떤 프레임 속도로 실행되든 일정한 회전 속도를 유지하게 합니다.
B. 자식 오브젝트 배치 (Batch 함수)
Batch 함수는 count 변수에 지정된 개수만큼 자식 오브젝트를 부모 주변에 원형으로 배치합니다.
1. 오브젝트 생성 및 재사용
if (i < transform.childCount)
{
bullet = transform.GetChild(i); // 기존 자식 오브젝트 재사용
}
else
{
bullet = Instantiate(prefab).transform; // 새 자식 오브젝트 생성
bullet.parent = transform; // 현재 오브젝트를 부모로 설정
}
- 성능 최적화: 이미 생성된 오브젝트가 있다면 재사용하고, 부족할 경우에만 새로 생성합니다. 이는 무기를 업데이트할 때 불필요한 메모리 할당을 줄여줍니다.
2. 원형 위치 계산
// 1. 회전 계산: 'count' 개수만큼 360도를 균등하게 나눕니다.
Vector3 rotVec = Vector3.forward * 360 * i / count;
// 2. 오브젝트를 계산된 각도만큼 회전시킵니다.
bullet.Rotate(rotVec);
// 3. 오브젝트의 '위' 방향(local up)으로 1.5f만큼 이동시킵니다.
bullet.Translate(bullet.up * 1.5f, Space.World);
이 세 줄이 핵심입니다.
- 먼저 전체 360도를
count개수로 나누어 각 오브젝트가 가져야 할 균등한 각도를 계산합니다. - 오브젝트를 해당 각도만큼 회전시킨 후, 오브젝트의 현재 '위' 방향(local up)으로 특정 거리(예: 1.5f)만큼 이동시킵니다.
- 결과적으로, 모든 자식 오브젝트는 부모 오브젝트의 중심에서 1.5f 떨어진 원형 궤도에 배치됩니다.
4. 유니티 적용 방법
- 새 스크립트 생성:
WeaponSample.cs이름으로 C# 스크립트를 생성하고 위 코드를 붙여넣습니다. - 부모 오브젝트 준비: 빈 게임 오브젝트(Empty Object)를 하나 만들고 이름을
WeaponParent등으로 지정합니다. 이 오브젝트에WeaponSample.cs를 부착합니다. - 자식 프리헵 준비: 회전 무기로 사용할 3D 모델이나 2D 스프라이트를 프리헵으로 만들어 준비합니다.
- 변수 설정:
WeaponParent오브젝트를 선택하고, Inspector 창에서Prefab슬롯에 준비한 자식 프리헵을 드래그하여 넣어줍니다.Count(예: 5)와Speed(예: 100) 값을 설정합니다.
Batch()함수 호출: 게임 시작 시 또는 무기의 개수가 바뀔 때마다 다른 스크립트에서WeaponParent오브젝트의Batch()함수를 호출해 주면 원형 배치가 완료됩니다.
728x90
반응형
'개발 > Unity' 카테고리의 다른 글
| (Unity) 근처 적을 스캔하고 최단 거리 대상 찾기 (1) | 2025.12.13 |
|---|---|
| Unity 내장 오브젝트 풀(Object Pool) 사용하기 (0) | 2025.10.13 |
| Unity에서 tag 비교할 때 CompareTag()를 사용해야 하는 이유 (0) | 2025.10.12 |
| Unity에서 커맨드(Command) 패턴 활용하기 (0) | 2025.10.11 |
| Unity에서 이벤트버스(Event Bus) 패턴 활용하기 (0) | 2025.10.08 |