Page 1 of 1

Detecting unit depth in water.

Posted: 27 Dec 2010, 08:28
by smoth
So I want to do some cool stuff with animation but I need a way to tell if the unit is underwater or even better the specific unit depth in the water. Now, I am currently using:

Code: Select all

setSFXoccupy(setSFXoccupy_argument)
{	
terraintype = setSFXoccupy_argument;	

		if(terraintype == 2)
		{	
		SET MAX_SPEED to [4]; 	
		
		speedMult 	=	5;
		}
			else
			{	
			SET MAX_SPEED to [1.0];	
			speedMult 	=	2.5;
			}
			
	get PRINT(get GROUND_WATER_HEIGHT(get PIECE_XZ(base)));
	
	if(get GROUND_WATER_HEIGHT(get PIECE_XZ(base)) <= -50000) 
	{	hide head;	}
	else
	{	show head;	}
}
Fun shit is that the head hides as soon as the toe touches the water. Also sfx occupy doesn't seem to to trigger except when the unit enters or leaves and fun shit is that the getwater height even though it is printing shit like:
[ 326] Value 1: 431640, 2: 0, 3: 0, 4: 0
[ 336] Value 1: 431640, 2: 0, 3: 0, 4: 0
[ 592] Value 1: -38516, 2: 0, 3: 0, 4: 0
[ 608] Value 1: -938666, 2: 0, 3: 0, 4: 0
[ 768] Value 1: -173538, 2: 0, 3: 0, 4: 0
[ 800] Value 1: -61020, 2: 0, 3: 0, 4: 0
[ 928] Value 1: -151035, 2: 0, 3: 0, 4: 0
the head hides as soon as the unit touches water :|

So maybe I need to be doing this different. I am not against setting up a gadget to test when units are in the water and then checking unit depth(assuming such a thing is possible) however, I wanted to ask around.

Here is what I am going to try and do. Effectively, I want to detect when a unit reaches a specific depth(this is an amphibious unit) at this point in time the unit will switch over to a swim mode animation with speed boost. However, AS IT stands now I can only pick up in or out of water, rather silly and sadly kind of stupid. So I was hoping someone here may have some idea. There are no examples of such a thing in spring and before someone says pelican, that is a hover unit and it doesn't have to check actual depth.

Re: Detecting unit depth in water.

Posted: 27 Dec 2010, 09:13
by yuritch
SetSFXOccupy is not good for what you want.

I used the following code to make an amphib unit:

Code: Select all

WaterCheck()
{
	var GroundHeight;
	while(TRUE)
	{
		GroundHeight=get GROUND_WATER_HEIGHT(get PIECE_XZ(hull));
		if (GroundHeight<=FLOAT_DEPTH)
		{
			bFloating = TRUE;
			move hull to y-axis FLOAT_DEPTH speed [5];
			turn hull to x-axis 0 speed <90>;
			turn hull to z-axis 0 speed <90>;
			if(bMoving)
			{
				emit-sfx SFXTYPE_WAKE1 from wake;
			}
			set MAX_SPEED to WaterSpeed;
			set UPRIGHT to 1;
		}
		else
		{
			bFloating = FALSE;
			if (GroundHeight<0)
			{
				move hull to y-axis GroundHeight now;
			}
			else
			{
				move hull to y-axis [0] now;
			}
			set MAX_SPEED to LandSpeed;
			set UPRIGHT to 0;
		}
		sleep 150;
	}
}
The unit is a vehicle, and upon reaching certain depth, it "floats up": wheels no longer touch the bottom, it becomes upright and gets much lower speed (too bad I can't make it stop leaving tracks on the bottom). WaterCheck() is started from Create().

This works reliably as far as I can tell. It can be optimized of course, for example setSFXOccupy might be used to disable the looping check when unit is out of the water and enable it again when it enters the water. Not that there is any noticeable performance loss with dozens of that unit on a map as it is.

And technically my vehicle is a hover, because there is no other (simple) way to make it float on the water surface. However upright=0 hovers behave like vehicles on land.

Re: Detecting unit depth in water.

Posted: 27 Dec 2010, 17:43
by SanadaUjiosan
Oh how I wish this conversation happened months ago. I may be working with these examples soon for something I wanted to do a long time ago.

Re: Detecting unit depth in water.

Posted: 27 Dec 2010, 17:48
by smoth
sanada, I will tell you what one of my programming instructors once told me.

Never be afraid to ask, odds are someone has already solved the problem and you will likely waste a lot of time in redundant effort when you simply could have asked.

Re: Detecting unit depth in water.

Posted: 29 Dec 2010, 00:03
by Deadnight Warrior
I had a similar problem with XTA amphibious ships. This code controls wether the ship is deep enough to sail or use it's wheels for land:

Code: Select all

MotionControl()
{
	var waterdepth;
	while( TRUE )
	{
		waterdepth = get GROUND_WATER_HEIGHT(get UNIT_XZ);
		if( waterdepth < [-6.9] ) {
			set UPRIGHT to 1;
		}
		else
		{
			set UPRIGHT to 0;
			if( waterdepth < 0)
				move body to y-axis ([6.9]+waterdepth) now;
			else
				move body to y-axis [0.0] now;		
		}
		if( ( !Floating ) AND (waterdepth < [-6.9]) )
		{
			move body to y-axis [0.0] now;
			Floating = 1;
			call-script transform();
			if (bMoving) start-script swim();
		}
		else if( Floating AND (waterdepth > [-6.9]) )
		{
			call-script reform();
			Floating = 0;
			turn base to x-axis <0.0> now;
			turn base to z-axis <0.0> now;
			if (bMoving) call-script walk();
		}
		sleep 66;
	}
}

Re: Detecting unit depth in water.

Posted: 03 Jun 2012, 13:09
by PicassoCT
Is there a lua version of this somewhere?

Re: Detecting unit depth in water.

Posted: 03 Jun 2012, 16:12
by FireStorm_
You can check out the shiva in BAR (look for "Swimming Animation")
Or find the skeleton script from the Cursed, which the shiva script is based on, regarding changing behaviour in water.

Re: Detecting unit depth in water.

Posted: 04 Jun 2012, 06:14
by knorke
for an alternative to the "poll y-position every blub moments" try:
UnitEnteredWater()
UnitLeftWater()
http://springrts.com/wiki/LuaCallinReturn

Re: Detecting unit depth in water.

Posted: 04 Jun 2012, 08:19
by PicassoCT
knorke wrote:for an alternative to the "poll y-position every blub moments" try:
UnitEnteredWater()
UnitLeftWater()
http://springrts.com/wiki/LuaCallinReturn
to awesome, to late.. i did it again .. : (

Re: Detecting unit depth in water.

Posted: 04 Jun 2012, 12:13
by Google_Frog
yuritch wrote:too bad I can't make it stop leaving tracks on the bottom
Just do Spring.SetUnitLeaveTracks(unitID, false) in the unit script.