public static void HandleCrossSceneReferences( IList<Scene> scenes ) { // If we don't allow cross-scene references, then early return. var crossSceneReferenceBehaviour = AmsPreferences.CrossSceneReferencing; bool bSkipCrossSceneReferences = (crossSceneReferenceBehaviour == AmsPreferences.CrossSceneReferenceHandling.UnityDefault); bool bSaveCrossSceneReferences = (crossSceneReferenceBehaviour == AmsPreferences.CrossSceneReferenceHandling.Save); if ( bSkipCrossSceneReferences || scenes.Count < 1 ) return; // We need to create an AmsMultiSceneSetup singleton in every scene. This is how we keep track of Awake scenes and // it also allows us to use cross-scene references. foreach( var scene in scenes ) { if ( !scene.isLoaded ) continue; // Reset all of the cross-scene references for loaded scenes. var crossSceneRefBehaviour = AmsCrossSceneReferences.GetSceneSingleton( scene, true ); for (int i = 0 ; i < EditorSceneManager.sceneCount ; ++i) { var otherScene = EditorSceneManager.GetSceneAt(i); if ( otherScene.isLoaded ) crossSceneRefBehaviour.ResetCrossSceneReferences( otherScene ); } } var xSceneRefs = AmsCrossSceneReferenceProcessor.GetCrossSceneReferencesForScenes( scenes ); if ( bSaveCrossSceneReferences && xSceneRefs.Count > 0 ) { AmsDebug.LogWarning( null, "Ams Plugin: Found {0} Cross-Scene References. Saving them.", xSceneRefs.Count ); AmsCrossSceneReferenceProcessor.SaveCrossSceneReferences( xSceneRefs ); } // Zero-out these cross-scene references so we can save without pulling in those assets. for(int i = 0 ; i < xSceneRefs.Count ; ++i) { var xRef = xSceneRefs[i]; int refIdToRestore = xRef.fromProperty.objectReferenceInstanceIDValue; if ( !bSaveCrossSceneReferences ) Debug.LogWarningFormat( "Cross-Scene Reference {0} will become null", xRef ); // Set it to null. xRef.fromProperty.objectReferenceInstanceIDValue = 0; xRef.fromProperty.serializedObject.ApplyModifiedPropertiesWithoutUndo(); // Restore if we're not about to enter play mode if ( !EditorApplication.isPlayingOrWillChangePlaymode ) { EditorApplication.delayCall += () => { AmsDebug.Log( null, "Restoring Cross-Scene Ref (Post-Save): {0}", xRef ); xRef.fromProperty.objectReferenceInstanceIDValue = refIdToRestore; xRef.fromProperty.serializedObject.ApplyModifiedPropertiesWithoutUndo(); }; } } }
/// <summary> /// Attempt to handle a cross-scene reference. /// </summary> static bool HandleCrossSceneReference( RuntimeCrossSceneReference xRef ) { MonoBehaviour cinemachineBehaviour = xRef.fromObject as MonoBehaviour; if ( !cinemachineBehaviour || !cinemachineBehaviour.isActiveAndEnabled ) return false; if ( !cinemachineBehaviour.GetType().Namespace.StartsWith( "Cinemachine" ) ) return false; AmsDebug.LogWarning( xRef.fromObject, "xSceneRef on Cinemachine Behaviour: {0}. Disabling/Enabling to ensure pipeline is up to date.", xRef ); cinemachineBehaviour.enabled = false; cinemachineBehaviour.enabled = true; return false; }
/// <summary> /// Attempt to handle a cross-scene reference. /// </summary> static bool HandleCrossSceneReference(RuntimeCrossSceneReference xRef) { if (!(xRef.fromObject is UnityEngine.Playables.PlayableDirector)) { return(false); } bool isDirty = false; string sourceField = xRef.sourceField; if (sourceField.StartsWith("m_SceneBindings")) { PlayableDirector_SceneBindings(xRef); isDirty = true; } if (sourceField.StartsWith("m_ExposedReferences")) { PlayableDirector_ExposedReferences(xRef); isDirty = true; } if (isDirty) { UnityEngine.Playables.PlayableDirector playableDirector = xRef.fromObject as UnityEngine.Playables.PlayableDirector; if (playableDirector) { #if UNITY_2017_3_OR_NEWER if (playableDirector.state == UnityEngine.Playables.PlayState.Playing) { AmsDebug.LogWarning(playableDirector, "To prevent issues, delay the PlayableDirector '{0}' until after cross-scene references are loaded. Cross-Scene Reference: {1}", playableDirector, xRef); playableDirector.RebuildGraph(); } #else if (playableDirector.gameObject.activeSelf) { AmsDebug.LogWarning(playableDirector, "Upgrade to Unity 2017.3 for proper Playables support. Hack work-around for 2017.1 and 2017.2: Disable/ReEnable the GameObject"); playableDirector.gameObject.SetActive(false); playableDirector.gameObject.SetActive(true); } #endif } } return(isDirty); }