Rotate entity by setEulerAngle doesn't work

**Note: You can jump straight to the [Question] part. I’m just giving you some background info to help you get the full picture. Thanks!


[1. Background]
I am working on a game prototype featuring multiplayer collision, similar to ‘Fall Guys’. This is my first project using a 3D game engine, and I am currently learning everything about 3D physics from scratch.

[2. References]
:Tutorials | Learn PlayCanvas
I based my project on ‘Crash Course’ tutorial for implementing player movement
And I referred to ‘Real Time Multiplayer’ for implementing real-time multiplayer features
(just 2 direct link is available. sorry for your inconvenience!)

[3. My project]
You can view my project here: PlayCanvas | HTML5 Game Engine

[4. Question]
Q1) Rotating Entity itself is not working
In the referenced project above (Crash Course), the ‘modelEntity’ is rotated to turn the player character. This seems effective, but I feel it’s just a visual trick because the entity itself isn’t rotating. I want to rotate the ‘Player’ entity itself, so that the ‘model Entity’, being a child of the Player, will rotate accordingly.

In the PlayerController.js:

        // 모델 회전
        var newAngle = 90 - (Math.atan2(z, x) * pc.math.RAD_TO_DEG);
        this.modelEntity.setEulerAngles(0, newAngle, 0);
        // this.entity.setEulerAngles(0, newAngle, 0);

Line 3 rotates the 3D model correctly
Line 4 does not rotate the 3D model(Player always looking at front)
What’s wrong with my code or understanding?

Q2) Logic for Synchronizing Multiplayer Animations and Rotations
I intend to ensure that animations and rotations for each client are synchronized through the server. Here’s my current approach for animation states:

  1. Client1 send their anim state(ex. isRunning) to server
    if (this.initialized && this.posSendTimer >= 0.05) {
        var animState = {
            isRunning : this.player.isRunning, 
            isJumping : this.player.isJumping
        };
        this.socket.emit("playerMoved", { id : this.id, pos : pos, rot : rot, animState : animState });
    }
  1. Server broadcasts anim state to other clients(Client2)
  socket.on("playerMoved", function (data) {
    // Broadcast the new position to all the other clients
    socket.broadcast.emit("updatePlayerTransform", data);
  });
  1. Client2 get anim state of Client1, and store its state in entity of Client1

    // 서버에서 유저의 포지션 업데이트 요청이 오는 경우 위치 업데이트
    this.socket.on('updatePlayerTransform', (data) => {
        if (this.initialized) {
            var isRunning = data.animState.isRunning;
            var isJumping = data.animState.isJumping;

            // 유저 데이터 세팅
            if (this.players && this.players[data.id]) {
                // anim state
                this.players[data.id].entity.isRunning = isRunning;
                this.players[data.id].entity.isJumping = isJumping;
            }
        }
    });
  1. Set boolean for playing animation
// update code called every frame
OtherController.prototype.update = function(dt) {
    // 더미 엔티티는 아래의 코드를 실행하지 않음
    if (!this.initialized) {
        return;
    }
    this.animStateTimer += dt;

    if (this.animStateTimer >= 1) {
        this.modelEntity.anim.setBoolean('isJumping', this.entity.isJumping);
        this.modelEntity.anim.setBoolean('isRunning', this.entity.isRunning);
        // 타이머 리셋
        this.animStateTimer = 0;
    }
};

The logic above is actually working well, but applying a similar approach for rotation data isn’t successful. If Q1 is resolved, I plan to:

  1. Have Client1 calculate the Euler angle of the player entity and send it to the server.
  2. The server then broadcasts this rotation data to other clients.
  3. Client2 receives this data from the server and sets the Euler angle of Client1’s entity using setEulerAngles, which should result in rotation.

Will this approach work effectively for a multiplayer game?


As I’m completely new to programming and 3D physics, any advice will be greatly appreciated.
Thank you for your assistance!

