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.
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');
}
};
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.
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?
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.
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.
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.
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.
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.
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
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
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…
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.
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.