Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location Loader issue #229

Closed
gabaguiarp opened this issue Nov 28, 2020 · 18 comments · Fixed by #236
Closed

Location Loader issue #229

gabaguiarp opened this issue Nov 28, 2020 · 18 comments · Fixed by #236
Labels
bug (critical) This needs to be fixed as soon as possible

Comments

@gabaguiarp
Copy link

Short description
I have spotted an issue with the Location Loader where, at some point, an error will cause two locations to be stacked, which results in critical bugs, like having two instances of the Player at the same time.

Expected behaviour
New scenes/locations must be able to load seamlessly, without causing errors. Therefore, previous scenes must be unloaded first.

To Reproduce

  1. Start on the Beach scene.
  2. Exit to Forest.
  3. Exit to Beach.
  4. Keep repeating several times, until an "Index out of range" exception is thrown and you'll have two different locations loaded at the same time!

Notes

  • This is a repost of from the Unity forums thread.
  • Possible fix: I've noticed that the LocationLoader script loads new scenes before unloading the existing ones, which makes me wonder: shouldn't this happen reversely? I mean, it makes more sense to unload the existing scenes first, before setting the new ones to load.

Screenshot
issue

@ciro-unity ciro-unity added the bug (critical) This needs to be fixed as soon as possible label Nov 28, 2020
@ErikBehar
Copy link
Contributor

So this is happening because the two exit locations ( forest to beach & beach to forest) happen to be on top of each other. If you move one of the two so that its not overlapping then you wont have this issue.

The loading order is random, since we do both load and unload Asynch.

So this is likely to trigger in the case where the new scene loads before the older scene is unloaded, thus the old pig triggers the enter in the new scene. This could also happen the other way if the spawn point happened to be on top of where an old trigger is in the other scene.

Overall this could probably be prevented by:
a) destroying the character prior to doing any load/unload ( this could also prevent other issues regarding SO's surviving past scene load, between the two character loads )
b) making sure exit / enters don't overlap at spawn or at exit
c) adding a global cool down to exit locations, so that they can't be triggered so fast ( a few seconds should be enough?)
d) add more defensive code, like checking if the pig that triggered is in the active scene

@ErikBehar
Copy link
Contributor

tested option D) 👍
add
to line 19 of LocationExit : && other.gameObject.scene == SceneManager.GetActiveScene()

seems to work fine

@gabaguiarp
Copy link
Author

So this is happening because the two exit locations ( forest to beach & beach to forest) happen to be on top of each other. If you move one of the two so that its not overlapping then you wont have this issue.

The loading order is random, since we do both load and unload Asynch.

So this is likely to trigger in the case where the new scene loads before the older scene is unloaded, thus the old pig triggers the enter in the new scene. This could also happen the other way if the spawn point happened to be on top of where an old trigger is in the other scene.

Overall this could probably be prevented by:
a) destroying the character prior to doing any load/unload ( this could also prevent other issues regarding SO's surviving past scene load, between the two character loads )
b) making sure exit / enters don't overlap at spawn or at exit
c) adding a global cool down to exit locations, so that they can't be triggered so fast ( a few seconds should be enough?)
d) add more defensive code, like checking if the pig that triggered is in the active scene

Good point, that didn't occur to me at all!

I agree with option D, but I have one more defensive solution to add:
e) Since this is open world and every location is "connected", why not position them as they should appear in relation to each other, as if they were pieces of a bigger world map?
What I mean is, for instance: if the world map has two locations, both 10 units wide, and the Beach location pivot is at (0, 0, 0), the Forest location pivot would be at (0, 0, 5). This way, it's like the Pig Chief had crossed real world coordinates.
Of course, to do this, every GameObject in each location scene should be parented to a top GameObject that acts as the location's pivot and can easily be modified as the dimensions of the scene are increased/decreased. This not only avoids the issue where the Player hits two "exit triggers" at the same time, as it is also helpful to "build" the complete world map in the editor in a modular way, by having two or more scenes open at the same time, without them overlapping.

