# In game engine with python, add appendage to object

I'm doing scripting in the game engine. I have two basic objects, a "SeaFloor" and "Kelp". I have python classes for each and the game engine.

My goal is to add the Kelp object to the scene and root it to the SeaFloor, so in the physics of the game it won't be moved by fish or current. Also, as the kelp grows, I only want it to grow "up".

I can get the kelp to appear using:

kelp = self.scene.addObject("Kelp", "SeaFloor")
kelp.worldPosition = pos


I think I have to do this with constraints, but I don't understand them very well. I would appreciate some advice on how to lock those two together.

These are two different tasks. Lets deal with them separately.

# Grow

I suggest you let the objects grow via an animation (e.g. shape-key, armature). With that you have full control how it grows.

When you use scaling ensure the object origin is at the button of the plant as scaling is always relative to the origin.

# Positioning

A simple solution is to check the ground "under" the object. Typically "under" is along -Z.

Perform a ray check along -Z starting from current position. Check for ground (property filter). Then you can place the object at the found hitPosition.

Check the BGE API for rayCast()

Example:

lookAtPosition = kelp.worldPosition.copy()
lookAtPosition .z -= 1 # position below current position
distanceToCheck = 100.0

hitObject, hitPosition, hitNormal = rayCast(
lookAtPosition,
kelp.worldPosition,
distanceToCheck,
"ground")

kelp.worldPosition = hitPosition


I hope it helps

• Thanks @Monster. If I understand this correctly, the logic is (1) grab the kelp position (2) create a segment "down" from that position then (3) continue looking along that segment until I see an object named "ground". Will kelp.worldPosition then place it halfway up the stock? – Brian Dolan Jul 27 '16 at 13:37
• I think you see it correctly. But I would not use the term "segment" but "position". RayCast() needs two positions - the position to look from (I assume you want the current position) and a position to look at. The max distance to check is defined by the distance parameter (this can exceed the distance to the look at position). The kelp will be placed exactly at the found intersection position (hit point). – Monster Jul 28 '16 at 6:31
• Follow up, if you'll indulge me. I used your function with "SeaFloor" and it did not work. The docs say that argument is " property name that object must have; can be omitted or “” => detect any object" but I can't figure out how to set that property. I tried own['ground'] = 'ground' in the SeaFloor init function to no avail. Leaving it as "" worked, but it finds everything beneath it. – Brian Dolan Jul 28 '16 at 7:46
• Simply add the property via GUI. It must exist. The type and value does not matter. – Monster Jul 29 '16 at 6:09