Listening for events in UnrealScript

Discussions about Coding and Scripting
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Listening for events in UnrealScript

Post by 1337GameDev »

I am curious how listening for arbitrary events is done in UnrealScript.

I know of the standard event functions -- a la Touch, BeginPlay, InitGame ,etc -- but am more curious on custom ones.

Right now, I'm curious about an event dispatched from a Trigger actor in a map file.
What would be used to listen for this, event, get the instigator and then do something in regards to the event?
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 »

A modified SpecialEvent or... a normal SpecialEvent killing Instigator. Rocket Science here ?
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie »

Create a custom Actor, set its Tag to the desired Event name and implement the code in function Trigger().

Example (untested):

Code: Select all

class MyTrigger expands Trigger;

event Trigger( Actor Other, Pawn EventInstigator ) {
	log(self @ "was triggered by" @ EventInstigator);
}

defaultproperties {
	Tag=MyDesiredEvent
}
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 »

Code: Select all

if ( EventInstigator != None && !EventInstigator.bDeleteMe )
	log(Self.Name@"was triggered by"@EventInstigator.GetHumanName());
else
	log(Self.Name@"was triggered.");
In other hand if you want to HUNT ALL Events, you will need a Master Actor spawning copies of these customs for each EVENT assigned at map's actors. If any of events is fired, you can see what Event has been done and when. You can even add TimeStamp - biography StatLog.uc class or write something similar...
If a player causes an unexpected Event not seen in map, you will want to add such actors nearby others having custom Tags. You might have a tagged Mover without any trigger. If admin does an Event to this Mover, it might be hunted as recommended above.

Notes:
- In X years of UT I never used such things, I'm not testing if UT it's working...
- Actors spawned Event-Hunters should not use RemoteRole, not needed any replication.
- Actors number might have a limitation, probably 2000 pieces are not that recommended, it causes a slow-down for iterators.
Buggie
Godlike
Posts: 2733
Joined: Sat Mar 21, 2020 5:32 am

Re: Listening for events in UnrealScript

Post by Buggie »

If you need few events from predefined list, you can write own actor which on game start spawn childs with desired tags. Which redirect requests to master actor.
It is relativity easy and need only one class for both master and child.
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev »

sektor2111 wrote: Tue Oct 27, 2020 12:27 pm

Code: Select all

if ( EventInstigator != None && !EventInstigator.bDeleteMe )
	log(Self.Name@"was triggered by"@EventInstigator.GetHumanName());
else
	log(Self.Name@"was triggered.");
In other hand if you want to HUNT ALL Events, you will need a Master Actor spawning copies of these customs for each EVENT assigned at map's actors. If any of events is fired, you can see what Event has been done and when. You can even add TimeStamp - biography StatLog.uc class or write something similar...
If a player causes an unexpected Event not seen in map, you will want to add such actors nearby others having custom Tags. You might have a tagged Mover without any trigger. If admin does an Event to this Mover, it might be hunted as recommended above.

Notes:
- In X years of UT I never used such things, I'm not testing if UT it's working...
- Actors spawned Event-Hunters should not use RemoteRole, not needed any replication.
- Actors number might have a limitation, probably 2000 pieces are not that recommended, it causes a slow-down for iterators.
I'll kep this in mind if I want a list of my own custom events to be listened for. Thanks!

I don't think i'd want to iterate through all map actors, and then spawn one for EACH event.
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev »

Barbie wrote: Tue Oct 27, 2020 11:28 am Create a custom Actor, set its Tag to the desired Event name and implement the code in function Trigger().

Example (untested):

Code: Select all

class MyTrigger expands Trigger;

event Trigger( Actor Other, Pawn EventInstigator ) {
	log(self @ "was triggered by" @ EventInstigator);
}

defaultproperties {
	Tag=MyDesiredEvent
}
This seems to be what I want.

Is this ONLY valid for Triggers (or subclasses)? Or can i just set the tag of my custom actor, and then set the tag to the custom event name?

In the Trigger method signature, what does "Actor Other" represent? I figured EventInstigator would be the Pawn that triggered the event. Is the Other actor be the Trigger that has the event name that matches my tag?

Also, im used to c#, javascript, c++, and various others.... can unreal script pass around functions? I'm curious if I can somehow store a kind of callback function in this custom trigger?
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 »

