영상을 불러오지 못했습니다

UE4 BlueprintCallable 함수에 실행 핀이 보이지 않는 이유

890 단어
4 분
UE4 BlueprintCallable 함수에 실행 핀이 보이지 않는 이유

이 글은 2021년 12월의 Unreal Engine 4.27 동작을 기준으로 원문을 교정해 옮겼다. 당시 UHT 소스에서 실제로 실행 핀을 결정하던 조건을 기준으로 설명한다.

BlueprintCallable을 붙인 C++ 함수를 Blueprint에 배치했지만 흰색 실행 핀이 나타나지 않았다.

UFUNCTION(BlueprintCallable)
UMyItem* FindItem() const;

BlueprintCallable이면 반드시 실행 핀이 생기고, BlueprintPure일 때만 실행 핀이 사라진다고 생각하기 쉽다. 그러나 UE 4.27에서는 const 함수에도 자동으로 적용되는 규칙이 하나 더 있었다.

UE 4.27 UHT가 Pure로 판단하던 조건#

당시 UnrealHeaderTool은 아래 네 조건을 모두 만족하는 함수를 자동으로 BlueprintPure로 표시했다.

  1. 함수가 const다.
  2. BlueprintCallable이다.
  3. 반환값이나 output parameter가 있다.
  4. BlueprintPure = false로 자동 변환을 막지 않았다.

엔진이 함수 본문을 분석해 실제 side effect가 있는지 판정한 것은 아니다. C++ 선언의 const와 Blueprint로 내보낼 output의 존재만 보고 적용한 규칙이었다.

const는 해당 객체의 일반 멤버를 변경하지 않는다는 C++ 계약이지만, 함수가 항상 가볍거나 외부 상태를 전혀 건드리지 않는다는 뜻은 아니다. 로그를 남기거나, 전역·subsystem 상태를 읽고 쓰거나, 비용이 큰 검색을 수행할 수도 있다.

실행 핀을 명시적으로 복원한다#

호출 순서를 눈에 보이게 만들고 싶다면 BlueprintPure = false를 지정한다.

UFUNCTION(BlueprintCallable, BlueprintPure = false)
UMyItem* FindItem() const;

const를 제거해서 해결할 수도 있다. 다만 함수가 객체 상태를 변경하지 않는다면 C++ 계약까지 약하게 만들 이유는 없다. const는 유지하고 Blueprint 노드의 실행 의미만 명시하는 쪽이 의도를 더 잘 드러낸다.

언제 Pure가 적합한가#

Pure 노드는 데이터가 필요한 지점에서 Blueprint compiler가 평가한다. 실행선이 없고 한 번만 호출된다는 보장도 없다. 따라서 아래 조건을 만족하는 함수에 잘 맞는다.

  • 빠르고 예측 가능한 getter다.
  • 여러 번 평가되어도 결과와 상태가 달라지지 않는다.
  • 호출 순서를 다른 노드와 조정할 필요가 없다.
  • 외부에 관찰 가능한 side effect가 없다.

반대로 호출 순서나 횟수를 통제해야 하는 함수에는 실행 핀이 있는 편이 안전하다.

  • 큰 배열이나 월드의 Actor를 검색한다.
  • 호출 횟수가 성능에 직접 영향을 준다.
  • cache, log, 통계나 subsystem 상태를 변경한다.
  • Blueprint 작성자가 호출 순서를 명확히 제어해야 한다.

원문의 표현에서 교정한 부분#

원문은 “side effect를 보유했느냐에 따라 엔진이 실행 핀을 정한다”고 설명했다. API 설계 기준으로는 맞는 방향이지만, UE 4.27 UHT가 함수 본문을 분석한 것은 아니다. 자동 Pure 처리는 const, output, BlueprintCallable, BlueprintPure=false 여부만 확인했다.

또한 void 함수에 입력만 있는 최소 예제는 당시 UHT의 자동 Pure 조건을 완전히 보여 주지 못한다. 이 글에서는 실제 조건이 드러나도록 반환값이 있는 예제로 바꿨다. 핵심 해결책인 BlueprintPure = false는 그대로다.

참고 자료#

글 공유하기

이 글이 도움이 되셨다면 다른 사람과 공유해 주세요!

UE4 BlueprintCallable 함수에 실행 핀이 보이지 않는 이유
https://velog.io/@hon454/BlueprintCallable-함수에-실행Exec핀이-없는-경우
작성자
Jihoon Jeon
게시일
2021-12-22
라이선스
CC BY-NC-SA 4.0
관련 게시글스마트
1
UE4 ACharacter::PlayAnimMontage 반환값이 실제 재생시간과 다른 이유
Unreal EngineUE 4.26의 ACharacter::PlayAnimMontage가 Play Rate와 Rate Scale이 반영되지 않은 원본 몽타주 길이를 반환하던 이유와 안전한 대안을 설명합니다.
2
면접 오답노트: 말하지 못한 주요 개념, Net Relevancy
Unreal Engine면접에서 제대로 답하지 못한 Net Relevancy를 다시 정리한다. AActor::IsNetRelevantFor의 판정 순서와 문서와 다른 부분, Owner가 판정을 바꾸는 방식, 연관성을 잃고 되찾을 때 RelevantTimeout과 액터 파괴, BeginPlay, OnRep, RPC에 생기는 일, ForceNetRelevant와 Replication Graph, Iris에서의 주의점, Dormancy, Priority와의 차이를 다룬다.
3
휴면 액터 깨우기: FlushNetDormancy, ForceNetUpdate, SetNetDormancy
Unreal EngineUE 5.8.3 엔진 소스 기준으로 FlushNetDormancy, ForceNetUpdate, SetNetDormancy가 각각 무엇을 바꾸는지 비교한다. 휴면 정책과 휴면 상태의 차이, ForceNetUpdate가 덤으로 하는 flush가 빠지는 조건, 값을 바꾼 뒤 깨우면 FastArray 변경이 사라지는 문제, 이를 막는 setter 패턴과 Push Model을 함께 쓸 때의 주의점을 정리한다.
4
Unreal Engine PIE에서 클라이언트와 서버 값을 한 줄로 비교하기
Unreal EnginePIE에서 클라이언트 코드가 같은 프로세스의 서버 월드와 서버 측 PlayerController를 찾아 위치·속도를 한 줄로 비교하는 에디터 전용 디버그 코드와, 네트워크 에뮬레이션으로 확인한 측정 결과를 정리합니다.
5
Unreal Engine - Replication Graph
Unreal EngineUE 5.8.3 소스와 테스트 프로젝트 실측으로 Replication Graph가 기본 드라이버의 무엇을 줄이고 무엇을 줄이지 않는지 확인한다. 액터 5,000개와 클라이언트 16개까지의 측정, 효과가 있는 설정값과 이름과 반대로 동작하는 설정값, 커스텀 그래프의 라우팅과 Team Node, 5.8.3에서 재현한 버그 다섯 가지, 도입 기준과 Iris와의 관계를 다룬다.
무작위 게시글무작위

댓글

Profile Image of the Author
Jihoon Jeon
안녕하세요! 서브컬처와 자전거를 사랑하는 개발자 전지훈입니다.
공지사항
제 블로그에 오신 것을 환영합니다! 예시 공지입니다.
카테고리
태그
최신 일상
사이트 통계
게시글
73
카테고리
10
태그
143
총 단어 수
133,527
운영 일수
0일
최근 활동
0일 전
사이트 정보
빌드 플랫폼
GitHub Actions
블로그 버전
Firefly v6.16.9
라이선스
CC BY-NC-SA 4.0
목차