[SOLVED] Creating a "look at" node setup

I am trying to figure out how to set up a “look at” with nodes. What I am trying to accomplish is the purple/blue box to point at the green box no matter where is moves. The purple/blue box should just rotate on the z axis so that it could “fire” on the green box. For this scenario the purple/blue box will be stationary. I guess I don’t understand the vector math or the “Look At” node well enough to make this work. Also, What axis (+y, -y, +x,-x) should the front (extending part of the purple/blue box) be on.

If any one can explain how the Look at node works in better detail that may be helpful also.

(edit)
I just noticed the Look node. However, I don’t understand it any better then the Look At. Would this be the way to go?

Thanks

Anyone have even a guess?

There’s a node for implementing haxe scripts, I’m pretty sure, so you could just once write this and then forget about the code, just drag your node in place again.
(in psuedocode because I’m remarkably lazy)

locOther=ob2.loc//the green box
locMine=ob.loc//the purple box
dif=locOther-locMine
max=math.sqrt(dif.x*dif.x+dif.y*dif.y+dif.z*dif.z)
dif.x/=max
dif.y/=max
dif.z/=max
angleX=math.ArcCos(dif.y)
angleY=math.ArcCos(dif.z)
angleZ=math.ArcCos(dif.x)
ob.setRotation(angleX,angleY,angleZ)

for example, assuming my memory of high school math is correct. This would obviously only work for one-eighth of three dimensional space, you have to use some if statements to decide when to inverse the values.

Alternatively write it in python and save it forever, you can copy it to other projects.

1 Like

I edited my response to be more accurate

We should get this a permanent logic node

If you only want to rotate around the z axis, this should work (at least accordgin to my testing):

First get the location of both objects (a cone and an icosphere in my case) and remove their z component, then subtract the position vectors and normalize the result, so you get the direction.

Then calculate the z angle. It is the angle between the x axis and our direction and can be calculated like this.


This setup might create a little hickup in the beginning, because for the perfect value of y = 0 neither floor nor ceil will provide an output. However this should not be that much of a problem when running the game, as the perfect 0 should never be created by any player driven character. If it is, one could just add a minimal value like 0.0001 to the y value before entering the floor / ceil nodes (which still would not remove the problem entirely but make it much more uncommon). A true fix would be to set it to +/-1 if the y value is exactly 0.

Finally, just apply the rotation.
image

(just to avoid any risc of misunderstanding, the output of each screenshot is the input of the next one)

1 Like

There is a “Look At” node, but I don’t know what it is doing exactly. From its UI looks it seems like it outputs the rotation an object that sits at the first vector looking at the second one, but its code seems like it outputs a quaternion which you can’t simply plug into a “Set Rotation” node, and also if I plug it into a print node the output doesn’t seem to be correct. I expected 4 floats, not this:

PrintNode.hx:12: {
name : ,
outputs : [[{
name : ,
outputs : [<…>],
inputs : [<…>,<…>],
tree : {
paused : <…>,
loopBreak : <…>,
_render2D : null,
_render : null,
_lateUpdate : null,
_update : <…>,
_remove : null,
init : null,
add : null,
name : <…>,
hx__closures
: <…>,
object : <…>
}
}]],
inputs : [{
node : {
name : ,
outputs : [<…>],
inputs : [<…>],
tree : {
paused : <…>,
loopBreak : <…>,
_render2D : null,
_render : null,
_lateUpdate : null,
_update : <…>,
_remove : null,
init : null,
add : null,
name : <…>,
hx__closures
: <…>,
object : <…>
}
},
from : 0
},{
node : {
name : ,
outputs : [<…>],
inputs : [<…>],
tree : {
paused : <…>,
loopBreak : <…>,
_render2D : null,
_render : null,
_lateUpdate : null,
_update : <…>,
_remove : null,
init : null,
add : null,
name : <…>,
hx__closures
: <…>,
object : <…>
}
},
from : 0
}],
tree : {
paused : false,
loopBreak : false,
_render2D : null,
_render : null,
_lateUpdate : null,
_update : [,],
_remove : null,
init : null,
add : null,
name : NodeTree_001,
hx__closures
: {
20 :
},
object : Mesh Object Plane
}
}

@Simonrazer - I found the same thing, I just didn’t understand what I was looking at when I did it or why I was getting such a weird outcome of plugging the look at node into set rotation. I guess we need a quat to vector node.

