Game Development Community

New Developer Question

by William James · in Torque Game Engine · 04/18/2007 (8:25 pm) · 3 replies

I've just purchased Torque and I must say I am impressed with what it can do. Right now I am not focused so much on creating my own game but on learning the engine. So I came up with some questions that will hopefully help me make some decisions instead of just browsing the forums and being blown away by TORQUE's abilities. I want to start off really simple.

**** A FPS TARGET PRACTICE *****
The player basically stays in one spot and aims at multiple targets. Again I'm just trying to dissect the script so I can learn it.



1. For a FPS (no TPPOV) is there a need to model a character if the weapon is the only thing showing.
2. Do I just model a highly detailed weapon.

#1
04/18/2007 (8:56 pm)
There's no definitive answers to your questions. You can handle your weapon system however you want (and there are many different approaches you could take).

With that said, if you're going to stick with stock, default code then yes, you will need a player object. You don't have to render this player object in first person view though. Typically, most people just render the weapon only in first person view and the player with weapon mounted to the player's hands in third person view. You can create different arm threads (positions) for different weapon holding positions in third person view (think of the difference in arms position when holding a pistol compared to a rifle).

Controlling whether the player is rendered in first person view:
[i]server/scripts/player.cs[/i]

datablock PlayerData(PlayerBody)
{
   renderFirstPerson = false;
...
...
}
Setting different arm threads per weapon:
[i]server/scripts/weapon.cs[/i]

function WeaponImage::onMount(%this,%obj,%slot)
{
   // 3rd Person Arm position
   // A typical setup is:
   // look   = default
   // looknw = no weapon
   // lookhg = hand gun / pistol
   // lookgr = grenade
   // lookde = deployable such as c4 pack / medkit etc
   // looksn = long rifle such as sniper rifle
   // lookms = heavy weapon such as RPG / Missile Launcher

   if (%this.armthread $= "")
      %obj.setArmThread(look);
   else
      %obj.setArmThread(%this.armThread);
...
...
}
Naturally you'd have to create the various threads within your animated player object and set up its shape constructor accordingly.

Some people take things one step further and use LOD to render arms with the weapon in first person view and just the weapon without arms in third person view.

See this resource for more detail: First/Third Person Different Weapon Models
#2
04/18/2007 (8:56 pm)
Regarding your target system, I came up with a basic system a long time ago and am willing to share my code. You should know that this is very rough and needs improvements in a lot of areas but should give you some ideas. For this code to work you will need a model with two animations, up & down (the target sliding up and down) and you will need to name them target1 - target6.
//-----------------------------------------------------------------------------
// Sentinel Games Weapon Pack Code
// Copyright (c) SentinelGames.com
// This script is for our target range
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Message to Client commands
// Usage: MessageToClient(%message);
// Where %message = Message Number
//-----------------------------------------------------------------------------
function messageToClient(%message)
{
  commandtoserver('messageToClient', %message);
}

