public class StageDataContainer : MonoBehaviour
{
[SerializeField] private Transform leftPlayerBeginTransform;
public Transform LeftPlayerBeginTransform => leftPlayerBeginTransform;
[SerializeField] private Transform rightPlayerBeginTransform;
public Transform RightPlayerBeginTransform => rightPlayerBeginTransform;
[Space(5)]
[SerializeField] private GameObject staticObstacle;
public GameObject StaticObstacle => staticObstacle;
[Space(5)]
[SerializeField] private Transform triggerTileRoot;
public List<TriggerTileViewBase> TriggerTiles=> triggerTileRoot.GetComponentsInChildren<TriggerTileViewBase>().ToList();
[Space(5)]
[SerializeField] private Transform dynamicObstacleRoot;
public List<DynamicObstacleBase> DynamicObstacles => dynamicObstacleRoot.GetComponentsInChildren<DynamicObstacleBase>().ToList();
}
이전 게시물대로 타일맵을 프리팹화, 내부 플레이어 시작 위치랑 각종 데이터 보유 타일들을 컨테이너에 넣었습니다.


좌/우 플레이어 시작 포지션에는 기즈모 스크립트를 달아서 씬에서도 확인 가능하게 만들었는데 프리팹 상태라 안 보이네요.
public class LocalManager : MonoBehaviour
{
public static LocalManager instance;
private StageManager stageManager;
public StageManager StageManager => stageManager;
private void Awake()
{
instance = this;
InitializeManagers();
StageManager.CreateAsync().Forget();
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.F1))
StageManager.ReStartAsync().Forget();
}
private void InitializeManagers()
{
stageManager = new StageManager();
}
}
public async UniTask CreateAsync()
//StageManager 중략
{
var stageDataContainer = await GlobalManager.instance.ResourceManager.CreateAssetAsync<StageDataContainer>("TestStage");
SetupPlayers(stageDataContainer);
SetupTriggers(stageDataContainer);
SetupDynamicObstacles(stageDataContainer);
}
private void SetupPlayers(StageDataContainer stageData)
{
var leftPosition = stageData.LeftPlayerBeginTransform.position;
var rightPosition = stageData.RightPlayerBeginTransform.position;
playerSetupService.SetupAsync(new PlayerSetupService.SetupData(leftPosition,rightPosition)).Forget();
}
private void SetupTriggers(StageDataContainer stageData)
{
triggerTileSetupService.SetupAsync(new TriggerTileSetupService.SetupData(stageData.TriggerTiles)).Forget();
}
private void SetupDynamicObstacles(StageDataContainer stageData)
{
foreach (var dynamicObstalce in stageData.DynamicObstacles)
{
}
}
싱글톤 매니저를 기존 전역 씬 싱글톤인 GameManager 명칭을 GlobalManager,
로컬 씬의 싱글톤 매니저인 LocalManager로 구분했습니다.
LocalManager는 씬 시작과 동시에 StageManager를 통해 스테이지를 생성합니다.
ResourceManager에서 위 스크린샷에 나온 TestStage 오브젝트를 생성하는 동시에 컴포넌트로 부착된 StageDataContainer를 가져오고
해당 클래스에서 각 플레이어 시작 위치, 트리거 및 동적 오브젝트 스크립트들을 셋업시킵니다.
그리고 PlayerSetupService.SetupAsync에 인자가 추가되었습니다.
public interface IStageObjectSetupService<T>
{
public UniTask<List<T>> SetupAsync(object data);
public void Release();
}
public class PlayerSetupService : IStageObjectSetupService<IPlayerPresenter>
{
public class SetupData
{
public readonly Vector3 leftPosition;
public readonly Vector3 rightPosition;
public SetupData(Vector3 leftPosition, Vector3 rightPosition)
{
this.leftPosition = leftPosition;
this.rightPosition = rightPosition;
}
}
public async UniTask<List<IPlayerPresenter>> SetupAsync(object data)
{
var setupData = data as SetupData;
leftPlayer = await CreateLeftPlayer(setupData.leftPosition);
rightPlayer = await CreateRighPlayer(setupData.rightPosition);
return new List<IPlayerPresenter>() { leftPlayer, rightPlayer };
}
//중략
}
이전에 배운 기법인데 아무래도 가변적으로 인자 종류가 바뀌는 경우가 생길 것 같은 경우 인자를 object로 두고
상속받은 클래스 내부에 간단한 데이터 전달용 모델 클래스를 만든 뒤 박싱 언박싱을 거쳐 인자로 전달해주는 방식입니다.
'무제_LR' 카테고리의 다른 글
| UI,,,,,구조,,,,및,,,,,매니저,,,인터페이스화,,,,,,,, (0) | 2025.11.10 |
|---|---|
| 스테이지 생성(트리거 타일) (0) | 2025.11.06 |
| 스테이지 데이터 구조 (0) | 2025.11.03 |
| Addressable 구조 구현, 테이블 적용 (0) | 2025.11.02 |
| 플레이어 MVP (0) | 2025.11.01 |