I currently am trying to set bounds for my nav mesh using the location constraint. That would have worked perfectly, but of course constraints are not available in the game engine. Is it possible to replicate this functionality easily?
1 Answer
Constraints are available, as actuators, but seem to be working strangely.
The constraint clearly has an effect, but it's not the hard boundary I would expect. The cube is still falling at a slow speed.
The documentation for Location Constraint says:
Limit the position of the Game Object within one World Axis direction. To limit movement within an area or volume, use two or three constraints.
It implies that this constraint should be a hard limit instead of a slow-down effect.
Maybe Blender is buggy, so I tried to make this simple constraint as a Python script.
import bge
controller = bge.logic.getCurrentController()
current_object = controller.owner
if current_object.worldPosition.z < 0.0:
current_object.worldPosition.z = 0.0
But the effect was the same! It was still slowly slipping downwards.
I guess it's because of the ever increasing downward speed, which teleports the objects further and further from the boundary after the constraint teleports it back to the boundary. The constraint works, but because it's not the only effect on the object, it's looks like it fails strangely.
To fix that, I see two practical possibilities:
- Nullify the velocity of the object. This has the effect of the boundary being "sticky", as it also nullifies movement parallel to the boundary. Adding
current_object.setLinearVelocity((0.0, 0.0, 0.0))
to the above script has this effect. - Switch off or negate the force and associated momentum when the object is at the boundary. This requires knowing all forces that act on the object.
Extending the above script:
import bge
controller = bge.logic.getCurrentController()
current_object = controller.owner
velocity = current_object.getLinearVelocity()
if velocity.z < 0.0 and current_object.worldPosition.z < 0.0:
current_object.worldPosition.z = 0.0
velocity.z = 0.0
current_object.setLinearVelocity(velocity)
It has the correct effect of limiting to the boundary, but random or changing forces pushing towards the boundary will create a small wobbly effect.
This all works on the object's "center", so if you want to have the object meeting a surface instead of intersecting it, you will have to calculate the boundary with the correct offset for the object.