Hi @ispret9110 and welcome!

As far I have seen, the main problem is that you can’t use setEulerAngles() on an entity with a dynamic rigidbody. This only works on entities with a kinematic rigidbody. That makes that the logic or setup need to be more complex than expected.

You can use entity.rigidbody.teleport(position, rotation) to apply a new position and rotation on an entity with a dynamic rigidbody. (Alternatively you can apply a force on the rigidbody).

1 Like

Hi @Albertos, Thanks! I’ve made some changes to my code as follows:

        // // 모델 회전
        // var newAngle = 90 - (Math.atan2(z, x) * pc.math.RAD_TO_DEG);
        // this.modelEntity.setEulerAngles(0, newAngle, 0);

        var newAngle = 90 - (Math.atan2(z, x) * pc.math.RAD_TO_DEG);
        var newRot = new pc.Vec3(0, newAngle, 0);
        this.entity.rigidbody.teleport(this.entity.getPosition(), newRot);

However, I’m encountering a problem with the .teleport() function, which requires position information as input. When I use the code above, the entity’s movement (applying force) is disrupted by the teleport, making it look unnatural.

I’m looking to rotate the entity without affecting its position. Do you have any suggestions for a solution? Thanks!

Good point. Unfortunately, I’m not aware of an example where a dynamic rigidbody is rotated by forces. Maybe applyTorque() can work for you, but I never used it myself.

1 Like

By the way, what is the reason you need to rotate the rigidbody? If it is for the other players of the multiplayer, I think it’s better to use a kinematic rigidbody for the specific entity instead. There is probably no reason to use a dynamic rigidbody for this entity, as the local entity of the other players still have a dynamic rigidbody.

1 Like

Thanks for the help. I’ll try to see if applyTorque() works for my situation!

The reason I am attempting to rotate the ‘dynamic rigid body itself’ is as follows:

  1. Why dynamic? I plan for my game to mimic the ‘real world’, with a little bit awkward and funny 3D physics. Games like Fall Guys, Human Fall Flat, and Nippon Marathon are my references. Therefore, I believe all entities that interact with the player (including the player itself) should be ‘dynamic’.
  2. Why rotate itself? As I mentioned earlier, the PlayCanvas tutorial suggests rotating just the 3D model, not the rigid body, to make it ‘appear’ as though it’s rotating. However, I think rotating the 3D visual model is merely a trick, because in the real world, the actual entity(or the rigid body?) should rotate. That’s why I am trying to rotate the player entity itself.

Thank you for taking the time to help me, and with your comments, I’m going to further my studies. Any additional comments are welcome!

1 Like

Generally, you don’t need to rotate the Player entity. The capsule shape is same width, no matter from which side you look at it. Rotating it won’t change the collision distance. However, rotating it does make controls more complex. Most of the games, don’t rotate the physical body (even though you would do it in real life, of course).

Some of the games you mentioned are using a powered rig. That is no capsule shape for the whole character, but a series of shapes, joined with constraints and controlling the bones with physics motors. To be honest, it is a bit advanced if you are only starting your development journey. I’d suggest to start with a capsule and the “funny interactions” side would come from static animations, rather than a physicalized rig.

1 Like

@LeXXik
Thank you very much for your kind explanation. Due to the various constraints I’ve encountered, I’ve decided to go with using a capsule-shaped rigid body and just rotate the model. The biggest issue I’m currently facing is finding a way to naturally synchronize 3D physics in a multiplayer environment, so I’ll set aside it for now. Implementing complex physical actions is something I’ll tackle once I gain more skills.

Networked physics is generally a hard problem and there is no silver bullet solution that is suitable for every case. The simplest option for you would be to have only a player to be a dynamic body. Others will not have any physics, and simply be visual mesh that has its position/rotation updated from the network. Because of the network lag and inconsistency in receiving the network data, you would need to add some interpolation, so the other players don’t appear teleporting around.

1 Like