I was not able to reproduce the behavior you describe. So I can’t tell what your exact situation is.
You do a lot of things that are not necessary. That might implement some unwanted side-effects. When you want to let the arrow stuck I think all you need is:
- place the arrow at the hit position (via setWorldPosition)
- parent the arrow to the hit object (via setParent) [this makes the object static already = no velocities]
Especially the last point has a lot of redundancies in your implementation. But I would say they should not harm.
You have two expressions with the same code [not “done” in own]. Your condition check does not benefit from that. I suggest you move it to an outer condition check:
if not "done" in own:
Additionally I suggest to avoid “ray”. While it reduces the code to a minimum it still reminds my on the cryptic notation of accountants ;). I recommend to name it hitObject as this expresses what it is rather than ray.
hitObject, hitPosition, hitNormal = rayCast(...
From what I see you do not even need the property “done”. I guess this arrow stuck just one time. I do not see the logic at your arrow object (because you selected the cube rather than the arrow). So I assume you have following logic:
ray sensor -> python controller.
supposed to stuck the arrow when the ray triggers.
To make this more efficient especially after you fired really a lot of arrows, it would be nice to avoid any running controllers and any evaluated ray sensors on the already hit arrows.
Replace the complete object. As you replace the mesh and completely change the arrows behavior, I think this is the bests option in your situation.
owner.worldPosition = hitPosition
stuckArrow = scene.addObject("stuckArrow", owner)
Switch state. This way the sensor and the controller are completely disabled and do not waste any time. You can do that via state actuator or via Python.
I hope it helps somehow