[SOLVED] Multiplayer animation with PlayCanvas and Photon

Hey,

A group of us are trying to currently build a multiplayer fps with playcanvas and photon.
At the moment, I have managed to spawn in multiple player models.
However when I try to translate over the animations, the animation of the current player is what the player sees on the enemys.
I mean that if I move, I see the enemy doing the move animation, if I jump, I see the enemy jumping etc, not the animation corresponding to the enemy’s respective movement.
Here is the current state of the project.
If I could get any pointers on how to separate out the animations that would be much appreciated.
https://playcanvas.com/editor/scene/1540070
Kind regards.

1 Like

The current state is at the latest checkpoint in the Alexis branch.

@Alexis_Shaju I am currently working on a multiplayer using Photon. There is a bit of learning involved but I will try to do my best to explain. There seems to be a missing item in your scripts. Here is an example from the forum of which you can have a look at.

Please have a look to the bottom of this post and there you will find an example project to look at.

I do not see in your project a file like game-room.js. In this file is the handling of all of the other players that are spawned or instantiated in your room. This script along with the player script and the Template of the character itself are used to represent in your view the other players that have joined in the room.

image

So the attached player.js script is to your script actually broadcasts your players information to the server connection where all of the other players are listening and broadcasting their positions.

To make the animation work for the players that you see you will have to first apply the same animations to the template(characterMedium) and accept the changes to the template. Then you will have to modify both player to broadcast character animation state and game-room.js to handle changing that state on the instantiated players in your view.

1 Like

I will have a look at the advice you gave and get back to you. Thanks a lot for this.

1 Like

@Tirk182
I have tried to mess around with the code and have not gotten anywhere. The game room logic, I think I can implement that by copying bits of code and modifying it for this project. However when I tried applying all animations and scripts to the template (characterMedium), now I get a spawn error with my original code. Like the second user that is instantiated takes over the first, and both users move the same model. If one user moves his, the other screen sees this user moving the model, if that makes any sense.

@Alexis_Shaju I had a look at your project. Is your player going to be first person or third person? If it is going to be first person then the camera will need to be moved and positioned inside the character. Currently it is outside and face toward the character.

I am not sure what code you have transferred over to your project. Here is an idea that will, I think help your understanding. Take the link that was in the forum answer and fork it so you can make it your own. Start slowly by replacing FPSPlayer with your player template. Make sure you position the camera inside properly and add your animations. Make sure you can walk around and can move the way you want to. Once this is working open another browser tab and join the game. You should see the other player appear as a capsule. That’s fine for now as you are just testing the interface. Then you can work on the other players in the room by altering the template Player.

I also noticed in your project that you are using AppVersion 1.0. I believe the latest is 2.0 and I don’t know what the impact will be on your current Photon usage.

The intention for our project is to make a multiplayer fps shooter game with animations hopefully. I think the camera is positioned at the player in the master branch. I’m currently working in the Alexis branch as it’s four of us trying to build different aspects of the project. At the moment, I have forked your project that you said to, and created a new scene in the Alexis branch. I will try and copy everything slowly and see where this leads.

1 Like

@Alexis_Shaju I am looking at your project from the link above. I don’t see a branch but maybe I am not looking at your link properly or have the wrong one.

Only project members are be able to see branches.

1 Like

I think you are on the right branch then. These are the branches I have in the current project.

@Tirk182 I have implemented the logic you said for the room handlers, I will commit it all to the current master branch so you can view it. One moment.

@Tirk182 Now you should see what I am working with in the master branch. I have created three new scenes. Please take a look at the GameRoom scene, here is where I want the otherPlayer to start making animations.
Sorry for all this mess, I thought we were seeing the same thing.

@Alexis_Shaju OK now I can see it better. I have not forked it yet but do see this.

image

I would delete and re add. Make sure you fill out your API info.

Also this needs added.

image

For me, both of these are already done? I don’t know if it’s something visual. For the moment, I have set the player as new model template with nothing done to this template.
image

