List your own various methods to see through camera obstacles

in 3rd person mode, my camera pushes out it’s near clipping plane when zooming in,
(zoom in through obstacle)

So, this is the code

sens2 keyboard is actually a property/ boolean now (so you don’t have to hold tab to go to first person)
sens = is actor alive
sens3= Right mouse


import bge




def main():


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


    sens = cont.sensors['Property1']
    sens2=cont.sensors['Keyboard']
    sens3=cont.sensors['Mouse']
    if 'Cam' not in own:
        scene=bge.logic.getCurrentScene()
        own['Cam']=scene.objects['CamPos1']
        own['Cam2']=scene.objects['CamPos2']
        
    else:    
        if sens2.positive:
            cam=own['Cam']
            own.worldPosition=(cam.worldPosition+own.worldPosi  tion*15)*0.0625
            own.worldOrientation=(cam.worldOrientation+(own.wo  rldOrientation*3))*.25
            
            
            if own.lens<=59 and sens3.positive:
                own.lens+=1
                own.near=6
            else:
                if own.lens>=29 and not sens3.positive:
                    own.lens=int(own.lens-1)
                    own.near=.1
                        
            
        else:
            
            cam=own['Cam2']
            own.worldPosition=(cam.worldPosition+own.worldPosi  tion*7)*.125
            own.worldOrientation=(cam.worldOrientation+own.wor  ldOrientation)*.5
            own.near=.1
            if own.lens<=74 and sens3.positive:
                own.lens=int(own.lens+1)
                
                
            else:
                if own.lens>=39 and not sens3.positive:
                    own.lens=int(own.lens-1)
                    
                        
            


main()



this handles camera position zoom and clip for my own game

I thought it was handy

you could use a ray and do Zoom + push out near clip in your own games, to “zoom through” obstructions

Is this a question?

Discussion

Poor title choice

My methods:

  • FreeView - Avoid flying through other objects (2.49)
  • FreeViewControl - ready to use FreeView with configurable mouse and keyboard control (uses the EventManager and LinkLib) (2.49-2.5+)

I have no idea if it works with 2.6+

I just watched the video on youtube, it looks great.
But…

own.worldPosition=(cam.worldPosition+own.worldPosition*15)*0.0625

Does that work? I don’t understand why you’re multiplying worldPosition by 15…? and then scaling the whole thing down again. Is the player scaled? In that case it’d be better to get the player.WorldScale and then multiply by that, rather than use a set number inside the function. Hard coding such numbers in to your code can cause problems later if you decide to change something (such as the scale of the player). I’ve found out the hard way about that. If it’s an ideal viewing distance, you could use that as a variable:

ideal_viewing_distance = 15.0

and then multiply the world position by that. Also using floats rather than integers helps to show that you’re talking about scales and distances rather than indexes or lengths. It all helps to increase readability of the code, something I’ve only just started to address myself. :slight_smile:

I also think

left_mouse = cont.sensors['left_mouse']

Is better than:

sens3=cont.sensors['Mouse']

Again purely for reasons of readability. I know you do some team project work so readability could be key in such projects.

Anyway, I like Monster’s utility but it’s a bit complex for a 1st/3rd person camera script. I tried running it in 2.71 but no luck, there were problems with Mathutils, instead of mathutils and Rasterizer, not bge.render also print without brackets, and Gamelogic instead of bge.logic. as well as dozens of other small bugs. I tried

import bge.logic as Gamelogic

but there were still too many other errors and too much code to search through to get it working.

One good solution I’ve seen is to have an empty at the player’s head (or as near as you want to get) and one at the ideal camera location. Just shoot a Ray from the player’s head to the camera empty and if it hits a wall or something, use the ray hitPosition to place the camera at the hit position. Near clipping should take care of any problems of the camera being inside the wall, and you can use a track to actuator or another home brew function to point the camera to the player, or the player’s target reticule.

The benefit of this method is that you can keep zoom at a constant level, and just move the position of the camera. Or you can also adjust zoom if you want to. If you want to have slow parenting you can give the ideal camera location slow parenting and parent the camera to it. That should stop the camera and empties getting out of sync.

Does that work? I don’t understand why you’re multiplying worldPosition by 15…? and then scaling the whole thing down again. Is the player scaled? In that case it’d be better to get the player.WorldScale and then multiply by that, rather than use a set number inside the function. Hard coding such numbers in to your code can cause problems later if you decide to change something (such as the scale of the player). I’ve found out the hard way about that. If it’s an ideal viewing distance, you could use that as a variable:

so, I have more than 1 camera position, so the camera has to move,
so rather than camera.worldPostition=target.worldPosition (instant snap)

I first came up with

camera.worldPosition=(camera.worldPosition+target. worldPosition)*.5

this moves the camera to the position in 2 frames (it’s too snappy)

so I then figured out

camera.worldPosition=(camera.worldPosition7+targe t.worldPosition).125

so it’s combining the vectors, but heavily weighting it on the camera side,

so you end up with this

its the equivalent to “Ease in”

But it’s only one line of code :smiley:

it also works for rotations

Attachments

OvetTime.blend (440 KB)

I do things kind of a different way. The way I do I use a ray that always cast from the camera to the direction the camera is going. Only looking for scenery objects. If it hits, then it turns that object transparent, simple. On a mouselick it looks for things in an order, casting a screenray. Did you hit a scenery object? no. Cast another ray, did you hit a interactive object? No, cast another ray, did you hit a enemy, No. cast another screenray, did you hit the ground? Well yes because thats the last thing you can hit if theres nothing there. If not then you hit nothing, so do nothing. I dont do any kind of camera moving around. If theres something in between it turns transparent, then searches for another property. The only thing running each tick is ray for scenery, everything else goes onclick event. Works pretty well. I dont like moving the camera around. It does cap out if it hits the ground, and wont let you go below the ground. I use distance contraint for that.