static void PlayableDirector_SceneBindings(RuntimeCrossSceneReference xRef) { var data = xRef.data; UnityEngine.Playables.PlayableDirector playableDirector = xRef.fromObject as UnityEngine.Playables.PlayableDirector; for (int i = 0; i < data.Count; i += 2) { Object key = data[i].@object; AmsDebug.Log(xRef.fromObject, "Restoring PlayableDirector Scene Binding {0} = {1}", key, xRef.toObject); playableDirector.SetGenericBinding(key, xRef.toObject); } }
/// <summary> /// Save all of the passed-in cross-scene references. The entries in the passed-in list will be removed as they are properly accounted for. /// </summary> /// <param name="editorCrossSceneRefs"></param> public static void SaveCrossSceneReferences( List<EditorCrossSceneReference> editorCrossSceneRefs ) { // Save all of the cross-scene references, removing them from our input list as we receive them for( int i = editorCrossSceneRefs.Count-1 ; i >= 0 ; --i) { var xRef = editorCrossSceneRefs[i]; AmsDebug.Log( null, "Saving Cross-Scene Reference: {0}", xRef ); try { RuntimeCrossSceneReference serializedReference = xRef.ToSerializable(); try { // Save the object var initialObject = xRef.fromProperty.objectReferenceValue; // Resolve it (this can throw exceptions) AmsCrossSceneReferenceResolver.Resolve( serializedReference ); #if UNITY_5_6_OR_NEWER xRef.fromProperty.serializedObject.UpdateIfRequiredOrScript(); #else xRef.fromProperty.serializedObject.UpdateIfDirtyOrScript(); #endif // Check to make sure it resolved properly if ( initialObject && xRef.fromProperty.objectReferenceValue != initialObject ) throw new ResolveException( string.Format("Resolve should have pointed to {0} ({1}) but instead resolved to {2} ({3})", initialObject ? initialObject.ToString() : "(null)", initialObject ? initialObject.GetInstanceID() : 0, xRef.fromProperty.objectReferenceValue, xRef.fromProperty.objectReferenceInstanceIDValue) ); } catch ( System.Exception ex ) { AmsDebug.LogError( xRef.fromObject, "Could not perform a runtime resolve on cross-scene reference {0}.\nReason: {1}. Please review Documentation.", serializedReference, ex.Message ); continue; } // Record the cross-scene reference var crossSceneRefBehaviour = AmsCrossSceneReferences.GetSceneSingleton( xRef.fromScene, true ); crossSceneRefBehaviour.AddReference( serializedReference ); // Add an updated reference map value if ( _referenceMap != null ) _referenceMap.Add( new KeyValuePair<SerializedProperty, Object>(xRef.fromProperty, xRef.fromProperty.objectReferenceValue) ); } catch ( UnityException ex ) { Debug.LogException( ex ); } } }
static void PlayableDirector_ExposedReferences(RuntimeCrossSceneReference xRef) { var data = xRef.data; UnityEngine.Playables.PlayableDirector playableDirector = xRef.fromObject as UnityEngine.Playables.PlayableDirector; for (int i = 0; i < data.Count; i += 2) { string key = data[i].@string; AmsDebug.Log(xRef.fromObject, "Restoring PlayableDirector Exposed Binding {0} = {1}", key, xRef.toObject); playableDirector.ClearReferenceValue(key); playableDirector.SetReferenceValue(key, xRef.toObject); } }
/// <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); }