This document is about: FUSION 2
SWITCH TO

무기 및 사격

개요

Weapons 컴포넌트는 플레이어 무기를 관리하는 역할을 합니다. 현재 무기의 목록을 유지하고 무기 교체를 처리합니다. 또한 FireReload와 같은 일반적인 무기 동작을 위한 인터페이스를 제공합니다. 무기 객체는 주울 수 있거나 바닥에 떨어뜨릴 수 있으며, 자세한 내용은 Weapon Drops 섹션에서 확인할 수 있습니다.

무기에는 두 가지 기본 클래스가 있습니다: WeaponWeaponFirearm. Weapon은 최소한의 무기 기능을 보유하고 있으며, WeaponFirearm은 발사 논리, 탄창 관리, 분산 및 반동과 같은 기본 총기 기능을 캡슐화합니다.

BR200의 무기와 투사체는 주로 히트 스캔 기능을 기반으로 하며, 이는 이 프로젝트에 편리했습니다. 무기와 투사체에 대한 보다 정교한 접근 방식과 다양한 투사체 접근 방식에 대한 자세한 문서는 Projectiles EssentialsProjectiles 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 EssentialsProjectiles Advanced 샘플을 확인하세요.

반동

무기 반동은 지속적인 사격 중에 무기가 위로 조준되는 경향이 있는 실제 무기를 기반으로 한 일반적인 게임 동작입니다. 일반적으로 게임에서 무기는 고정되거나 반무작위적인 경로를 따라가며, 플레이어는 이를 통해 반동 효과를 입력으로 상쇄할 수 있습니다.

BR200에는 반동 시스템이 있습니다. 모든 무기는 반동 패턴(일명 스프레이 패턴)을 가질 수 있습니다. 반동 패턴은 지속적인 발사 동안 무기의 경로를 정의하는 스크립트 할 수 있는 오브젝트입니다. 반동은 플레이어의 시야 회전에 직접 영향을 미치며, 플레이어는 이에 대항할 수 있습니다. 이 과정을 반동 감소라고 하며, Agent 스크립트의 SetLookRotation 메서드에서 찾을 수 있습니다. 발사가 중지된 후, 시야 회전은 자동으로 초깃값으로 돌아갑니다.

recoil pattern
반동 패턴과 분산 없이 발사할 때 실제 총알 구멍

반동 패턴은 연속적인 모든 총알의 정확한 위치를 정의합니다. 초기 반동 시퀀스(반동 시작 값)가 완료된 후, 반동은 무한 루프(반동 무한 값)를 따릅니다.

무기 분산은 반동 위치 위에 적용되므로 분산 값에 따라 여전히 약간의 발사 무작위성이 있습니다.

동적 분산

모든 총기 무기는 분산 동작 설정이 있습니다.

weapon dispersion

분산은 지속적인 발사 동안 증가하고, 발사가 멈추면 자동으로 기본 값으로 감소합니다. 무기 분산은 캐릭터의 상태(달리기, 공중, 조준)에 따라 추가로 곱해집니다.

weapon dispersion
분산 및 반동 설정

관통

투사체 관통(또는 침투)은 게임 세계의 특정 객체를 관통하여 발사할 수 있는 능력입니다. 이는 보통 대미지 페널티가 동반됩니다.

관통은 HitscanWeapon에서 히트를 처리할 때 직접 계산됩니다. 각 투사체는 다양한 재질에 대한 대미지 승수를 지정하는 관통 설정을 가질 수 있습니다. 대미지 승수가 0인 객체는 투사체가 관통하지 않습니다. 재질은 게임 객체에 할당된 유니티 태그에 따라 구분되며, 태그의 해시를 기반으로 런타임에 확인됩니다.

piercing setup

대미지 감소

투사체 대미지는 발사 원점에서 거리에 따라 감소합니다. 대미지 감소는 DummyProjectile 컴포넌트에 정의된 설정에 따라 제어됩니다.

dummy projectile

3인칭 슈팅

3인칭 슈팅은 플레이어가 카메라를 통해 보는 것과 게임 세계에서 플레이어 캐릭터가 실제로 명중할 수 있는 것 사이의 차이를 처리해야 합니다.

