Jump to content

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


Sir_Skurpsalot

Recommended Posts

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.

Link to comment
Share on other sites

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 .

Link to comment
Share on other sites

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");
}
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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(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(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();
 
}
//-----------------------------------------------------------------------------
/
//-----------------------------------------------------------------------------
/
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...