3rd-Person Camera

Blitz3D Forums/Blitz3D Programming/3rd-Person Camera

Mattizzle(Posted 2007) [#1]
What would you folks suggest as the best way to determine if a camera's view of the player is being obstructed by any object? My setup up so far is a main pivot always positioned at the player's center and gets rotated by the mouse. Then the camera is parented to that pivot and moved back some. And then I've got another pivot that is parented to the main pivot and stays in a preset location for the camera to move back to when there is no longer any obstruction. Now, I've tried several different things and failed every attempt. So now I'm resorting to you geniouses for help.

Thanks in advance,
Mattizzle


puki(Posted 2007) [#2]
I've tried several different things and failed every attempt


The above is potentially a key to all of this - whose to say something that you tried was correct, but you implemented it wrong and therefore do not know it was the answer.

Most people go the route of 'picking' - whether it be creating a system of linepicking or by using Blitz3D's built-in 'Pickmode'.

You can set an entity (ie a mesh/piece of scenery) as being an 'obscurer' via EntityPickMode.

If you've not tried that then play around with it - other than that post a bit more info regarding what you have tried as the 'PickMode' solution is normally the first thing someone would try.


Mattizzle(Posted 2007) [#3]
Yes, I too believe I've implemented my attempts incorrectly... >.<

I've tried EnitityVisible, EntityInView, Linepick, and even having a cube scaled to the length of the distance between the camera and player and tested for collision. And so since nothing I tried worked, rather than spending hours and hours trying to correctly implement one of those methods, I decide to find out here the way that is best and then spend my time implementing the best way.


jfk EO-11110(Posted 2007) [#4]
I did a 3rd person camera some time ago. I'd suggest to smooth the camera motion: When there's a pivot at the cameras desired position then move the camera towards it, by a fraction of the distance. This gives a nice rubberband effect.

There may also be a target pivot, usually the characters head or shoulders. During the camera positioning the pickmode of the Character should be disabled. The worlds mesh(es) must be pickable. Now simply LinePick from the target pivot to the cameras current location. If linepick will return zero then there's nothing between them. If it's not, then position the camera at the pickedx, pickedy, pickedz location, point towards target, move a little bit forward.

This way the camera will always use the best location and won't get stuck in corners.


Mattizzle(Posted 2007) [#5]
Hi Jfk. I knew you'd show up with your linepick. :-P I did try to linepick but I don't really understand the parameters it takes. Why doesn't it just ask for a source and target entity? I know you're the master of linepick, could you give me a code example of how to use it in this situation (with a pivot at the player and a pivot at a preset location behind the player)

Thanks in advance,
Matt

Ps - using a fraction of the distance is great! I've always thought Cos was the way people smooth motion.


jfk EO-11110(Posted 2007) [#6]
linepick is simple
p=linepick( entityx(npc),entityy(npc),entityz(npc), entityx(camera)-entityx(npc),entityy(camera)-entityy(npc),entityz(camera)-entityz(npc) )


Mattizzle(Posted 2007) [#7]
OH! I've been reversing the entities! So it goes from target to camera and not camera to target. Thanks JFK I 'll try it!


Mattizzle(Posted 2007) [#8]
It is starting to shape up but I'm still having a problem:


And c\Pivot is the parent pivot that is moved to the player's location every frame (before this code), c\Cam is the camera of course, and c\tzPivot is the target pivot (the preset location to move the camera back to.)

The above works well except when the camera is positioned at the picked xyz, the screen starts shaking intensly. And when i comment out the else block which moves the camera back, there is no longer any shaking. Thus, its like the else is being executed with the if.

...While typing this post I just realized hey why not try and run two linepicks one for false and one for true:


Works flawlessly...

Any idea why the first doesn't work and the latter does?

Edit: After more testing I noticed the camera would still shake if it got close to the player (like against a wall) and so out of pure luck and just messing around I came up with this:



puki(Posted 2007) [#9]
The second version is a choice of 2 states - it is absolute.

The first version is either something or anything.


Mattizzle(Posted 2007) [#10]
Well think about it logically though: The way I've set it up with "if not 'nothing in the way' " and the only other option being "nothing in the way", how could an 'else' not work in this case? I just can't figure it out. But besides that, I now have a perfect 3rd person camera regardless of else staments if you check the edit (especially examine the second 'MoveEntity' - I got that idea from what jfk said earlier - jfk's my hero now :-P )


jfk EO-11110(Posted 2007) [#11]
In the last version you do 2 linepicks, although you could simply store it in a variable
p=linepick(...
if p<>0
...
if p=0
(They are the same linepicks, no?)


But basicly I don't understand this line:
If EntityZ(c\Cam) > EntityZ(c\tzPivot) Then MoveEntity c\Cam, 0,0,-0.5

What's your goal? If Z of cam < Z of char then move cam away from char ??

Note, MoveEntity works relative to the entities orientation. Probably you meant TranslateEntity ?


Vertigo(Posted 2007) [#12]
Just out of curiosity, has anyone tried this?

alpha a cube to 0 so its hidden.
Parent the camera to that.
Check collisions against the cube only.
Parent the cube to the player.

Before collisions check, hide the entity of the cube.
Place the cube at 0,0,0 orientation relative to the player.
Unhide the entity of the cube to check for collisions once again, and then just move its z negative until it hits something.

Isnt this a lot faster than doing line picks every frame?
Just an idea... and mine are usually bad ones haha


Mattizzle(Posted 2007) [#13]
@ My hero :-P - That line is actually this now:
If EntityZ(c\Cam) > EntityZ(c\tzPivot) Then MoveEntity c\Cam, 0,0,(EntityZ(c\tzPivot)-EntityZ(c\Cam))*0.1

But besides the z parameter change, I think you're thinking that 'c\tzPivot' is at the player, which it is not. 'c\tzPivot' is actually a child pivot that is always at a local 0,0,-20 position relative to the main camera pivot (which is at the head of the player). Thus, my line of code there will move the camera back until it reaches that pivot (0,0,-20). The reason for it is so when there's nothing between the camera and player (ie linepick = 0) that the camera doesn't just fly off into space. 'tzPivot' is the limit. (hehe it rhymes)


@ Verty - Sure you'd have a faster fps but of course in compromize it would be taking alot more frames to check where the camera should be, plus if I read correctly you'd need two 'updateworld()'s'. But something I tried was along those lines:

and even having a cube scaled to the length of the distance between the camera and player and tested for collision


+ moving the camera to the collision xyz globaly...
And that didn't work well, however I probably just implemented it wrong because it sure makes sense in theory.

On a lighter note -- I now have an extremely fast an optimized 3rd person camera that works perfectly for a ninja fight!

Many thanks to all!
Mat -- tizzle

PS - I think an addition to the code archives is in order... ;-)


jfk EO-11110(Posted 2007) [#14]
Hey, cool sig <:o) . You may want to see my merchandising products as well :P