Blender game get coords of an object in another object's local space

Hello,
I am making a FPS , and I want to implement one of those hit direction detection things… [That red thing in the image around the crosshair]

to do this , I kinda have an idea but need help with writing the code for it.


[Dont worry, this is not my game scene]
That angle is the angle for the detection thing
Is there a better and more efficient way to do this?
also what do you call that detection thing?

[follow towards the 12th post, the title of this thread was edited]

if you know who hit you, you can get the world vector
wvec = enemy.worldPosition-owner.worldPosition

and then translate it to local space
lvec = owner.worldOrientation.inverted()@wvec

you likely want to ignore the Z axis
lvec[2] = 0
lvec.normalize()

lastly, you need a hud element that points the axis that the player faces (assume Y).
align the object to your lvec
hitdetect.alignAxisToVect(lvec, 1, 1.0) aligns the objects Y to the local hit vector
hitdetect.alignAxisToVect([0,0,1], 2, 1.0) aligns to camera to stay flat

might get the job done but out of curiosity,
what does the “@” do?

and i got an error:

 unsupported operand type(s) for @: 'Matrix' and 'Vector'

bge? use * instead of @

i did the * instead of the @ and it kinda works as long as i only move…
but if I turn, the thing goes haywire
update: it goes haywire anyway even if i only move
update 2: it seems to scale up if i bring it too close to the target object

blender 2.8 requires the @

without a blend, i cant know for sure.

I should’ve mentioned this at the begining. . .
i am using blender internal game engine 2.79 [no upbge or armory3d]

so i was messing around doing research and made this:

lobj = own.worldPosition - obj.worldPosition
lobj = own.worldOrientation * lobj
angle = atan(lobj.z/lobj.x) *180/3.1415

but , this too does’nt work

This will give you the angle of player to shooter.

    import math

    own = cont.owner

    shooter = own.scene.objects['shooter'].worldPosition    
    angle = own.worldOrientation.col[1].angle(shooter)
    
    print(math.degrees(angle))

now you need to put the hit locator at that angle (assuming Y axis is player forwards/north)

#edit maybe you need some more info:

  • add circle 8 verts (instead of default 32)
  • extrude it inwards
  • select all rotate it a bit so top line gets nice and flat
  • select 1 face of it
  • hit p select by selection
  • remove the others

now you have 1 piece of the cake that can rotate around, putting that piece.orientation on that angle wil give you the indication

Just a minor change with the angle measurement thing,
step 1>> get enemy position in player local space
step 2>> project the enemy position onto the player’s local x-z plane [basically, enemy.position.y = 0]
step 3>> get angle between the local z axis and the other line from the player’s origin to the projected enemy.

anyone know how to code this?
btw im ok with radians no need to convert it to deg.

Now , i need to do the ‘step 1’ part.
i have to get the coordinates of an object in another object’s local space
how do i do this?
[i edited the title for this]

this?

local_coord = obj.worldTransform.inverted() * obj.worldPosition

yes @Cotacks,
but there should be two objects in that line of code right?
i dont understand
is “obj” the frame of reference or the other object?

yes, and you would need a bit more then that, so i created a blend for you let me know if this is what you want.

green = player
red = shooter
orange = indicator

indicator will shows the direction to shooter from the players pos, so if it is a bit off that is correct for the setup we have, parent the indicator to the player and it works flawlessly, now you should be able to either parent it or use it in an overlay scene.

# Hit indicator by cotaks

def test(cont):
    
    own = cont.owner
    
    player = own
    hit_locator = own.scene.objects['hit_locator']
    shooter = own.scene.objects['shooter']

    local_coord = player.worldTransform.inverted() * shooter.worldPosition

    angle = player.localOrientation.col[1].angle(local_coord)
    
    ori = player.worldOrientation.to_euler()
    ori.z = -angle
    
    pos = player.worldPosition - shooter.worldPosition
    
    if pos.x > 0.0:
        ori.z = angle
        
    hit_locator.localOrientation = ori

hit indicator.blend (532.8 KB)

Thanks,
I found the solution
and thanks for the blend file @cotacks