Skip to content
Cauê Waneck edited this page Apr 2, 2018 · 1 revision

You can declare UE delegate types by creating a typedef to one of the following classes:

  • Event
  • Delegate
  • MulticastDelegate
  • DynamicDelegate
  • DynamicMulticastDelegate

The first type parameter should refer to the typedef itself - so that the name and metadata can be found. The second type parameter is the function signature of the delegate, e.g.:

typedef FMyCustomEvent = unreal.DynamicMulticastDelegate<FMyCustomEvent, Int->Int->Void>;

To specify that the bound functions for the delegate should be const, use :thisConst metadata:

// only binds to C++ functions with the signature "void foo() const"
@:thisConst typedef FConstNotify = unreal.Delegate<FConstNotify, Void->Void>;

For DynamicMulticastDelegates that can be bound in Blueprints, you can use :uParamName to specify the name of each argument as it will appear in Blueprints. If not specified, a default name will be chosen:

// uParamNames are applied in the same order as the arguments
@:uParamName("Instigator") @:uParamName("DamageCauser") @:uParamName("DamageDealt")
typedef FDiedEvent = unreal.DynamicMulticastDelegate<FDiedEvent, APawn->AActor->Int->Void>;

@:uclass class ACharacter extends AActor {
  // can be bound to in blueprints with parameter names
  @:uproperty(BlueprintAssignable, Category=Pawn)
  var DiedEvent:FDiedEvent;
}

Using delegates

Depending on the delegate type, there are different APIs:

Delegate<Function>

  • BindLambda(fn:Function):Void - BindLambda takes any Haxe function. The only way to unbind to it is to call Unbind()
  • BindUObject(obj:unreal.UObject, method:unreal.MethodPointer<unreal.UObject, Function>):Void - BindUObject takes an object, and a C++ method pointer related to that object. unreal.MethodPointer is a special type that represents a C++ method pointer. It only exists on functions exposed to Unreal, like a @:ufunction that is defined in Static, or a function that contains the @:uexpose metadata. In order to get it, one must call unreal.MethodPointer.fromMethod(obj.functionName)
  • Unbind() - Unbinds the current bound function
  • IsBound():Bool - Checks if the delegate is bound
  • GetUObject() - if BindUObject was used, returns the UObject that was used
  • Execute(arg1, arg2, arg3, ... argN):ReturnType - Executes the delegate
  • ExecuteIfBound(args:...):Void - Executes the delegate if it's bound

Warning: Binding functions using BindUObject requires the function to be exposed to C++. This can be a small issue if you're compiling with cppia - it means that any change to the signature of that function will trigger a full C++ compilation. In order to avoid that, you can consider using a pattern like delegate.AddLambda(function(arg1, arg2, ..., argN) if (!obj.isValid()) delegate.Unbind(); else obj.someFunction(arg1, arg2, ..., argN)

DynamicDelegate<Function>

In order to bind to DynamicDelegate types, using unreal.CoreAPI; must be set along side with the import statements

  • BindDynamic(expression):Void - DynamicDelegates can only be bound to @:ufunction types. BindDynamic is a macro that ensures this happens. An example of a way to call it is delegate.BindDynamic(obj.someUFunction)
  • Unbind(), IsBound(), GetUObject(), Execute(...), ExecuteIfBound(...) - Same as Delegate<Function>

MulticastDelegate<Function>

  • IsBound():Bool - Returns whether there are any functions bound
  • Clear():Void - Clears all delegates bound to delegate
  • AddLambda(fn:Function):unreal.FDelegateHandle - Adds a Haxe function. Works like Delegate's BindLambda, and the same remarks apply to it
  • AddUObject(obj:UObject, fn:unreal.MethodPointer<UObject, Function>):unreal.FDelegateHandle - Adds a UObject-derived method pointer. See the remarks about Delegate's BindUObject - the same remarks apply to it
  • AddUniqueUObject(expr):Void - Works like AddUObject, but can bind any function - even functions that are only defined in Haxe (without the @:ufunction or @:uexpose metadata). This is the same as binding a function though AddLambda, but before calling it checking if an object is still valid - and if it's not, unbind, like so:
var handle = null;
// equivalent to delegate.AddUniqueUObject(obj.someFunction)
handle = delegate.AddLambda(function(arg1, arg2, ... argN) {
  if (!obj.isValid()) {
    delegate.Remove(handle);
  } else {
    obj.someFunction(arg1, arg2, ... argN);
  }
});
  • IsBoundToObject(obj:UObject):Bool - Returns whether there is a delegate bound to obj
  • Remove(handle:unreal.FDelegateHandle):Void - Removes a bound function by using its FDelegateHandle
  • Broadcast(arg1, arg2, ... argN):Void - Broadcasts the arguments to all multicast delegates

DynamicMulticastDelegate<Function>

Like DynamicDelegate, in order to bind to DynamicMulticastDelegate, using unreal.CoreAPI; is needed

  • AddDynamic(expr):Void - Adds a @:ufunction of a UObject-derived object to the invocation list. Can be called ilke delegate.AddDynamic(obj.someUFunction)
  • AddUniqueDynamic(expr):Void - Same as AddDynamic, but only if a delegate with the same signature does not exist already in the invocation list
  • RemoveDynamic(expr):Void - Removes a @:ufunction of a UObject-derived object from the invovation list. Can be called like delegate.RemoveDynamic(obj.someUFunction)
  • IsAlreadyBound(expr):Bool - Returns whether a @:ufunction of a UObject-derived object is already bound to this delegate. Can be called like delegate.IsAlreadyBound(obj.someUFunction)
  • IsBound():Bool, Clear():Void - Same as MulticastDelegate<Function>