Listening for events in UnrealScript

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

Listening for events in UnrealScript

Post by 1337GameDev » Tue Oct 27, 2020 5:56 am

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: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 » Tue Oct 27, 2020 7:05 am

A modified SpecialEvent or... a normal SpecialEvent killing Instigator. Rocket Science here ?

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie » 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
}
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 » 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.

Buggie
Adept
Posts: 421
Joined: Sat Mar 21, 2020 5:32 am

Re: Listening for events in UnrealScript

Post by Buggie » Tue Oct 27, 2020 1:39 pm

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
Experienced
Posts: 85
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev » Wed Oct 28, 2020 2:00 am

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
Experienced
Posts: 85
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev » Wed Oct 28, 2020 2:02 am

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: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 » 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.

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie » Wed Oct 28, 2020 12:20 pm

1337GameDev wrote:
Wed Oct 28, 2020 2:02 am
Is 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 am
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?
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 am
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?
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.
You do not have the required permissions to view the files attached to this post.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

1337GameDev
Experienced
Posts: 85
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev » Thu Oct 29, 2020 1:14 am

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
Experienced
Posts: 85
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev » Thu Oct 29, 2020 1:17 am

Barbie wrote:
Wed Oct 28, 2020 12:20 pm
1337GameDev wrote:
Wed Oct 28, 2020 2:02 am
Is 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 am
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?
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 am
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?
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: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 » 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;
			}
..................

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Listening for events in UnrealScript

Post by Barbie » Thu Oct 29, 2020 12:43 pm

1337GameDev wrote:
Thu Oct 29, 2020 1:14 am
is 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
Experienced
Posts: 85
Joined: Thu Apr 16, 2020 3:23 pm
Personal rank: GameDev

Re: Listening for events in UnrealScript

Post by 1337GameDev » Thu Oct 29, 2020 10:34 pm

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: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Listening for events in UnrealScript

Post by sektor2111 » Fri Oct 30, 2020 4:21 am

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.