I was testing around a little. And yes the LookAt node does output a quat.
However there is currently no way (that I am aware of) to go from Quat -> Euler in nodes. You cannot even seperate the Quat.
In the logic pack, there is a Seperate Quat node, but

  • it seems to be incompatible with upstream armory
  • it requests a transform, not a quat.

After modifying the node, I was easily able to make a cone look at me, whereever I was using this setup

However, I think there still are some issues with this:

  • LookAt always uses the Z axis, so if you arrange your objects like this in Blender:
    image
    This will be the result:
    image
    As you can see the tip is pointing towards me, although it is the upwards facing part of the cone.
  • When walking around the cone, it will always look at me, but rotate around its local z axis.

Changing the LookAt nodes source to use the x axis improved this somewhat, so I guess adding a “facing direction” input to the LookAt node would be a good idea.
Also, if that node would directly output an Euler vector instead of / alongside a Quat, one would not even need the SeperateQuat node.

So that’s what I’ve found out for now. I will push the new SeperateQuat node to the logic_pack. As for the LookAt node, I think adding a facing input and euler output would be a good idea, but I might have just misunderstood the concept of the node.

1 Like

Thank you very much for your work on this. I believe this is one of those things that will be a big addition/improvement for many games. Looking at your enemy is a pretty standard part of any tower defense and many other games.

Armory will need a LookAt that works for very situation,with constraints axis options also.

I just created a new pull request for the logic pack, which features a new Looking at node, which

  • expects two objects
  • expects a main rotation axis (most likely the z axis)
  • expects a face vector (most likely the x axis) (This is not intended to change during the game, I do not recommend using a vector from transform node) (actually this is the face vector in local coordinates, and thus most likely the x axis)

image
image

It rotates the first object to look at the second one.
First it rotates around the main axis (like your head looking left/right) and then around a secondary axis defined by the cross product of the main axis and the position-difference vector (think of looking up/down).
Looking into constraints now.

5 Likes

This is awesome. Can’t wait to give it a go.

Needs the progressive versions of Look_at :
Look_at_linear
Look_at_lerp

To get some object turns at their own speed.

There is many applications, like characters that have rotation speed and other game objects.

1 Like

@zaethan I tried this and it works fine except one thing. What if I don’t want any rotation on a secondary axis? What would I set the main axis vector to in order to accomplish this?

I think we need an extra Bool input for that. I don’t think this can be accomplished by using the main axis vector.
While I was testing around with constraints, I also added the option to disable the secondary rotation. However the other things did not work as I wanted them to, so I didn’t push anything yet

I haven’t fully tested it yet but I tried changing the code and commented out the section with the secondary axis. Hopefully that will solve my issue.

I have created a new pull reqeust with a new version of the node.
It now looks like this:

To use the new node you have to remove and re-add it to the nodetree.
An example setup:

  • It now uses the position vectors instead of the objects and outputs the rotation as euler or quat instead of applying it.
  • The Bool output is true, unless a restriction property is enabled and the rotation would exceed that restriction. This can then then be used with a IsTrue or Branch node to turn rotation on and off, if the object cannot see the other one. (This way you could switch between casually looking around and targeting an object. Think of a security camera which scans the area in front of it, until it sees you and goes bak to scanning when it cannot see you anymore)
  • By outputting the rotation, one should be able to use the linear interpolation node to make an object have its own rotation speed by interpolating between the current and the new rotation.
4 Likes

@zaethan - Thanks for all your work on this - It is working perfectly at this point. Have one question for you. I am using this this node to have a cannon (for the lack of a better word) that will fire at my character. The tower turns and faces the character correctly, so then I put a empty in from of the tower and parented it to the tower. then I am spawning a projectile to fire at the character. The problem is the impluse is in world space so it doesn’t fire forward. Any ideas on how to fix this. I don’t see anything to use local space.

Edit: by placing the resulting vector from the node into the impulse input i get the projectile moving in the right direction. Just with no velocity. Still seeing what I cam come up with to add velocity to it.

Edit 2: I think I need to do some vector math to add the velocity but don’t really understand it well enough. What you use to accomplish this?

Edit 3: or if there is a way to create a impulse along local axis node, I think that would work. Sorry I don’t know how to modify the translate on local axis node to do this.

That’s exactly what I’m looking for. I really don’t know how to edit an existing node to this.
Is there a way to download your node?
Thx for your answer