Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use characterController for secondary players #64

Closed
bigrig2212 opened this issue Dec 11, 2022 · 9 comments
Closed

Use characterController for secondary players #64

bigrig2212 opened this issue Dec 11, 2022 · 9 comments

Comments

@bigrig2212
Copy link

Anyone using CC for secondary player control? ie: not the player attached to the camera. I want to do that, but looks like camera controls are entangled a bit. I'll work on separating it out - unless anyone has already done so - or if you have a quick tip SSatGuru?

@ssatguru
Copy link
Owner

I just added support for secondary player / npc .
just set camera to null when creating the CC.
Example:
cc = new CharacterController(player, null, scene);
instead of
cc = new CharacterController(player, camera, scene);

note that for such use cases, the CC mode will always be set to 1
as mode 0 requires camera

Please try and let me know if you run into any issues.

Ofcourse the other option is to create two cameras and assign the inactive camera to the seconday player.

@bigrig2212
Copy link
Author

bigrig2212 commented Dec 30, 2022

Hallo! Thx so much for the update. (missed the alert from github)
Integrated the code - but am not sure how to indicate to the secondary controller(s) that the secondary player(s) should move and in what direction.

Seems like there should be a method to send the rotation and keyUp , keyDown + modifiers? So that the actions of one player can be broadcast the others - and then those actions replicated on the secondary players?

I started to play around with this: playerCCs[playerId].walk = true;
But realized the issue around rotation + modifiers.
Also seems that keypress from one player are captured by the 2ndary player controllers.

Thought you might have a better idea for how it was supposed to work?

(here's a visual showing what i'm doing for reference: syncing of one chars anim/pos to another player)

@ssatguru
Copy link
Owner

ssatguru commented Dec 31, 2022

see https://github.com/ssatguru/BabylonJS-CharacterController#controlling-avatar-programmatically

so if you have two controllers cc1 and cc2 for player1 and player2 respt. as follows

cc1 = new CharacterController(player1, null, scene);
cc2 = new CharacterController(player2, null, scene);

then

to make player1 walk , do cc1.walk(true)
to make player2 walk , do cc2.walk(true)
to turn cc2.turnLeft(true);
and so on
Ofcourse to rotate you can always use any standard node/mesh api to rotate.

to disable keypress from influencing 2nd player
cc2.enableKeyBoard(false);

see https://github.com/ssatguru/BabylonJS-CharacterController#enablingdisabling-the-keyboard-controll

@bigrig2212
Copy link
Author

bigrig2212 commented Jan 15, 2023

K, i got it mostly working. Few things:

  1. Dont think enableKeyBoard(false) is working. So i'm doing this instead (where my primary player is always named "player_1":
    CharacterController.prototype.enableKeyBoard = function (b) { if (this._playerName != 'player1') { return; }

  2. As per your comment above regarding rotation: i fire an event with the rotation and then apply the to the 2ndary character(s) like so:
    this.players[playerDetails.id].rotation = new BABYLON.Vector3(playerDetails.moveData.char_rot._x, playerDetails.moveData.char_rot._y, playerDetails.moveData.char_rot._z);

  3. The position of the 2ndary characters does not exactly match the position of that character in the main player's view. In other words, the positions get out of sync. So i adjust the position along with the rotation. This is not ideal as it results in little jump backs. But not sure how to work around? Maybe just to turn off player movement for 2ndary characters in the character controller and just use the sync'd positional data instead. I may try that.
    this.players[playerDetails.id].position = new BABYLON.Vector3(playerDetails.moveData.char_pos._x, playerDetails.moveData.char_pos._y, playerDetails.moveData.char_pos._z);

  4. There are some commands missing, like fastrun, idleJump, falling. I added these in, for example:
    CharacterController.prototype.idleJump = function () { this._act._jump = true; };
    And if the anims have been renamed, like cc.setRunJumpAnim(agMap["Jump"], 0.6, false);, then the command will fail, so need to make sure to make those consistent.

  5. Lastly, a question: is there any easy to prevent the characters from colliding into each other? eg: overlapping each others space.

And that's a wrap. Great stuff. thx ssatGuru.

@ssatguru
Copy link
Owner

ssatguru commented Jan 17, 2023

@bigrig2212

  1. You are right about enableKeyBoard(false).
    If you do enableKeyBoard before you do start() it doesnot work.
    So if you do
cc.enableKeyboard(false);
cc.start()

it does not work.
But if you do

cc.start()
cc.enableKeyboard(false);

it works.
I will fix this so the order is not important.

  1. Nice

  2. Looks like you are doing multiplayer coding. I guess synching in mutiplayer is tricky.
    Not my area of expertise. So not sure I can provide the best advise.

a) fastRun. There is walk and there is run but there is no fastrun. So 'a' to walk , 'shift a' to run. There is no key combination for fastrun. So you can think of "walk-run" as "walk-fastwalk" or "run-runfast".
b) idleJump, runJump. The Charactercontroller does idle jump if character is idle and run jump if character is walking/running. So you just do jump() and CharacterController figures out if it needs to do idle or run jump.

  1. the characters should not be overlappng each other space. Each of them have colliders which should prevent that.
    If you find the spaces are overalapping you might ahve to adjust the radius of the collider. The collider is the ellipsoid.
    you normally adjust this before calling the character controller. Example
player.checkCollisions = true;
player.ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5);
player.ellipsoidOffset = new BABYLON.Vector3(0, 1, 0);

@ssatguru
Copy link
Owner

I have put in a fix for 1. also added test file for testing npc/secondary characters

@bigrig2212
Copy link
Author

Nice. Keyboard fix works like a champ.
Also, i figured out the issue with collisions. It has to do with GLBs that when loaded, are put into an empty root container. So collisions don't register on that container. Kindof the same issue described here. So the solution is to either put a bounding box around the non-primary players. Or set checkCollisions = true; on one of the meshes lower down that is not empty, like so: meshes[1].checkCollisions = true;

Just being sure not to load two players in the same location, otherwise they get stuck to each other.

@bigrig2212
Copy link
Author

I also set all of the positioning code to apply to player1 only - and the syncing works a lot better now.
eg:
CharacterController.prototype._moveAVandCamera = function () { if (this._playerName == 'player1') { this._avStartPos.copyFrom(this._avatar.position); }

@bigrig2212
Copy link
Author

Hi again. Back to the missing anim functions. There are some anims that dont work for the secondary players. Like slideBack. I added a prototype for it.

    CharacterController.prototype.slideBack = function () {
        this._act._slideBack = true;
    };

And then call it like:
cc.slideBack(true);

But it doesnt trigger the anim for the 2ndary player. Doesn't error out anymore though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants