Boats floating on water

in the game engine, i cant seem to figure out how to make a boat float on water, can i do it with the logic bricks or is there a python script for it?

how about not making it dynamic?

It depends what sort of floating you want. You could try implement buoyancy: if you don’t want to make it completely accurate (theres no need to if you can make it look right with less), then all you need to do is add a force pushing an object upwards (opposite to gravity) when the object is below water level.

Or you could just have a normal static plane that looks like water and have the boat just move normally on that…?

Maybe even sub-divide the plane to create animated waves, cast a ray below the boat to find the point on the water plane thats closest to the boat and reposition the boat on the z-axis to align it with the wave on the water plane. If done right, the boat should remain on top of water, and bob up/down with the waves.

I really like your idea Hendore, but what about smoothening the motion of the boat? I thought about making the boat’s normal equivalent to the hit normal, so the boat would basically sail on top, but what if the boat started moving…? The boat would move and rotate in a choppy, unrealistic manner – almost instantly going to the correct position and rotation. It would look better if it was almost delayed in a way, right? Sure, you could do something like:

if own.position[2] > ray.hitPosition:
own.position = own.position[0], own.position[1], own.position[2] - 0.1
elif own.position[2] < ray.hitPosition:
own.position = own.position[0], own.position[1], own.position[2] + 0.1
elif own.position[2] == ray.hiPosition:
own.position = ray.hitPosition

^ to slowly make the boat’s position equivalent to the ray.hitPosition… but how would you do that for the rotation?

I dont mean to be picky, especially since I dont have any boat problems at the moment (I’ve ran into some problems before, though).

Too complicated and resource intensive!!! Especially if you have a large game…

You wouldn’t have to reposition anything if you just recalculated the wave mesh every tick. (which is the reason that it is so resource intensive)
If you want the script to do that…its right here:

# From -
##Animates a mesh to wave.##
##Mode can be 'radial','linearX','linearY', or 'linearXY'##
##Use recalculatemesh to recalculate the physics mesh.
##WARNING: recalculation can cause slow downs.
def meshWave(ob,speed,amplitude,length,mode='radial',x=0,y=0,recalulatemesh=True):
	import time
	if not ob.has_key('init'):
		ob['init'] = time.clock()
	elapsedT = (time.clock()-ob['init'])*speed
	verts = getVertexArray(ob.meshes[0])
	if not ob.has_key('init'):
		ob['init'] = 1
	for vert in verts:
		pos = vert.getXYZ()
		if mode == 'radial':
			dist = sqrt((pos[0]-x)**2+(pos[1]-y)**2)
			z = sin((dist/length)+elapsedT*pi/180*90)*amplitude
		elif mode == 'linearX':
			z = sin((pos[0]/length)+elapsedT*pi/180*90)*amplitude
		elif mode == 'linearY':
			z = sin((pos[1]/length)+elapsedT*pi/180*90)*amplitude
		elif mode == 'linearXY':
			z = sin((pos[0]/length)+elapsedT*pi/180*90)*cos((pos[1]/length)+elapsedT*pi/180*90)*amplitude
	if recalulatemesh: ob.reinstancePhysicsMesh()

object = GameLogic.getCurrentController().owner
speed = 10
amplitude = 5
length = 10
mode = 'radial'
x = own.worldPosition[0]
y = own.worldPosition[0]
recalcMesh = True # reinstance the physics mesh.

meshWave(object, speed, amplitude, length, mode, x, y, recalcMesh)

It should work…I didn’t remember what all the parameters did…but I just made them up…

This script should be attached to the water.


I might try that! i will post my results in a second.

ok i tried it and it kind of worked though it kept on jumping out of the water, i wish it would just float like a real boat would

The upwards force you add needs to be higher when the object is deeper in water, the force should decrease as the object raises so that when it is level/near level with the water surface, the gravity and upwards/lift forces should be similar values. May take a little tweaking.

how would i do that?

Try this hope it will help.