Suggestions how best to do this...

There are no stupid questions, just stupid answers.
27 posts Page 2 of 3
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Fri Aug 19, 2016 10:58 pm
@
User avatar
Azaezel
Thanks for the explanation. I have already done it in the PlayerData::onAdd, so I am glad to see that you have suggested that too. I assume that this will then work for each player that joins the game? At some stage I will set install it on another PC to test this.
Azaezel
DEVGRU
Posts: 496
Joined: Tue Feb 03, 2015 9:50 pm
 
by Azaezel » Tue Aug 23, 2016 10:08 pm
Yes, though a word of caution as a general pragmatic note: aiplayer derives from player, so be careful of inheritance there, as well as slamming the system with too much code going off simultaneously by spawning a bunch of stuff at once leading to heavy load going off at near the same time. Why I favor stuff like https://github.com/Azaezel/Torque3D/tree/AI_manager for smoothing out execution.
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Wed Aug 24, 2016 11:23 am
Thanks for the caution. At the moment I am just using it for basic things such as opening doors etc.
TorqueFan
Posts: 130
Joined: Thu Apr 30, 2015 5:35 am
by TorqueFan » Fri Aug 26, 2016 4:02 pm
...
Our end what we do is tack on triggers programatically so if nobody is around an interactive object we save some load,
...
Dude, you wouldn't by chance mind giving an example of that "tacking on triggers so if nobody is around" bit would you? I am in the middle of constructing a custom AI system in source and it's using signals. I was wondering what the best way to handle the 'tick' is? I'm trying to determine whether or not I should have a custom 'Manager' class handle all that in its 'tick' functions or if I should have the clients gather the local information to see if a signal should be triggered? From what I've managed to gather so far, it's looking kind of like both...the client gets the stuff in range and the custom Manager class could use that information to trigger those in range.

@ flysouth : Are you trying to keep all of this in script? I have grown partial to using the ScriptTickObject class for having stuff 'tick' in script. You could have the ScriptTickObject call whatever is dynamically being refreshed, but I'd be careful using this approach. The good thing about the ScriptTickObject is you can throttle back the speed it ticks so whatever script you're feeding into it doesn't get called a bajillion times a second. I'd recommend a bit of research around that class. Also IIRC to get the ScriptTickObject to 'start up' you have to 'turn it on' using a script function. Can't remember the syntax off the top of my head, but if you decide to use the ScriptTickObject and need help just ask. I have at least one good example of it on my hard drive someplace.
Steve_Yorkshire
Posts: 345
Joined: Tue Feb 03, 2015 10:30 pm
 
