Implemented Swimming/But Why Isnt This Working
by J.C. Smith · in Torque Game Engine Advanced · 05/04/2006 (11:00 am) · 3 replies
Hey all. Been one of those 10 hour debugging sessions where I just can't figure out a problem I had while implementing swimming. Swimming itself is now functioning.
The basic idea was that I made an invisible (null texture) DIF and placed it about 5 feet below the water level, and then our players could walk on top of that, and we could let our boats float on top of it. That part works.
Part two of that was that I would check to see if our position is submerged more than a meter in the water (by using a hack, since the TSE waterblock doesn't have a working submerged level check). That part also works.
The third part is where I'm having the bug though, and it's odd because it seems like it should be such an easy check. When the player fires a weapon I have the onFire do a check to see is we are submerged (by exposing this to the console) are if we are I have it manually override our image state back to ready. The problem must be in the consolefunction, but I can't see where and I'm getting frustrated. Maybe someone will look at this and figure it out instantly, as sometimes can be the case. This is edited for brevity, but you must also set up the SwimAnim in yoru player.h and player.cpp files for whatever slot it needs to be in your project (depending on animations)
In the public area of the player definition in player.h we have this:
and in player.cpp we have this:
Before the settimescale in setactionthread()
and I hacked the point in water function to look like this:
Basically I modified PointinWater so that it didn't require it to be an eWaterObjectType. Now using this code I am positive that the watercheckis working 100% by the results in game. If you are less than a meter in the water you will be running, once you get a meter in, it switches to a swim animation. That works flawlessly, meaning that the checkifswimming() is working fine from C++.
However when I call the function from the console (or from my onfire method) I get unexpected results. On one part of my map it works perfectly and on other regions it doesn't work at all. So say our client is 6395 and I do an echo(6395.player.isSwimming()); from the console, I get unexpected results. Often it displays true (1) when I am not in the water, and that has caused my routine to disable firing while submerged to give unexpected results. Meanwhile it's working 100% on the animations so in C++ the routines are working, it has something to do with how I am exposing the functions to the console, but I am stumped.
If anyone has any ideas let me know. If not, maybe this will serve to show someone an easy way to rig in swimming in TSE.
The basic idea was that I made an invisible (null texture) DIF and placed it about 5 feet below the water level, and then our players could walk on top of that, and we could let our boats float on top of it. That part works.
Part two of that was that I would check to see if our position is submerged more than a meter in the water (by using a hack, since the TSE waterblock doesn't have a working submerged level check). That part also works.
The third part is where I'm having the bug though, and it's odd because it seems like it should be such an easy check. When the player fires a weapon I have the onFire do a check to see is we are submerged (by exposing this to the console) are if we are I have it manually override our image state back to ready. The problem must be in the consolefunction, but I can't see where and I'm getting frustrated. Maybe someone will look at this and figure it out instantly, as sometimes can be the case. This is edited for brevity, but you must also set up the SwimAnim in yoru player.h and player.cpp files for whatever slot it needs to be in your project (depending on animations)
In the public area of the player definition in player.h we have this:
bool checkIfSwimming(); bool mSwimming;
and in player.cpp we have this:
bool Player::checkIfSwimming()
{
Point3F curPos = getPosition();
if (pointInWater( Point3F(curPos.x, curPos.y, (curPos.z + 1.0f) )))
{
return true;
}
return false;
}
ConsoleMethod( Player, isSwimming, bool, 2, 2, "Returns if a player is swimming")
{
return object->checkIfSwimming();
}Before the settimescale in setactionthread()
if (checkIfSwimming()) setActionThread(PlayerData::SwimAnim,true,false,false);
and I hacked the point in water function to look like this:
bool Player::pointInWater( Point3F &point )
{
SimpleQueryList sql;
if (isServerObject())
gServerSceneGraph->getWaterObjectList(sql);
else
gClientSceneGraph->getWaterObjectList(sql);
for (U32 i = 0; i < sql.mList.size(); i++)
{
WaterBlock* pBlock = dynamic_cast<WaterBlock*>(sql.mList[i]);
if (pBlock->isUnderwater( point ))
{
return true;
}
}
return false;
}Basically I modified PointinWater so that it didn't require it to be an eWaterObjectType. Now using this code I am positive that the watercheckis working 100% by the results in game. If you are less than a meter in the water you will be running, once you get a meter in, it switches to a swim animation. That works flawlessly, meaning that the checkifswimming() is working fine from C++.
However when I call the function from the console (or from my onfire method) I get unexpected results. On one part of my map it works perfectly and on other regions it doesn't work at all. So say our client is 6395 and I do an echo(6395.player.isSwimming()); from the console, I get unexpected results. Often it displays true (1) when I am not in the water, and that has caused my routine to disable firing while submerged to give unexpected results. Meanwhile it's working 100% on the animations so in C++ the routines are working, it has something to do with how I am exposing the functions to the console, but I am stumped.
If anyone has any ideas let me know. If not, maybe this will serve to show someone an easy way to rig in swimming in TSE.
#2
05/05/2006 (3:17 am)
Why not just use the built in ShapeBaseImage 'is wet' state check? I'm not sure if it works in TSE, but I would recommend using it over a script base method. Search for "getImageWetState" in the shapeBase files if you'd like to take a look at it.
#3
It's a wierd bug. I've put con::print statements in to see exactly what it's doing, and it's giving odd behaviors. Any time that you are actually in the water... it correctly is set at 1. If you are not in the water, then depending on where you are standing, it is either properly at 0 or it is cycling between 0 and 1 at intervals. I tried networking it, that didn't solve it.
In certain positions though your always out of the water, and in certian others it's buggy, which leads me to believe that it maybe it's as stated above, a bug with the TSE waterblocks. I'm not sure. The thing that sticks in my mind though is that the animations are always correct, when I'm in the water at the proper point (1.0f deep) then it always puts me into swimming mode, and when I am not, then it uses the normal run animations. Even in the areas where the check is giving the oscillating true and false on the checks, the animation is always right. Which completely befuddles me.
For wet flag, I don't think it's working for TSE. I tried doing a stateTransitionOnWet in the weaponimage, but it never transitions.
05/05/2006 (6:04 am)
Hey all. Thanks for the responses. It's a wierd bug. I've put con::print statements in to see exactly what it's doing, and it's giving odd behaviors. Any time that you are actually in the water... it correctly is set at 1. If you are not in the water, then depending on where you are standing, it is either properly at 0 or it is cycling between 0 and 1 at intervals. I tried networking it, that didn't solve it.
In certain positions though your always out of the water, and in certian others it's buggy, which leads me to believe that it maybe it's as stated above, a bug with the TSE waterblocks. I'm not sure. The thing that sticks in my mind though is that the animations are always correct, when I'm in the water at the proper point (1.0f deep) then it always puts me into swimming mode, and when I am not, then it uses the normal run animations. Even in the areas where the check is giving the oscillating true and false on the checks, the animation is always right. Which completely befuddles me.
For wet flag, I don't think it's working for TSE. I tried doing a stateTransitionOnWet in the weaponimage, but it never transitions.
Torque Owner Dave
I don't know, but could this be having a knock-on effect with your code? Are the places where these unexpected events happen below the waterblock level?
Dave.