public sealed class ComponentManager : MonoBehaviour, IIdentifiable
Defines a manager which handles a variety of task, from handling persistent data to
initializing all
Worlds and
Active Grids in the scene. There should only be one Component Manager in each of your scenes.
You can destroy and create Active Grids and Worlds during runtime via the Component
Manager class. To create these
components at runtime, you will need to provide one or more prototypes. Prototypes
store default configuration data
as well as references to other crucial components that cannot be identified at runtime.
Prototypes should be attached
to disabled game objects.
To save/load data, use one of the provided implmentations of IPersistentStateManager
(or create your own) in combination with the
Save and Load methods.
There is a limited window in which persistent data can be loaded via the Load method.
This window
will close immediately when CreatePersistentActiveGrid, CreateNonPersistentActiveGrid,
CreatePersistentWorld,
or CreateNonPersistentWorld are called for the first time. It will also close once
the Component Manager has been initialized. You can delay initialization by unchecking
"Initialize On Awake," but you
will have to manually call Initialize or InitializeGradually.
Name | Type | Description |
---|---|---|
ID | int |
The ID that uniquely identifies this Component Manager. |
InitializationProgress | float |
Gets the progress of a gradual initialization operation, which you can use in a loading
bar when Initializing the Component Manager. Ranges between 0f (before
initialization has begun) and 1f (after initialization completes).
|
InitializationTriggered | bool |
Gets a value indicating whether one of the Component Manager's initialization methods has been called already. |
IsInitialized | bool |
Gets a value indicating whether the Component Manager has been fully Initialized (and
without errors).
|
WasInitializedGradually |
Gets a value indicating whether the Component Manager was initialized gradually. If false, it means Initialize was used to initialize the manager, either from a manual method call or because Initialize on Awake was enabled on the manager. Note, you should only check this property if IsInitialized returns true. |
public Dictionary<int, ActiveGrid>.ValueCollection ActiveGridsInScene()
Can be used to iterate over the collection of ActiveGrids in the scene in a garbage free manner.
Dictionary<int, ActiveGrid>.ValueCollection
Internally the Active Grids in the scene are stored in a dictionary, with the Active
Grids as values. This returns those values, which you
can iterate over using a foreach statement.
public void ConvertOldSaveData(PersistentDataController persistentDataController, IPersistentStateManager persistentStateManager, List<string> oldDataKeys, List<OldActiveGridData> oldActiveGridData = null)
Use this to convert data that was saved via the Component Manager using a Persistent
Data Controller to a format compatible with Persistent State Managers.
This method will basically load the data and re-save it using the passed in Persistent
State Manager, so the Persistent State Manager should be setup to save data just as
if the
Save method were being used. The data is only loaded for re-saving purposes, it will not
be used by the Component Manager when
it is initialized like the normal Load method. As such, you will still need to call the
Load method once you have converted the data.
Under some scenarios it is possible for the conversion to fail, either in part or
in total. When this happens, a DataConversionException will be thrown. It is recommended
to place this method's
invocation in a try/catch statement, catching the DataConversionException and handling
it properly. If the exception is not thrown, it means the data was converted 100%
successfully and you can
delete the old data either manually or using the DeleteOldData method. Conversion
failures may be fixable through modifications to your scene (common), or they may
be due to corrupted save data (rare).
Please note that for runtime created Active Grids and Worlds, the protoype ID is now
used to identify prototypes rather than the index of the prototype in the Prototype
Array. Since the old save data
will still be using the index, it's important to ensure the ordering of prototypes
is the same now as it was when the data was saved, and that all prototypes that were
in use at the time of
saving are still in use, so that the prototypes can be matched correctly. In addition,
the ID's of the prototypes must be configured so that all prototypes of a specific
component type (World or
Active Grid) use unique ID's (note, they do not need to be different than non prototypes
that have been added to the scene in the Unity Editor, as these use a different pool
of IDs).
Once conversion has been executed, you are free to re-order and remove prototypes,
so long as you do not change the IDs and do not remove prototypes that are present
in persistent data.
Name | Type | Description |
---|---|---|
persistentDataController | PersistentDataController |
The upgraded persistent data controller that represents the old persistent data controller that was used to save the data you want to convert. If you haven't upgraded your Persistent Data Controller yet, please take a look at the Pertinent Data Controller Section in the Upgrading Chapter of the In-Editor Guide. |
persistentStateManager | IPersistentStateManager |
The new Persistent State Manager to use to re-save the old data. This manager should be configured correctly to save to a save file. The file should be set prior to calling this method. |
oldDataKeys | List<string> |
When data conversion is 100% successful, this list will be full of every key associated with the old persistent data. You can then manually delete the old save data associated with these keys using the Persistent Data Controller, or pass the list into the DeleteOldData method to let the Component Manager do it automatically. The passed in list must not be null or a DataConversionException will be thrown; also note that the list is cleared by the method so you don't need to clear it beforehand. |
oldActiveGridData | List<OldActiveGridData> |
Active Grids that were formerly ring based used some settings to define there inner area and outer ring width. These settings are no longer used with the addition of Loading Blueprints, so the conversion method basically ignores them. However, you may wish to manually set your Active Grids to specific Loading Blueprints based on the saved inner area size and outer ring width value. If you are interested in doing this, you can pass in a non null, empty List and for each Active Grid (inspector or runtime created) that has persistent data saved in the old data, an entry will be added to the list. You can then use the ActiveGrid.PreInitialize_SetLoadingBlueprint method to set the Loading Blueprint that best matches the old data. |
Type | Condition |
---|---|
DataConversionException | The conversion method is setup so that if any single piece of the old data cannot be converted correctly, this exception is thrown. This is primarily intende to give you an idea on whether the conversion was successful. If conversion is 100% successful, oldDataKeys will be full of keys belonging to the old data, which you can delete manually or use with the DeleteOldData method if you want to clear the old save data. |
public static void ConvertOldSaveData(string oldSaveData, IPersistentStateManager persistentStateManager, List<OldActiveGridData> oldActiveGridData = null)
Use this to convert old data saved using the Component Manager's GetSaveData method
(no longer available) to a format compatible with Persistent State Managers.
This method will basically load the data and re-save it using the passed in Persistent
State Manager, so the Persistent State Manager should be setup to save data just as
if the
Save method were being used. The data is only loaded for re-saving purposes, it will not
be used by the Component Manager when
it is initialized like the normal Load method. As such, you will still need to call the
Load method once you have converted the data.
Under some scenarios it is possible for the conversion to fail, either in part or
in total. When this happens, a DataConversionException will be thrown. It is recommended
to place this method's
invocation in a try/catch statement, catching the DataConversionException and handling
it properly. If the exception is not thrown, it means the data was converted 100%
successfully and you can
delete the old string data if you wish. Conversion failures may be fixable through
modifications to your scene (common), or they may be due to corrupted save data (rare).
Please note that for runtime created Active Grids and Worlds, the protoype ID is now
used to identify prototypes rather than the index of the prototype in the Prototype
Array. Since the old save data
will still be using the index, it's important to ensure the ordering of prototypes
is the same now as it was when the data was saved, and that all prototypes that were
in use at the time of
saving are still in use, so that the prototypes can be matched correctly. In addition,
the ID's of the prototypes must be configured so that all prototypes of a specific
component type (World or
Active Grid) use unique ID's (note, they do not need to be different than non prototypes
that have been added to the scene in the Unity Editor, as these use a different pool
of IDs).
Once conversion has been executed, you are free to re-order and remove prototypes,
so long as you do not change the IDs and do not remove prototypes that are present
in persistent data.
Name | Type | Description |
---|---|---|
oldSaveData | string |
The old data you wish to convert. |
persistentStateManager | IPersistentStateManager |
The new Persistent State Manager to use to re-save the old data. This manager should be configured correctly to save to a save file. The file should be set prior to calling this method. |
oldActiveGridData | List<OldActiveGridData> |
Active Grids that were formerly ring based used some settings to define there inner area and outer ring width. These settings are no longer used with the addition of Loading Blueprints, so the conversion method basically ignores them. However, you may wish to manually set your Active Grids to specific Loading Blueprints based on the saved inner area size and outer ring width value. If you are interested in doing this, you can pass in a non null, empty List and for each Active Grid (inspector or runtime created) that has persistent data saved in the old data, an entry will be added to the list. |
Type | Condition |
---|---|
DataConversionException | The conversion method is setup so that if any single piece of the old data cannot be converted correctly, this exception is thrown. This is primarily intended to give you an idea of whether the conversion was successful. If conversion is 100% successful, you can safely delete the old save data. If it fails and this exception is thrown, you can examine the exception message to determine whether it's an issue that can be fixed with changes to the scene or not. |
public ActiveGrid CreateNonPersistentActiveGridUsingIPlayer(int IDOfPrototypeToConstructGridFrom, World alternateWorldToSyncTo = null, IPlayer alternatePlayerToAssociateWithGrid = null, PlayerMover playerMoverToAssociateWithGrid = null)
Creates and initializes a non-persistent Active Grid based on the prototype
and the specified optional parameters.
The grid data will not be saved with the component manager's save data.
When the Active Grid is initialized, the World the grid is
synced to will also be initialized, as well as this Component Manager if it has not
already been initialized.
Note, however, that you will need to manually enable World Updating on the Active
Grid via the
TrySetIfWorldShouldBeUpdated
or
TrySetIfWorldShouldBeUpdatedThenWaitForWorldUpdate
method. With World Updating disabled (the default state if one of those methods are
not called),
the Active Grid will not trigger the World to load/unload objects!
Name | Type | Description |
---|---|---|
IDOfPrototypeToConstructGridFrom | int |
The prototype to construct the grid from (number shown in inspector). |
alternateWorldToSyncTo | World |
An alternate world for the grid to start synced to. This world can be either persistent or non persistent. |
alternatePlayerToAssociateWithGrid | IPlayer |
If provided, the grid will use this IPlayer to create as the Player upon initialization, otherwise the grid will be associated with the default Player of the prototype (determined by Player Type). If a IPlayer is not passed in and no player is assigned via the prototype's inspector, an exception will be thrown. |
playerMoverToAssociateWithGrid | PlayerMover |
If provided, the grid will use this PlayerMover when moving the Player. If alternatePlayerToAssociateWithGrid is set and playerMoverToAssociateWithGrid is null, the Active Grid will not use the default PlayerMover of the prototype. Instead, the player mover will be set to null and the Player will be moved by setting its Position property. Therefore, you must be sure to provide a valid object for this argument if you provide an alternate player and want to make use of PlayerMover. |
ActiveGrid
The created and initialized non persistent Active Grid.
Type | Condition |
---|---|
InvalidPrototypeException | Thrown when IDOfPrototypeToConstructGridFrom is invalid. |
MissingComponentException | Thrown when persistentDataToSetStateFrom is not null and contains a World that should exist but does not anymore. |
UninitializedSAMObjectException | Thrown if the method is called before the Component Manager has been fully initialized. |
public ActiveGrid CreateNonPersistentActiveGridUsingTransform(int IDOfPrototypeToConstructGridFrom, World alternateWorldToSyncTo = null, Transform alternatePlayerToAssociateWithGrid = null, PlayerMover playerMoverToAssociateWithGrid = null)
Creates and initializes a non-persistent Active Grid based on the prototype
and the specified optional parameters.
The grid data will not be saved with the component manager's save data.
When the Active Grid is initialized, the World the grid is
synced to will also be initialized, as well as this Component Manager if it has not
already been initialized.
Note, however, that you will need to manually enable World Updating on the Active
Grid via the
TrySetIfWorldShouldBeUpdated
or
TrySetIfWorldShouldBeUpdatedThenWaitForWorldUpdate
method. With World Updating disabled (the default state if one of those methods are
not called),
the Active Grid will not trigger the World to load/unload objects!
Name | Type | Description |
---|---|---|
IDOfPrototypeToConstructGridFrom | int |
The ID of the Prototype to use to construct the Runtime Active Grid. Remember, all Active Grid Prototypes in use in the current scene must have unique IDs. |
alternateWorldToSyncTo | World |
An alternate world for the grid to start synced to. This world can be either persistent or non persistent. |
alternatePlayerToAssociateWithGrid | Transform |
If provided, the grid will use this Transform to create a Transform based Player upon initialization, otherwise the grid will be associated with the default Player of the prototype (determined by Player Type). If a transform is not passed in and no player is assigned via the prototype's inspector, an exception will be thrown. |
playerMoverToAssociateWithGrid | PlayerMover |
If provided, the grid will use this PlayerMover when moving the Player. If alternatePlayerToAssociateWithGrid is set and playerMoverToAssociateWithGrid is null, the Active Grid will not use the default PlayerMover of the prototype. Instead, the player mover will be set to null and the Player will be moved by setting its Position property. Therefore, you must be sure to provide a valid object for this argument if you provide an alternate player transform and want to make use of PlayerMover. |
ActiveGrid
The created and initialized non persistent Active Grid.
Type | Condition |
---|---|
InvalidPrototypeException | Thrown when IDOfPrototypeToConstructGridFrom is invalid. |
MissingComponentException | Thrown when persistentDataToSetStateFrom is not null and contains a World that should exist but does not anymore. |
UninitializedSAMObjectException | Thrown if the method is called before the Component Manager has been fully initialized. |
public World CreateNonPersistentWorld(int IDOfPrototypeToConstructWorldFrom, string[][] alternateGroupNamesToUse = null, Vector3? alternateWorldOrigin = null, Cell? alternateOriginCell = null, List<int> worldRegionNumbersToAutoLoad = null, List<string> worldRegionNamesToAutoLoad = null)
Creates and initializes a non persistent World using the information from the prototype and optional parameters. The non persistent world will be saved with the component manager's save data, but only non persistent Active Grid's will be able to sync to it. Calling this method will initialize this Component Manager if it has not already been initialized.
Name | Type | Description |
---|---|---|
IDOfPrototypeToConstructWorldFrom | int |
The ID of the Prototype to use to construct the Runtime World. Remember, all World Prototypes in use in the current scene must have unique IDs. |
alternateGroupNamesToUse | string[][] |
A 2D array of alternate group names that each LOD of each World Grouping on the world should start with. The group names controls which asset chunks are loaded by the world. If a particular index is null, the Group Name from the save data will be used for it. If the save data is null, the default Group Name from the Streamable Grid on the prototype will be used. |
alternateWorldOrigin | Vector3 |
An alternate world origin for the created World to use. If null, the world origin from the save data will be used. If save data is not present, the prototypes world origin will be used. |
alternateOriginCell | Cell |
An alternate Origin Cell for the created World to use. If null, the Origin Cell specified
in the save data will be used.
If the save data is null, the Origin Cell from the prototype is used.
|
worldRegionNumbersToAutoLoad | List<int> |
A list of valid World Region Numbers (as shown in the prototypes inspector) that you would like to be auto loaded. This is in addition to any World Regions that have Auto Load enabled in the prototype inspector, and any World Regions indicated by worldRegionNamesToAutoLoad. |
worldRegionNamesToAutoLoad | List<string> |
A list of valid World Region Names (as shown in the prototypes inspector) that you would like to be auto loaded. This is in addition to any World Regions that have Auto Load enabled in the prototype inspector, and any World Regions indicated by worldRegionNumbersToAutoLoad. |
World
The created and initialized non persistent World.
Type | Condition |
---|---|
InvalidPrototypeException | Thrown when IDOfPrototypeToConstructWorldFrom is invalid. |
UninitializedSAMObjectException | Thrown if the method is called before the Component Manager has been fully initialized. |
ActiveGrid CreatePersistentActiveGrid(int IDOfPrototypeToConstructGridFrom, World alternatePersistentWorldToSyncTo = null)
Creates and initializes a persistent Active Grid based on the prototype
and the specified optional parameters.
The persistent grid data will be saved with the component manager's save data, and
can only be synced with persistenet worlds.
When the Active Grid is initialized, the World the grid is
synced to will also be initialized, as well as this Component Manager if it has not
already been initialized.
Note, however, that you will need to manually enable World Updating on the Active
Grid via the
TrySetIfWorldShouldBeUpdated
or
TrySetIfWorldShouldBeUpdatedThenWaitForWorldUpdate
method. With World Updating disabled, the Active Grid will not trigger the World
to load/unload objects!
Notice that unlike with non persisten Active Grids, there is no option to provide
an alternate
player or player mover. This is because there is no way to save the alternate player
and player mover
with the grid's persistent data, therefore persistent grids are limited to having
to use the player
assigned to the prototype!
Name | Type | Description |
---|---|---|
IDOfPrototypeToConstructGridFrom | int |
The ID of the Prototype to use to construct the Runtime Active Grid. Remember, all Active Grid Prototypes in use in the current scene must have unique IDs. Because this Active Grid is Persistent, it will be saved with persistent data and reconstructed when the Load method is called. The ID of the Prototype is saved with the data, and as such, this ID must remain the same, or the data will be discarded. |
alternatePersistentWorldToSyncTo | World |
An alternate world for the grid to start synced to. This must be a persistent world. |
ActiveGrid
The created and initialized persistent Active Grid.
Type | Condition |
---|---|
InvalidPrototypeException | Thrown when prototypeToConstructGridFrom is invalid. Valid values range from 1 to [number of prototypes]. |
MissingComponentException | Thrown when persistentDataToSetStateFrom is not null and contains a World that should exist but does not anymore. |
InvalidPersistenceException | Thrown when alternatePersistentWorldToSyncTo not null and is not a persistent World. |
UninitializedSAMObjectException | Thrown if the method is called before the Component Manager has been fully initialized. |
public World CreatePersistentWorld(int IDOfPrototypeToConstructWorldFrom, string[][] alternateGroupNamesToUse = null, Vector3? alternateWorldOrigin = null, Cell? alternateOriginCell = null, List<int> worldRegionNumbersToAutoLoad = null, List<string> worldRegionNamesToAutoLoad = null)
Creates and initializes a persistent World using the information from the prototype and optional parameters. The persistent world will be saved with the component manager's save data, and both persistent and non persistent Active Grids can sync to it. Calling this method will initialize this Component Manager if it has not already been initialized.
Name | Type | Description |
---|---|---|
IDOfPrototypeToConstructWorldFrom | int |
The ID of the Prototype to use to construct the Runtime World. Remember, all World Prototypes in use in the current scene must have unique IDs. Because this World is Persistent, it will be saved with persistent data and reconstructed when the Load method is called. The ID of the Prototype is saved with the data, and as such, this ID must remain the same, or the data will be discarded. |
alternateGroupNamesToUse | string[][] |
A 2D array of alternate group names that each LOD of each World Grouping on the world should start with. The group names controls which objects are loaded by the world. If a particular index is null, the Group Name from the save data will be used for it. If the save data is null, the default Group Name from the Streamable Grid on the prototype will be used. |
alternateWorldOrigin | Vector3 |
An alternate world origin for the created World to use. If null, the world origin from the save data will be used. If the save data is null, the prototypes world origin will be used. |
alternateOriginCell | Cell |
An alternate Origin Cell for the created World to use. If null, the Origin Cell specified
in the save data will be used.
If the save data is null, the Origin Cell from the prototype is used.
|
worldRegionNumbersToAutoLoad | List<int> |
A list of valid World Region Numbers (as shown in the prototypes inspector) that you would like to be auto loaded. This is in addition to any World Regions that have Auto Load enabled in the prototype inspector, and any World Regions indicated by worldRegionNamesToAutoLoad. |
worldRegionNamesToAutoLoad | List<string> |
A list of valid World Region Names (as shown in the prototypes inspector) that you would like to be auto loaded. This is in addition to any World Regions that have Auto Load enabled in the prototype inspector, and any World Regions indicated by worldRegionNumbersToAutoLoad. |
World
The created and initialized persistent World.
Type | Condition |
---|---|
InvalidPrototypeException | Thrown when IDOfPrototypeToConstructWorldFrom is invalid. |
UninitializedSAMObjectException | Thrown if the method is called before the Component Manager has been fully initialized. |
public void DeleteOldData(PersistentDataController persistentDataController, List<string> oldDataKeys)
Convenience method for deleting old data saved using a Persistent Data Controller. You can use this method after calling ConvertOldSaveData (PersistentDataController version) and having it complete 100% successfully (no DataConversionException thrown). That method will populate the oldDataKeys list with all of the keys associated with the old data. This method then just cycles through these keys and calls PersistentDataController.TryDeleteData for each one.
Name | Type | Description |
---|---|---|
persistentDataController | PersistentDataController |
The upgraded persistent data controller that represents the old persistent data controller
that was used to save the data you want to delete.
If you haven't upgraded your Persistent Data Controller yet, please take a look at
the Pertinent Data Controller Section in the Upgrading Chapter.
|
oldDataKeys | List<string> |
When data conversion is 100% successful using the ConvertOldSaveData method, the oldDataKeys list will be filled with every key associated with the old persistent data. Pass that list into this method to delete the data associated with the keys. The list is cleared upon completion. |
public void DestroyActiveGrid(int IDOfActiveGridToDestroy)
Destroys the Active Grid with IDOfActiveGridToDestroy. All cell users associated with
the Active Grid are removed from cells on the World the Active Grid
is Currently synced to. If those cells have no more cell users after this removal,
the cell chunks are removed from the scene.
This removal is performed over a series of frames for performance reasons, however
this method destroys the Active Grid immediately and does not wait
for the cell users (and associated cell chunks) to be removed from the world. If you
need to wait for this process to complete (perhaps you only want to perform
some action after the cell users/asset chunks have been removed), use DestroyActiveGridAndWaitForCellUsersToBeRemoved instead.
Name | Type | Description |
---|---|---|
IDOfActiveGridToDestroy | int |
The ID of the Active Grid to destroy. |
Type | Condition |
---|---|
InvalidIDException | Thrown when IDOfActiveGridToDestroy is not the ID of a valid Active Grid in the scene. |
Example:
class DestroyActiveGridExample { ActiveGrid myActiveGrid; public void OnDestroyActiveGrid() { //You should only have one component manager in the scene ComponentManager componentManager = GameObject.FindObjectOfType<ComponentManager>(); componentManager.DestroyActiveGrid(myActiveGrid.ID); } }
public IEnumerator<YieldInstruction> DestroyActiveGridAndWaitForCellUsersToBeRemoved(int IDOfActiveGridToDestroy)
Destroys the Active Grid with IDOfActiveGridToDestroy.
All cell users associated with the Active Grid are removed from the cells on the World
the Active Grid
is Currently synced to. If those cells have no more cell users after this removal,
the cell chunks are removed from the scene.
This removal is performed over a series of frames for performance reasons, and the
Active Grid will only be destroyed after this removal
process completes. This method should be used if you need to know when the cell users/objects
are removed and want to wait for the process to complete.
Use like any other coroutine.
Name | Type | Description |
---|---|---|
IDOfActiveGridToDestroy | int |
The ID of the Active Grid to destroy. |
Type | Condition |
---|---|
InvalidIDException | Thrown when IDOfActiveGridToDestroy is not the ID of a valid Active Grid in the scene. |
Example:
Normal StartCoroutine Exampleclass DestroyActiveGridExample { ActiveGrid myActiveGrid; //This method should have been called via StartCoroutine public IEnumerator OnDestroyActiveGrid() { //You should only have one component manager in the scene ComponentManager componentManager = GameObject.FindObjectOfType<ComponentManager>(); yield return StartCoroutine(componentManager.DestroyActiveGridAndWaitForCellUsersToBeRemoved(myActiveGrid.ID)); } }
Example:
Coroutine without using StartCoroutineclass DestroyActiveGridExample { ActiveGrid myActiveGrid; //This method should be started using StartCoroutine or iterated over manually in another coroutine public IEnumerator<YieldInstruction> OnDestroyActiveGrid() { //You should only have one component manager in the scene ComponentManager componentManager = GameObject.FindObjectOfType<ComponentManager>(); IEnumerator<YieldInstruction> e = componentManager.DestroyActiveGridAndWaitForCellUsersToBeRemoved(myActiveGrid.ID); while(e.MoveNext()) yield return e.Current; } }
public IEnumerator<YieldInstruction> DestroyActiveGridsAndWorldsAndUnloadWorldCells()
Can be used to destroy every initialized Active Grid and World in the scene. Before
doing so, all World Cells associated with the Active Grids and
Worlds are removed from the scene. This is useful for removing scene assets that have
been loaded and kept in the scene,
specifically when your Scene Chunk Streamer has the 'Keep Scenes Intact' option enabled.
When that option is enabled, the loaded scenes that
contain Streamable Asset Chunks are kept in the scene, and these scenes will not be
removed automatically when the scene containing the Component
Manager and other Streamable Assets Manager game objects is unloaded. In these circumstances,
it is necessary to manually remove the
scene assets prior to unloading the main scene that contains the Component Manager
and other game objects. You can use this method for that purpose.
Once this method is called, you should not interact with any Streamable Assets Manager
objects, including this Component Manager. Therefore, if you wish
to save data, you should do so before calling this method. The only correct use of
this method is to call it, wait for it to complete, and then
unload the main containing the Component Manager and other SAM game objects.
IEnumerator<YieldInstruction>
An IEnumerator<YieldInstruction> that can be iterated over or used as a coroutine.
See the
YieldInstruction page for more info.
public void DestroyWorld(int IDOfWorldToDestroy)
Destroys the World with IDofWorldToDestroy. All World Cells and Asset Chunks associated
with the World are removed from the scene.
This removal is performed over a series of frames for performance reasons,
though the World's destruction will be reflected
in the persistent data if you save during the process.
If you care about when the removal process completes (and thus when the
World is actually destroyed) use DestroyWorldAndWaitForChunksToBeRemoved instead
and provide a callback method.
Name | Type | Description |
---|---|---|
IDOfWorldToDestroy | int |
The ID of the World to destroy. |
Type | Condition |
---|---|
InvalidIDException | Thrown when IDOfWorldToDestroy is not the ID of a valid World in the scene. |
Example:
class DestroyWorldExample { World myWorld; public void OnDestroyWorld() { //You should only have one component manager in the scene ComponentManager componentManager = GameObject.FindObjectOfType<ComponentManager>(); componentManager.DestroyWorld(myWorld.ID); } }
public IEnumerator<YieldInstruction> DestroyWorldAndWaitForChunksToBeRemoved(int IDOfWorldToDestroy, Action<World> onCompletedCallback)
This method is virtually the same as DestroyWorld, except with this method you can pass in a System.Action which will be called just before the World has been destroyed (but after all World Cells and Asset Chunks associated with the World have been removed from the scene). Note that the World argument that is passed into your Action will be valid for only the frame that the action is called, because the actual World object is destroyed just after the action completes.
Name | Type | Description |
---|---|---|
IDOfWorldToDestroy | int |
The ID of the World to destroy. |
onCompletedCallback | Action<World> |
A callback action which will be called just before the World is destroyed. |
Type | Condition |
---|---|
InvalidIDException | Thrown when IDOfWorldToDestroy is not the ID of a valid World in the scene. |
public bool DoesOldDataExist(PersistentDataController persistentDataController)
Can be used to determine whether any persistent data saved using the Persistent Data
Controller
exist for this Component Manager. If such data exist, you should use
ConvertOldSaveData
to convert it to the format used by your Persistent State Manager, before calling
the
Component Manager's Load method.
This method should only be used at runtime (in game).
Name | Type | Description |
---|---|---|
persistentDataController | PersistentDataController |
The Persistent Data Controller that would have been used to save the data. Note that the PersistentDataController found in the old DynamicLoadingKit namespace is not valid here; you will need to convert your custom PersistentDataController or PlayerPrefsPersistentDataController to a version from the DeepSpaceLabs.SAM namespace. |
bool
True if data exist, false otherwise.
Type | Condition |
---|---|
DuplicateIDException | If World components exist with the same ID, this exception may be thrown. The same goes for Active Grid components using the same ID. |
public void Initialize()
Initializes the Component Manager over two frames. This in turn closes the window
for loading persistent data
and initializes all non prototype
Active Grids/Worlds in the scene.
This should only be used if "Initialize On Awake" is unchecked in the inspector, and
then only at the beginning
of the game from another scripts Awake method. If the game has started (i.e., the
update cycle is running), you should use
InitializeGradually instead (for performance reasons).
This is meant to be used for debugging and testing mostly. For an actual game, it
is recommended to use
InitializeGradually
as it offers better performance and can be used with a loading screen.
Progress Tracking is also only available when using InitializeGradually
(using the InitializationProgress property).
public IEnumerator<YieldInstruction> InitializeGradually()
Initialzes the Component Manager over a series of frames. This coroutine exits only
after all initial World Cells and Asset
Chunks have been loaded, which allows you to display a loading screen or use some
other device to hide the game world until it is fully loaded.
This should only be used if "Initialize On Awake" is unchecked in the inspector.
The progress of this method can be tracked via the
InitializationProgress property,
which should only be queried after the method starts executing. Once the
Initialization process is completed, that property will always return 1f.
Because this method is more performant and progress can be tracked, we recommend it
for a live game (non testing environment).
IEnumerator<YieldInstruction>
An IEnumerator<YieldInstruction> that can be iterated over or used as a coroutine.
See the
YieldInstruction page for more info.
public void Load(IPersistentStateManager persistentStateManager)
Loads save data that was saved via the Save method. This method makes use of the
IPersistentStateManager interface.
You can use one of the provided implmentations of this interface or create your own
implementation, as the interface
provides maximum flexibility to control how your save system works.
VERY IMPORTANT: There is a limited window in which persistent data can be loaded via
this method. This window
will close immediately when CreatePersistentActiveGrid, CreateNonPersistentActiveGrid,
CreatePersistentWorld,
or CreateNonPersistentWorld are called for the first time. It will also close once
the Component Manager has been initialized. You can delay initialization by unchecking
"Initialize On Awake," but you
will have to manually call Initialize or InitializeGradually.
Name | Type | Description |
---|---|---|
persistentStateManager | IPersistentStateManager |
The save data for the Component Manager to use to setup the state of this Component Manager and all persistent Worlds and Active Grids. |
performComponentManagerIDCheck | bool |
If true, the method will perform a check of this Component Manager's ID against the
ID stored in the save data. If they do not match, an
exception will be thrown.
|
Type | Condition |
---|---|
InvalidOperationException | Thrown when this method is called and Use Custom Save/Load Solution is not checked in the inspector, or if the Component Manager passed the phase where persistent save data can be loaded. |
ArgumentNullException | Thrown when this method is called and persistentStateManager is set to null. |
InvalidPersistentDataException | Thrown when this method is called and the persistent data loaded is found to be invalid. This really should not happen and indicates a critical error in your save/load process. |
public void Save(IPersistentStateManager persistentStateManager)
Saves this component manager data, including the data of all persistent
Active Grids and Worlds in the scene in a single frame.
While the Component Manager chooses which data is saved, the actual mechanism for
saving is under the control of whatever
Persistent State Manager
you pass into this method.
It should go without saying, but this method can only be called after the Component
Manager has been initialized.
Type | Condition |
---|---|
InvalidOperationException | Thrown when called before the Component Manager has been initialized. |
public void SubscribeToActiveGridMovedEvents(World filterWorld, int filterWorldGrouping, Action<object, ActiveGridMovedEventArgs> methodToSubscribe)
Subscribe to Active Grid Moved Events, which is an event Active Grid's fire a Grouping
on the Active Grid has its individual grid moved. Always make sure you call
UnsubscribeToActiveGridMovedEvents at a later time when using this method! Usually,
it's best to put the Subscribe in OnEnable and Unsubscribe in
OnDisable.
While you can subscribe to this event directly via an Active Grid, doing so here is
typically much easier as you can specify a World and/or
World Grouping to listen to, and then have access to the events from all Active Grids
that are synced to that World and/or Grouping.
Name | Type | Description |
---|---|---|
filterWorld | World |
A World you can use to filter out events. Notification of an event will only occur when an Active Grid firing the event is synced to this World. If you provide a filterWorld but no filterWorldGrouping, then you will receive notification for all World Groupings firing the event. If you do not provide a filterWorld (passing in null), then you will receive notification for all Active Grids firing the event, for the World Groupings not filtered out via filterGridLayer. |
filterWorldGrouping | int |
The World Grouping to use to filter events. If a valid value is provided (1 or greater),
the subscriber will only be notified of events that occur on this
World Grouping (and only for the filterWorld if provided). An invalid value (0 or
less) will be interpreted as the subscriber wanting to be notified of
events on all World Groupings. For instance, if you want to receive notification about
every event on every Active Grid and World Grouping, pass in null for
filterWorld and 0 for filterGridLayer. If you want to receive notifications about
all events on all World Groupings for any Active Grids synced to a
specific World, provide a filterWorld but pass in 0 for filterGridLayer. If you want
to be notified of events on World Grouping 1 for any Active Grid,
pass in null for filterWorld and 1 for filterGridLayer.
|
methodToSubscribe | Action<object, ActiveGridMovedEventArgs> |
The method that will be called when an event from the correct Active Grid and World Grouping is triggered. |
public void SubscribeToCellPlayerIsInChangedEvents(World filterWorld, int filterWorldGrouping, Action<object, CellPlayerIsInChangedEventArgs> methodToSubscribe)
Subscribe to Cell Player Is In Changed Events, which is an event Active Grid's fire
when the cell the player is in changes. Always make sure you call
UnsubscribeFromCellPlayerIsInChangedEvents at a later time when using this method!
Usually, it's best to put the Subscribe in OnEnable and Unsubscribe in
OnDisable.
While you can subscribe to this event directly via an Active Grid, doing so here is
typically much easier as you can specify a World and/or
World Grouping to listen to, and then have access to the events from all Active Grids
that are synced to that World and/or Grouping.
Name | Type | Description |
---|---|---|
filterWorld | World |
A World you can use to filter out events. Notification of an event will only occur when an Active Grid firing the event is synced to this World. If you provide a filterWorld but no filterWorldGrouping, then you will receive notification for all World Groupings firing the event. If you do not provide a filterWorld (passing in null), then you will receive notification for all Active Grids firing the event, for the World Groupings not filtered out via filterGridLayer. |
filterWorldGrouping | int |
The World Grouping to use to filter events. If a valid value is provided (1 or greater),
the subscriber will only be notified of events that occur on this
World Grouping (and only for the filterWorld if provided). An invalid value (0 or
less) will be interpreted as the subscriber wanting to be notified of
events on all World Groupings. For instance, if you want to receive notification about
every event on every Active Grid and World Grouping, pass in null for
filterWorld and 0 for filterGridLayer. If you want to receive notifications about
all events on all World Groupings for any Active Grids synced to a
specific World, provide a filterWorld but pass in 0 for filterGridLayer. If you want
to be notified of events on World Grouping 1 for any Active Grid,
pass in null for filterWorld and 1 for filterGridLayer.
|
methodToSubscribe | Action<object, CellPlayerIsInChangedEventArgs> |
The method that will be called when an event from the correct Active Grid and World Grouping is triggered. |
public bool TryGetActiveGridByID(int ID, out ActiveGrid activeGrid)
Tries to get the Active Grid specified by ID.
Name | Type | Description |
---|---|---|
ID | int |
The ID of the Active Grid to get. |
activeGrid | ActiveGrid |
When this method returns, contains the value associated with the specified ID if the ID is found; otherwise, null. |
bool
A bool indicating whether the ActiveGrid was found.
public bool TryGetWorldByID(int worldID, out World world)
Tries to get the World specified by worldID.
Name | Type | Description |
---|---|---|
worldID | int |
The ID of the World to get. |
world | World |
When this method returns, contains the value associated with the specified worldID if the worldID is found; otherwise, null. |
bool
A bool indicating whether the World was found.
public void UnsubscribeToActiveGridMovedEvents(World filterWorld, int filterWorldGrouping, Action<object, ActiveGridMovedEventArgs> methodToUnsubscribe)
Unsubscribe from Active Grid Moved Events, which is an event Active Grid's fire when one of the grids on the Active Grid is moved. This method should be paired with a previous call to SubscribeToActiveGridMovedEvents! Usually, it's best to put the Subscribe in OnEnable and Unsubscribe in OnDisable.
Name | Type | Description |
---|---|---|
filterWorld | World |
The World you provided (or null if you passed in null) when you called SubscribeToActiveGridMovedEvents. |
filterWorldGrouping | int |
The filterWorldGrouping you provided when you called SubscribeToActiveGridMovedEvents. |
methodToUnsubscribe | Action<object, ActiveGridMovedEventArgs> |
The method that was provided when you called SubscribeToActiveGridMovedEvents. |
public void UnsubscribeToCellPlayerIsInChangedEvents(World filterWorld, int filterWorldGrouping, Action<object, CellPlayerIsInChangedEventArgs> methodToUnsubscribe)
Unsubscribe from Cell Player Is In Changed Events, which is an event Active Grid's fire when the cell the player is in changes. This method should be paired with a previous call to SubscribeFromCellPlayerIsInChangedEvents! Usually, it's best to put the Subscribe in OnEnable and Unsubscribe in OnDisable.
Name | Type | Description |
---|---|---|
filterWorld | World |
The World you provided (or null if you passed in null) when you called SubscribeFromCellPlayerIsInChangedEvents. |
filterWorldGrouping | int |
The filterWorldGrouping you provided when you called SubscribeFromCellPlayerIsInChangedEvents. |
methodToUnsubscribe | Action<object, CellPlayerIsInChangedEventArgs> |
The method that was provided when you called SubscribeFromCellPlayerIsInChangedEvents. |
public Dictionary<int, World>.ValueCollection WorldsInScene()
Can be used to iterate over the collection of Worlds in the scene in a garbage free manner.
Dictionary<int, World>.ValueCollection
Internally the Worlds in the scene are stored in a dictionary, with the Worlds as
values. This returns those values, which you
can iterate over using a foreach statement.