무기 능력치
Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 50개 중 20번째.
검과 망치는 같은 방식으로 작동합니다. 휘두르고, 기다렸다가, 다시 휘두릅니다. 둘의 차이는 수치에 있습니다. 검은 피해량이 4이고 0.5초마다 휘두르며, 망치는 피해량이 10이고 1.5초마다 휘두릅니다. 따라서 두 무기 모두 하나의 Weapon 스크립트를 사용하고, 각 무기의 수치는 에셋에 저장됩니다.
[CreateAssetMenu(menuName = "Combat/Weapon Data")]
public class WeaponData : ScriptableObject
{
public string weaponName;
public int damage;
public float swingTime;
public GameObject hitEffect;
}public class Weapon : MonoBehaviour
{
public WeaponData data;
private float nextSwing;
public void Swing(Health target)
{
if (Time.time < nextSwing) return;
nextSwing = Time.time + data.swingTime;
target.TakeDamage(data.damage);
Instantiate(data.hitEffect, target.transform.position, Quaternion.identity);
}
}프로젝트에는 Sword 에셋(4, 0.5, 불꽃 프리팹)과 Hammer 에셋(10, 1.5, 먼지 프리팹)이 있습니다. 기사와 오우거 모두 Weapon 스크립트를 갖고 있습니다. 기사의 data 필드에는 Sword가, 오우거의 필드에는 Hammer가 할당됩니다. 창은 Create 메뉴에서 에셋을 하나 더 만들면 되며, 스크립트는 전혀 수정할 필요가 없습니다. hitEffect처럼 에셋은 프리팹이나 다른 에셋을 참조할 수 있지만, 씬에 있는 오브젝트는 참조할 수 없습니다. 에셋은 프로젝트 안에 있고 모든 씬의 외부에 있기 때문입니다.
무기를 다르게 만드는 다른 방법들은 각각 수치를 코드에 넣습니다. if (weaponName == "Sword") damage = 4; else if ...는 무기가 추가될 때마다 코드가 길어지고, 수치만 설정하는 Weapon의 Sword 하위 클래스는 에셋마다 클래스가 하나씩 필요합니다. 하위 클래스는 화살을 발사하는 활처럼 다르게 작동하는 무기에 사용합니다. 더 강하게 공격하거나 더 빠르게 휘두르기만 하는 무기에는 그 자체의 에셋만 있으면 되고, 코드는 필요하지 않습니다.
챌린지
중급사격장에는 총이 네 개 있습니다. 권총 두 개, 소총 한 개, 새 블래스터 한 개입니다. Space를 누르고 있으면 모두 발사됩니다. Gun 스크립트는 gunType에 대한 if/else로 총알, 발사 간격, 피해량을 선택하는데, 블래스터는 여기에 포함되어 있지 않아 발사되지 않습니다(Console를 확인하세요).
모든 총이 에셋에서 수치를 읽도록 만드세요. GunData.cs는 준비되어 있고, 프로젝트에는 이를 사용해 만든 Pistol, Rifle, Blaster 에셋이 있으며, 각 에셋에는 고유한 총알 프리팹이 있습니다.
Gun에 GunData 타입의 public 필드data를 추가하세요. Inspector에서 각 총의 에셋을 여기에 넣습니다.data.bulletPrefab을 발사하고, 발사 간격은data.fireInterval을 사용하며, 각 총알에data.damage를 지정하세요.gunType, 두 개의 총알 필드, private 복사본, if/else를 제거하세요.
Play를 누르고 Space를 누른 채로 있다가 Check를 누르세요.
직접 해보기
using UnityEngine;
using UnityEngine.InputSystem;
public class Gun : MonoBehaviour
{
public string gunType = "Pistol";
public GameObject pistolBullet;
public GameObject rifleBullet;
private GameObject bulletPrefab;
private float fireInterval;
private int damage;
private float nextShot;
void Start()
{
if (gunType == "Pistol")
{
bulletPrefab = pistolBullet;
fireInterval = 0.25f;
damage = 1;
}
else if (gunType == "Rifle")
{
bulletPrefab = rifleBullet;
fireInterval = 0.6f;
damage = 4;
}
}
void Update()
{
if (Keyboard.current.spaceKey.isPressed && Time.time >= nextShot)
{
nextShot = Time.time + fireInterval;
GameObject bullet = Instantiate(bulletPrefab, transform.position + transform.forward, transform.rotation);
bullet.GetComponent<Bullet>().damage = damage;
}
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.