Ambiera Forum

Discussions, Help and Support.

Ambiera Forum > CopperCube > Programming and Scripting
3rd Person Player & Camera Controller 2021

marcw
Registered User
Quote
2021-02-22 11:35:47

Hello everybody,

Thank you to Hadoken and to Dieter (CSP_Games) for sharing their amazing skills while creating this new Third Person Camera Controller.

Hadoken, I also downloaded your custom-made imported terrain populated with animated plants. It is a nice example of creativity. Congratulations.

:-)


csp-games
Guest
Quote
2021-02-23 21:03:15

Hey, Hadoken and Marcw,

I have uploaded a 3rd version. This one contains a suppression of the terrain hopping due to collision handler. As a sideeffect it causes smooth sliding down a steep slope. It may be a good idea to apply this to other projects to, in one way or another.
It does a linepick right under the player and simply positions him at the impact point. Collision handler will then have nothing to do in terms of gravity. Exceptions for jumping, falling etc. should be made. However, much smoother walking on terrain (that was a real problem with low framerates).

As far as I see, except for the relatively few clipping errors, after having fixed several issues and bugs, it is now pretty useable IMHO. There is only one thing that really bothers me, and that is, when you walk straight into a wall and keep on walking against it, the cam does some weird bouncing. I can only explain this by the fact that after I have moved the player forward and then positioned the camera accordingly, CC will then apply collision handling, moving the player back again, but not the camera. In theory, it should be done this way:
move player
apply collsion response
position camera

but I currently don't see a way to insert the cossision handler there, or to split the camera in two parts and execute them before and after the collision handler. Maybe it could be done with a delayed player position: Camera is using the player position data of the previously rendered frame, that has collision applied. or even easier, first position camera, based on current player position, then apply walking to player. I think that's it...

Writing about these things often helps to find solutions :)

The other things you mentioned, most of them you should be able to fix by your own. Like, simply limit this.walkspeed_x to 0.5, instead of 1 as it is now for slower strafe sideways walking. Or check the shift keys to potentially *2 that speed.
Use a multiplyer that is one with no shift key and 2 with shift pressed.
Not sure what you mean by player cannot rotate more than 360 degrees - is he supposed to? If the delay of the camera is big, the player may reach a 360 degree advance, at which point unpredictable things may happen :) but it was never meant to lag that much. That said, there is still a nasty bug in the delta timing of the rotation catch-up of the camera vs player, the lag is much bigger with lower framerates, bad bad, but I forgot to fix this.

Version 3 also contains code to play animations, only walk and idle so far, but you can add more using the same principle. There needs to be a hierarchy: for example you would not want a walk animation while jumping, even if the player presses the walk key. BTW jump is still a mess, feel free to fix. And by that I also want to come to a conclusion:

I hereby declare this project open source and I encourage you to make it better, all of you!

Thanks a lot for your attention.

BTW I made a cra


csp-games
Guest
Quote
2021-02-23 21:07:47

oops, how did THAT happen, by accident clicked SUBMIT...

I made a crazy ascii renderer based on CC, that is using the TPP cam. It renders 80x80 pixel, then converts it to letters and writes them into a html TEXTAREA (just like where we type comments). But this is really more like abstract art than a real game:

https://jfkeo1010etc.itch.io/tex...


marcw
Registered User
Quote
2021-02-23 22:42:08

Hello everybody,

Dieter, I briefly tested the two behaviors (webgl + windows) of your 3rd version of your TPP camera in a scene populated with the built in terrain.
The detection of the collision with the terrain works nicely with the default "walk" speed of the camera.

(walk is bracketed in my comment, because I noticed that it is not relative to the avatar (the player) animation.

It seems that you have more than two hands - like Shiva ;-) - to code so fast and to post your daily comments in this forum.
Be convinced that it is a compliment.
I am simply impressed.

And about your html Textarea I could discern a converted CopperCube's scene in the ascii rendering. Nice demo.

:-)


csp-games
Guest
Quote
2021-02-23 22:58:13

Thanks Marc, I highly appreciate it.

I write those scripts because I think I can do it in 1-2 hours, but then it takes like 10 or more. Of course after so much work I need to socialize :) So I'm writing comments. But I may soon vanish due to real world circumstances. So I try to enjoy these times as much as I can. Using Coding as a distraction can be relatively obsessive - but it's not so bad. Some people, doing the same thing, are paid 10 grand monthly. So generally society recognizes a value in what I do. Just not when I do it. :) Bah. Those game design companies around here have no clue. May they stick with their space invader clones (they really do).


