✅ 오늘의 백로그
1. 오브젝트 풀 멀티 연동
1. 오브젝트풀 연동
오늘은 오브젝트풀을 연동시켜야 하는데
찾아보니까 Fusion에서 오브젝트풀 자체를 제공하고 있는 것을 확인하였다.
Fusion 2 - Fusion 객체 폴링 | Photon Engine
Fusion 객체 폴링 샘플은 NetworkRunner가 생성하는 모든 NetworkObject에 대해 새 프리팹을 인스턴스화하지 않고도 객체를 풀링 하는 방법을 보여줍니다. 이를 위해 맞춤형 INetworkObjectProvider 구현을 사용
doc.photonengine.com
내가 이 문서를 보고 이해한 내용은..
「
어제 스폰매니저를 구현했을 때 처럼
네트워크가 접목되면 instantiate, destroy를 사용할 수 없기때문에
INetworkObjectProvider 라는 인터페이스를 활용해서
오브젝트 활성화는 AcquirePrefabInstance 함수를,
오브젝트 비활성화 및 리턴은 ReleaseInstance 함수를 사용해주어야 한다.
이렇게 오브젝트풀을 재활용할 수 있도록 만들었다면
Network Runner가 이 사실을 알아야 하므로
Network Runner가 StartGame() 함수를 호출할 때 INetworkObjectProvider 해당 인터페이스를 인자로 전달해주어야 한다.
」
이렇게 인데.. 맞는지 한번 트라이해보좌!
1. Register 함수
기존에 프레임 드랍 방지를 위해서
Get하기 전에 미리 큐를 생성해놓기 위해 만들어둔 함수이다.
이걸 멀티플레이로 연동하려면
- 프리팹에 Network Object 컴포넌트가 붙어있을 것
- 컴포넌트가 붙어있다면 NetworkId를 기준으로 추가하기

해보다가 잘 안돼서 다시 확인해보니
저런 주석문이 있었다.
Fusion 2 - NetworkObjectProvider | Photon Engine
Spawned가 호출되면, StartGame()의 StartArgs에서 전달된 INetworkObjectProvider가 연결될 GameObject를 가져오거나 생성하는 작업을 수행합니다. INetworkObjectProvider의 기본 구현체는 NetworkObjec
doc.photonengine.com
이 클래스는..
Spawned가 호출되면, StartGame()의 StartArgs에서 전달된 INetworkObjectProvider가 연결될 GameObject를 가져오거나 생성하는 작업을 수행합니다.
라고 설명되어있다.
아 그러니까 INetworkObjectProvider로 인터페이스를 만들면
프로바이더가 중간에 껴서 동작되는 것 같다..
결론은 NetworkObjectProvider 를 구현해주어야 오브젝트풀이 작동된다는 것 같음 ㅠ

그래서 우선 INetworkRunnerCallbacks을 상속받은 스크립트에서
StartGame() 메서드 안에 프로바이더를 장착해주었고
/// <summary>
/// Fusion 2용 프로바이더
/// 기본 프로바이더를 상속하고 풀의 Get/Return 메서드 연결
/// </summary>
public sealed class FusionPoolProvider : NetworkObjectProviderDefault
{
readonly ObjectPoolManager _pool;
public FusionPoolProvider(ObjectPoolManager pool)
{
_pool = pool;
}
// Fusion이 네트워크 스폰을 요청할 때 호출됨
protected override NetworkObject InstantiatePrefab(NetworkRunner runner, NetworkObject prefab)
{
// 풀에서 꺼내기
var pooled = _pool.Get(prefab.gameObject);
// 위치/회전/활성화는 Runner.Spawn 경로에서 처리할것
return pooled.GetComponent<NetworkObject>();
}
// Fusion이 네트워크 디스폰을 요청할 때 호출
protected override void DestroyPrefabInstance(NetworkRunner runner, NetworkPrefabId prefabId, NetworkObject instance)
{
if (instance)
_pool.Return(instance.gameObject);
}
}
프로바이더 클래스에서
오브젝트풀을 받아와 프리팹이 생성/삭제 되도록 연결해주었다.
그리고 천우인은 비처럼 쏟아지는 녀석이기 때문에
동기화 작업을 해주지 않았다.
워낙 빠르게 흐르기도 하고 양도 많아서 플레이어끼리 비교할 대상이 안될 것 같고
플레이어끼리 같을 필요도 없기 때문에!!
플레이어끼리 위치가 같아야하는 흑기 이상현상을 토대로 테스트해보려고 한다.

그래서 흑기 스크립트에서
기존에 검은 구체를 로컬로 생성하는 부분을
네트워크로 생성하도록 변경해주었다.

잘 되겠지를 희망에 품으며 게임을 시작해보았으나ㅋ
역시나! 에러 투성이다.
에러를 해석해보니
AcquirePrefabInstance가 ObjectPoolManager.Get(prefab) 안에서 null 값이라 프리팹 스폰이 실패된 것 같다.
Get(prefab) 안에서 null이 일어나려면..
Register를 호출해서 등록이 안됐다는 뜻인데..
코루틴으로 딜레이를 줘도 계속 똑같은 반응이다.
그래서 어느 프리팹이 그렇게 할당이 안되는가 로그를 찍어봤는데

여기가 비어있었음 ^^... 하아 ㅠㅠ ㅋㅋㅋㅋㅋ 진짜 장난하노ㅑ!!


구체를 연결해주고 실행해보니
구체 위치는 똑같아 보이긴 하는데...
이젠 크기가 다른 문제 발생 ㅋㅋㅋㅋ아아악!! 아아악!!! 🚨 위잉 위잉 힘들면 울리는 사이렌 등장 위이이잉!!!!!!!!!!!!!!

다행히 이건 손쉽게 해결 가능했다
Network Transform에서 크게 동기화를 해주는 게 있었따 ㅠㅠ

히히 똑같은 위치, 똑같은 크기로 동기화 완료!!

그러나 무시무시한 문제점이 하나 있었으니..
아까 에러 잡겠다고 로그를 엄청 남겨놔서 발견하게된 문제점인데 ㅠ
풀매니저가 Network Object 컴포넌트를 갖고 있는 모든 애들에게 다 접근하고있다..
get함수로 갖고오는 애는 DarkAura 뿐인데 왜 Player랑 Dark Sphere을 갖고오는 걸까..?

위에서 연결한 프로바이더 때문이었다..!
이 작업을 하지 않아도 멀티 연동이 되기 때문에 이 로직을 삭제해주었더니 해결되었다.