How to set up functions that need to be done constantly at an interval?

There are no stupid questions, just stupid answers.
9 posts Page 1 of 1
Sir_Skurpsalot
Posts: 52
Joined: Tue Jan 28, 2020 6:32 pm
by Sir_Skurpsalot » Sat Apr 04, 2020 11:17 pm
How do I get started setting up functions that need to be done constantly at an interval? Other engines have update functions that run every frame, how is that sort of stuff done in Torque? Specifically I want to shoot a raycast from the player LOS constantly every so many milliseconds. Thanks for reading.
fLUnKnhaXYU
Posts: 158
Joined: Wed Nov 15, 2017 8:19 am
by fLUnKnhaXYU » Sun Apr 05, 2020 1:39 am
I think schedule might be what you're looking for
in your read the docs check the bottom index page 941 and see simObject::schedule . Also just search for schedule and you'll see a few examples also search file contents of your torque3d demo script files for examples . you'll need to look into starting , pausing , cancelling a schedule as well , things like that . If I'm not mistaken a schedule will be given an ID number which you can use . It'll probably be worth your time to master the use of schedule .
Jason Campbell
Posts: 358
Joined: Fri Feb 13, 2015 2:51 am
 
by Jason Campbell » Sun Apr 05, 2020 5:34 am
Here's an example of a 5 second interval that checks for StaticObjectType(you can change it to anything) from the players eyepoint at a distance of 4.

Just execute the function rayCast anywhare.
function rayCast(%client)
{
   %player = ServerConnection.getControlObject();
   %eye = %player.getEyeVector();
   %vec = vectorScale(%eye, 4);
   %start = %player.getEyeTransform();
   %end = VectorAdd(%start,%vec);
   %found = ContainerRayCast (%start, %end, $TypeMasks::StaticObjectType, %player);
   if(%found)
   {
     echo("found StaticObjectType!");
   }
   echo("checking");
  schedule(5000, 0, "rayCast");
}
Sir_Skurpsalot
Posts: 52
Joined: Tue Jan 28, 2020 6:32 pm
by Sir_Skurpsalot » Sun Apr 05, 2020 1:30 pm
Ok sweet, thanks guys.
Jason Campbell
Posts: 358
Joined: Fri Feb 13, 2015 2:51 am
 
by Jason Campbell » Sun Apr 05, 2020 2:52 pm
No problem. In schedule the 5000 is 5 secs so changing it to 500 would be half a sec. In the %vec variable 4 is the unit distance of the ray. Search up TypeMaska if you want it to look for Players or even terrain.
Duion
Posts: 1603
Joined: Sun Feb 08, 2015 1:51 am
 
by Duion » Mon Apr 06, 2020 11:52 am
Doing things at every frame in script is very bad for performance, I tried and each of those things reduced the overall performance by 5 FPS, so having two of those functions may to tolerable, but not more.

So try something like every 1-3 seconds. You probably want to check if the player is viewing an object that can be interacted with, so it may even be beneficial if there is a slight delay so a GUI does not pop up if you just sway around with your view, but only if you actually look at an object.

Otherwise I would try to borrow some function that is already there that does something like this, like the shapeNameGUI or what it is called, it displays a health bar if you look at a player object, so it seems there is already something like this in the engine that does what you need and it is probably done in C++ which is more performance friendly.
fLUnKnhaXYU
Posts: 158
Joined: Wed Nov 15, 2017 8:19 am
by fLUnKnhaXYU » Mon Apr 06, 2020 9:10 pm
Thats a brilliant suggestion . The following is just copied from the engine/source of the dev folder namely from the guiCrossahirHud.cpp
Its is using ray cast but confined to a rectangle which of course is editable through scripting , Im sure that it should be possible to activate the rectangle with and/or only with a button press and perhaps deactivated if the camera angle/rotation what have you change is excessive . Or delay the appearance of items found beneath the cursor a second or so . Also it seems that there should be a way of knowing what objects are within an area of the scene such as the small rectangle without a raycast probing for them .



//==========================================================================================
guiCrosshairHud.cpp

//-----------------------------------------------------------------------------
/
// Vary basic cross hair hud.
/
// Uses the base bitmap control to render a bitmap, and decides whether
/
// to draw or not depending on the current control object and it's state.
/
// If there is ShapeBase object under the cross hair and it's named,
/
// then a small health bar is displayed.
//-----------------------------------------------------------------------------
/

void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect)

{

   // Must have a connection and player control object

   GameConnection* conn = GameConnection::getConnectionToServer();

   if (!conn)

      return;


   GameBase* control = dynamic_cast<GameBase*>(conn->getCameraObject());

   if (!control || !(control->getTypeMask() & ObjectMask) || !conn->isFirstPerson())

      return;


   // Parent render.

   Parent::onRender(offset,updateRect);


   // Get control camera info

   MatrixF cam;

   Point3F camPos;

   conn->getControlCameraTransform(0,&cam);

   cam.getColumn(3, &camPos);


   // Extend the camera vector to create an endpoint for our ray

   Point3F endPos;

   cam.getColumn(1, &endPos);

   endPos *= gClientSceneGraph->getVisibleDistance();

   endPos += camPos;


   // Collision info. We're going to be running LOS tests and we

   // don't want to collide with the control object.

   static U32 losMask = TerrainObjectType | ShapeBaseObjectType;

   control->disableCollision();


   RayInfo info;

   if (gClientContainer.castRay(camPos, endPos, losMask, &info)) {

      // Hit something... but we'll only display health for named

      // ShapeBase objects.  Could mask against the object type here

      // and do a static cast if it's a ShapeBaseObjectType, but this

      // isn't a performance situation, so I'll just use dynamic_cast.

      if (ShapeBase* obj = dynamic_cast<ShapeBase*>(info.object))

         if (obj->getShapeName()) {

            offset.x = updateRect.point.x + updateRect.extent.x / 2;

            offset.y = updateRect.point.y + updateRect.extent.y / 2;

            drawDamage(offset + mDamageOffset, obj->getDamageValue(), 1);

         }

   }


   // Restore control object collision

   control->enableCollision();

}
//-----------------------------------------------------------------------------
/
//-----------------------------------------------------------------------------
/
Sir_Skurpsalot
Posts: 52
Joined: Tue Jan 28, 2020 6:32 pm
by Sir_Skurpsalot » Mon Apr 06, 2020 10:59 pm
My application is that I need to check for "friendlies" in the player's line of sight, I don't think it can be done without constant ray casting.
Duion
Posts: 1603
Joined: Sun Feb 08, 2015 1:51 am
 
by Duion » Tue Apr 07, 2020 8:07 am
Then I would add that into the function that checks for enemies, since there must already be a function in the engine that does that.

The default engine already checks for players, for health of the players and displays a health bar and for player names, those will be displayed above them and then you probably can copy some of the code to check for friendly or not.

But aside from that, I would not check for friendlies at all, in my game each team has a specific skin, so you can visually distinguish friendly from enemy and if you still shoot them, there is a value in the options where you turn friendly fire on or off, so there is not really the need to check for friendlies in the engine.

I know there are some games that check if friendly or not and then prevent you from shooting friendlies but that is a stupid solution in my opinion, most games simply turn of damage to friendlies if needed.
9 posts Page 1 of 1

Who is online

Users browsing this forum: Google [Bot] and 12 guests