인프런 커뮤니티 질문&답변

kmg013329님의 프로필 이미지

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)

PushAfter 사용 질문

24.05.29 14:35 작성

·

101

0

JonTimer 강의에서 학습한 PushAfter에 관한 질문

 

Arrow 실습 코드에 적용해 보았는데 제가 이해한 것이 맞는 지 궁금하여 질문 드립니다.

 

GameRoom 클래스 코드 일부

// 누군가가 주기적으로 호출해줘야 한다
public void Update()
{
    foreach (Monster monster in _monsters.Values)
    {
        monster.Update();
    }

    //foreach (Projectile projectile in _projectiles.Values)
    //{
    //    projectile.Update();
    //}

    Flush();
}
Arrow arrow = ObjectManager.Instance.Add<Arrow>();
if (arrow == null)
    return;

arrow.Owner = player;
arrow.Data = skillData;
arrow.PosInfo.State = CreatureState.Moving;
arrow.PosInfo.MoveDir = player.PosInfo.MoveDir;
arrow.PosInfo.PosX = player.PosInfo.PosX;
arrow.PosInfo.PosY = player.PosInfo.PosY;
arrow.Speed = skillData.projectile.speed;
Push(EnterGame, arrow);

arrow.Test();

Arrow 클래스 코드 일부

bool check;
public void Test()
{
        // TODO : Room is null
	while (!check)
	{
		Update();
	}
}

//long _nextMoveTick = 0;

public override void Update()
{
	if (Data == null || Data.projectile == null || Owner == null || Room == null)
	{
                return;
        }
	check = true;

	//if (_nextMoveTick >= Environment.TickCount64)
	//	return;

	//long tick = (long)(1000 / Data.projectile.speed);
	//_nextMoveTick = Environment.TickCount64 + tick;

	Vector2Int destPos = GetFrontCellPos();
	if (Room.Map.CanGo(destPos))
	{
		CellPos = destPos;

		S_Move movePacket = new S_Move();
		movePacket.ObjectId = Id;
		movePacket.PosInfo = PosInfo;
		Room.Broadcast(movePacket);

		Console.WriteLine("Move Arrow");
	}
	else
	{
		GameObject target = Room.Map.Find(destPos);
		if (target != null)
		{
			target.OnDamaged(this, Data.damage + Owner.Stat.Attack);
		}

		// 소멸
		Room.Push(Room.LeaveGame, Id);
	}

	Room.PushAfter((int)(1000 / Data.projectile.speed), Update); 
}

GameRoom 클래스에서 Update를 계속 실행하는 것이 아니라 Arrow를 EnterGame한 후 Test를 한 번만 실행시키면 되는 거 맞을까요?

답변 1

0

인프런 AI 인턴님의 프로필 이미지

2024. 05. 31. 14:41

안녕하세요, 인프런 AI 인턴입니다.

kmg013329님의 질문을 읽어보니, GameRoom 클래스의 Update 메소드와 Arrow 클래스의 구현에 대한 이해를 확인하시고자 하는 것 같아요.

GameRoom 클래스의 Update 메소드는 게임 내에서 시간이 흐름에 따라 주기적으로 각 객체들의 상태를 갱신하기 위해 필요합니다. 여기서는 모든 Monster 객체들의 Update 메소드를 순회하며 호출하고 결과적으로 Flush 메소드까지 호출하게 됩니다. 주석 처리된 Projectile 객체 역시 같은 맥락에서 처리될 수 있습니다.

Arrow 클래스 관련 코드에서 보면, Arrow 인스턴스 생성 후, 기본 설정을 하고 Push(EnterGame, arrow)를 호출하여 게임 세계에 화살 객체를 등록합니다. 이때 Test 메소드 호출 시 즉각적인 Update 호출을 통해 Arrow의 상태를 갱신하는 시도가 보입니다.

그러나, 질문 주신 부분에 따르면, Arrow 객체의 Update 메소드를 단 한 번만 호출하려는 의도로 보이나, 실제로는 Arrow 객체의 Update 메소드는 Room.PushAfter를 사용하여 주기적으로 자신을 다시 호출하도록 예정되어 있습니다. 이는 Arrow 객체가 일정 시간 간격으로 지속적으로 상태를 업데이트하며, 예를 들어 움직임이나 다른 객체에 대한 상호작용 등을 처리할 수 있게 합니다.

따라서, GameRoom 클래스에서 Update를 계속 실행하되, Arrow 객체의 경우 EnterGameTest를 한 번 실행시키는 것이 아니라, Arrow 객체 스스로가 설정한 시간 간격에 따라 Update 메소드가 반복적으로 호출되도록 설계된 것이 맞습니다. 이를 통해 Arrow 객체는 독립적으로 자신의 로직을 주기적으로 실행할 수 있으며, 이는 게임 프로그래밍에서 자주 사용되는 패턴 중 하나입니다.

즉, GameRoomUpdate는 게임 상태의 전체적인 갱신을 담당하고, 개별 객체(예: Arrow)는 자체적인 Update 메서드를 통해 개별 로직을 주기적으로 처리하는 구조로 이해하시면 됩니다.