function serverCmdMessageToClient(%this,%message)
{
   switch(%message)
   {
      case 1:
         centerPrint(%this, "Good shot, you hit the target!", 3, 1);
      case 2:
         centerPrint(%this, "Well done, you hit all targets... You won!", 3, 1);
      case 3:
         centerPrint(%this, "Starting game... get ready!", 3, 1);
      case 4:
         centerPrint(%this, "Ending game.", 3, 1);
      case 5:
         centerPrint(%this, "You left the playing area, score reset.", 3, 1);
   }
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Target shape, datablock, animation and support functions
//-----------------------------------------------------------------------------
datablock StaticShapeData(Target)
{
   category       = "Target";
   className      = "Targets";
   shapeFile      = "~/data/shapes/target/target.dts";
   maxDamage      = 2;
   destroyedLevel = 1;
};

function StaticShapeData::create(%data)
{
   %obj = new StaticShape() 
   {
      dataBlock = %data;
   };
   return %obj;
}

function Targets::onAdd(%this,%obj)
{
   %obj.playThread(0,"down");
}

function Targets::onDamage(%this,%obj)
{
   %damageAmt = %obj.getDamageLevel();
      if (%damageAmt >= %this.destroyedLevel)
      {
         %obj.setDamageState(Destroyed);
      }
}

function Targets::damage(%data,%myObj,%sourceObj,%position,%amount,%damageType)
{
   if (%damageType $= "Radius")
      return;

   %hitTarget = %myObj.getName();

   if($targetActive && $curTarget $= %hitTarget)
   {
      messageToClient(1);
      animateTargetDown(%myObj);
      TargetScore();
   }
}

function animateTargetUp(%myObj)
{
   $curTarget.playThread(0,"up");
}

function animateTargetDown(%myObj)
{
   if($score $= $winningScore[$round])
   {
      messageToClient(2);
      $round++;
   }

   $targetActive = false;
   $curTarget.playThread(0,"down");
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Game loop & game play functions
//-----------------------------------------------------------------------------
function commenceTargetGame()
{
   //Set up our round and scoring parameters
   $round             = 1;

   //Round 1
   $roundTime[1]     = "5000";
   $winningScore[1]  = 3;

   //Round 2
   $roundTime[2]     = "4000";
   $winningScore[2]  = 5;

   //Round 3
   $roundTime[3]     = "3000";
   $winningScore[3]  = 10;

   //Set our targets raised count to 0 and flag the game as active
   $targetsActivated = 0;
   $gameActive       = true;

   //Dispay our score GUI and make sure it's set to 0
   resetTargetScore();

   //Tell the client the game is about to start
   MessageToClient(3);

   //Start the game!
   if($gameActive)
   schedule(5000, 0, "initiateTargets");
}

function endTargetGame()
{
   //Game has ended
   $gameActive   = false;
   $targetActive = false;

   //Inform the client game has ended
   messageToClient(4);

   //Lower all the targets
   lowerTargets();
}

function initiateTargets()
{
   if($gameActive)
   {
      %targetCount = 7;
      %activeTarget = getRandom(%targetCount-1);
      $targetsActivated++;

      if ($targetsActivated <= $winningScore[$round]) //was <=
      {
         $curTarget = target @ %activeTarget;
         $targetActive = true;
         animateTargetUp(%myObj);
         schedule($roundTime[$round], 0, "animateTargetDown",%myObj);
         schedule(5000, 0, "initiateTargets");
         echo("function1 called");
      }

      if ($targetsActivated >= $winningScore[$round])//was ==
      {
         if($targetsActivated < $winningScore[3])
         echo("==>time to start round " @ $round);
      }
   }

   else if($gameActive $= 0)
   {
      endTargetGame();
   }

   echo("","Targets Activated = " @ $targetsActivated);
   echo("","Round = " @ $round);
}

function raiseTargets()
{
   for (%i = 0; %i <= 6; %i++)
   {
      %j = "target"@%i;
      %j.playThread(0,"up");
   }
}

function lowerTargets()
{
   for (%i = 0; %i <= 6; %i++)
   {
      %j = "target"@%i;
      %j.playThread(0,"down");
   }
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Scoring
//-----------------------------------------------------------------------------
function resetTargetScore()
{
   $score = 0;
   score.setValue("0");
   addScore();
}

function addScore()
{
   PlayGui.add(ScoreGui);
}

function removeScore()
{
   PlayGui.remove(ScoreGui);
}

function targetScore()
{
   $score++;
   score.setValue($score);
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Target Trigger
//-----------------------------------------------------------------------------
$TimesEntered=0;

datablock TriggerData(TargetTrigger)
{
   tickPeriodMS = 100;
};

function TargetTrigger::onEnterTrigger(%this,%trigger,%obj)
{
   $TimesEntered++;

   if ($timesEntered == 1)
   {
      Parent::onEnterTrigger(%this,%trigger,%obj);
      commenceTargetGame();
   }

   if ($timesEntered >= 1)
   {
      return;
   }
}

function TargetTrigger::onLeaveTrigger(%this,%trigger,%obj)
{
   Parent::onLeaveTrigger(%this,%trigger,%obj);

   if ($timesEntered == 1)
   {
      MessageToClient(5);
      removeScore();
   }

   else
   {
      return;
   }
}

function TargetTrigger::onTickTrigger(%this,%trigger)
{
   Parent::onTickTrigger(%this,%trigger);
}
//-----------------------------------------------------------------------------
That should give you enough to chew on for a while.
#3
04/19/2007 (3:09 am)
Thanks for the replies, I'll give them a try and come back as soon as I grasp it all.

Thanks again