just_in_case
Moderator
Quote
2021-02-24 07:17:06

@Dieter I really appreciate your contribution to the community, No doubt you are the most talented and experienced person than most of us. Really liked the ASCII Renderer. Also the TPP cam for windows its really useful, but there is a bug with that if you have more than one cam in scene then it will affect all of them. I always recommend to use a property named camera with type as scenenode, instead of getting active camera in behaviors cause one might can have multiple cameras in the scene and then it will affect them all as soon as they become active. It can be fixed easily. I am pretty sure many of us is going to use this behavior only instead of the default one. I wish for your good health and prosperity. People are greedy so am I. I don't want you to vanish cause I want to see more stuff by you. Many Thanks! for sharing your skills with us.


csp-games
Guest
Quote
2021-02-24 14:31:24

Thank you for your kind words, just_in_case,

I wasn't aware you can have multiple active cameras simultanously - you mean like each one has it's own viewport and renderer? That's weird because I store the active camera in a simple variable, then move it using that handle. I can't even understand how it can move multiple cameras this way.

Anyway, I take your word for granted. The solution to this problem is rather easy. Get the idea by the name, or use a variable that you set elsewhere. There is this line in my script:

mycam=ccbGetActiveCamera()

which must be modified accordingly.

Then there is still the missing delta factor in the rotation smoothing, I will upload a corrected version asap, meanwhile you can already alter this by yourself, as follows. Locate these lines:

this.omycam_yaw+=(this.mycam_yaw-this.omycam_yaw)/this.RotSmoothAmount; // don't use zero for RotSmoothAmount here (should add a catcher)
this.omycam_pitch+=(this.mycam_pitch-this.omycam_pitch)/this.RotSmoothAmount;

and replace them by:

this.omycam_yaw+=(this.mycam_yaw-this.omycam_yaw)/(this.RotSmoothAmount/delta); // don't use zero for RotSmoothAmount here (should add a catcher)
this.omycam_pitch+=(this.mycam_pitch-this.omycam_pitch)/(this.RotSmoothAmount/delta);

Now for the one problem that is still a game-breaker to me, the weird camera bouncing when walking against a wall, I tried hard to find a solution. I tried to alter the order from
move player
position camera

to position camera
move player

