채널톡 아이콘

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

literate_t님의 프로필 이미지

작성한 질문수 64

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part9: MMO 컨텐츠 구현 (DB연동 + 대형 구조 + 라이브 준비)

DummyClient #2

화살 처리 관련 질문이 있습니다!

작성

·

48

0

안녕하세요.

제가 겪은 오류 관련해서 이미 예전 질문 글이 있었고 그와 관련해서 잡 캔슬이 얼마나 중요한지 알게 되면서 이것저것 정리하면서 생각해보다 보니까 문득 화살을 파괴할 때느 잡 캔슬을 하지 않았던 게 생각 나더군요.

사용자가 상호작용을 할 때만 발사되는 거라서 몬스터나 비전큐브랑 같지 않다는 건 아는데요. 문득 이런 의문이 들었습니다. Arrow.Update()가 다음과 같습니다~

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

    int tick = (int)(1000 / Data.projectile.speed);
    Room.PushDelayed(tick, Update);

    Vector2Int destination = GetFrontCellPosition();
    if (Room.Map.ApplyMove(this, destination, applyCollision: false))
    {
        GameRoom room = Room;
        S_Move movePacket = new();
        movePacket.ObjectId = Id;
        movePacket.PosInfo = PositionInfo;
        room.Broadcast(CellPos, movePacket);
    }
    else
    {
        GameObject target = Room.Map.Find(destination);
        if (target != null)
        {
            // 피격
            target.OnDamaged(this, Data.damage + Owner.TotalAttack);
        }

        // destroy
        Room.Push(Room.LeaveGame, Id);
    }
}

제가 상상해낸 버그의 해결 방법은 이미 알고 있습니다. 다만 그런 상황이 가능할까 궁금하더라고요.

화살을 파괴하는 일감인 (Room.LeaveGame, Id)가 잡큐에서 실행되기 전에 Update() 함수 초기에 예약해둔 일감 Room.PushDelayed(tick, Update)이 잡큐에서 먼저 실행되면 한 화살이 아직 파괴되기 전이므로 대미지가 두 번 이상 발생할 수 있는 상황이 올까? 싶었습니다. 저희가 GameLogic에서 일감들을 flush 하고 Job 클래스를 보면 JobTimer를 먼저 flush하니까요. 타이밍 이슈로 충분히 그럴 수 같은데? 생각이 들더라구요. 아직 재현된 이슈는 아닙니다. 가끔씩 화살이 몬스터를 뚫고 지나가기도 하는데 이런 타이밍 이슈와 관련이 있을까 하는 생각도 같이 들었습니다. 제 부족한 경험으로는 명쾌한 해답을 찾기가 어렵네요ㅠ

답변 1

0

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

안녕하세요, 인프런 AI 인턴입니다. literate_t님이 질문하신 내용은 실시간 시스템에서 발생할 수 있는 타이밍 문제와 관련이 있습니다. 화살이 몬스터를 관통하는 현상은 주로 업데이트 루프와 관련된 비동기적 처리에서 발생할 수 있는 상황입니다.

화살 파괴와 타이밍 이슈에 대해:
1. 일감 순서: 잡큐에서 Room.LeaveGame이라는 화살 제거 작업이 실행되기 전에 Room.PushDelayed(tick, Update)가 먼저 실행되면, 이전 프레임에서 예약된 움직임이 아직 처리되지 않으면서 충돌 처리가 이뤄질 가능성이 있습니다. 이런 경우 대미지가 두 번 발생할 수도 있죠.

  1. 타이밍 이슈: 특히 서버와 클라이언트 간의 상태 동기화가 늦어지면서 이러한 문제가 발생할 수 있습니다. Update에서 다음 스케줄을 예약하는 방식이 곧 문제가 될 수 있습니다. 연속된 움직임이 처리되기 전에 객체가 파괴되지 않도록 주의해야 합니다.

  2. 버그 해결 접근법:

    • 기간 설정: Room.PushDelayedRoom.Push 간의 스케줄링을 적절히 설정하여 Update가 중복 실행되는 것을 방지해야 합니다.
    • 충돌 검사 및 로직 검토: if 조건에 따라 제대로 충돌 검사 및 제거 로직이 작동하는지 확인이 필요합니다.

유사한 질문이 포함된 기존 게시물을 참고하시길 권장합니다:

위 링크들을 통해 실무에서의 비슷한 문제와 그 해결 방법을 참고하시기 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.