My camera code

Not sure it’s the fastest way to do this since I’m better at scripting than knowing the whole blender feature set :stuck_out_tongue:

But basically here’s the code I finally got working, it’s what I was trying to do in one of my other questions.

import bge

def lerp(val1, val2, amt):
   return (val2 - val1)*amt+val1


def followObject(cont):
   own = cont.owner
   object = bge.logic.getCurrentScene().objects["object_you_want_to_focus_on"]
   pos = object.worldPosition
   top =object.getAxisVect([0.0,0.0,1.0])
   
   own_pos = own.worldPosition
   target = [pos[0]+(top[0]*40),pos[1]+(top[1]*40)+5,pos[2]+(top[2]*40)]
   
   own.worldPosition =    [lerp(own_pos[0],target[0],0.1), 
                                lerp(own_pos[1],target[1],0.1), 
                                lerp(own_pos[2],target[2],0.1)]
   
   avect = own.getVectTo(object)[1]
   own.alignAxisToVect([avect[0]*-1,avect[1]*-1,avect[2]*-1],2,0.1)

What I do for those new, I made my own lerp function above. Could be a function included in the python’s or blender’s api but I already knew the function so didn’t check and just made it. And it’s the basic Linear Interpolation function out there.

Next I make the actual followObject function that’ll make the camera, or any other object, align and follow with a delay at whatever object you tell it to.

I get the owner with and the object, then I get the object’s position and get its normalized z vector. Here:
pos = object.worldPosition
top = object.getAxisVect([0.0,0.0,1.0])
z vector because I want to align my camera to the top of the object. (you can easily align it with a different vector by just changing the vector passed to getAxisVect. Like [0.0,1.0,1.0] would be aligned diagonally going up and to the y axis.)

Next I get the owner position and make a target position by taking the object’s original position and adding onto it the normal I got earlier to each axis * 40. This will make a new 3d vector 40 blender units along the normal away from the original object’s position.

Next I set the camera’s worldPosition to a lerp of each axis in the target position we just made while making a new vector in the process. Since we’re using lerp it’ll make a nice smooth delay to the target position. Lerp is really really useful. Just like it’s cousin slerp. You can change the delay by messing with the float in lerp(own_pos[2],target[2],0.1) 0.0-1.0 .

Now we’ve moved the camera where we want we need to align it. So we’ll get a normalized vector pointing toward our object from our camera with getVectTo.

Now lastly we can easily align the camera to the vector because blender has something built in for it. We’ll use alignAxisToVect. And we’ll take the vector we just got and reverse it by multiplying *-1 because we need to align to the -z axis. Otherwise the camera will point to the opposite way. Then give it a 2 for z axis and lastly the float at the end can specify the delay just like before. 0.0-1.0

Here’s a blend showing a grey pointy thing with the behavior above and a red pointy thing with some cool tweaking to make it revolve around the main object while facing it! Enjoy!
camera.blend (555 KB)

So my first contribution back to the community ^-^ let me know what you guys think

Just a quick note. If you use code tags [ code] put code here

 Then it will preserve indentation:

if this and this:
do that



And yes, blender has a logic brick that does this, but I am interested to test out this version as well. Thanks

Right, I thought I remembered there was a bbcode for that. And of the logic bricks I know of, like I said I haven’t experimented with them all but I know of “edit object”>“track to” and I wasn’t getting the result I liked. Track to would pivot on the z axis and mess up my control scheme completely. That all could be worked around with time, but I’m lazy and making it myself was so much faster lol.

Plus it can be used for some nice effects like the one bit that orbits the cube, and it’s perfectly customizable too since it’s simple.

I was meaning the camera logic brick, not track-to. At least for the one on top.

Hi!
i not see the other TD :frowning:
but you have found the way :wink:

i want suggest to keep paking the vector when possible
you can put one vector directly in the function also.
in this way your code still more clear

avect = own.getVectTo(object)[1]
own.alignAxisToVect([avect[0]-1,avect[1]-1,avect[2]*-1],2,0.1)

to

avect = own.getVectTo(object)[1]
own.alignAxisToVect(-avect , 2, 0.1)

if you have dubt , if the variable keep the reference or not , you can use .copy() to be sure
to cut the reference , this return a vector new (without reference)

pos = obj.worldPosition
pos.x = 5000 # you see that the obj change position

pos = obj.worldPosition.copy()
pos.x = 5000 # you see that the obj NOT change position

plus this here other things that you can do with vector:

vector + vector = vector
vector - vector = vector
vector * vector = float!
vector * float = vector
matrix * vector = vector
vector * matrix = vector

but you here sure that is different from slow parent?? mhh
:wink:

Thanks for the tips on the vector math! I’m not a huge python programmer but I know enough to program in just about any language. And it is vastly different from slow parent for me :stuck_out_tongue:

My case if very specific, mostly in that I want my camera to hover above the player but not rotate with it. When I use parenting my camera rotates with it which screws up the design of the game. But for most cases slow parent works fine yes.

You can vertex parent if you don’t want it to rotate. (Select Camera, Shift+select Object. Tab, Select a vertex, Ctrl+P)

y not just copy the cameras world position to the players worldposition and add some z to the position. This would always keep location but not rotation…camera.worldPosition = player.worldPosition…then camera.worldPosition(2) = player.worldPosition(2) + 10…sorry phone will not indent =(

Because the player’s head might not always be pointing in the z-axis. In my game up could be many directions, I need it to hover over the player regardless of the player’s orientation. That’s the usefulness of this. The player could be on the wall and the camera will still be fine, or even walking on the roof. Or walking from the floor onto the wall and then onto the roof, the camera will stay in the relative location from the player that you set, and maintain it.

Also I want to point out Lerp which is a really cheap way to do a linear delay in anything. GUIs, movement, scales, whatever.

You can vertex parent if you don’t want it to rotate. (Select Camera, Shift+select Object. Tab, Select a vertex, Ctrl+P)

Yeah I heard about that, I tried it but it didn’t work for me. Caused wonky behavior.

Also, I’d like to point out the following:
Linear Interpolation is already included in Blender, as is Spherical Linear Interpolation. You can access it from the mathutils module, in many different classes.
You ought to use a list comprehension for applying identical transforms to components of vectors. However, in using the Vector.lerp method you needn’t modify individual components.

I didn’t see the other thread you mentioned, so…

Please provide a link to the thread… Or maybe you could write a short description of the this does. I tried reading through the explanation, but got totally lost.

Just dropping by to say thanks, i did not actually know about the lerp function, it’s amazing!
Thanks