Dynamic Camera Focus Help

Hello,

I am wondering if there is a way I can sort of “ray-cast” or something (I don’t know a lot about this kind of thing.) that would set the focal point of the camera. Using, say, an empty as the point of focus and make the camera track to it. I’d need the empty to, basically, check if there is a wall, or collision object and if so, stick the empty to it and have the camera track the position, as if the empty is a projectile.

Or, instead of having the camera track it, just fire the empty at a wall, like a projectile, and see if it hits, and if so, make that the focal distance/center, since the empty will always be at the center and do this every tick for the entirety of the game.

I may have already answered my own question, but I have no idea how I might construct something like this using logic bricks/Python code.

I think I’d prefer python, so I don’t have to setup a lot of bricks each time, but bricks are fine too, they might be simpler.

Thanks in advance! Sorry I’m such an idiot.

Also, for a reference of what I am trying to do:

I’ve noticed that people in games do a “head-bob” effect, but it tends to be disorienting, since our eyes cancel out such an effect naturally. I’ve noticed when I walk, I still feel the effect, but it’s only cancelled in the focus of my eyes, not in my peripheral vision. So I just need the focus to stay still while the camera does the “head-bob”, so it’s still “realistic”, but not so disorienting.

http://devlog-martinsh.blogspot.com.es/search/label/DoF

I must admiy by your original post i didnt actually understand the result your are trying to acheive. I came up with a few theories as to what i think your asking.

  1. You are tracking an enemy behind a wall, and once the enemy walk behind the wall out of view, you want the camera to keep tracking the enemies postion on the other side of the wall as it moves accross the wall, and then the camera still be tracked to the enemy when it comes out from behind the wall.

  2. If an enemy is walking behind the wall, as soon as the enemy moves behind the wall, you want the camera to shoot/ go to the wall, and track the enemy from just on the other side of the wall and return to the normal position when the enemy come out from behind the wall.

  3. You want the camera to move around the wall to keep the enemy in focus when its on the other side of the wall. Then return to normal position after the enemy comes out from behind the wall.

  4. BPR - using DOF to keep the enemy in focus when it goes behind wall, blurring the wall and keeping the enemy sharp in focus.

  5. Shooting the camera through the wall to keep the enemy in focus, then returning to original position after the enemy comes out from behind the wall.

Not sure what the head bop has to do with this.

We are going to need some extreme clarification or an example of what your trying to acheive.

Just use a small bouce animation on the camera?

I’m not too good at explaining things clearly. I don’t need Depth of Field (yet), I just need a focal point that is centered on the camera, but “sticks” to collision objects. No enemies or anything, the projectile reference was just an example of how the system was imagined to work. If I look at a wall in real life that becomes my focal point, where my eyes will focus and as long as I keep looking at that point, that is where my “rotation center” of my eyes is, and therefore if I walk around the room, that is the point my eye rotate/revolve around. What I’m trying to do is set an automatic focus for a virtual camera by setting the distance via an empty, or any object for that matter that will, in short, “stick” to the wall where the center of the camera is looking and become the rotation/revolution center for the camera. So, when I apply the walking effect, the “head-bob”, that occurs when we walk, the focal point or center point will not change until you move it manually, such as with a mouse movement.

I’ll be making a video shortly about what I mean, hopefully visuals will help clarify.

I guess, you could say it’s similar to a Range Finder in First Person Shooters, where it judges the distance to an object and displays it for you, but instead of displaying it, I need that point to become the rotational center for the camera or rather the camera controller that contains the head-bob animation.

This is really confusing for me too, so I can’t really explain something I’m trying to solve…

  • place a empty at the camera center spot (orgin).
  • parent the empty to the camera
  • let this empty shoot a ray toward the y direction (forwards they way you looking at)
  • grab the ray.hitPosition.
  • spawn an empty at the ray.hitPosition
  • move the camera to the empty.worldPosition

the basic way to get the camera on the spot you want.

This sounds like it will move the camera to the hit location, I just need the camera to stay put and rotate around the hit position from where it currently is.