by Steve_Yorkshire » Fri Aug 26, 2016 5:42 pm
Just skim read the thread but off my head ...
Thanks for the caution. At the moment I am just using it for basic things such as opening doors etc.
You could slap a trigger over the door area (making it larger so the player doesn't run into the door to have it operate) and have it operate that way with the trigger's onEnterTrigger function. Probably a good idea to have it contain a variable for open or shut (isOpen) and have the door object ID (doorID) given to the trigger. But the gist should be something like.
function doorTrigger::onEnterTrigger(%this,%trigger,%obj)
{
   %door = %trigger.doorID();
   if(%trigger.isOpen == false)
      if(%obj.getType() $="Player")//only players open doors, note AIPlayer derives from Player
         %door.playThread(0, "openDoor");//your animation for the door or call whatever function that opens it here
}
Alternatively you could have the player touch the door on the Player's OnCollision callback.
function Player::onCollision(%this, %obj, %col)
{
   // assuming door is staticObject
   if (%col.getType() & $TypeMasks::StaticObjectType)
   {
      %db = %col.getDataBlock();
      if (%db.getClassName() $= "DoorData" ) 
      {
         // Open door
         %col.playThread(0, "openDoor");//for animation or whatever function call to open door
      }
   }
}
Anyhow those or all things which can help reduce using looping schedules.
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Fri Aug 26, 2016 10:54 pm
I want the player to press a key to open the door.
What is the difference between the overhead of a trigger and a looping schedule?
I read on a forum post that the triggers are shedules as well.
TorqueFan
Posts: 130
Joined: Thu Apr 30, 2015 5:35 am
by TorqueFan » Sat Aug 27, 2016 12:33 am
@
User avatar
Azaezel
: Ah okay, yea, I gotcha. That's actually close to what I was doing in script when I first put all this AI system together. I mean the way you guys are adding the triggers onAdd(). I can get all my signals firing if I add a trigger for each signal I want to fire, easy peasy. What I'm actually trying to achieve at this point is a tad more advanced. I'm moving that trigger based scripted system into source, and what I'd really like to see happen is have the client detect what's in range and THEN fire the signal. This way, although all of the potential objects may be registered to the event, only those in range of each client will actually fire the event. Tbh I'm fairly close to nailing it, of course I'd be glad to share when it's complete.

@
User avatar
flysouth
: Well, if you have a schedule running it's full-on running as often as you tell it to. With a trigger, it can just sit idle and do nothing until something is within its bounds. Of course, regardless of what you do there is going to be a 'listener' of some sort paying attention to what's going on to fire off the event.

I must be too deep in my current implementation, I didn't completely address your question flysouth. I'd recommend you avoid triggers/scheduling altogether.

What you should do is have your event(the moving of the door/collision) fire off after a successful raycast. So shoot a ray at the door from your player's eye and once it hits, fire off the event that handles the animation of the door/collision shape.
flysouth
Posts: 105
Joined: Sun May 15, 2016 10:16 am
by flysouth » Sat Aug 27, 2016 1:06 am
What you should do is have your event(the moving of the door/collision) fire off after a successful raycast. So shoot a ray at the door from your player's eye and once it hits, fire off the event that handles the animation of the door/collision shape.
I am scheduling a raycast evry 300 ms to look in front of my player to see what the player can interact with. I dont want them to collide with door to do this. When a door is detected an option to unlock or open the door is shown in a HUD. They can then decide to open it if they want.
According to the T3D doc the trigger tick is every 100ms so it might have more overhead than my schedule raycast every 300ms???
TorqueFan
Posts: 130
Joined: Thu Apr 30, 2015 5:35 am
by TorqueFan » Sat Aug 27, 2016 3:45 am
According to the T3D doc the trigger tick is every 100ms so it might have more overhead than my schedule raycast every 300ms???
Okay that's a bit clearer, I see what you're up to now. You want that dynamic GUI dialog to automatically pop up. I took it to mean you wanted to walk up to the door, hit a button, and the door opens(no popup involved).

Well in any event constantly firing a raycast out in front of the player detecting stuff will surely keep things 'ticking', although I'd still approach it just a tad differently to reduce any additional overhead. Consider that the player may be out in the wilds someplace, far away from any potential door to be opened, yet he continues to cast rays out looking for doors that couldn't possibly exist. Here I'll try to address your implementation to the best of my understanding:

Triggers :
From old documentation :
The defaultTrigger datablock defines its tick frequency at 100 ms.
So here we see that you can create your own trigger datablock, and instead define its tick frequency to whatever you want(i.e. 300ms that you currently use while raycasting). Alright, great, so you can use triggers at the same tick rate - how does that help?? Let's take a closer look at the Trigger class again.

In the same link provided above, check out the function DefaultTrigger::onTickTrigger (near the bottom of the page, also referenced here.) What this field allows you to do is enter in a command that you want to be executed while objects are inside the trigger. So, not only can you have your raycast function be called by the trigger at the same rate, you can also have it only fire off the raycast search while the player is close enough to the door for it to matter.

Meaning you can create a trigger area much larger than just a few feet across, say maybe 10 feet x 10 feet, and have that trigger call to your player's raycast function only while the player is within that range of the door. Now you have the same functionality you did before but it's a LOT more efficient.

Now, to be completely clear about the Trigger class, it should be understood that the Trigger itself will continue to tick at the rate you set it to even if nothing is in the Trigger's area. However, and this is the important part; the Trigger class's onTick() source code will immediately return and won't execute any code unless the criteria you set for the Trigger are met. So it will continue to 'listen' but it won't execute the raycast search code unless the player object is within the bounds of the trigger.

Disclaimer:
As usual bear in mind of course there are many ways to approach any given problem(be it in source or in script). For what you've got going, this seemed fairly appropriate, although I can see other paths as well if it isn't optimal to your needs. Personally I've spent a good deal of time and planning avoiding as many triggers and schedules as possible, but in some cases you just have to use the available classes to the best of your ability or craft up new ones :lol:. Think it over, see if it helps, cheers!

P.S.
Another thing to consider is that you could avoid the raycast code altogether. If you are going through all of that just to get a GUI control to pop up you might as well place a small trigger area in front of the door. Then when a player hits it, the GUI control pops up indicating the player is close enough to open the door. If the gameplay is of a type where clicky GUI navigation is happening to interact with stuff, whether or not the center target reticle is 'looking at' the door shouldn't matter. If you are standing on the door square you can open the door. Food for thought =)
27 posts Page 2 of 3

Who is online

Users browsing this forum: No registered users and 13 guests