히트를 계산할 때 먼저 목표 지점을 알아야 합니다. 목표 지점은 플레이어가 조준하는 위치를 지정하며, FixedUpdateNetwork()마다 무기 스크립트에서 카메라에서 직접 레이캐스트를 발사하여 계산합니다. 발사 입력이 처리되면 무기는 목표 지점을 가져와 캐릭터 발사 위치에서 목표 지점까지 다시 레이캐스트를 발사하여 실제 히트를 얻습니다.

third person shooting
3인칭 슈팅 다이어그램
노트: 발사 위치는 총구 끝이 아닙니다. 원래는 총구 위치를 사용했지만, 무기 위치가 애니메이션에 의해 영향을 받기 때문에 급격한 움직임(예: 좌우 이동) 동안 발사 경험이 덜 안정적이었습니다. 따라서 캐릭터 어깨 근처의 고정 발사 위치로 변경했습니다.

이 기본 계산 외에도 더 나은 슈팅 경험을 위한 몇 가지 추가 개선 사항이 있습니다:

  • 플레이어의 캐릭터에서 목표 지점에 도달할 수 없을 때, 실제 착륙 지점을 나타내기 위해 빨간 십자가가 표시됩니다.
red cross
목표 지점에 도달할 수 없을 때 빨간 십자가가 표시됩니다.
  • 발사 위치에서 목표 지점까지의 레이캐스트는 발사 위치 또는 목표 지점 근처에 있지 않은 환경 히트를 무시하여 코너 문제라고 부르는 문제를 완화합니다. 이는 코너, 나무 및 기타 객체 주위의 사격 동작을 크게 개선합니다. 플레이어는 실제로 조준점이 가리키는 곳에 발사하지만, 코너 바로 옆에서 조준할 경우 코너 뒤의 플레이어를 사격할 수 있는 작은 여유를 제공합니다. 이 무시 동작은 모든 투사체 계산에 사용되는 ProjectileUtility에 있습니다.
corner issue
투사체가 목표 지점에 도달하기 위해 코너를 무시합니다.
  • 목표 지점이 플레이어 캐릭터와 가까울 때 및 목표 지점으로의 방향과 캐릭터 전방 사이의 각도가 너무 클 때, 목표 지점이 전방 방향으로 일정 거리 계산됩니다.
angle ignore
조준점 각도가 너무 클 경우 무기가 앞으로 발사됩니다.

발사체

BR200에서는 수류탄을 제외하고 게임 세계를 통해 이동하는 발사체를 거의 사용하지 않습니다. 더 정교한 발사체 예제는 발사체 기초Projectiles Advanced 샘플을 확인하세요.

수류탄

수류탄은 아이템 상자에서 찾을 수 있습니다. 수류탄이 장전되면 작은 카운트다운이 수류탄 폭발 시간을 최솟값까지 감소시킵니다(ThrowableWeapon 참조). 수류탄 발사체는 보이지 않는 수류탄 발사기로 발사된 것처럼 특수 무기에 의해 처리됩니다.

참고: 플레이어는 숫자 키 4로 수류탄을 순환할 수 있습니다.

폭발 수류탄

폭발 객체를 생성하는 수류탄입니다.

explosive grenade

섬광 수류탄

수류탄이 폭발할 때 해당 방향을 바라보고 있으면 일정 거리 내의 플레이어를 눈부시게 합니다. 간단한 플레이어 실명 효과는 AgentSenses 컴포넌트에서 계산됩니다.

flash grenade

연막 수류탄

연기 효과를 생성하는 수류탄입니다.

Smoke Grenade="~/fusion/v2/samples/br200/br-smoke-grenade.gif">

체력 및 대미지 시스템

모든 히트는 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의 히트 방향, 히트 확인 및 대미지 숫자 표시, 혈흔 효과 생성.

플레이어가 다른 플레이어를 히트할 때, 총알의 충격과 히트 효과(혈흔)는 즉시 표시됩니다. 그러나 히트 확인(UI의 빨간 십자가와 히트 숫자)는 서버의 새로운 상태의 일부로 히트를 수신한 후 플레이어에게 표시됩니다(히트가 서버에 의해 "확인됨"). 이는 작은 지연을 도입하지만(네트워크 조건에 따라 다름), 플레이어에게 유효한 히트만을 보장합니다.
Back to top