Player Input 컴포넌트가 씬에 2개 있으면 Multiplayer Play Mode의 추가 인스턴스에서 Player Input 입력 안 먹는 문제
public class ManualPlayerSpawner : NetworkBehaviour
{
bool isPlayerSpawned = false;
[SerializeField] private NetworkObject playerPrefab;
[ServerRpc(RequireOwnership = false)]
public void SpawnPlayer()
{
print("SpawnPlayer()");
if (isPlayerSpawned) { print("Player already spawned"); return; }
foreach (NetworkConnection client in ServerManager.Clients.Values)
{
if (!client.IsAuthenticated) continue;
NetworkObject obj = Instantiate(playerPrefab);
Spawn(obj, client, gameObject.scene);
isPlayerSpawned = true;
}
}
}
(작동 제대로 안 해줌)
(Cannot complete action because client is not active 문구만 반환)
수동 Spawner
만들어보려고 했으나, 어려움이 많았음. 유튜브에서 멀티 게임 튜토리얼 먼저 진행.
https://www.youtube.com/watch?v=Fj2DeO31oF4
(~30분)
What is Multiplayer game?
: 각자 컴퓨터에서 로컬 게임이 돌아가고, 네트워킹으로 서로의 변화를 mimicking해주는 것.
서로의 컴퓨터에 있는 오브젝트들은 네트워크 상의 id만 같은 것이지, 절대 같은게 아님.
ParrelSync
Network가 준비되기 전에 Network와 관련된 뭔가 하면 안된다.
Awake() 막 쓰면 안된다는 거.
멀티 스레드 서버
이벤트 : 잠자는 스레드를 깨우는 도구
Event event1;
void Thread1() { event1.Wait(); } // 이벤트 신호를 기다린다
void Thread2() { event1.SetEvent(); } // 이벤트에 신호한다
자동 이벤트 : 스레드 깨운 뒤에 상태 값 0
수동 이벤트 : 깨워도 1로 남음
Semaphore sema1;
void Main() { sema1 = Semaphore(2); }
void Thread1()
{
sema1.Wait();
sema1.Release();
}
void Thread2()
{
sema1.Wait();
sema1.Release();
}
void Thread3()
{
sema1.Wait();
sema1.Release();
}
atmoic operation : 뮤텍스나 임계 영역 잠금 없이도 여러 스레드가 안전하게 접근 가능
멀티스레드 버그는 발생 빈도도 랜덤이고, 버그 원인과 발생지가 다를 때 많음.
void func1()
{
// lock(a_mutex) 누락
print(a);
}
void func2()
{
lock(a_mutex)
a = a+10;
}
읽기에 락 안 걸면 가끔 비정상적 값 출력
프로그램 규모 커지면 잠금 순서 지키기 어려움.
최선은 규칙을 최대한 적게 유지하는 것.
잠금 범위 너무 넓으면
잠금 범위 너무 좁으면
로그 출력이나 콘솔 함수 (printf나 cout) 는 디바이스 타임 발생
디버깅 목적으로 콘솔 출력 뿌리는데 메모리에 잠금하면 병목 생김
void func()
{
lock(list_mutex);
A* a = list.GetFirst();
unlock(list_mutex);
a->x++; // 문제가 되는 부분
}
잠금 전염성 : 잠금으로 보호된 리소스에서 얻은 값이나 포인터가 로컬 변수에 있어도 잠금 유지해야 함
합성 가능성의 부족 (lack of composability) : 여러 모듈이나 로직을 쉽게 조립할 수 없는 것.
사용자 A 변수 차감 → 사용자 B 변수 증가인 프로그램 있을 때,
사용자 A도 B도 뮤텍스로 잠가놨어도
송금 프로그램이 둘 이상 스레드 실행할 때, 오작동 가능. (A만 깎고 B 증가 못한다던지)
잠금 중인 뮤텍스 삭제하는 실수 종종 한다.
파괴자 함수에 "이미 잠금돼있으면 오류 발생" 넣으면 감지 가능