But surprisingly it didn't fix the issue. I came then to the conclusion that the collision handler of CC isn't executed every frame (just like dynamic shadow rendering btw), resulting in just this bouncing effect. I tried to find a command in both, coppercube api and copperlicht api, to trigger a collision update (like UpdateWorld in Blitz3D), without success. Although the in-the-docs briefly mentioned ccbUpdatePhysicsGeometry() didn't cause an error, it also had no impact, I guess it's for the "real" physics only (which isn't supported for WebGL target). So I pretty much am at the point of tossing CC-internal collision handling and replace it by something homebrew (a lot of work!) or use the cannon.js that Jaime A. Zegpi was able to use with CC: https://www.ambiera.com/forum.php?t=8793

So that's the current state of the project on my side. If anybody finds a solution to this problem (like forcing collision update on each frame), pls let me know. It's pity, but the way CC handles collision makes it impossible to compete with unity etc.

I was just kind of challenged by a unity user who currently is writing a tpp cam too, so this really hurts. I could have done it as good as him, but not with this collision-handler in a locked box.


csp-games
Guest
Quote
2021-02-24 18:08:21

Additional suspicion:

As mentioned, the main problem seems to be the lack of a collision update on each frame. But I think I remember that mesh nodes are treated differently compared to camera nodes in the collision update. I can't remember having had the camera acting like that when I used to walk towards and into a wall in the fps extension - do you? So the camera collision may very well be updated each frame - well, there's a chance.

Based on that one could attach the player mesh to an inactive camera as a child node, serving only as a dummy that forces the collision update on the player mesh each frame. That said, it may be camera that collision is not working when the camera is inactive...(?)

However, this workaround would require to mod the script in that you can't just rotate that dummy camera like we do now with the player mesh, but we would have to position it's target accordingly. Not a big deal with sin and cos, esp. since all takes place on the Yaw axis only, but it does complicate things in general - by ten or so lines, and a reduction of readability.

I'm getting a bit under time-pressure here, so I'd be glad if somebody would pick this up and try it out.


just_in_case
Moderator
Quote
2021-02-24 18:23:22

@dieter, by having multiple cameras, i mean if there are more than one camera in the scene but they are inactive initially. for example having a free flying camera or a model viewer camera in the scene. which get activated for example on a key press then the action switch active camera is invoked and now the sitched camera if it is a model viewer or any other type of camera then it will also become a tpp cam as you have used ccbGetActiveCamera in your behavior so it will change any camera which will become active.

I know how to fix this issue. you can specify a property in the behavior like
<property name="TPP_Camera_node" type="scenenode" 

and now change
 	var mycam=ccbGetActiveCamera();
to
 var mycam = this.TPP_Camera_node;


but then there might be a new problem which is the player will still be moving if tpp cam is not the active cam. and in order to fix this there is a need to create an if condition in your behavior which will check the property "Active" of
this.TPP_Camera_node
and if it is found to be true then execute all the player movement and all other stuff if its not the active camera then don't do anything.

other than that I don't think Coppercube supports multiple renderers except in the editor.

Regarding the collision handler yeah coppercube really lacks that functionality even in windows platform if you a cube with collision enabled and is hidden then its collision will still be there. hiding an object will not turn off the collision.

I don't know if it will work or not but maybe using the ccbSetSceneNodePositionWithoutCollision along with proximity behavior or with actual collision detection using the collision API can be a workaround fix for that.

for example you can attach a proximity behavior or you can script your own fake proximity box around the camera and if any scenenode comes in its range then the camera will start moving "ccbSetSceneNodePositionWithoutCollision" and if it leaves the range then it will use the standard movement with collision.
It is just an idea might work. I never tried doing that practically by myself.
my coding skills are not that great but am good with logics so maybe creating your fake collision box can also help its not hard to do that. In my RTS clone i used a fake collision box so that the player will avoid those area and will move to other direction and will treat that collision box as an obstacle to mimic a path finding system or you can say obstacle avoiding system.

hope this helps.


csp-games
Guest
Quote
2021-02-24 18:52:57

Hadoken, I downloaded and played your demo. Nice work. The shadow you may want to make semi-transparent, for example with Gimp, lower the alpha-opaqueness of the shadow layer, over an empty background-layer, then save as 32bit png.

I have noticed there is a blt of "wob" varying speed when walking forward (same as strafe, just much less), that is a relict of the fps camera, which was the basis from which I developed the TPP cam. So any such factor in speed and motion for the player forward+back motion (always named Z, regardless of player angle) should be without that wob factor or additor (wob is/was a variable used in the script for the wobble effect, later for the swim effect (underwater cam) for varying speed fx), and was meant now only for strafe, not for foward walking..


csp-games
Guest
Quote
2021-02-24 19:08:10

just_in_case, thank you very much.

That if condition could be:

if(this.TPP_Camera_node == ccbGetActiveCamera())

The problem with proximity is, AFAIK it will use the mesh center, but the triangles may be all over the place, far from the center.

A real collision handler is slow, which is why Niko implemented it this way, non-each frame update. You have to check every triangle in the scene, at least whether one of their 3 vertices is in proximity defined by the collision radius (when using sphere vs world geometry), and if so, do costy plane intersection math.

However, I'm thinking one simple hack of a solution may be: do a few linepicks from the players belly outwards and see if he's about to hit a wall, if so, refuse to move him further in that direction, but position him at impact (minus his radius). But I guess making sliding collision work that way is yet another challenge.


csp-games
Guest
Quote
2021-02-24 19:52:26

little update

Based on that one could attach the player mesh to an inactive camera as a child node, serving only as a dummy that forces the collision update on the player mesh each frame. That said, it may be camera that collision is not working when the camera is inactive...(?)


I just tried that, but not only behaves that dummy camera just like the player (causing camera bouncing explained earlier), but the player also became invisible, despite the dummy cam being visible yet inactive. I tried both, player mesh attached to dummy camera directly and with intermediate joint node. Both the same, collision not handled each frame, just like the player mesh before (no idea why I thought the camera is treated differently). So, that was a "shot into the oven".


csp-games
Guest
Quote
2021-02-25 11:10:38

Ok everybody, I conclude once again:

The cam bouncing problem wasn't solved, but it's not so bad. Except for when the player is sliding along a wall, which is a common gameplay situation, he would rarely try to walk trough a wall (which exposes the problem mostly). So it isn't really a game-breaker, even if it is far from beautiful. Maybe over time we'll find a solution. An other problem is: if there is a solution by using copperlicht api directly then it will work for WebGL target only. Anyway, I have trust in you guys, not only to find solutions, but also to enrich and modify it so it serves all scenarios.

To make this easier I give a brief explanation of the basic principle here:

-the user controls the player mesh only. Whatever the camera does, it's just a reaction on the player meshs motion and rotation.

-when the user is walking, a speed variable is set to be different than zero. It will go up to 1.0 when walking forward and down to -1.0 when walking backwards. There are two such variables, one for forward and backward, and one for sideways (the latter only used when StrafeLeftRight is on).

Therefor the keys (at comment "check keys") don't move the player directly, they just alter the speed variable. If no walk-key is pressed, speed is quickly reduced to zero (over about 5 frames).

Only after the speed variables are calculated, their values are actually applied to the player position. If you have read and understood my sinus cosinus tutorial, you will easily understand how these values can move the player in any direction he faces:

let x be player x and z be player z and
a=player angle

x=x+sin(a) * speed_x
z=z+cos(a) * speed_z

will do the trick. this is simplified, in the script there are more factors / multiplyers, like delta (to make it framerate-independent)

So in any case you can alter the speed limits set at "check keys" to dynamically alter the walking speed.

-Rotation: the player can rotate by cursorkeys left/right (if StrafeLeftRight is off) or by mouselook on the mouse X axis.
This will directly affect the players direction he's facing, which is called his pitch angle. But the camera will not directly be positioned behind him using the same angle. Instead the angle diffrence between the current camera and the position right behind the players back is taken and divided into a number of parts (set in RotSmoothAmount). The camera is then moved only one of these steps in order to catch up with its goal position behind the player. This means, if the player stops turning, the camera will have a chance to catch up, but the closer it gets to that point, the smaller the steps will be, resulting in the camera slowing down in the angle alignement, perceived as smoothed motion of the camera . At bit like a rubberband, the more you stretch it, the faster it will snap back.

Finally, preventing the camera from getting behind walls: Now that we have the position where the smoothed camera should be, we can't just place it there, because this might be behind a wall, obstructing sight on the player. We don't want to use collision to prevent this. So what is done is:

A linepick is performed from the player to that calculated cam position. this is like a ray. If that ray hits a wall, the camera will be positioned at the ray impact position. Otherwise, it will be positioned at the previously calculated position. This results in the camera, sliding along walls if the player stands close to, and with his back against a wall. It looks like collision response, but it's not.

This is the main concept. If you understand it, you can easily modify the source.


csp-games
Guest
Quote
2021-02-25 11:24:15

I want to add one word about the shift-keys: while the script has its key handler where you can add keys for more functionality, this handler can deliver only ascii keys, meaning it cannot read Shift, Ctrl, Alt and similar special keys. I would therefor advise you to check those keys in a main scene node behavior for keypresses, that is able to handle such keys, as far as I remember. There you can set some variables, which can then be used in the tpp camera script. For example:
On shift key press:
ccbSetCoppercubeVariable("is_running",2);

On shift key release:
ccbSetCoppercubeVariable("is_running",1);

and in the cam script:


...
if (bb2js__keyDown==1) // walk bck
{
this.mycam_speed_z-=acc*delta;
if (this.mycam_speed_z < -ccbGetCoppercubeVariable("is_running"){this.mycam_speed_z=-ccbGetCoppercubeVariable("is_running");}
this.is_walking_z=1;
}
...


(note: variable bb2js__keyDown refers to cursor down key (contrary to left right up), not to any key pressed down - sorry about the confusion. Also, the valiable this.mycam_speed_z refers to player speed, but is still named mycam speed because this script is based on a fps camera and I didn't bother to alter that name yet. )


csp-games
Guest
Quote
2021-02-25 11:53:33

Oh and BTW I have uploaded final version 4.

https://jfkeo1010etc.itch.io/min...

It fixes the rotation delta bug and a few others. You may want to adjust RotSmoothAmount,

Hope this helps.


Create reply:


Posted by: (you are not logged in)


Enter the missing letter in: "Internation?l" (you are not logged in)


Text:

 

  

Possible Codes


Feature Code
Link [url] www.example.com [/url]
Bold [b]bold text[/b]
Image [img]http://www.example.com/image.jpg[/img]
Quote [quote]quoted text[/quote]
Code [code]source code[/code]

Emoticons


   






Copyright© Ambiera e.U. all rights reserved.
Privacy Policy | Terms and Conditions | Imprint | Contact