노드
노드는 서로 연결되어 복잡한 동작을 만들 수 있는 로직 단위예요. 프로그램에서 함수처럼 동작하지만, 시각적으로 표현된다고 생각하면 돼요.
타입 정의
노드 타입을 생성하여 blueprint에 인스턴스화하고 저장할 수 있어요. 노드 타입은 Node 클래스를 상속하고, [NodeType] 속성으로 정의돼요. 아래는 그 예시예요:
[NodeType(
Id = "c76b2fef-a7e7-4299-b942-e0b6dec52660",
Title = "Hello World",
Category = "CATEGORY_DEBUG",
Width = 1f
)]
public class HelloWorldNode : Node {
// Node implementation
}
파라미터 요약:
Id: 노드 타입의 고유 식별자; 각 새로운 노드 타입에 대해 새로운 GUID를 생성해야 해요. 이는 노드 인스턴스의 UUID(node.Id)와는 달라요.Title: 노드 팔레트에 표시될 노드 타입의 이름.Category: 선택 사항. 노드 팔레트에서 노드를 그룹화하는 데 사용돼요.Width: 선택 사항. 기본적으로 노드의 너비는1f인데,2f로 설정하면 해당 노드는1f너비의 노드보다 두 배의 공간을 차지해요.
자주 사용되는 노드 카테고리: CATEGORY_ARITHMETIC, CATEGORY_ASSETS, CATEGORY_BLENDSHAPES, CATEGORY_CHARACTERS, CATEGORY_DATA, CATEGORY_DEBUG, CATEGORY_EVENTS, CATEGORY_CONTROL_FLOW, CATEGORY_INPUT, CATEGORY_MOTION_CAPTURE, CATEGORY_INTERACTIONS.
직접 카테고리 이름을 사용할 수도 있지만, 위 카테고리들은 사용자 언어로 자동으로 현지화돼요.
컴포넌트
노드 타입은 데이터 인풋, 데이터 아웃풋, 플로우 인풋, 플로우 아웃풋, 트리거를 정의할 수 있어요.

라이프사이클
엔티티 페이지에 나와 있는 라이프사이클 단계 외에도, 노드는 다음과 같은 추가적인 라이프사이클 단계가 있어요:
OnAllNodesDeserialized(): 해당 blueprint의 모든 노드가 역직렬화된 후에 호출됩니다. 같은 blueprint의 다른 노드에 접근해야 할 때 유용해요.OnUserAddToScene(): 사용자가 노드를 노드 팔레트에서 드래그하여 에디터에 추가할 때 호출됩니다.
트리거링 플로우
플로우 인풋 메서드에서 플로우 아웃풋의 Continuation을 반환함으로써 플로우 아웃풋을 트리거할 수 있어요. 예를 들어:
[FlowInput]
public Continuation Enter() {
// Do something
return Exit;
}
[FlowOutput]
public Continuation Exit;
만약 플로우가 여기서 끝난다면, null을 반환하여 플로우가 종료되었음을 나타낼 수 있어요.
[FlowInput]
public Continuation Enter() {
// Do something
return null;
}
때로는 플로우 아웃풋을 지연시키거나 수동으로 트리거하고 싶을 수 있어요. 이럴 때는 InvokeFlow(string flowOutputPortKey) 메서드를 사용하여 플로우 아웃풋을 트리거할 수 있어요. 예를 들어:
[FlowInput]
public Continuation Enter() {
async void TriggerExitLater() {
await UniTask.Delay(TimeSpan.FromSeconds(5));
InvokeFlow(nameof(Exit)); // Start a new flow from the "Exit" output port
}
return null; // You still need to return a Continuation. Since *this* flow technically ends here, we return null
}
비직렬화 데이터 인풋 & 아웃풋
노드만이 가지고 있는 특별한 점은 비직렬화 데이터 인풋 및 아웃풋을 가질 수 있다는 점이에요. (에셋이나 플러그인에서는 불가능하며, 아예 표시되지 않아요.) 이를 통해 노드 간에 Unity 오브젝트인 GameObject나 Texture2D 같은 데이터를 주고받고 처리할 수 있어요.
다음과 같이 제네릭 데이터 인풋 또는 아웃풋도 가질 수 있어요:
[DataInput]
public object MyGenericInput; // Note it's 'object', not 'Object'
[DataOutput
public object MyGenericOutput() => ...
어떤 타입의 데이터 아웃풋 포트든 MyGenericInput에 연결할 수 있어요(값은 단순히 object로 업캐스트 돼요). 반대로, MyGenericOutput은 어떤 데이터 인풋 포트에도 연결될 수 있지만, 인풋 포트 타입이 MyGenericOutput이 반환하는 타입과 호환되지 않으면 인풋 포트로 받은 값은 null이 됩니다.
타입 컨버터
노드를 연결할 때, Warudo에서 자동으로 데이터 타입을 변환할 수 있어요. 예를 들어 float아웃풋을 int 인풋에 연결하면 값이 단순히 소수점 이하가 잘려서 변환돼요.
DataConverters 클래스를 사용해서 커스텀 타입 컨버터를 등록할 수 있어요. 가장 쉬운 방법은 DataConverter<T1, T2> 클래스를 구현하는 거예요:
public class MyFloatToIntConverter : DataConverter<float, int> {
public override int Convert(float data) => (int) data;
}
그런 다음, 플러그인의 OnCreate 메서드에서 컨버터를 등록할 수 있어요:
public override void OnCreate() {
base.OnCreate();
DataConverters.RegisterConverter(new MyFloatToIntConverter());
}
노드 타입의 OnCreate에서 타입 컨버터를 등록하지 않아야 해요. 그렇게 하면 노드 인스턴스가 생성될 때마다 컨버터를 등록 하게 돼요!
코드 예시
기본
-
ExampleNode.cs
다양한 노드 컴포넌트의 기본 형식을 보여주는 표준 예시예요. -
StructuredDataExampleNode.cs
"내부" 데이터 타입을 생성해요.(구조화된 데이터) -
GetRandomSoundNode.cs
랜덤 사운드 노드를 가져오는 예시예요. -
LiteralCharacterAnimationSourceNode.cs
캐릭터 애니메이션 (소스) 노드예요. -
SmoothTransformNode.cs
부드러운 트랜스폼 노드예요.
고급
-
FindAssetByTypeNode.cs
AutoCompleteList (드롭다운) 예시예요. -
MultiGateNode.cs
동적 데이터/플로우 포트 예시예요. -
ThrowPropAtCharacterNode.cs
캐릭터에게 소품을 던지는 예시예요. -
SpawnStickerNode.cs
로컬/온라인 이미지 스티커를 생성하는 예시예요.