@ErikBehar
Copy link
Contributor

You might run into issues trying to position a scene, because it might not actually match real world sizes to each other, and which exit entrance combo should the pivot be on.

Overall it might be more helpful to separate them in a grid instead ?

@gabaguiarp
Copy link
Author

Yes, that's sort of what I'm suggesting. It's basically like each scene is a piece of a grid.
One scene's pivot should match the direction the previous scene exit leads to. It's just like you were building it all in one Master Scene and then slicing each location to pieces (scenes), very similar to what this tutorial describes.

@jandd661
Copy link
Contributor

The scenes where being loaded additively. Unless there is a plan to do some fancy level phasing, the scenes should be loaded LoadSceneMode.Single am I missing something? Anyway, I have a PR #231 for a proposed fix.

Video: https://youtu.be/9rZnrfmYvfw

@gabaguiarp
Copy link
Author

Scenes need to be loaded additively, because the game starts with an Initialization scene that must be persistent. That scene is responsible for displaying the loading screen interface between loads, managing audio, and possibly carry Player Data, along with other background operations.

It's true that each scene in the project has a reference to the Initialization scene and automatically loads it on Start if it is not already present in the hierarchy, but that is meant for debugging purposes. Loading scenes with LoadSceneMode.Single will prevent that session's data from being carried, since the Initialization scene will be reloaded and therefore reset.

@ErikBehar
Copy link
Contributor

Also we are sending an array of scenes ( meaning you could load several scenes if required)

@jandd661
Copy link
Contributor

Ah, I see. Nothing is ever easy is it :D Ok, I closed the PR #231 and will take another look with that info in mind. Thanks.

jandd661 added a commit to jandd661/open-project-1 that referenced this issue Nov 28, 2020
jandd661 added a commit to jandd661/open-project-1 that referenced this issue Nov 29, 2020
jandd661 added a commit to jandd661/open-project-1 that referenced this issue Nov 29, 2020
jandd661 added a commit to jandd661/open-project-1 that referenced this issue Nov 29, 2020
@jandd661
Copy link
Contributor

jandd661 commented Nov 29, 2020

OK, I got it worked out. It now works as you guys said it should work. I also left some TODOs for expansion that I can come back to if needed. Pretty handy little scene loader. Still have lots to do though =)
PR: #236
Video: https://youtu.be/VQWs_yalU6o

@ErikBehar
Copy link
Contributor

ErikBehar commented Nov 29, 2020

OK, I got it worked out. It now works as you guys said it should work. I also left some TODOs for expansion that I can come back to if needed. Pretty handy little scene loader. Still have lots to do though =)
PR: #236
Video: https://youtu.be/VQWs_yalU6o

I think these are good changes, albeit :

  1. does not properly support loading multiple scenes (of course can be added in future)
  2. should still do the check I suggested on the exit, since the issue is still happening, just being prevented from surfacing symptoms (but could have other side effects in the future) ... I've taken the liberty of implementing both A) & D) suggested solutions above, to be extra safe in this PR Issue #229 : prevent old pig from triggering anything in new scene #237

PS: note that we don't prevent the new pig from possibly triggering something (other than exits) in the old scene yet. Possibly we should wait to spawn the new pig until we are sure the old scenes are unloaded ?

@jandd661
Copy link
Contributor

jandd661 commented Nov 29, 2020

@ErikBehar Good deal. Please explain "does not properly support loading multiple scenes" so I know what the intent is. I get the ability to layer scenes for phasing and such but it seems to be a very convoluted way of doing things just to persist data. Thanks.

@gabaguiarp
Copy link
Author

I agree with the changes too, but also think that @ErikBehar suggestion on adding a check method is essential to avoid issues. It's always safer to double-check when we are working with operations that handle a lot of instances at the same time.

PS: As far as I've checked, @jandd661 changes do support loading multiple scenes; that's the whole point of the video posted. Are you missing something @ErikBehar ?

@gabaguiarp
Copy link
Author

