반응형
이제 본격적으로 주무기를 만들어보자
1. 변수 할당
public class Rifle : MainWeapon
{
private bool canReset = true; // 처음에만 총알 넣어주기 위해
private float nextFireTime; // 다음 발사 주기
protected override void Awake()
{
base.Awake();
maxLoadedAmmo = 30; // 장전될 수 있는 탄약
initializeAmmo = 180; // 총기 최대 탄약
damage = 27; // 데미지
bulletRange = 50f; // 총알 발사 거리
fireRate = 0.06f; // 총알 발사 주기
recoilX = 0.2f; // 좌우 반동
recoilY = 1.5f; // 수직 반동
recoilRecoverySpeed = 2f; // 반동 회복 속도
reloadTime = 2.5f; // 장전 시간
adsSpeed = 6; // 정조준 속도
adsFOV = 45; // 정조준시 CameraFOV
bulletSpread = 0.3f; // 탄 퍼짐 정도
maxSpread = 1f; // 최대 탄퍼짐
ResetAmmo(initializeAmmo); // 탄약 세팅
}
// 시작할 때, 탄약 세팅 함수
public void ResetAmmo(int _totalAmmo)
{
if (canReset)
{
loadedAmmo = maxLoadedAmmo;
remainAmmo = _totalAmmo - loadedAmmo;
canReset = false;
}
}
}
우선 라이플은 메인 웨폰을 상속받는다
그리고 탄약을 세팅해주자
탄약 세팅시 최초 1회만 해주어야 하기 때문에 bool변수로 더 이상 호출되는 일을 막자
2. 슈팅과 장전
// 슈팅 함수
public override void Shoot(Transform _firePos)
{
if (Time.time >= nextFireTime && !isReloading && canShoot)
{
nextFireTime = Time.time + fireRate;
base.Shoot(_firePos);
if (loadedAmmo <= 0)
{
Reload();
}
}
}
// 장전 함수
public override void Reload()
{
base.Reload();
}
총을 쏠때 마우스 왼쪽키가 눌려있으면 계속 발사를 해줄 것이기 때문에 강제적으로 텀을 만들어줘야한다
Time.time이 nextFireTime 보다 클 때만 발사가 가능하게 해주고 총을 발사할 수 없는 상황이나 장전중에도 발사를 막는다
또한 만약 장전되어 있는 총알이 0보다 작거나 같다면 재장전을 해주도록 하자
장전함수는 이미 부모 클래스에서 다 만들어줬으므로 받아오기만 하면 된다
3. 발사 함수
public override void FireBullet()
{
RaycastHit hit;
Vector3 _bulletDir = GetShootDir(cam.transform);
Vector3 direction = cam.transform.forward + _bulletDir;
Debug.DrawRay(cam.transform.position, direction * bulletRange, Color.red, 1f);
if (canShoot)
{
base.FireBullet(firePos);
// 카메라 포지션에서 정면으로 총알 사거리만큼 쏨
if (Physics.Raycast(cam.transform.position, direction, out hit, bulletRange))
{
if ((canAttackMask.value & (1 << hit.transform.gameObject.layer)) == 0)
{
return;
}
IDamageAble target = hit.transform.GetComponent<IDamageAble>();
if (target != null)
{
target.Damaged(damage, hit.point);
}
}
}
}
총알은 레이캐스트로 만들었다.
이는 총알을 Instantiate 하지 않고 가상의 레이저를 쏴 대상을 확인 후, 데미지를 입히는 방식이다.
먼저 설정해줘야 하는 부분이 있는데, 총알을 맞을 수 있는 대상은 레이어와 IDamageAble 인터페이스를 가지고 있어야 한다.
레이캐스트는 맞은 대상의 레이어를 판단할 수 있기 때문에 이부분을 활용했는데,
Layer를 비교하려면 비트 연산을 사용해야 하는 것을 배웠다.
// 처음 작성한 코드
if (hit.transform.gameObject.layer == canAttackMask)
// 결과 : 비교가 불가능 하므로 오류 발생
// 수정한 코드
if ((canAttackMask.value & (1 << hit.transform.gameObject.layer)) == 0)
4. 결과
반응형
'유니티 > 기능구현' 카테고리의 다른 글
[Unity] 유니티 C#) FPS 주무기를 어떻게 구현할까? ( 저격총 ) (4) | 2024.10.27 |
---|---|
[Unity] 유니티 C#) FPS 주무기를 어떻게 구현할까? ( 샷건 ) (0) | 2024.10.23 |
[Unity] 유니티 C#) FPS 주무기를 어떻게 구현할까? ( 주무기 클래스 ) (10) | 2024.10.17 |
[Unity] 유니티 C#) 투척무기 구현을 어떻게 할까? ( 던지기 ) (0) | 2024.08.11 |
[Unity] 유니티 C#) 투척무기 구현을 어떻게 할까? ( 궤적 표시 ) (0) | 2024.08.10 |