일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Security
- gameplay ability system
- dirty cow
- CTF
- 언리얼엔진
- MLFQ
- DP
- 운영체제
- Unreal Engine
- 언리얼 엔진
- Race condition
- DSP
- gas
- stride
- Replication
- unity
- photon fusion2
- 메카님
- 유니티
- animation
- Rr
- ability task
- boss monster
- ret2libc
- Multiplay
- 게임개발
- 게임 개발
- 유스케이스
- MAC
- Delegate
- Today
- Total
다양한 기록
[Fortress Craft] ** Request Authority When Master Client Connection Exit ** / Monster Spawner 본문
[Fortress Craft] ** Request Authority When Master Client Connection Exit ** / Monster Spawner
라구넹 2025. 2. 6. 02:52using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fusion;
namespace Agit.FortressCraft
{
public class MonsterSpawner : NetworkBehaviour
{
[SerializeField] NetworkObject Monster;
[SerializeField] float spawnDelay = 10.0f;
[SerializeField] int maxSpawnConut = 3;
public int SpawnCount { get; set; }
private TickTimer spawnTimer;
public override void Spawned()
{
SpawnCount = 0;
spawnTimer = TickTimer.CreateFromSeconds(Runner, 0.01f);
RPCCheckSpawnCount(SpawnCount);
}
// FixedUpdateNetwork는 Athority 있는 거에서만 돌아서 FixedUpdate에서 처리 필요
private void FixedUpdate()
{
if (Runner == null) return;
Debug.Log("Count: " + SpawnCount);
if (spawnTimer.Expired(Runner))
{
spawnTimer = TickTimer.CreateFromSeconds(Runner, spawnDelay);
if (!Runner.IsSharedModeMasterClient) return;
else Object.RequestStateAuthority();
if (SpawnCount >= maxSpawnConut) return;
MonsterController monster = SpawnMonster();
++SpawnCount;
RPCSetSpawnCount(SpawnCount);
monster.Spawner = this;
}
}
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
public void RPCCheckSpawnCount(int cnt)
{
if( SpawnCount != cnt )
{
RPCSetSpawnCount(SpawnCount);
}
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPCSetSpawnCount(int cnt)
{
SpawnCount = cnt;
}
private MonsterController SpawnMonster()
{
NetworkObject monster = Runner.Spawn(Monster, (Vector2)transform.position, Quaternion.identity);
return monster.GetComponent<MonsterController>();
}
}
}
해결해야 했던 상황1
마스터 클라이언트가 나가도 스포너와 몬스터가 정상 작동해야 함
(유닛 스포너는 클라이언트 나가면 사라지면 된다는 점에서 차이가 있음)
만들다가 알아낸 점은 FixedUpdateNetwork는 StateAuthority가 있는 경우에서만 작동함
그런데 Spawned에서는 없어도 작동함
그리고 마스터 클라이언트는 게임에서 나가는 순간 다른 유저로 변경됨
⇒ 어떤 유저에서도 FixedUpdate는 돌아가니까 FixedUpdate에서 마스터 클라이언트인지 체크하고 스크립트를 진행시키면 됨
해결해야 했던 상황2
스포너에서 소환할 수 있는 몬스터의 수를 제한하고 싶었음
그래서 소환된 상태의 몬스터의 수를 저장해둘 프로퍼티 SpawnCount를 만들었음
처음엔 Networked 프로퍼티였는데, 동기화가 제때 안됨
(값에 변화가 확실히 있는 경우에만 동기화를 해줌, 1더하고 바로 1빼서 동기화시키기 이런 거 안됨)
그래서 해결한 방법
FixedUpdate에서 마스터 클라이언트는 StateAuthority를 가지도록 요청하게 만드는 것
그러면 RPC의 타겟으로 활용이 가능해짐
새로 들어온 유저는 Spawned에서 RPCCheckSpawnCount를 호출
⇒ StateAuthority를 가지는 마스터 클라이언트만 해당 RPC를 받음
⇒ 해당 마스터 클라이언트가 다른 유저들에게 스폰 카운트를 뿌려줌
이 방법 이전엔 INetworkRunnerCallbacks 인터페이스를 사용하려고 했는데 안됨
왜냐 ⇒ OnPlayerJoin 콜백에서 RPC를 사용할 경우, 스포너가 Awake일 때 RPC를 시도하게 됨
그런데 Spawned에서 0으로 바꿔주는 코드가 있음 ⇒ 해봐야 다시 0으로 초기화됨
(Spawned는 테스트 결과 FixedUpdate가 불린 이후에나 호출됨)
'유니티 엔진 > Fortress Craft' 카테고리의 다른 글
[Fortress Craft] 성장의 가호 (증강 시스템) (0) | 2025.02.06 |
---|---|
[Fortress Craft] Sound, FxSound (0) | 2025.02.06 |
[Fortress Craft] Unit Upgrade (공격) (0) | 2025.02.06 |
[Fortress Craft] 맵 확장 (0) | 2025.02.06 |
[Fortress Craft] Normal Monster With Scriptable Object (0) | 2025.02.06 |