@ErikBehar As for destroying the player, I wonder if it wouldn't be more reliable to do it in the Spawn method itself. Something like:

IEnumerator Spawn(int spawnIndex)
{
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null) Destroy(player);
yield return new WaitUntil(() => SceneManager.GetActiveScene() == gameObject.scene);
// Spawn code
// ...
}

@ErikBehar
Copy link
Contributor

ErikBehar commented Nov 29, 2020

@ErikBehar As for destroying the player, I wonder if it wouldn't be more reliable to do it in the Spawn method itself. Something like:

IEnumerator Spawn(int spawnIndex)
{
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null) Destroy(player);
yield return new WaitUntil(() => SceneManager.GetActiveScene() == gameObject.scene);
// Spawn code
// ...
}

I think we want to destroy the old pig as early as possible, so on the exit script is the earliest... if you wait to the spawn, you might run into the same issues we are trying to prevent.

I do think adding the wait for the new pig might be good idea, although I think it would be best to wait for all the old unloading scenes to be done loading instead of just the active scene. This would require listening to some event from the loader.

@ErikBehar
Copy link
Contributor

@ErikBehar Good deal. Please explain "does not properly support loading multiple scenes" so I know what the intent is. I get the ability to layer scenes for phasing and such but it seems to be a very convoluted way of doing things just to persist data. Thanks.

Sorry, didnt look at the video, I only looked at the code changes, and I was looking at "SetActiveScene" function and wasn't completely sold on it working well when I read the code before. I see that its always setting active_scene now. I guess this is fine with the current assumption that the active scene should always be the first one.

@gabaguiarp
Copy link
Author

@ErikBehar As for destroying the player, I wonder if it wouldn't be more reliable to do it in the Spawn method itself. Something like:
IEnumerator Spawn(int spawnIndex)
{
var player = GameObject.FindGameObjectWithTag("Player");
if (player != null) Destroy(player);
yield return new WaitUntil(() => SceneManager.GetActiveScene() == gameObject.scene);
// Spawn code
// ...
}

I think we want to destroy the old pig as early as possible, so on the exit script is the earliest... if you wait to the spawn, you might run into the same issues we are trying to prevent.

I do think adding the wait for the new pig might be good idea, although I think it would be best to wait for all the old unloading scenes to be done loading instead of just the active scene. This would require listening to some event from the loader.

Seems acceptable to me.

Maybe moving _scenesToLoadAsyncOperations[0].completed += SetActiveScene to the end of the TrackLoadingProgress coroutine will get the job done. That way, the first scene will only become active after all the others finish loading.
Of course, we'll add this inside the else statement in LoadScenes too, or create a method called OnLoadingFinished to do both the activation and _scenesToLoadAsyncOperations clearing.

@ciro-unity
Copy link
Contributor

Thanks everyone, the issue is fixed... for now!
We need to do some more work on the scene loading, specifically to support multiple entrances/exits from locations. I'll talk about it during the stream on Tuesday, and I'll create a task card for it!

DeivSky added a commit to DeivSky/open-project-1 that referenced this issue Jan 7, 2021
* moved inventory scripts to align with project conventions

* actually destroy the gameobject an not the component

* added a background color to the item type

* created player inventory and first ingredient which can be collected

* make it possible to show items of inventory in inspector

* made Item fields as they were before

* hair color mask material, old lady hairdo and glass, moustache, and shell bowl

Various art assets to make the townsfolk more unique. Bowl made from a giant shell.

* Added trap to small testing ground

Useful for testing

* Fix for issue Location Loader issue UnityTechnologies#229

* Revert "Fix for issue Location Loader issue UnityTechnologies#229"

This reverts commit c7d75ff.

* Proposed fix for issue UnityTechnologies#229 with test scenes

* Revert "Proposed fix for issue UnityTechnologies#229 with test scenes"

This reverts commit 14a6a3a.

* Revert "Revert "Proposed fix for issue UnityTechnologies#229 with test scenes""

This reverts commit 3e9fb2d.

