// todo figure out a way to call messages on all objects... // so we can get actorstate.GameValue("Health") for instance... public static ObjectLoadState AddNewObject(PrefabReference prefabRef, string scene, Vector3 pos, Quaternion rot, bool permanent, out object obj, out string id) { bool sceneIsLoaded = SceneLoading.currentLoadedScenes.Contains(scene); id = GetNewGUID(); DynamicObjectState objectState = new DynamicObjectState(id, scene, prefabRef, permanent); id2ObjectState.Add(id, objectState); if (sceneIsLoaded) { DynamicObject dynamicObject = GetAvailableInstance(prefabRef, pos, rot, id, false, false, false); MoveDynamicObjectToTransform(dynamicObject, pos, rot.eulerAngles, false); dynamicObject.AdjustState(objectState, scene, pos, rot.eulerAngles, false); obj = dynamicObject; } // add an unloaded representation, instantiate later when the scene is loaded else { if (!prefabRef.isEmpty) { DynamicObject basePrefab = PrefabReferenceCollection.GetPrefabReference <DynamicObject>(prefabRef); obj = basePrefab.AdjustState(objectState, scene, pos, rot.eulerAngles, true); } else { obj = objectState; } } return(objectState.isLoaded ? ObjectLoadState.Loaded : ObjectLoadState.Unloaded); }
void OnLoadGame() { ClearAll(); bool hasworldSaved = GameState.gameSaveState.ContainsKey(OBJECT_STATES_KEY); if (hasworldSaved) { scenesAlreadyLoaded = (List <string>)GameState.gameSaveState.Load(LOADED_SCENES_KEY); id2ObjectState = (Dictionary <string, DynamicObjectState>)GameState.gameSaveState.Load(OBJECT_STATES_KEY); alias2ID = (Dictionary <string, string>)GameState.gameSaveState.Load(ALIASES_KEY); foreach (var k in alias2ID.Keys) { id2Alias.Add(alias2ID[k], k); } DynamicObjectState savedPlayer = GetStateByAlias(PLAYER_ALIAS); GameManager.player.transform.WarpTo(savedPlayer.position, Quaternion.Euler(savedPlayer.rotation)); GameManager.player.Load(savedPlayer); } else { Debug.LogError("No Game State Saved..."); } }
// set scene, position, rotation, and spawn options of state beforehand static void LoadNewDynamicObjectWithState(DynamicObjectState state, bool preAdjusted) { DynamicObject dynamicObject = GetAvailableInstance(state); MoveDynamicObjectToTransform(dynamicObject, state.position, state.rotation, preAdjusted); dynamicObject.Load(state); state.isUntouched = false; }
// TODO: player guid ? public static ObjectLoadState GetObjectByGUID(string id, out object obj) { DynamicObjectState state = GetStateByID(id); if (state != null) { obj = state.isLoaded ? (object)state.loadedVersion : state; return(state.isLoaded ? ObjectLoadState.Loaded : ObjectLoadState.Unloaded); } obj = null; return(ObjectLoadState.NotFound); }
// if delayedInstantiate, we dont have anything to actually load or unload to state // serves as a delayed 'Instantiate' call since we cant serialize prefab object references :/ public void Load(DynamicObjectState state) { SetID(state.id); SetLoadedVersion(state); if (!state.delayedInstantiate) { LoadAttachedStates(state); } state.delayedInstantiate = false; }
static void MoveObject(ObjectLoadState state, object obj, string scene, MiniTransform target) { bool sceneIsLoaded = SceneLoading.currentLoadedScenes.Contains(scene); if (state == ObjectLoadState.Loaded) { DynamicObject dynamicObject = (DynamicObject)obj; // moving loaded DO to a scene and position thats already loaded if (sceneIsLoaded) { MoveDynamicObjectToTransform(dynamicObject, target.position, target.rotation, false); } // moving loaded DO to an unloaded scene/position else { if (dynamicObject.isPlayer) { MovePlayerToUnloadedScene(scene, target); } else { DynamicObjectState objState = GetStateByID(dynamicObject.GetID()); dynamicObject.AdjustState(objState, scene, target.position, target.rotation, false); objState.loadedVersion = null; // give to pool again dynamicObject.gameObject.SetActive(false); } } } else if (state == ObjectLoadState.Unloaded) { DynamicObjectState objState = (DynamicObjectState)obj; if (objState.id == alias2ID[PLAYER_ALIAS]) { Debug.Log("Cant Move Player When Player Is Unloaded..."); return; } objState.scene = scene; objState.position = target.position; objState.rotation = target.rotation; objState.isUntouched = false; //moving an unloaded object to a loaded scene if (sceneIsLoaded) { LoadNewDynamicObjectWithState(objState, false); } } }
public static void RemoveObjectByGUID(string id, bool disableObject = true, bool logErrorIfPermanent = true) { if (!suppressStateRemovalOnDisable) { DynamicObjectState state = GetStateByID(id, false); if (state != null) { if (!state.permanent) { id2ObjectState.Remove(id); if (id2Alias.ContainsKey(id)) { alias2ID.Remove(id2Alias[id]); id2Alias.Remove(id); } if (disableObject) { if (state.isLoaded) { // will call this again, but our guid should be removed so // this wont loop endlessly.... state.loadedVersion.gameObject.SetActive(false); } } } else { if (logErrorIfPermanent) { if (id2Alias.ContainsKey(id)) { Debug.LogError("Cant Delete Object Aliased: '" + id2Alias[id] + "', it is marked permanent"); } else { Debug.LogError("Cant Delete Object ID: " + id + ", it is marked permanent"); } } } } } }
public static DynamicObject GetAvailableInstance(DynamicObject prefab, Vector3 position, Quaternion rotation, string gUID, bool createState, bool createID, bool permanentState) { DynamicObject inst = pool.GetAvailable(prefab, null, true, position, rotation, DynamicObject.onPoolCreateAction, null); if (createID) { gUID = GetNewGUID(); } inst.SetID(gUID); if (createState) { DynamicObjectState objectState = new DynamicObjectState(gUID, null, inst.prefabRef, permanentState); id2ObjectState.Add(gUID, objectState); inst.AdjustState(objectState, null, position, rotation.eulerAngles, false); } return(inst); }
public DynamicObjectState AdjustState(DynamicObjectState state, string scene, Vector3 position, Vector3 rotation, bool delayedInstantiate) { state.isUntouched = false; state.prefabRef = prefabRef; state.scene = scene; state.position = position; state.rotation = rotation; state.delayedInstantiate = delayedInstantiate; if (!delayedInstantiate) { SetLoadedVersion(state); GetAttachedStates(state); } return(state); }
void GetObjectStatesInScene(string scene, bool isUnloading, bool justDisable) { // get all the loaded objects in the current scene, that are active and available // (for instance an equipped item is not considered available, that shold be saved by the inventory component...) List <DynamicObject> dynamicObjects = FilterObjectsForScene(scene, DynamicObject.GetInstancesAvailableForLoad()); if (dynamicObjects.Count > 0) { // teh list of saved objects to populate for (int i = 0; i < dynamicObjects.Count; i++) { DynamicObject dynamicObject = dynamicObjects[i]; if (!justDisable) { DynamicObjectState state = GetStateByID(dynamicObject.GetID()); if (state != null) { dynamicObject.AdjustState(state, scene, dynamicObject.transform.position, dynamicObject.transform.rotation.eulerAngles, false); if (isUnloading) { state.loadedVersion = null; } } } // TODO: add prevent disable on scene transfer (e.g. companions following...) // disabling the scene our object is in // give to pool again (if disabling scene) if (isUnloading) { dynamicObject.gameObject.SetActive(false); } } } }
void OnSceneLoaded(Scene scene, LoadSceneMode mode) { string sceneName = scene.name; if (GameManager.IsMainMenuScene(sceneName)) { return; } if (movingPlayer) { if (GameManager.playerExists) { MoveDynamicObjectToTransform(GameManager.player, movePlayerTarget.position, movePlayerTarget.rotation, false); } movingPlayer = false; } // tODO: objects that are pre placed already alias refed might be copy if // existing state already has loaded object // e.g. (maybe a companion traveled with player back to where it was originally placed in editor) // get all the active objects that are default in the current scene List <DynamicObject> editorPlacedObjects = FilterObjectsForScene(sceneName, DynamicObject.GetInstancesThatNeedID()); // get reference to all states that were pre defined programatically for this scene... // (before we add the states for the manually placed ones) List <DynamicObjectState> states = GetStatesForScene(sceneName); if (scenesAlreadyLoaded.Contains(sceneName)) { // add them to the pool for availablity for (int i = 0; i < editorPlacedObjects.Count; i++) { // if it needs a guid it comes with the scene... so this shouldnt matter (maybe...) editorPlacedObjects[i].gameObject.SetActive(false); } } // scene loaded for the first time // create object states and id's for default placed objects else { scenesAlreadyLoaded.Add(sceneName); // give id's and states for those default objects for (int i = 0; i < editorPlacedObjects.Count; i++) { string id = null; if (editorPlacedObjects[i].usesAlias) { id = editorPlacedObjects[i].GetID(); if (!string.IsNullOrEmpty(id)) { DynamicObjectState aliasedState = GetStateByID(id); // if our aliased state is untouched then we use this object if (aliasedState.isUntouched) { // dotn load in this scene again, just in case we were trying to if (states.Contains(aliasedState)) { states.Remove(aliasedState); } editorPlacedObjects[i].AdjustState(aliasedState, sceneName, editorPlacedObjects[i].transform.position, editorPlacedObjects[i].transform.rotation.eulerAngles, false); aliasedState.isUntouched = false; } // we've adjusted the state, disable this object and use the state else { editorPlacedObjects[i].gameObject.SetActive(false); } // if our aliased state scene is this one, continue; } } id = GetNewGUID(); id2ObjectState.Add(id, editorPlacedObjects[i].AdjustState(new DynamicObjectState(id, sceneName, editorPlacedObjects[i].prefabRef, false), sceneName, editorPlacedObjects[i].transform.position, editorPlacedObjects[i].transform.rotation.eulerAngles, false)); editorPlacedObjects[i].SetID(id); } } for (int i = 0; i < states.Count; i++) { LoadNewDynamicObjectWithState(states[i], !states[i].isUntouched); } }
public static DynamicObject GetAvailableInstance(DynamicObjectState state) { return(GetAvailableInstance(state.prefabRef, state.position, Quaternion.Euler(state.rotation), state.id, false, false, false)); }