1337GameDev wrote: Wed Oct 28, 2020 2:00 am I don't think i'd want to iterate through all map actors, and then spawn one for EACH event.
Then light me how do you want to find Events without scanning Actors. What magic should to the trick either way ? If you know C++ then you can write something right there, UScript is slow and limited but it might be calling C++ using a native function declaration - See Actor.uc class.

What Barbie was posting is something custom but that log from function Trigger it's not how I do things. A map might have Events without an Instigator. Calls at a NULL instigator will return Accessed None errors, there is no reason for not using Sanity Checks. A TimedTrigger or a StochasticTrigger might do multiple events chained in a Dispatcher, all of these won't have any deal with any Instigator.
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie »

1337GameDev wrote: Wed Oct 28, 2020 2:02 amIs this ONLY valid for Triggers
The function Trigger() is declared in class'Actor', so you can use it in any subclass of it.
1337GameDev wrote: Wed Oct 28, 2020 2:02 amIn the Trigger method signature, what does "Actor Other" represent? I figured EventInstigator would be the Pawn that triggered the event. Is the Other actor be the Trigger that has the event name that matches my tag?
I thought that too, that "Other" is the Actor that has raised the event, but a test has shown: If I trigger the event by a Trigger, "TFemale0" is both "Other" and "EventInstigator". If I kill a Pawn that raises the event on death, "TFemale0" is "EventInstigator" and "Other" is "Nali0".
1337GameDev wrote: Wed Oct 28, 2020 2:02 amAlso, im used to c#, javascript, c++, and various others.... can unreal script pass around functions? I'm curious if I can somehow store a kind of callback function in this custom trigger?
It should work, but consider that the game runs on Windows and Linux. Better ask for example Anth, Spongebob or Higor for details on this.
Attachments
Test_Trigger's_Other.unr.7z
(2.91 KiB) Downloaded 15 times
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev »

sektor2111 wrote: Wed Oct 28, 2020 7:25 am
1337GameDev wrote: Wed Oct 28, 2020 2:00 am I don't think i'd want to iterate through all map actors, and then spawn one for EACH event.
Then light me how do you want to find Events without scanning Actors. What magic should to the trick either way ? If you know C++ then you can write something right there, UScript is slow and limited but it might be calling C++ using a native function declaration - See Actor.uc class.

What Barbie was posting is something custom but that log from function Trigger it's not how I do things. A map might have Events without an Instigator. Calls at a NULL instigator will return Accessed None errors, there is no reason for not using Sanity Checks. A TimedTrigger or a StochasticTrigger might do multiple events chained in a Dispatcher, all of these won't have any deal with any Instigator.
Well my problem wasn't with iteration, but spawning one for each event.

And yeah, i figured that an instigator might be a None value. I would do a none check for those before using.

Thanks for the info, your explanation makes sense.

Edit: is it possible to convert a string to a name data type? I do not see any obvious way
Last edited by 1337GameDev on Thu Oct 29, 2020 1:52 am, edited 1 time in total.
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev »

Barbie wrote: Wed Oct 28, 2020 12:20 pm
1337GameDev wrote: Wed Oct 28, 2020 2:02 amIs this ONLY valid for Triggers
The function Trigger() is declared in class'Actor', so you can use it in any subclass of it.
1337GameDev wrote: Wed Oct 28, 2020 2:02 amIn the Trigger method signature, what does "Actor Other" represent? I figured EventInstigator would be the Pawn that triggered the event. Is the Other actor be the Trigger that has the event name that matches my tag?
I thought that too, that "Other" is the Actor that has raised the event, but a test has shown: If I trigger the event by a Trigger, "TFemale0" is both "Other" and "EventInstigator". If I kill a Pawn that raises the event on death, "TFemale0" is "EventInstigator" and "Other" is "Nali0".
1337GameDev wrote: Wed Oct 28, 2020 2:02 amAlso, im used to c#, javascript, c++, and various others.... can unreal script pass around functions? I'm curious if I can somehow store a kind of callback function in this custom trigger?
It should work, but consider that the game runs on Windows and Linux. Better ask for example Anth, Spongebob or Higor for details on this.
This makes perfect sense. Thanks for explaining!

And i might reach out to them to see. Thanks for the info.

Thanks for the example map. That makes perfect sense now :)
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 »