@Alexis_Shaju Ok I see what you are doing now. Looking much better. Have a look to your camera. Is there a reason it is flipped 180 on the Y. Also Gun

No reason at all, moved that back to 0 now. Back to what you said at the beginning. If I program the enemy player model with all the animations etc and add it to template. And set that as the model viewed as the enemy player, should the animations done by the enemy portray on my screen?

@Alexis_Shaju This will have to be broadcasted using player.js. So what you will have to do is add to the structure in this code.

Like

Player.prototype.raiseEvent = function () {
    if (!this.tmpVec.x || !this.tmpVec.y || !this.tmpVec.z) return;
    const data = {
        position: {
            x: this.tmpVec.x,
            y: this.tmpVec.y,
            z: this.tmpVec.z,
        },
        player: {
            name: this.app.loadBalancing.myActor().name,
        }

    };
    //console.log("raiseEvent!!");
    this.app.loadBalancing.raiseEvent(0, data);
};

I am adding to mine currently. So you could add the name of the animation you want to play here in a variable.

After this is done then you will have to edit game-room.js Here

GameRoom.prototype.updatePlayerPosition = function (content, actorNr) {

    const { x, y, z } = content.position;
    const pName = content.player.name;
    const player = this.entity.findByName(actorNr);

    // Display Actor
    this.playerName = player.findByName('State').element;
    this.playerName.text = pName;
    player.<<<<<<<<<<<<<<<<Animation state to run <<<<<<<<<<<<<<<

    // Set the position
    player.setPosition(x, y, z);
};

@Tirk182 Sorry I’m getting a little confused with this. Does the player.js broadcast the animations themselves of a enemy player to current player and this is shown through game-room.js or how exactly is this working? Could you show me what you have written?

Sorry for being a little stupid, just a cs student in the making, struggling with coding. :smiley:

@Alexis_Shaju Yes I can do my best. So for reference the player.js is attached to your player only. It’s main function in life is to transmit information about your local player to the rest of the players in the game room.

As you move your local player the postUpdate reads your position and then calls it raiseEvent function which in turn stuffs the structure called data with important information about you and then it runs Photon SDK raiseEvent passing data. Keep in mind when you joined the room the SDK assigned you a actorNr.

Next game-room.js main function is to instantiate other players in the room which are just representations or clones in the room. So look to this function in game-room.js

GameRoom.prototype.updatePlayerPosition = function (content, actorNr) {

    const { x, y, z } = content.position;
    const pName = content.player.name;
    const player = this.entity.findByName(actorNr);

    // Display Actor
    this.playerName = player.findByName('State').element;
    this.playerName.text = pName;

    // Set the position
    player.setPosition(x, y, z);
};

So this function is called every time one of the remote players changes their position. In your view this is a clone of them. So in the message received you will see content and actorNr. actorNr is the player number that sent the message. content is actually the data sent. So what happens is that the position in this case will update the clone in your local screen based on what was sent by the actual other player or players.

I am working on a better example to post currently but, you can see that I have added a data member to the structure which will contain player info. Under the tag I have created a data member called name. So every time my local player updates it passes the player name entered when joining the room. So it passes data.

const pName = content.player.name;

In game-room.js I create a variable to hold the player name. And then I use it to display over the other players heads so I can see there names in my local players view.

I don’t know how you are activating your animation states but your could pass a state number.
player.js

    const data = {
        position: {
            x: this.tmpVec.x,
            y: this.tmpVec.y,
            z: this.tmpVec.z,
        },
        player: {
            name: this.app.loadBalancing.myActor().name,
            animState: this.<<<<<<<<<<<<<<<<current animation state
        }

game-room.js

    const pName = content.player.name;
    const player = this.entity.findByName(actorNr);
    const playerAnim = content.player.animState;

   player.set<<<<<<<<<<<<<<<<activavate state playerAnim

Again I did not have a deep look at you animation activations. Let me know if this helps.