Scene Exists and Scene Visible

What is the difference between Scene.Exists and Scene.Visible?

Every scene I use has its own xml file that points to a .png.
When I change scenes that I already loaded with their url files it looks as if they are loaded every time again I change scene. For instance a walking character that suddenly ‘holds’ with a standidle Playanimation spritescreen causes a little hickup. When I repeat the movement and stop it is fine. Maybe because the 2 scene URL are still in memory or cache?

I don’t know if I am clear. I don’t know how to upload a small video recording of this issue to show otherwise.

image

Visible: Determine if a scene is visible to the eyes or not. Scene is still able to collide with other scenes even if it’s not visible.
Exists: Pretty much self-explained. Scene with Exists = False is treated as if it’s not exists in the scene graph (cannot be seen, cannot collide with other scenes, cannot be picked).

You can use any recording tool (Open Broadcaster Software for example) to record the issue and upload it to https://streamable.com/ (no need to register an account).

That is indeed the case. That is, when doing MyScene.URL := 'something-new', we load the new scene (from disk).

Internally we have a cache of resources (like textures). If a few sprite sheets use the same texture, it will indeed be in the cache, and not freed/reloaded.

You can use “warmup cache” to preload some scenes ( Customize look by CastleSettings.xml | Manual | Castle Game Engine ) to have their textures loaded at the application start, and always kept in cache. I do not know whether it is related to your problem though.

If you want to toggle some scenes at runtime (replacing one sprite sheet with another), it is generally fastest to have 2 scenes, have both scenes loaded (set their URLs at loading, and do not change URL while the game is running), and only toggle their Exists property, so that only one scene is present at given time. Toggling Exists property is always instant, things are already loaded etc.

Thanks. Meanwhile I found out that the problem only occurs when I use destination coordinates where the Scene has to ‘stop walking’.
(see my last code in topic ‘Moving in 8 directions’. )
With just key presses ‘walk-stop’ everything is allright without hickup when stopping.
and I do not change URL in a scene; every scene has it’s own ‘unique’ URL file designed in CGE.

videos: (thanks Kagamma for the link) :slight_smile:

When using click mouse coordinates https://streamable.com/czmlz1

And as you can see it’s only occuring the first ‘stop’. When continuing ‘walk-stop’ in the same direction there is no hickup with the next stop.

When I control with key presses https://streamable.com/63jy6z

Procedure TStatePlay.GoRight;
begin
   Player.Stand := false;
  Player.StandIdleScene.Exists := false;
  Player.WalkRightScene.Exists := true;
  Player.WalkRight := true;
  Player.WalkRightScene.PlayAnimation(Player.Personalia.FirstName + 'walkright', true);
end;

Procedure TStatePlay.StandRight;
begin
  Player.Stand := true;
  Player.WalkRightScene.Exists := false;
  Player.StandIdleScene.Exists := true;
  Player.StandIdleScene.PlayAnimation(Player.Personalia.FirstName + 'standright', false);
end;                          

With mouse-clicked coordinates:

procedure TStatePlay.PlayerDestinationUpdate;
begin
  if Player.X >= Round(Player.Destination.X) then
  begin
   if Player.WalkRight then StandRight; 
end;

Update:

This is very strange:
When I use a string variable instead of Boolean in the previous procedure there is no hickup?

procedure TStatePlay.PlayerDestinationUpdate;
begin
 if Player.Personalia.FirstName = 'john' then
 if Player.X >= Round(Player.Destination.X) then StandRight;
 end;

I tried different Boolean, local and global but they give a glitch when changing scene, but with string if…then… it works okay!
How can this be?

We don’t know in what context you use this code. It’s not really possible to help looking at this short code snippet – what happens, and what should happen, depends on a lot of things.

Note that what you post is not just “changed variable from string vs boolean”.

In one version you show:

procedure TStatePlay.PlayerDestinationUpdate;
begin
  if Player.X >= Round(Player.Destination.X) then
  begin
   if Player.WalkRight then StandRight; 
end;

In another version you show:

procedure TStatePlay.PlayerDestinationUpdate;
begin
 if Player.Personalia.FirstName = 'john' then
 if Player.X >= Round(Player.Destination.X) then StandRight;
end;

So in 1st version, you

  • added additional condition (checked early) on Player.Personalia.FirstName = 'john'

  • removed condition (checked in the middle) on Player.WalkRight.

Thanks.
I will try to upload the problem as soon as the Translation problem of background scene (other topic :slight_smile: is solved.
This one however is not a small code, it needs rather some code to work
:slight_smile:

Okay, here it is anyway.

8 direction problem.zip (30.1 MB)

I also uploaded this in the topic ‘moving in 8 directions’.
But the problem here is also the ‘hickup’ stop of the character from walk to stop (only first time walk-stop in the same direction).

I had to do some filename fixes to make it work on Linux (case-sensitive filesystem). E.g. data/Characters/John Carring must be data/characters/john carring as your code uses Player.Personalia.FirstName := lowercase('John') and later assumes that this is a proper directory name part.

As for the hiccup at animation:

  • That is because PlayAnimation doesn’t immediately change the model state to correspond to the new animation, there may be 1 frame when the previous state is displayed. This is often OK, and more optimal (as it doesn’t matter when you just display 1 scene, and only change animations using PlayAnimation).

    Note that this is documented: PlayAnimation .

  • In your case this results in visible “hiccup” as you switch to a different scene (you have different scenes for walk and stand), and the 1st frame of a new scene may not correspond to 1st frame of your animation.

  • The solution is to use ForceInitialAnimationPose right after every PlayAnimation call, as PlayAnimation docs say. E.g.

    with Player.StandIdleScene do
    begin
     ....
      PlayAnimation(Player.Personalia.FirstName + 'standse', false);
      ForceInitialAnimationPose;
    end;

or

  Player.StandIdleScene.PlayAnimation(Player.Personalia.FirstName + 'standright', false);
  Player.StandIdleScene.ForceInitialAnimationPose;

With this modification, the hiccup is gone.

Sorry for that. You mentioned this earlier. I still have to remove some capitals from maps and filenames.

Yes, this works. Thanks!
:slight_smile: