Adding object at ray hit position and rotation!

How do I add object from inactive layer to active one at ray hitPosition facing directly to ray, or even better - aligned to ray hitNormal direction. I just need to know how exactly is it done.

import bge
cont = bge.logic.getCurrentController()
own=cont.owner

ray = cont.sensors['Ray']

if ray.positive:
    added = bge.logic.getCurrentScene().addObject('objectName',own,duration)
    added.alignAxisToVect(ray.hitPosition-own.worldPosition, 0, 1)
    added.worldPosition= ray.hitPosition

if you want to align to hitNormal you can do that as well,
but I think you have to add

from mathutils import Vector

just under import bge,

and do

alignAxisToVect(Vector(ray.hitNormal),axis,time)

Oh… Will this work if I add a lot of objects like that in a row(add a new one when previous one is not gone yet)?


AttributeError: Vector subtraction: (list - Vector) invalid type for this operation

it shows this error for this line:


added.alignAxisToVect(ray.hitPosition-own.worldPosition, 0, 1)

Otherwise it works very well, thanks!:slight_smile: But aligning rotation not yet. However, is it possible to align rotation to a hitNormal?

OK! Now 2 more questions:
*How to align the added object rotation to ray hit normal?
*How to parent the added object to the hit object(so it stays on it’s surface)?

Just aligning axis left. The parent was easy:


added.setParent(ray.hitObject, 0, 0)

AttributeError: Vector subtraction: (list - Vector) invalid type for this operation

Looks like ray.hitPosition is a list, do you have xray enabled? either way I would replace:

ray.hitPosition

with

ray.hitPosition[0]

for the first item in that list.

Hopefully this helps

Hey, will this work?


added.alignAxisToVect(ray.hitNormal)

Yes, final script is:


import bge
cont = bge.logic.getCurrentController()
own=cont.owner

ray = cont.sensors['Ray']

if ray.positive:
    added = bge.logic.getCurrentScene().addObject('objectName',own,duration)
    added.alignAxisToVect(ray.hitNormal)
    added.worldPosition= ray.hitPosition
    added.setParent(ray.hitObject, 0, 0)

Just FYI, by default the hitnormal of a ray will return the actual normal of the surface it hits, but there’s a flag you can toggle when casting the ray to change it so the normal will always point back along the ray towards its origin (so if you want something to point back along the ray, there’s no need to subtract the hit position from the ray origin).

not in a ray sensor, it always returns the face normal

and if you have the end point vector of the ray you can use that and align to it before you move the object to the hitpoint, (in own.rayCast)

Ah yep, I was thinking of raycast, and I had it backwards- by default a raycast normal points back to the ray’s origin, you can set a flag to get the normal of the hit face instead. Apologies!

  • face (integer) – normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin

http://www.blender.org/api/blender_python_api_2_75_1/bge.types.KX_GameObject.html?highlight=raycast#bge.types.KX_GameObject.rayCast