[SOLVED] Collision mesh does not work

project: PlayCanvas | HTML5 Game Engine
I have multiple scenes in my game, and that’s the way i navigate between scenes:

var ChangeSceneAction = pc.createScript('changeSceneAction');

ChangeSceneAction.attributes.add("sceneName", {
    title: 'Scene Name',
    type: "string"
});

ChangeSceneAction.attributes.add('location', {
    type: 'string',
    description: "The scene position to player teleport"
    });

ChangeSceneAction.prototype.initialize = function() {
    this.entity.action = () => {
        if(!window.playerState)
            window.playerState = {};

        window.playerState.entryName = this.location;
        window.playerState.currentScene = this.sceneName;
        this.app.scenes.changeScene(this.sceneName);
        this.app.off('player:action');
    }
};

It works well as u can see in the video bellow, but the physics just does not works as expected on the scene that i enter, and this is weird, it just does not work as work before.

Demo Link

[Update]

For some reason the colision of the objects is changing when i change the scene, i don’t know why, yet

Hi @Rafael_Alves!

It’s hard to see what exactly the problem is. It appears that the player falls through the ground at the end of the video?

Maybe you can tell how to reproduce the problem. Please also share which scene, entities and scripts are involved.

To reproduce, just start the game from scene “Campus” and go to the building seen in the video, press ‘E’ at the door to enter the scene ‘Predio1’, and for some reason all the colisions will be replaced. So you’ll fall through the ground, because the collision is moved, and not fitting the ground anymore.

The scripts:

  • ChangeSceneAction:
var ChangeSceneAction = pc.createScript('changeSceneAction');

ChangeSceneAction.attributes.add("sceneName", {
    title: 'Scene Name',
    type: "string"
});

ChangeSceneAction.attributes.add('location', {
    type: 'string',
    description: "The scene position to player teleport"
    });

ChangeSceneAction.prototype.initialize = function() {
    this.entity.action = () => {
        if(!window.playerState)
            window.playerState = {};

        window.playerState.entryName = this.location;
        window.playerState.currentScene = this.sceneName;
        this.app.scenes.changeScene(this.sceneName);
        this.app.off('player:action');
    }
};
  • InteractiveArea:
var InteractiveArea = pc.createScript('interactiveArea');

InteractiveArea.prototype.initialize = function() {
    this.entity.isTrigger = true;
    this.entity.collision.on('triggerenter', this.onTriggerEnter, this);
    this.entity.collision.on('triggerleave', this.onTriggerLeave, this);
};


InteractiveArea.prototype.onDestroy = function() {
    this.entity.collision.off('triggerenter', this.onTriggerEnter, this);
    this.entity.collision.off('triggerleave', this.onTriggerLeave, this);
};

InteractiveArea.prototype.onTriggerEnter = function(entity) {
    if(entity.name != "player")return;

    this.app.on('player:action', this.entity.action);
};

InteractiveArea.prototype.onTriggerLeave = function(entity) {
    if(!entity.name == "player")return;

    this.app.off('player:action');
};
  • The event dispatcher of action - for Desktop for example:
if(e.keyCode === pc.KEY_E)
        this.app.fire('player:action', this.entity)

and the movement scripts.

When debugging for some reason in the scene ‘Predio3’, it just works perfectlyh, really don’t know why the scenes ‘Predio1’ and ‘Predio2’ reproduce this.

An project fork to tests:
debug

Do you set the position of the player by script when you change the scene?

I telepert it to the entry scene position, imagine doors

Scene 1 |Door| Scene 2

Basicly when the player use the door

it teleport him to the door inside the Scene 2

  • Scene 1
    • door
  • Scene 2
    • door

When the player goes to Scene 1 to Scene 2

I do rigidboy.teleport

And the player initialize the position at the door in scene 2

And the same to go from Scene 2 to Scene 1

Can you please check if the position is valid and if the position is above the ground?

Check, and is above ground and not inside anything, did not understood what do u mean with ‘valid’. But, i think that’s

By valid I mean a correct vector 3, if not you can get an unexpected result. My guess is that the player is teleported too low, causing them to fall through the ground. I will check this when I have some time. In which script do you do the teleport?

In the CharacterController, i check if has some teleport call on window
And if it’s do the teleport