So, aside form the last step, this sounds promising!

This sounds like it will move the camera to the hit location, I just need the camera to stay put and rotate around the hit position from where it currently is.

ok do the few steps as above, now when you placed the empty on the spot you want to rotate around, simply parent the camera to the empty, then rotate the empty around z axis, now the cam stays on the spot you want, and the physics get transfered to the empty its parented to, thus moving/rotating the empty will rotate the camare around it.

I feel like I’m still a bit lost, though. My apologies. I think what I need is a bit contradictory, now that I think about it. Where the empty will move, as if parented to the camera, but it’s hit point in space becomes the camera’s rotation center… So, in other words, they are trying to parent to each other in some strange way. Unless I can find a work around that allows for the camera to track the empty created, as well as having the empty follow where the camera is pointing.

Maybe you have solved that already and I just missed it by a mile.

I’ll experiment with it a little bit more and see how that goes. Thank you for your answers!

Here is a video explanation. Probably not any better, but I tried.

Also, it was recorded in 720p on a 1080p monitor. I didn’t figure you really needed the full quality to see what I meant, but if you do I can try again.

###THIS VIDEO IS NO LONGER VALID###


https://youtu.be/aCqv0f-cABk

Alright, I have a basic setup for how I’m going to get this to work, all I need now is a way to spawn my Camera_Focus empty when a ray is cast along the +Y and collides with something. I have the range for the ray set to 2000 BU or 2km I think. I set it this far because the skybox is sitting at about 1km diameter around the test world, so if somebody can help me find out how to get the ray’s hit location/position and spawn the Camera_Focus empty there, I’d be grateful! I need it to fire the ray, get the position of the Camera_Focus and respawn it every tick.

If you’d like a copy of the blend file, just let me know!

The logic brick setup will probably need to be altered, since I already have the Track To Camera_Focus setup for my test.

Alright, so I’ve watched some tutorials about the raycasting and nearly got a working prototype, but the camera won’t align properly. It may have something to do with the parenting, but I’m not sure how to fix it. Anyone want to help me debug, please?

https://drive.google.com/open?id=0B2B74029Ph5SUXY0YXd4YnNQcEE

this script will cast a ray and place the focus at the hitPosition every frame.
hook it up to an always(true pulse) -> python(module) - scriptname.ray_cast

from bge import logic

def ray_cast():
    
    #basic stuff
    cont = logic.getCurrentController()
    own = cont.owner
    scene =  logic.getCurrentScene()
    
    distance = 100 #2000 is to far to cast
    
    #grab focus object
    cam_focus = scene.objects['camera_focus']
    
    #shoot a ray in y direction with the distance given above
    to = own.worldPosition + own.worldOrientation.col[1]
    ray = own.rayCast(to, own, distance)
    
    if ray:  
        # add the focus object for 1 seond
        cam_focus.worldPosition = ray[1]

Thanks for the code! I added it in as you said, and had to edit the object name in the script, but the object is not appearing where the ray cast is meant to occur.

I don’t know if you saw, but this is the code that was displaying the object in the correct position:

from bge import render, logic


from mathutils import Vector


def main(cont):
    
    scene = logic.getCurrentScene()
    own = cont.owner
    
    ray = cont.sensors["RayHit"]
    always = cont.sensors["HitAlwaysActive"]
    
    if ray.positive:
        
        render.drawLine(own.worldPosition, ray.hitPosition, [255, 0, 0])
        
        if always.positive:
            
            focusPosition = scene.addObject("Camera_Focus", own)
            focusPosition.worldPosition = Vector(ray.hitPosition)
            focusPosition.alignAxisToVector(ray.hitNormal, 2)

I had the drawLine added, so I could see if it was positioned correctly

Main issue I’m having now is having the camera Track To the object.

edit ok looked at your blend.
i changed the parenting for you and changed the script also removed some bricks so check em.

anyway the effect you looking for is this?
http://www.pasteall.org/blend/41476

That is actually almost perfect! Thanks for your help!