Issue related to World.GetGameObjectByID() Bug?

boat

Active member
Sorry if this should be in scripting forum but since TRS19 is in early release and more people see this thread....... Please could someone from N3V answer? Chris?

I am using the new World.GetGameObjectByID() call to see if an asset still exists in the world and has not been deleted. (I mean deleted not just unloaded).

The call seems to produce the desired result but only if the asset I am checking has something typed into the ‘name’ box. If that box is blank then no result will be returned even if the asset is in plain view.

My question is, why if I have a reference to the GameObjectID does the asset also need to have had a previously typed in name for GetGameObjectByID to work? Could this change in a future version?

I am using this in Surveyor Mode to check if any ATLS Controllers have been deleted. The default for most ATLS assets is a blank name box. The implications are that all existing Routes with ATLS in them will have to be edited and a ‘name’ typed in to all the existing ATLS assets. (New ones can use autoname).

To clarify, in the following bit of Library script, ‘ControllerIds[]’ is an array of Controller assets which have contacted the Library.
If the asset still exists ‘results.size()’ will equal 1. If deleted it will be 0. However, if any asset has a blank name,
‘results.size()’ stays 0 even if that asset still exists! Is this by design?

Thanks

Mike.

thread void CheckChannels() {
int i;
Message msg;
for (i = 0; i < ControllerIds.size(); i++) {
deleted = false;
AsyncObjectSearchResult searchObj = World.GetGameObjectByID(ControllerIds,false);
Sniff(searchObj, "ObjectSearch", "AsyncResult", true);
wait()
{
on "ObjectSearch", "AsyncResult", msg:
if (msg.src != searchObj) continue;
break;
}
NamedObjectInfo[] results = searchObj.GetResults();
if (results.size() == 0) deleted = true;
}

for (i = 0; i < deleted.size(); i++) {
if (deleted) {ControllerIds[i,i+1] = null;Channels[i,i+1] = null;deleted[i,i+1] = null;break;}
}


}
 
OK, no replies. I presume then that assets do need a name to be found. I suppose NamedObjectInfo() is a clue.

I am also having to use the GetGameObjectByID search to get a reference to an object I want to post a message to. (Unless I’m missing an easier way to get a reference on an object I have the GameObjectID of?)

Would it be possible to request that PostMessage(GameObject dest, string major, string minor, float seconds) have an alternative? So that PostMessage(GameObjectID dest, string major, string minor, float seconds) would work?

Mike
 
Hi Mike,

You are correct in that objects must be named in order to be search-able in this manner (or via the list functions). At present there is no plan to extend this, but I may have a chat with the team about it later today.

Similarly, there is no current plan to add a GameObjectID variant of PostMessage. The Sniff variant was provided so that scripts don't need to force load an object only to Sniff it, and then have it unload again and never be used (as that's obviously quite bad for performance). PostMessage and SendMessage need the object loaded in order to work though, so there's no benefit to adding those variants (except perhaps shortening some common code, but World.SynchronouslyLoadGameObjectByID covers most of that).

Terry Palmer
Programmer
N3V Games
 
Hi Terry,

Many thanks for getting back on this. I will work with naming assets for now. Obviously if you do change that it will alleviate the need to edit existing un-named assets.

I see what you mean about making use of SynchronouslyLoadGameObjectByID to get a quick reference to an object I want to load anyway. I don’t think I’d fully thought that through.

On the Post/Send Message thing, I suppose I was thinking that there could be times when it might be easier to let a script post to an asset that isn’t loaded when there is no real need for it to be loaded.
This may sound silly but in the case of ATLS, if a train on an unloaded part of the map hits an ATLS Trigger, (I’m told that Trigger will load automatically), I will then need to load its ATLS Controller to keep track of movements. However if that Controller posts a message to a traffic light or even a level crossing barrier, if the user isn’t watching who cares if the light/barrier doesn’t load and doesn’t change colour or raise?
If it could use GameObjectID to post/send the message, the assets needn’t load if no one is watching but will have loaded if someone is. The Post Message would be wasted but presumably not throw an exception?
As you say though, there are longer ways around that with existing calls.

Just a thought.

Regards,

Mike
 
However if that Controller posts a message to a traffic light or even a level crossing barrier, if the user isn’t watching who cares if the light/barrier doesn’t load and doesn’t change colour or raise?
...
As you say though, there are longer ways around that with existing calls.

I would say simply use the one of the calls that will only work for loaded objects. I assume this is what you are alluding to in the last sentence, but here's an example just in case (or for others who may read this post).

Code:
[FONT=courier new]
   GameObject obj = World.GetGameObjectByIDIfLoaded(objID);
   if (obj)
     PostMessage(obj, "MessageType", "NotifyWhatever", 0);[/FONT]

You could even add a PostMessageIfLoaded() function to your class if you have to do this a lot.

Terry Palmer
Programmer
N3V Games
 
I would say simply use the one of the calls that will only work for loaded objects. I assume this is what you are alluding to in the last sentence, but here's an example just in case (or for others who may read this post).

Code:
[FONT=courier new]
   GameObject obj = World.GetGameObjectByIDIfLoaded(objID);
   if (obj)
     PostMessage(obj, "MessageType", "NotifyWhatever", 0);[/FONT]

You could even add a PostMessageIfLoaded() function to your class if you have to do this a lot.

Terry Palmer
Programmer
N3V Games

Thanks again Terry,

Yes, that was the call I was thinking. That and DoesGameObjectStillExist(). I’ve not explored either option yet but seeing how to use World.GetGameObjectByIDIfLoaded() in your example helps a lot. I wasn’t sure before if even that call needed a sniff. I now see it doesn’t. I now think the PostMessage issue is not such an issue.
(Any help is most welcome by the way. I’m just an amateur coder. No official training.)

Still be useful not to need a ‘name’ in the GetGameObjectByID searches though. Unless I’ve missed an easier way to detect fully deleted objects?

Regards,

Mike
 
Last edited:
Back
Top