* Update Beach Scene with test data

* Revert "Update Beach Scene with test data"

This reverts commit 90ac457.

* Updated Beach Scene with test data for Scene Loader

* Update TestingGround_Small.unity

Grouped object

* Remove Fresnel properties from ToonShading subgraph

I moved Albedo out from ToonShading and into the main shadergraph. I then created the new subgraph Albedo_Fresnel which contains the lerp operation needed for the slimes. The Albedo subgraph has been added to all toon shadergraph variants.

* Fix Plant Critter mesh scaling and name (UnityTechnologies#239)

* Townsfolk_M animations, Palm2

* Added Event that takes GameObject in parameter

* Added events for pickup, cook and talk

* Added interaction example scene

* Added interaction manager script

* Added interaction to main character prefab

* Added Rigidbody component to the Interaction GO on the pig

* Changed interaction key to E (From K)

* Moved Interaction script to scripts folder

* Added tags for interactions

* Added examples to interaction example scene

* Game input update after interaction key change

* [Bot] Automated dotnet-format update

* Remove Albedo Influence on Specular Light Brightness

Swapping the order of the multiply and add nodes in the ToonShading subgraph to multiply albedo by diffuse light alone, then add specular highlights.

Along with this is the need ability to control specular light transparency, which can now be done using the Specular Color property's alpha channel.

* New tree type

* Reset HasBeenPrewarmed (UnityTechnologies#243)

* [WIP] Added some table furniture (UnityTechnologies#233)

* Added some table furnitures

* Corrected all furniture prefabs to be prefab variant

* Added back recklol Dissolve effect (UnityTechnologies#217)

* Added recklol dissolve effect with some tweaks

* Added names to dissolve outputs

* Added a dissolve effect option in contextual menu and add alpha cutoff in Toon_Disolve

* [Bot] Automated dotnet-format update

* updated interaction manager

* interaction ui event

* [Bot] Automated dotnet-format update

* Imported Smurjo's models, reorganised folders

* Hotfix for null checking `ToState`. (UnityTechnologies#244)

* Wiki and Readme images

* Update README.md

* TownAssets

More enviroment 3D assets.
-Small house in the same style.
-Empty market stands
-Small market items for decoration
-A door.

* Added interaction UI when interaction ends

* Update README.md

* Added enable UI action map from InputReader

* Updates on interaction manager

* Interaction go on the pig is now a prefab

* Added pick up sfx and play sound action

* Added pick up state to the state machine

* pickUp state in states folder

* Added item event type

* Added dialogue event type

* removed comment from Interaction UI event channel

* Added interaction events and updated interaction manager

* pushing interaction example scene

* Added isPickingUp SO condition to state machine

* Added pickup state to state machine

* Added timer pick animation condition and is picking up condition

* Added pick up trigger action to state machine

* updated pig chef animator controller for pick up animation

* [Bot] Automated dotnet-format update

* start talking interaction event name updated

* Initial decoupling of CameraManager and SpawnSystem. Spawn system still needs reference to CameraManager, because it must provide it to Protagonist.

* Updated prefabs

* Added description to EventChannels

* Introduced RuntimeAnchors

Used in Spawn and CameraSystem for decoupling purposes

* [Bot] Automated dotnet-format update

* Added Frying Pan asset (UnityTechnologies#252)

* Added Frying pan assets

* Changed material smothness

* Updated furnishing texture and colliders on furniture (UnityTechnologies#251)

* Issue UnityTechnologies#245 simple fix for camera erratic behaviour (UnityTechnologies#250)

* hair color mask material, old lady hairdo and glass, moustache, and shell bowl

Various art assets to make the townsfolk more unique. Bowl made from a giant shell.

* Fix Plant Critter mesh scaling and name (UnityTechnologies#239)

* Townsfolk_M animations, Palm2

* New tree type

* simple fix for camera

* Reset HasBeenPrewarmed (UnityTechnologies#243)

* [WIP] Added some table furniture (UnityTechnologies#233)

* Added some table furnitures

* Corrected all furniture prefabs to be prefab variant

* Added back recklol Dissolve effect (UnityTechnologies#217)

* Added recklol dissolve effect with some tweaks

* Added names to dissolve outputs

* Added a dissolve effect option in contextual menu and add alpha cutoff in Toon_Disolve

* [Bot] Automated dotnet-format update

* Imported Smurjo's models, reorganised folders

* Hotfix for null checking `ToState`. (UnityTechnologies#244)

* Wiki and Readme images

* Update README.md

* Update README.md

* Initial decoupling of CameraManager and SpawnSystem. Spawn system still needs reference to CameraManager, because it must provide it to Protagonist.

* Updated prefabs

* Added description to EventChannels

* Introduced RuntimeAnchors

Used in Spawn and CameraSystem for decoupling purposes

* [Bot] Automated dotnet-format update

* Changed the wait to EndOfFrame

Co-authored-by: Smurjo <Johanna@johanland.de>
Co-authored-by: treivize <42570903+treivize@users.noreply.github.com>
Co-authored-by: Ciro Continisio <ciro@unity3d.com>
Co-authored-by: Dave Rodriguez <drod7425@gmail.com>
Co-authored-by: David Lischinsky <david.lischinsky@outlook.com>
Co-authored-by: Jan Urbanec <UrbanecJ@seznam.cz>

* State Machine - Proposed fix for Issue 228 (UnityTechnologies#227)

* Added Sliding to JumpAscending

Player was unable to jump if sliding which caused the player to get stuck in geometry/holes.

* Added IsActuallyMoving Condition SO and update PigChef Transition Table

IsActuallyMovingSO evaluates character movement by the character controller's velosity.sqrMagnitude. Returns true if the character controller is moving beyond the threshold. Characters can no longer jump while sliding but can jump if they get stuck.

* Update .gitignore

* Small fixes

Reconnected disconnected assets in the TransitionTable, reverted changes on the .gitignore, added multiplication in threshold verification equation

Co-authored-by: Ciro Continisio <ciro@unity3d.com>

* [Bot] Automated dotnet-format update

* Shader tweaks and reorganisation

* Shading style wiki images

* Add files via upload

* Add UI system, Inventory UI and update Inventory System

* [Bot] Automated dotnet-format update

* Fixes to example, moved files in Examples folder

* [Bot] Automated dotnet-format update

* Switched layers of occluding objects

* Leftover lightmaps

* Relocated stray assets

* post merge fixes

* Fixed event for interaction pick up

* Changed Events to Event Channels

* [Bot] Automated dotnet-format update

* added null check before event raise on interaction

* [Bot] Automated dotnet-format update

* bard hare in interaction example scene for talk interaction test

* Adding interaction UI + Events

* Fix last commit

* [Bot] Automated dotnet-format update

* updated event name for interaction ended

* Adding initialization script

* [Bot] Automated dotnet-format update

* Add an on Interaction Ended Event raise

* [Bot] Automated dotnet-format update

* Added collider on bard hare prefab

* updated example scene for interaction

* testing ground scene cleaning

* Imported ground textures

* New FryKing animations and prefab

* Renamed UI scene to gameplay scene

* Removed old comments from InteractionManager

* First setup

* Small fixes

* ChefHat accessory

* palm leaf set and lobster

Prefabs for the cooking festival

* New art assets

* setup IK for the pig on the arms

* Added small internal cooldown to the PlayLandParticlesAction StateAction (UnityTechnologies#260)

* Added small internal cooldown to PlayLandParticlesAction StateAction

https://open.codecks.io/unity-open-project-1/decks/15-code/card/18k-avoid-spamming-particles-on-sliding

Whenever the PlayLandParticlesAction StateAction is exited by the state machine, it checks if total elapsed time is greater then the total elapsed time of the last particle call + a small amount.

If so, only then do we tell the DustParticle Controller to play, and we also set the new time to beat to be the current time.

* Update PlayLandParticlesActionSO.cs

Removed the unnecessarily verbose extra function

Co-authored-by: Ciro Continisio <ciro@unity3d.com>

* [Bot] Automated dotnet-format update

* Fix/LocationSO not serialized properly (UnityTechnologies#258)

* Fix GameSceneSO not serialized properly.

* Add a reference to the script as a ObjectField in the GameSceneSO

To edit the code faster

* Fix typo

* Renaming and cleaning folders

* clening assets folder

* Add control over cooking when near pot

* [Bot] Automated dotnet-format update

* Added new interaction scene example

* Skybox experiments

* ClearSky skybox

* Reworked the CM camera, added collider, noise

* Reorganised scenes

* Removes spaces in scene names

* Bushes, new Fern plant

* Reintroduced camera noise

* Update ReplaceTool.cs (UnityTechnologies#221)

* "Replace" context-menu with a searchable popup  (UnityTechnologies#223)

* "Replace" context-menu with a popup window

* [Bot] Automated dotnet-format update

* Selection interactive preview

* Whoops, wrong merge resolve

* [Bot] Automated dotnet-format update

* Show popup at screen mouse position

* Mini-previews on renderable objects + minor GUI improvements

* [Bot] Automated dotnet-format update

* Editors cache fix, remove dummy editor

* Destroy only cached editor

* Rename "ReplacePrefabTreeView" to "PrefabSelectionTreeView"

* catch ClearPreviewCache error

* fix null texture warning

* Fix popup fit on smaller screens

* Fix black frame when closing popup during repaint

* Expand folder on single-click

* Remove editor Destroy, as error is still showing inside try catch

* Revert delayed close, as it made popup not-closable in some cases

* Added editor for ScriptableObject with events. It allows to automatically show buttons for each event and raise them. (UnityTechnologies#256)

* "Editor window to quickly open scenes" task (UnityTechnologies#267)

* Added the Quick Scene Access Tool

* removed unused file

* [Bot] Automated dotnet-format update

* Imported lobster, palm leaf set, tavern owner's hair

* AnimationRigging setup, lantern grab clip

* Added BardHare and FryKing animations

* Added Run and Faint animation for PigChef, implemented Run as BlendTree

* Removed Localisation samples

* Added the ability to run for keyboard players

* Input and Camera tweaking

* Input and Camera tweaking

* [Bot] Automated dotnet-format update

Co-authored-by: circa94 <hannesklose@hotmail.de>
Co-authored-by: Chema Damak <chema.damak@unity3D.com>
Co-authored-by: Llaczky <72225106+Llaczky@users.noreply.github.com>
Co-authored-by: Smurjo <Johanna@johanland.de>
Co-authored-by: jandd661 <74697341+jandd661@users.noreply.github.com>
Co-authored-by: Dane Byrd <daneobyrd@gmail.com>
Co-authored-by: treivize <42570903+treivize@users.noreply.github.com>
Co-authored-by: Ciro Continisio <ciro@unity3d.com>
Co-authored-by: Amel Negra <amel.negra@unity3d.com>
Co-authored-by: Dave Rodriguez <drod7425@gmail.com>
Co-authored-by: Jan Urbanec <UrbanecJ@seznam.cz>
Co-authored-by: erizzoalbuquerque <erizzoalbuquerque@gmail.com>
Co-authored-by: Erik Behar <invadererik@gmail.com>
Co-authored-by: John McAllister <jandd661@gmail.com>
Co-authored-by: Smurjo <73852662+Smurjo@users.noreply.github.com>
Co-authored-by: MTrecozzi <47111522+MTrecozzi@users.noreply.github.com>
Co-authored-by: Rainaldi Satria <57592497+rainaldisatria@users.noreply.github.com>
Co-authored-by: uChema <59874519+uChema@users.noreply.github.com>
Co-authored-by: juicedup12 <37230501+juicedup12@users.noreply.github.com>
Co-authored-by: Neonage <alexander.neonage@gmail.com>
Co-authored-by: Can Chen <canchen@usc.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment