유저 분산 시스템 구현, 왜?
온라인 RPG는 오픈 직후 혹은 이벤트 시간대에 특정 위치(NPC, 퀘스트, 포털)에 유저가 한꺼번에 몰린다.
특히 자동 이동이 많은 모바일게임 환경에서는,
모든 유저가 같은 타겟 좌표로 이동하게 되어 캐릭터가 한 지점에 겹쳐지는 현상이 자주 발생한다.
퀘스트 수락 / 완료 시, 던전 입구 대기, 월드 이벤트 참여 ,NPC 대화 상호작용 등등..
이런 문제는 지저분하고, 완성도가 낮아져 보일 수 있다. 첫인상에 타격을 준다.
실제 내가 서비스했던 게임에서 적용한 방법과 조금 더 기능을 보완해서 샘플 프로젝트를 만들어봤다.
설계 고민
처음에는 단순히,
"같은 목저지로 이동하더라도, 유저가 도착 위치에서부터 살짝 다른 위치에 서면 어떨까?"
1차 시도 : 랜덤 오프셋 분산
NPC를 중심으로 여러 개의 도착위치를 원형으로
고르게 미리 만들어두고, 그 위치를 도착하게 하면 어떨까?

랜덤하게 뭐 대충 +-0.5cm 정도의 값을 더해서 이동하도록 만들었다.
하나로 겹쳐보이지는 않지만, 그래도 문제는 있었다.


=> 일관성부족, 시각적 불균형
2차 시도 : 위치 점유하기
각 유저가 도착하면 그 슬롯을 점유하고 있으면 어떨까?
이 접근법은
1. A유저가 먼저 도착하면 슬롯을 점유
2. B유저가 오면 남은 슬롯 중 가장 까운 위치를 선택
3. 슬롯이 다 차면 기존 슬롯과 모두 다른 슬롯으로 재 생성
예약 규칙
1. 플레이어가 출발하는 위치에서부터 가장 가까운 빈 슬롯을 찾는다.
2. 빈 슬롯이 배정되면 그 슬롯을 점유 상태로 표시
3. 빈 슬롯이 없으면 처음에 생성한 슬롯 리스트와 다른 슬롯리스트를 생성 후 슬롯 찾기
4. 목적지 도착 후 슬롯 해제

고르게 분포하는 플레이어들,
하지만! 그래도 문제점이 있다.
빈 슬롯만 찾다보니, NPC 반대편에 있는 슬롯을 행해 간다.
(NPC대화하러 간건데, NPC를 지나쳐 뒤로 지나쳐가는 모습은 이상하다.)
3차 시도 : OverlapSphereNonAlloc 사용하기
1. 2차시도 마찬가지로 먼저 점유가 안된 빈슬롯으로 향한다.
2. 점유가 안된 슬롯이, NPC 건넌편에 있다, 가장 가까운 슬롯으로 이동한다.
3. 목표 슬롯에 다른 플레이어와 OverlapSphereNonAlloc 검사를 진행하여, 그 플레이어와 겹치지 않게 살짝 이동한다.
private bool TryNudgeAround(Vector3 centerPos, out Vector3 nudged)
{
nudged = centerPos;
int hit = Physics.OverlapSphereNonAlloc(centerPos, nudgeProbeRadius, _overlapBuf, pawnMask, QueryTriggerInteraction.Ignore);
bool isFree = hit == 0;
if (isFree)
{
return true;
}
float step = 360f / Mathf.Max(4, nudgeMaxTries);
for (int i = 0; i < nudgeMaxTries; ++i)
{
float angle = step * i;
Vector3 dir = Quaternion.Euler(0f, angle, 0f) * Vector3.forward;
Vector3 cand = centerPos + dir * nudgeSearchRadius;
int h = Physics.OverlapSphereNonAlloc(cand, nudgeProbeRadius, _overlapBuf, pawnMask, QueryTriggerInteraction.Ignore);
bool isCandFree = h == 0;
if (isCandFree)
{
nudged = cand;
return true;
}
}
return false;
}
4. 점유하고 있는 슬롯에 플레이어가 점유하고 있는 플레이어가 3명 이상이면 새로운 슬롯 리스트를 생성한다.

5. 방해 오브젝트에도 레이어를 세팅하면 그 오브젝트를 피한 도착지점으로 보정한다.

마무리
아직은 개선점이 더 필요하다.
- 멀티플레이어에서 플레이어들이 동시에 출발 했을때, 점유슬롯 관련
- NPC 방향에 따른 위치 조정 등등..

'Unity > 기능구현' 카테고리의 다른 글
| 유니티) 좌우로 흐르는 글자(텍스트) (4) | 2021.12.22 |
|---|---|
| 유니티) 타이머를 만들기 (일시정지) (0) | 2020.12.30 |
| 유니티) 가변셀, 가변스크롤 LayoutRebuilder.ForceRebuildLayoutImmediate (0) | 2020.07.23 |
| 유니티) 포물선 궤적그리기,포탄 궤적 (1) | 2019.03.20 |
| 유니티) 미니맵 만들기 RenderTexture (0) | 2019.02.25 |





















































































































