CharacterController.prototype.initialize = function() {
    this.handleTeleportPosition();
...
CharacterController.prototype.handleTeleportPosition = function () {
    if(!window.playerState || !window.playerState.entryName) return;
    const entityName = window.playerState.entryName;
    const entity = pc.app.root.findByName(entityName);
    if(!entity) return;
    entity.enabled = true;

    this.entity.rigidbody.teleport(entity.position);
    window.playerState.entryName = undefined;
};


May actually be what u are thinking, because on scene “Predio3”

It just works perfectly.

But i actually feel that’s a scene load problem, in the another scene at the first scene i enter on the video, before the player actually fall through the ground

it creates an invisible wall. And if u run comming for the “Predio2”, this wall is not there, so u can pass.

But comming from “Campus” to “Predio2” this wall is created, and from “Predio1” the ground on “Predio1” collides,

But comming from “Campus” to “Predio1” the player just fall.

Can you try to add the code below on line 10 of your code above and check the results with the console of your browser?

console.log(entity.position);

I’m also curious what entity exactly is and what happens when return is executed if entity is undefined. :see_no_evil:

I debugged your project and when I add an extra entity with a collision component and a rigidbody component the problem is solved. That means there is a problem with the mesh collision of the building.

1 Like

Log when undefined:
image

Just come nothing, because has a return before it

image

Log when defined is the door entity.

The logic:

I have components like these:
image

And that’s simple,

var ChangeSceneAction = pc.createScript('changeSceneAction');

ChangeSceneAction.attributes.add("sceneName", {
    title: 'Scene Name',
    type: "string"
});

ChangeSceneAction.attributes.add('location', {
    type: 'string',
    description: "The scene position to player teleport"
    });

ChangeSceneAction.prototype.initialize = function() {
    this.entity.action = () => {
        if(!window.playerState)
            window.playerState = {};

        window.playerState.entryName = this.location;
        window.playerState.currentScene = this.sceneName;
        this.app.scenes.changeScene(this.sceneName);
        this.app.off('player:action');
    }
};

The ChangeSceneAction, receive the scene to go and where to teleport the player, in the location field.

The script put the location on the global object window, and in the another scene on the init of the character controller, it takes the object name in the window object.

const entity = pc.app.root.findByName(entityName);

And teleports the player to the refered object.

This is how i change scenes to simulate the door opening.

I did not understood, the physics work correctly at the starting. But when i change scene some weird things happens.The problem is not the collision and the rigidbody itselfs, is their interaction when changing scenes.

As you can see in my demo video. The collisions at the beggining of the scenes just works fine. And is just perfect. But after entering some building weird things happens.

And starting from buildings the buildings is perfect too. But after exit it the ‘Campus’ is weird.

Seems to be some loading fail when loading scenes. I don’t really understend why this happens. But i can try to remake the modelling.

It looks like you are right.

Do you have any idea @yaustar? The mesh collision seems to work when you launch from the scene directly, but after loading it using changeScene() the player entity has no collision anymore with this mesh collision.

See the Demo. Please

Demo

I’ll explain key points of demo

Analysis of Scene Collisions and Transition Issues

Scenario 1: Starting from Campus

  • Timestamp 0:34: Notice how the player collides perfectly with the building at 0:42.
  • Timestamp 0:45: Switch to ‘Predio2’. For some reason, this creates an invisible wall that the player collides with at 0:49.

Scenario 2: Starting from Predio2

  • Timestamp 1:24: Observe that the player reaches the exact same place as in 0:49, but now the invisible wall is gone, and the scene is perfect.
  • Timestamp 1:52: Switch back to ‘Campus’. Notice how the building that collided at 0:42 no longer collides, which doesn’t make sense.

Scenario 3: Starting from Campus (Again)

  • Timestamp 2:21: Observe the perfect collision with the same building as at 0:42, now at 2:24.
  • Timestamp 2:33: Switch to ‘Predio1’. Note that the ground collision in ‘Predio1’ fails, causing the player to fall.

Scenario 4: Starting from Predio1

  • Timestamp 2:54: The ground collision is perfect.
  • Timestamp 3:05: Reach the same place where the player fell at 2:34. This time, the collision works fine, and the player does not fall.
  • Timestamp 3:14: Switch to ‘Campus’.
  • Timestamp 3:15: Switch back to ‘Predio1’. This time, the player does not fall, indicating that the ground collision is functioning correctly.

Conclusion

After studying these scenarios, especially the part “starting from Predio1,” it is evident that the problem cannot be with the modeling. When starting from Predio1, the collisions work perfectly. It also cannot be an issue with the ChangeScene script, as seen at 3:14 when switching to Campus and back to Predio1 at 3:15. The Predio1 scene loads correctly, and collisions work fine.

This leaves us with a perplexing problem that does not seem to fit known issues. If anyone has experienced similar problems, further insights would be appreciated.

U can try to reproduce the same errors yourself, just entering the project:
Project

1 Like

Not off hand and the project is too large to debug without spending a significant amount of time.

I woud look at trying to create the smallest reproducible possible. Focus on two scenes, delete all code that isn’t related to moving and changing scenes, etc

I would also consider creating an empty that just changes scene to the Predio2 and seeing if it still happens

1 Like

Okay @yaustar, and i did it as you can see here just deletes everything animations, buildings glb’s, this is the simplest reproducible póssible. And unfortunally the problem keeps happenning…

Would appreciate if you could try for me, please.

Ok, had a closer look and it looks like you are hitting a collision mesh caching issue. ie you are using the same collision mesh (at maybe different scales/positions) in different scenes. Ammo caches the first instance in the first scene you load and reuses it in the second scene it loads.

@LeXXik can explain more about this. The short term fix would be to ensure you don’t use the same render asset as collision meshes in multiple scenes.

eg in this fork, I’ve remove all references of collision to the asset Piso Laje_H15+Marmorite_100x100_cm [1116382] Geometry from Campus scene.

https://playcanvas.com/project/1232390/overview/f-deubg

Now it works fine.

Possible related thread: Memory Leak when dynamically assigning Collision Mesh using renderAsset

4 Likes

Wow! Thank you so much! I was stuck for about a week. Really thanks bro!

Just to add how I got to that point, I used LeXXik’s physics debug renderer to see that when I changed scenes, some collision looked wrong (position). I tried using an empty scene as the first scene which would load the second scene 1 sec later, that worked fine.

I then tried destroying all the entities first, waiting a bit and then loading the second scene to see if it was a race condition, that still didn’t work.

Then I remembered about this cache bug in Ammo/Engine that multiple people ran into and verified it by checking what render assets where used for collision.

4 Likes