무기 및 사격
개요
Weapons
컴포넌트는 플레이어 무기를 관리하는 역할을 합니다. 현재 무기의 목록을 유지하고 무기 교체를 처리합니다. 또한 Fire
및 Reload
와 같은 일반적인 무기 동작을 위한 인터페이스를 제공합니다. 무기 객체는 주울 수 있거나 바닥에 떨어뜨릴 수 있으며, 자세한 내용은 Weapon Drops 섹션에서 확인할 수 있습니다.
무기에는 두 가지 기본 클래스가 있습니다: Weapon
과 WeaponFirearm
. Weapon
은 최소한의 무기 기능을 보유하고 있으며, WeaponFirearm
은 발사 논리, 탄창 관리, 분산 및 반동과 같은 기본 총기 기능을 캡슐화합니다.
BR200의 무기와 투사체는 주로 히트 스캔 기능을 기반으로 하며, 이는 이 프로젝트에 편리했습니다. 무기와 투사체에 대한 보다 정교한 접근 방식과 다양한 투사체 접근 방식에 대한 자세한 문서는 Projectiles Essentials 및 Projectiles Advanced 샘플에서 확인할 수 있습니다.
히트 스캔 무기
히트 스캔 무기는 게임에서 기본 무기입니다. 발사 시 히트 스캔 무기는 레이캐스트를 사용하여 히트를 평가합니다. 모든 투사체에 대해 네트워크 객체가 생성되는 대신, 시각적 효과를 계산하기 위해 동그란 버퍼에 작은 ProjectileData
구조체가 저장됩니다. 히트 스캔 무기는 대상에게 날아가는 더미 시각 전용 투사체를 생성할 수 있습니다(DummyProjectile
스크립트 참조).
C#
public struct ProjectileData : INetworkStruct
{
public Vector3 Destination;
public Vector3 ImpactNormal;
public int ImpactTagHash;
}
[Networked, Capacity(10)]
private NetworkArray<ProjectileData> _projectileData { get; }
투사체 무기
투사체 무기(ProjectileWeapon
, ThrowableWeapon
)는 시간이 지남에 따라 이동하는 독립적인 투사체 객체를 생성합니다. 투사체는 매 시뮬레이션 틱마다 이전 위치와 새로운 위치 사이에서 짧은 레이캐스트를 실행합니다. 이 프로젝트에서는 투사체 무기를 수류탄에만 사용합니다. 더 깊이 있는 구현을 보려면 Projectiles Essentials 및 Projectiles Advanced 샘플을 확인하세요.
반동
무기 반동은 지속적인 사격 중에 무기가 위로 조준되는 경향이 있는 실제 무기를 기반으로 한 일반적인 게임 동작입니다. 일반적으로 게임에서 무기는 고정되거나 반무작위적인 경로를 따라가며, 플레이어는 이를 통해 반동 효과를 입력으로 상쇄할 수 있습니다.
BR200에는 반동 시스템이 있습니다. 모든 무기는 반동 패턴(일명 스프레이 패턴)을 가질 수 있습니다. 반동 패턴은 지속적인 발사 동안 무기의 경로를 정의하는 스크립트 할 수 있는 오브젝트입니다. 반동은 플레이어의 시야 회전에 직접 영향을 미치며, 플레이어는 이에 대항할 수 있습니다. 이 과정을 반동 감소라고 하며, Agent
스크립트의 SetLookRotation
메서드에서 찾을 수 있습니다. 발사가 중지된 후, 시야 회전은 자동으로 초깃값으로 돌아갑니다.
반동 패턴은 연속적인 모든 총알의 정확한 위치를 정의합니다. 초기 반동 시퀀스(반동 시작 값)가 완료된 후, 반동은 무한 루프(반동 무한 값)를 따릅니다.
무기 분산은 반동 위치 위에 적용되므로 분산 값에 따라 여전히 약간의 발사 무작위성이 있습니다.
동적 분산
모든 총기 무기는 분산 동작 설정이 있습니다.
분산은 지속적인 발사 동안 증가하고, 발사가 멈추면 자동으로 기본 값으로 감소합니다. 무기 분산은 캐릭터의 상태(달리기, 공중, 조준)에 따라 추가로 곱해집니다.
관통
투사체 관통(또는 침투)은 게임 세계의 특정 객체를 관통하여 발사할 수 있는 능력입니다. 이는 보통 대미지 페널티가 동반됩니다.
관통은 HitscanWeapon
에서 히트를 처리할 때 직접 계산됩니다. 각 투사체는 다양한 재질에 대한 대미지 승수를 지정하는 관통 설정을 가질 수 있습니다. 대미지 승수가 0인 객체는 투사체가 관통하지 않습니다. 재질은 게임 객체에 할당된 유니티 태그에 따라 구분되며, 태그의 해시를 기반으로 런타임에 확인됩니다.
대미지 감소
투사체 대미지는 발사 원점에서 거리에 따라 감소합니다. 대미지 감소는 DummyProjectile
컴포넌트에 정의된 설정에 따라 제어됩니다.
3인칭 슈팅
3인칭 슈팅은 플레이어가 카메라를 통해 보는 것과 게임 세계에서 플레이어 캐릭터가 실제로 명중할 수 있는 것 사이의 차이를 처리해야 합니다.
히트를 계산할 때 먼저 목표 지점을 알아야 합니다. 목표 지점은 플레이어가 조준하는 위치를 지정하며, FixedUpdateNetwork()
마다 무기 스크립트에서 카메라에서 직접 레이캐스트를 발사하여 계산합니다. 발사 입력이 처리되면 무기는 목표 지점을 가져와 캐릭터 발사 위치에서 목표 지점까지 다시 레이캐스트를 발사하여 실제 히트를 얻습니다.
이 기본 계산 외에도 더 나은 슈팅 경험을 위한 몇 가지 추가 개선 사항이 있습니다:
- 플레이어의 캐릭터에서 목표 지점에 도달할 수 없을 때, 실제 착륙 지점을 나타내기 위해 빨간 십자가가 표시됩니다.
- 발사 위치에서 목표 지점까지의 레이캐스트는 발사 위치 또는 목표 지점 근처에 있지 않은 환경 히트를 무시하여 코너 문제라고 부르는 문제를 완화합니다. 이는 코너, 나무 및 기타 객체 주위의 사격 동작을 크게 개선합니다. 플레이어는 실제로 조준점이 가리키는 곳에 발사하지만, 코너 바로 옆에서 조준할 경우 코너 뒤의 플레이어를 사격할 수 있는 작은 여유를 제공합니다. 이 무시 동작은 모든 투사체 계산에 사용되는
ProjectileUtility
에 있습니다.
- 목표 지점이 플레이어 캐릭터와 가까울 때 및 목표 지점으로의 방향과 캐릭터 전방 사이의 각도가 너무 클 때, 목표 지점이 전방 방향으로 일정 거리 계산됩니다.
발사체
BR200에서는 수류탄을 제외하고 게임 세계를 통해 이동하는 발사체를 거의 사용하지 않습니다. 더 정교한 발사체 예제는 발사체 기초 및 Projectiles Advanced 샘플을 확인하세요.
수류탄
수류탄은 아이템 상자에서 찾을 수 있습니다. 수류탄이 장전되면 작은 카운트다운이 수류탄 폭발 시간을 최솟값까지 감소시킵니다(ThrowableWeapon
참조). 수류탄 발사체는 보이지 않는 수류탄 발사기로 발사된 것처럼 특수 무기에 의해 처리됩니다.
폭발 수류탄
폭발 객체를 생성하는 수류탄입니다.
섬광 수류탄
수류탄이 폭발할 때 해당 방향을 바라보고 있으면 일정 거리 내의 플레이어를 눈부시게 합니다. 간단한 플레이어 실명 효과는 AgentSenses
컴포넌트에서 계산됩니다.
연막 수류탄
연기 효과를 생성하는 수류탄입니다.
체력 및 대미지 시스템
모든 히트는 HitUtility
에서 처리되며, 여기서 HitData
구조체가 생성되고 대미지는 가능한 신체 부위 승수에 따라 곱해집니다. BodyPart
는 기본 지연 보상 Hitbox
의 자식 클래스이며, 대미지 승수가 추가됩니다(예: 머리는 승수가 1보다 높고, 팔다리는 승수가 1보다 낮음). 그런 다음 HitData
는 대상의 Health
컴포넌트에 의해 처리됩니다.
체력 컴포넌트는 모든 클라이언트에 히트를 동기화하는 데 필요한 정보만 포함하는 BodyHitData
구조체를 생성합니다. 히트는 작은 네트워크 순환 버퍼의 BodyHitData
구조체에 저장됩니다.
C#
public struct BodyHitData : INetworkStruct
{
public EHitAction Action;
public float Damage;
public Vector3 RelativePosition;
public Vector3 Direction;
public PlayerRef Instigator;
}
[Networked, Capacity(4)]
private NetworkArray<BodyHitData> _hitData { get; }
RelativePosition
이 절대 위치 대신 BodyHitData
에 저장된 것을 주목하세요. 프록시의 위치는 서버에서 수신된 마지막 두 틱 사이에서 보간 되므로, 상대 위치가 더 나은 히트 효과(예: 혈흔 효과)를 몸에 정확히 배치하는 데 유리합니다.
히트 버퍼의 변경 사항에 따라 적절한 히트 반응이 트리거 됩니다 - UI의 히트 방향, 히트 확인 및 대미지 숫자 표시, 혈흔 효과 생성.