• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Code How to attach an event object to an actor from unrealscript?

-=THOR=-

Grizzled Veteran
Sep 20, 2011
1,050
50
I examined the Actor class, and realized that there is no way to "subscribe" to an event, like the Touch event in a "delegate" fashion. Unless you're creating a subclass, which is not an option for me, the class will call only the Kismet events.

I want to avoid Kismet as much as possible, so I though I could create a subclass for the event, and use it to internally catch the activations, and offer a "delegate" way to subscribe with other classes. Unfortunately all the methods of the kismet events are FINAL (THANKS UDK), so no luck...

So I thought of creating a Fake Kismet event which would mimic the Touch event, but contain an internal Kismet touch event. I manually linked the internal event to my fake event. When my fake event is activated, all I'd have to do is to trigger my delegates...

Code:
class ActorTouchedSubscriber extends SequenceAction;

[...]

// Kismet Event.
var SeqEvent_Touch mSeqEvent_Touch;

// Kismet Links.
var SeqOpOutputInputLink mLink_Touched;
var SeqOpOutputInputLink mLink_UnTouched;
var SeqOpOutputInputLink mLink_Empty;

// Kismet Variables.
var SeqVar_Object mSeqVar_Instigator;

// Subscribed Actor.
var Actor mActor;

function SubscribeToActor(Actor iActor)
{
    // Subscribe to the output links.
    mLink_Touched.LinkedOp = self;
    mLink_Touched.InputLinkIdx = 0;
    mSeqEvent_Touch.OutputLinks[0].Links.AddItem(mLink_Touched);
    mLink_UnTouched.LinkedOp = self;
    mLink_UnTouched.InputLinkIdx = 1;
    mSeqEvent_Touch.OutputLinks[1].Links.AddItem(mLink_UnTouched);
    mLink_Empty.LinkedOp = self;
    mLink_Empty.InputLinkIdx = 2;
    mSeqEvent_Touch.OutputLinks[2].Links.AddItem(mLink_Empty);
    
    // Add a variable to the 
    mSeqEvent_Touch.VariableLinks[0].LinkedVariables.AddItem(self.mSeqVar_Instigator);
    
    // Add the event to the actor.
    mActor = iActor;
    [COLOR="Red"][B]mActor.GeneratedEvents.AddItem(self.mSeqEvent_Touch);[/B][/COLOR]
}

event Activated()
{
   // Sort which input was triggered, and call the delegates...
}

Defaultproperties
{
	ObjName="ActorTouchedSubscriber"
	ObjCategory="Don't Use"

	InputLinks.Empty
	InputLinks(0)=(LinkDesc="Touched")
	InputLinks(1)=(LinkDesc="UnTouched")
	InputLinks(2)=(LinkDesc="Empty")

	VariableLinks.Empty
	VariableLinks(0)=(ExpectedType=class'SeqVar_Object',LinkDesc="Instigator",PropertyName=mInstigator)
}

BUT then when I tried to compile my code.. and it failed at mActor.GeneratedEvents.AddItem, because the array is CONST. Hooray, I didn't notice that little detail. It looks like GeneratedEvents is populated by the editor. I thought that if what was done by the editor, we could do it manually... Nothing is less sure, I haven't found a way to add my event to the actor. Any idea how I do this? The Kismet action AttachEventToActor does that, I hope I won't need to instantiate that class just to do that simple job...

Any other idea?
 
Last edited:
I'm afraid without information about what you're trying to accomplish it's hard to offer advice. My initial feeling is that you're trying to do something one way when there is another method that you should be using. In my experience there is very little you can't do via UnrealScript. It might not be the most optimized way but it is usually doable.
 
Upvote 0
Well, consider two cases...

I'm in class A, which derives from Object.
I have a link to Pawn B.
A wants to know when B dies.

How do you do this with UnrealScript? How do you "subscribe" to a death event from Unrealscript (polling is not an option to me). In other words, the end-result I'm looking for, is that I want a method to be called in A, when B dies.

Now if I have an actor C.
A wants to know when C is touched by B.

How do you do this with Unrealscript? How do you "subscribe" to a touch event form Unrealscript (polling is still not an option to me). In other words, the end-result I'm looking for, here, is that I want a method to be called in A, when C is touched by B.
 
Last edited:
Upvote 0
There's no way to do that unless the original object is specifically set up for it with Delegate functions. Almost nothing in stock Unreal uses that feature of the scripting - generally just UI stuff.

However, with the specific example of Pawn death, you're in luck. That's one of the events that the stock code cascades through Mutator objects. Default Pawn behavior is to call PreventDeath on all Mutators when they're dying. You can just instantiate and register a Mutator object to get easy access to that event and a handful of specific other ones.

With Touch, though, you're SOL. The only way to get your code running on a Touch is to override that function on one of the touching actors. You can't just hook in to an event externally, the execution path is very linear.
 
Last edited:
Upvote 0
Thanks for your reply.

Since there are only 5-6 Kismet boxes that are of major interest to me, I tried to create wrappers that would dynamically create Kismet objects to subscribe to and catch such "events". I would then have implemented the callback mechanism I wanted with those wrappers. For example, for the Touch event, I wanted to create a TouchSubscriber class, deriving from SequenceAction. TouchSubscriber contains a TouchEvent, and a AttachToEvent objects. I would have dynamically linked the inputs of TouchSubscriber with the outputs of TouchEvent, and used AttachToEvent to attach the TouchEvent to my actor. TouchSubcriber would then have received a callback through the "Activated" event. TouchSubcriber could then easily implement a callback scheme of any kind (delegates, interfaces, etc).

However I got a crash and didn't put too many efforts to make it work. Have you ever tried to dynamically create Kismet objects? Do you think it could be possible, or too many stuff being done behind the scenes by the editor that we don't have access to?
 
Upvote 0