강의

멘토링

로드맵

Inflearn brand logo image

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

백구님의 프로필 이미지
백구

작성한 질문수

절대강좌! 유니티 6 - TPS 게임으로 배우는 유니티 마스터클래스

Bullet, AimDot 코드 질문

해결된 질문

작성

·

92

1

  1. 오브젝트 풀링 - PoolManager 구축 32분 15초

5초 뒤에 사라지게 하는 invoke를 사용했는데, 총알 발사 후 물체에 맞고 사라진 후에 다시 발사되기까지 5초가 걸리지 않으면, 총알이 발사되자마자 사라지는 현상이 발생하는 것 같습니다. 이러한 현상을 해결하는 방법이 있을까요?

  1. 인터페이스 활용한 피격 데미지 구현 6분 56초

Update에서 실행되던 Aim Dot 색 바꾸는 코드를 Fire로 옮기면 Fire할 때만 색이 바뀌는데, 해당 부분만 다시 업데이트문으로 옮겨주면 될까요?

답변 2

1

이재현님의 프로필 이미지
이재현
지식공유자

안녕하세요. 백구님,

문의하신 글로만으로는 정확히 어디가 문제인지 파악하기는 어렵다는 점 양해 부탁드립니다.

  1. 정상적인 경우라면 5초가 지나지 않아도 발사를 하게되면 새로운 객체가 풀에 생성됩니다. 하지만 발사하자마자 사라진다면 총구 앞에 다른 충돌체가 있어서 바로 소멸될 수 도 있습니다.

  2. 지속적으로 Monster에 타겟팅 되었을 때 바로 에임 마크의 색을 바꾸시려면 색상 변경하는 부분만 Update로 이동하시고 localScale 변경하시는 부분은 Fire 함수 안에 두셔도 되세요.

1번 문제가 해결되지 않으시면 콘솔뷰에 오류가 있는지 먼저확인해주시고 다시 한번 질문해주세요.

백구님의 프로필 이미지
백구
질문자

콘솔뷰에 오류는 없는 것 같습니다.

공중에 날아간 총알을 처리하기 위해 5초가 지나면 invoke로 release를 부르고, 이미 물체에 부딪혀 사라졌는지 확인하기 위해서 release 안에 activeself를 확인해 주는 것으로 이해했는데,

물체에 충돌하고 invoke로 release가 호출되기 전에 다시 해당 총알을 pool에서 가져오면, 처음 총알 호출에서 5초 기다린 후 호출된 release에서 activeself를 true로 체크해 총알을 release할 수 있다고 생각했는데 아닌가요?

가까운 장애물에 총알을 쏘다가 바로 먼 곳으로 연사하면 몇몇 총알이 중간에 사라지는 현상이 있어서요..

이재현님의 프로필 이미지
이재현
지식공유자

정확히 이해하셨습니다. 그러나 물체(드럼통)에 충돌하면 바로 Release를 하기 때문에 Pool에 바로 들어가야 합니다. RemoveBullet의 OnCollisionEnter에서 바로 릴리즈하는 코드가 있는지 확인해주세요. (12번라인)

종합하자면, Invoke로 5초후에 Release 하는 경우는 총알이 충돌 없이 멀리 날아간 경우에만 일정시간이 지나면 Release하기 위함입니다. 드럼통이나 몬스터에 맞았을 경우에는 바로 릴리즈해서 사용가능한 상태로 만드는 것입니다.

혹시라도 계속해서 이상한 현상이 발생하신다면 소스코드를 압축해서 구글드라이브 같은 클라우드에 올려주시고 URL을 보내주시면 소스코드를 검토해 드리겠습니다. ~

백구님의 프로필 이미지
백구
질문자

oncollisionenter에서 release하면 5초 뒤의 invoke에서의 release는 실행되지 않나요?

이재현님의 프로필 이미지
이재현
지식공유자

강의에서는 RemoveBullet.cs 와 MonsterController.cs 의 OnCollisionEnter 에서는 다음과 같이 Release()를 호출했기에 충돌후 즉시 릴리즈 되어 Pool로 되돌아 갑니다. 여기서 Invoke 함수를 호출하시면 않되세요~

