플레이어
개요
플레이어
(Player
스크립트, Player
프리팹)는 게임에서 연결된 피어를 나타내며 비주얼이 없습니다. 플레이어는 Agent
(게임 세계에서 생성된 시각적 표현)의 재스폰 후에도 있어야 하는 사용자 ID, 닉네임, 선택한 캐릭터 및 기타 데이터에 대한 공통 메타데이터에 대한 접근을 제공합니다.
에이전트
(Agent
스크립트, AgentBase
프리팹, 그리고 변형)은 플레이어가 제어하는 게임 내 캐릭터를 나타냅니다. GameplayMode
에 의해서 스폰 되며, 체력
, 무기
및 다른 컴포넌트를 가지고 있습니다. 캐릭터는 스폰 되며 필요에 따라 스폰 해제됩니다.
다음 다이어그램은 컴포너 계층을 실행 폭포로 보여 줍니다:
입력 처리
다음 다이어그램은 입력 처리와 액션 실행을 나타내고 있습니다:
노트:
Frame
: 유니티 렌더 프레임 번호,Tick
: Fusion 고정 업데이트 틱 번호- 각 프레임의 시작 부분에서 장치의 입력이
BeforeUpdate()
에 수집되어Render Input
데이터 구조체에 기록됩니다(입력 권한에서만 실행). - 동일한 입력이
Cached Input
에도 누적됩니다(예: 룩 로테이션 델타). - 누적 델타 시간이 다음 고정 틱(프레임 103)을 시뮬레이션할 수 있을 정도로 큰 경우
Cached Input
은NetworkEvents.OnInput()
콜백을 통해 폴링/소비됩니다.- 가장 최근의
Render Input
은 이미 축적되어 있고 다음의FixedUpdateNetwork()
에서 처리되기 때문에 지워야 하므로 (FixedUpdateNetwork()
및Render()
부터) 두 번 적용되지 않습니다. - 플레이어 입력은 Fusion의
BeforeTick()
에서 읽히고Fixed Input
에 저장됩니다(입력 및 상태 권한에서 실행). - 다른 스크립트에서 호출된
FixedUpdateNetwork()
는Fixed Input
을 사용하여 게임 플레이 액션을 생성합니다. - 다른 스크립트에서 호출된
Render()
는Render Input
을 사용하여 게임 플레이 액션을 생성합니다(렌더 예측 움직임, 슈팅은 FUN에서만 수행됨).
- 누적 델타 시간이 다음 고정 틱(프레임 101, 102)을 시뮬레이션할 만큼 크지 않은 경우
- 다른 스크립트에서 호출된
Render()
는Render Input
과Cached Input
을 사용하여 게임 실행(예측된 움직임, 모양 회전)을 생성합니다.
- 다른 스크립트에서 호출된
이 다이어그램은 단순화된 버전이며 모든 극단적인 사례를 다루는 것은 아닙니다. 자세한 내용은 문서화된 코드를 확인하십시오.
모양 회전 부드럽게 하기
Fusion BR은 어떤 조건에서도 원활한 모양 회전을 위한 맞춤형 솔루션과 함께 제공됩니다.
다음 로그는 일반적인 하드웨어(125Hz 속도로 폴링 된 마우스)와 높은 렌더링/출력 새로 고침 속도(200+FPS)를 사용할 때 원시 입력에 대한 앨리어싱 문제를 보여줍니다. 렌더링 된 출력은 CPU/GPU가 아무리 좋아도 항상 떨립니다.
이 문제를 해결하기 위해 입력 값이 타임스탬프와 함께 기록된 다음 현재 프레임의 값이 정의된 시간 범위의 평균으로 계산됩니다(Fusion BR은 기본적으로 25ms 윈도우를 사용합니다). 이로 인해 아주 부드럽게 인식될 수 있지만(특히 높은 재생 속도의 모니터에서 두드러짐) 입력 지연은 매우 작습니다. 샘플링 속도가 더 높은 하드웨어를 사용하면 보정 윈도우를 최소로 줄일 수 있습니다.
다음 그래프는 시간별로 원시 마우스 델타(하단 선)과 캐릭터 모양 회전(상단 선)을 표시합니다.
다음 그래프는 보정 마우스 델타(하단 선) 및 캐릭터 모양 회전(상단 선)을 시간 단위로 보여줍니다.
이것은 또한 불규칙한 손/마우스 움직임(책상 표면, 근육)으로 인한 샘플링 오류(책상 표면)와 마이크로 지터를 줄이는 데 도움이 됩니다.
캐릭터 애니메이션
이 프로젝트에는 플레이 가능 API에 기반한 맞춤형 애니메이션 컨트롤러 구현이 있습니다. 틱 단위로 정확한 애니메이션 평가 및 다이나믹 성능 스케일링을 지원합니다.
다음 다이어그램은 Mecanim
과 유사한 아키텍처를 보여줍니다.
에이전트의 개체 계층에 설정된 애니메이션 계층 및 상태는 다음과 같습니다:
애니메이션 레이어:
Locomotion
: 이동을 위한 기본 바디 레이어FullBody
: 전신 동작을 위한 레이어를 로코모션과 함께 오버라이드LowerBody
: 캐릭터 하반신 회전을 위해 레이어 오버라이드UpperBody
: 일반적으로 로코모션과 블렌딩된 상반신 동작을 위한 레이어 오버라이드Shoot
: 일반적으로 로코모션과 블렌딩된 손동작을 위한 레이어 오버라이드Look
: 위쪽과 아래쪽을 보기 위한 추가 상체 레이어
애니메이션 컨트롤러의 복잡성에 따라 200명의 플레이어를 평가하면 서버의 병목 현상이 쉽게 발생할 수 있습니다. 더 나은 성능을 위해 서버는 연결된 플레이어 수를 기준으로 n번째 프레임마다 인터레이스 된 PlayableGraph
평가를 허용합니다. 레이어 또는 상태 가중치와 같은 모든 중요한 속성은 여전히 모든 프레임에서 계산됩니다. 다음 표에서는 인터페이스 평가에 대한 규칙을 보여 줍니다.
연결된 플레이어 | PlayableGraph 평가 |
---|---|
> 150 | 매 4번째 프레임마다 |
> 100 | 매 3번째 프레임마다 |
> 50 | 매 2번째 프레임마다 |
이외 | 매 프레임마다 |
캐릭터 컨트롤러
본 샘플은 이동 시 Fusion KCC를 사용합니다. 성능, 게임 플레이 상호 작용 및 사용자 지정에 중점을 둔 일반적인 저수준 캐릭터 컨트롤러입니다.
Fusion KCC의 특징은 다음과 같습니다.
- 위치 및 룩 회전(피치 + 요) 제어
- 캡슐 콜라이더로 정의된 모양
- 로컬 플레이어의 렌더 이동 예측
- 동적(물리학적) 및 운동학적(비현실적) 속도 기반의 움직임 결합
- 외부 힘 - 폭발, 플랫폼 이동 등…
- 가속 이동 및 마찰
- 사용자 지정을 위한 고급 KCC 프로세서 파이프라인(속도 및 방향 오버라이드, 블로킹)
- 기본 속성(반경, 높이, 무게 등)에 대한 즉시 사용 가능한 네트워크 동기화, 기타 속성(선택 사항)의 동기화
- 사용자 지정 충돌기 필터링 및 무시 목록
- CCD(연속 충돌 감지)
- 충돌 콜백
- 접지 스냅 및 계단 높이 지원
- 로컬 모드 지원(네트워크 트래픽 없음).
- 네트워크 및 성능 최적화
- 플랫폼에 독립적이고 모바일 친화적
- 프레임별 디버그에 대한 기본 지원 - 에디터 그리기 및 로깅
플레이어의 체력이 일정 한계 이하로 떨어졌을 때, 플레이어는 현재 전투 중이 아닐 때 자동 치유가 작동하여 플레이어의 체력을 보충하기 시작합니다.
제트팩
제트팩은 연료를 배출하는 동안 수평으로 빠르게 비행하고 탐색할 수 있는 기능을 제공합니다. 연료는 아이템 상자에 들어 있는 연료통을 주워서 보충할 수 있습니다.
제트팩의 상태는 연료 소비량, 프로펠러, 소리 및 켬/끄기 상태를 처리하는 Jetpack
스크립트에 의해 처리됩니다. 공중에서의 실제 움직임은 JetpackKCCProcessor
에 의해 처리됩니다. 이 스크립트는 KCC 속도를 재정의하고 기본 동작을 무시합니다.
관람자 모드
플레이어들이 탈락하거나 매치에 너무 늦게 합류하면 관람자 모드로 들어갑니다. 관람자 모드에서는 플레이어가 다른 플레이어의 관점에서 경기를 관찰할 수 있습니다. 코드에서, 이것은 실제로 매우 간단하게 처리됩니다. 카메라와 UI는 SceneContext
에서 할당된 ObservedAgent
를 기반으로 동작합니다. ObservedAgent
는 로컬 플레이어 에이전트 또는 예상 플레이어 에이전트일 수 있습니다.