1337GameDev wrote: Thu Oct 29, 2020 1:14 am Edit: is it possible to convert a string to a name data type? I do not see any obvious way
I wrote something for this in MapGarbage and it uses two variables defined in main class working with Local variable from function.

Code: Select all

final function name StrToName(string AString)
{
	local Name TempName;

	tmp = AString;
	SetPropertyText("NullName",GetPropertyText("tmp"));
	TempName = NullName;
	NullName = '';
	tmp = "";
	return TempName;
}
where <tmp> and <NullName> are main variables of class having this function for being taken as property. It turns a string into a name because even if both are Text, compiler returns a mismatch type.

Here Is a sample of a call for it - tagging Lift stuff automated:

Code: Select all

final function CreateComboTags()
{
	local Name UsedTag;
	local string Ads;
	local Actor A;
	local int AEntExit, ACenter, AMover;
	local bool bSelection;

	foreach MyMap.AllActors(class'Actor',A)
	{
		if ( A.bSelected )
		{
			bSelection = True;
			if ( LiftExit(A) != None )
			{
				if ( string(UsedTag) ~= "" || string(UsedTag) ~= "None" )
				{
					Ads = string(A.Name)$"_MG";
					Ads = Right(Ads,8);
					UsedTag = StrToName(Ads);
					log("Using"@UsedTag@"as private combo identification.",'TagAssigned');
				}
				LiftExit(A).LiftTag = UsedTag;
				log ("Actor"@A.Name@"will use LiftTag ="@LiftExit(A).LiftTag,'LE');
				AEntExit++;
				continue;
			}
..................
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie »

1337GameDev wrote: Thu Oct 29, 2020 1:14 amis it possible to convert a string to a name data type?
See wiki.beyondunreal.com/Typecasting#string_to_name:

Code: Select all

var name NameConversionHack;
 
function name StringToName(string str) {
  SetPropertyText("NameConversionHack", str);
  return NameConversionHack;
}
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
1337GameDev
Skilled
Posts: 198
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev »

sektor2111 wrote: Thu Oct 29, 2020 7:20 am
1337GameDev wrote: Thu Oct 29, 2020 1:14 am Edit: is it possible to convert a string to a name data type? I do not see any obvious way
I wrote something for this in MapGarbage and it uses two variables defined in main class working with Local variable from function.

Code: Select all

final function name StrToName(string AString)
{
	local Name TempName;

	tmp = AString;
	SetPropertyText("NullName",GetPropertyText("tmp"));
	TempName = NullName;
	NullName = '';
	tmp = "";
	return TempName;
}
where <tmp> and <NullName> are main variables of class having this function for being taken as property. It turns a string into a name because even if both are Text, compiler returns a mismatch type.

Here Is a sample of a call for it - tagging Lift stuff automated:

Code: Select all

final function CreateComboTags()
{
	local Name UsedTag;
	local string Ads;
	local Actor A;
	local int AEntExit, ACenter, AMover;
	local bool bSelection;

	foreach MyMap.AllActors(class'Actor',A)
	{
		if ( A.bSelected )
		{
			bSelection = True;
			if ( LiftExit(A) != None )
			{
				if ( string(UsedTag) ~= "" || string(UsedTag) ~= "None" )
				{
					Ads = string(A.Name)$"_MG";
					Ads = Right(Ads,8);
					UsedTag = StrToName(Ads);
					log("Using"@UsedTag@"as private combo identification.",'TagAssigned');
				}
				LiftExit(A).LiftTag = UsedTag;
				log ("Actor"@A.Name@"will use LiftTag ="@LiftExit(A).LiftTag,'LE');
				AEntExit++;
				continue;
			}
..................
This is kind of clever actually.

Hmm, how does this compare to Barbie's method?

Also, I think I will use a base class actor that you override a method in a subclass to dispatch, to use as a container for a callback function.

I couldn't find anything in unrealscript for ut1 that could treat a function as a first class value.
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 »

Barbie's is faster, mine is a bit slower, but I prefer to clean data after use, so I won't change code, I need even that variable String as well mainly in all class not only Name variable. String used will be one from now on called in functions and not each function with a new String variable - I adjusted these codes as long as I did a recheck of what I use because of this opportunity - I think mod will use less memory right now... And then, when I see my code running out of glitches I'm not fixing what is not broken.
Post Reply