coll.gameObject.GetComponent<Bullet>().Release();

그리고 Invoke 로 Release를 호출하는 부분은 Bullet.cs의 Shoot 메소드에서만 다음과 같이 처리하고 있습니다.

Invoke(name(Release), 5.0f)

위 3개의 코드를 다시 한번 확인해주세요. 아마도 RemoveBullet 또는 MonsterController에 Invoke로 호출하는 부분이 또 들어가 있으신지도 확인하셨으면 합니다.

정상적으로 코드 작성하셨다면, 다른 원인일 수 도 있습니다. 그때는 Bullet.cs 의 Shoot() 메소드에서 Invoke 메소드를 주석처리 하시고 테스트해보셔서 이상이 있는지를 확인해 보셔야 합니다. 테스트 후 않되시면 다시 한번 질문글 남겨주세요.

 

백구님의 프로필 이미지
백구
질문자

invoke를 주석처리하면 해당 문제가 발생하지 않습니다.

 

충돌 후 release되어 pool로 돌아가는 거는 잘 동작하는데, 돌아간 거를 다시 불러왔을 때, pool로 돌려보내기 전에 기다렸던 invoke가 남아있지 않는 건가요?

pool에 있던 bullet을 shoot해줄 때 기존의 invoke를 cancel해주지 않아도 되는 것인지 궁금합니다.

이재현님의 프로필 이미지
이재현
지식공유자

그곳에서 다른 문제가 있었나보네요.

추가 질문에 대한 답변입니다.

Bullet.cs에서 Invoke를 호출한 이후에 5초가 지나기 전에 다른 물체와 충돌을 하면 바로 Release를 해서 Pool로 되돌아 가는데, 이때 해당 Bullet 게임오브젝트를 SetActive(false)를 통해서 자체를 비활성화 시킵니다. 이때 실행중이던 Invoke 함수는 자동으로 취소가 됩니다. 따라서 Invoke가 호출한 프로세스는 남아있지 않고 호출되지도 않습니다.

 

 

백구님의 프로필 이미지
백구
질문자

궁금한 부분이 해결되었습니다.

답변 감사합니다.

0

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

질문하신 내용은 두 가지 문제로 나눌 수 있을 것 같습니다:

1. 오브젝트 풀링과 Invoke 관련 문제

오브젝트 풀링을 사용하면서 ‘Invoke’ 함수로 일정 시간 후에 오브젝트를 비활성화하는 방법을 사용하고 계신데, 이 경우 발생할 수 있는 문제 중 하나는 오브젝트가 비활성화되기 전에 다시 활성화되면 예기치 않게 동작할 수 있다는 것입니다. 이를 해결하기 위해 다음과 같은 방법을 고려해볼 수 있습니다.

  • 마지막 활성화 시간 추적: 각 오브젝트가 풀에서 활성화될 때 마지막 활성화 시간을 추적하여, Invoke를 사용하여 비활성화하기 전에 이미 재활용되었는지 확인합니다.
  • CoRoutine 사용: 대신 코루틴(Coroutine)을 사용하여 시간 초과 후 오브젝트를 비활성화하는 것이 더 유연할 수 있습니다. 코루틴에서는 활성화 상태를 직접 확인할 수 있기 때문에 재활용될 경우 코루틴을 멈추거나 시간을 조절할 수 있습니다.

관련 유사 질문의 해결책을 참고해 보세요:
- Unity PoolManager - 오브젝트 풀 문제 해결방법

2. AimDot 색상 변경

Aim Dot의 색상 변경을 Update에서 Fire로 옮긴 후, 문제없이 업데이트할 필요가 있다는 질문입니다. 이는 구현 의도에 따라 다를 수 있지만, 보통은 Aim Dot의 시각적 변화를 실시간으로 반영하는 것이 좋습니다. Update 메서드를 사용하여 주기적으로 Aim Dot의 색상을 체크하고 업데이트하는 방식을 추천합니다.

이와 관련된 유사한 질문과 해결책을 여기서 확인하실 수 있습니다:
- AimDot 구현 시 Update 사용 사례

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드립니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

백구님의 프로필 이미지
백구

작성한 질문수

질문하기