private static void AddKey(AnimationWindowState state, EditorCurveBinding binding, System.Type type, PropertyModification modification) { GameObject activeRootGameObject = state.activeRootGameObject; AnimationClip activeAnimationClip = state.activeAnimationClip; AnimationWindowCurve curve = new AnimationWindowCurve(activeAnimationClip, binding, type); object currentValue = CurveBindingUtility.GetCurrentValue(activeRootGameObject, binding); if (curve.length == 0) { object outObject = null; if (!ValueFromPropertyModification(modification, binding, out outObject)) { outObject = currentValue; } if (state.frame != 0) { AnimationWindowUtility.AddKeyframeToCurve(curve, outObject, type, AnimationKeyTime.Frame(0, activeAnimationClip.frameRate)); } } AnimationWindowUtility.AddKeyframeToCurve(curve, currentValue, type, AnimationKeyTime.Frame(state.frame, activeAnimationClip.frameRate)); state.SaveCurve(curve); }
private static bool ValueFromPropertyModification(PropertyModification modification, EditorCurveBinding binding, out object outObject) { if (modification == null) { outObject = null; return false; } if (binding.isPPtrCurve) { outObject = modification.objectReference; return true; } float num; if (float.TryParse(modification.value, out num)) { outObject = num; return true; } outObject = null; return false; }
/// <summary> /// Attempts to extract the name of serialized key for the given property modification. /// </summary> /// <param name="obj">The object that that modification is applied to.</param> /// <param name="mod">The modification.</param> /// <param name="keyName">An output parameter containing the name of the key that the /// modification maps to.</param> /// <returns>True if the key was found, false otherwise.</returns> private static bool TryExtractPropertyName(ISerializedObject obj, PropertyModification mod, out string keyName) { //- // We want to extract 2 from _serializedStateValues.Array.data[2] // We could probably use a regular expression, but this is fine for now if (mod.propertyPath.StartsWith("_serializedStateValues.Array.data[")) { string front = mod.propertyPath.Remove(0, "_serializedStateValues.Array.data".Length + 1); string num = front.Substring(0, front.Length - 1); int index; if (int.TryParse(num, out index) && index >= 0 && index < obj.SerializedStateKeys.Count) { keyName = obj.SerializedStateKeys[index]; return true; } } keyName = string.Empty; return false; }
extern public static bool IsDefaultOverride(PropertyModification modification);
extern private static Type Internal_PropertyModificationToEditorCurveBinding(PropertyModification modification, [NotNull] GameObject gameObject, out EditorCurveBinding binding);
internal static void AddCandidate(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride) { AnimationMode.AddCandidate_Injected(ref binding, modification, keepPrefabOverride); }
public static extern Type PropertyModificationToEditorCurveBinding(PropertyModification modification, GameObject gameObject, out EditorCurveBinding binding);
public static extern void SetPropertyModifications(UnityEngine.Object targetPrefab, PropertyModification[] modifications);
/// <summary> /// Adds the key. /// </summary> /// <param name="time">Time.</param> /// <param name="rootGameObject">Root game object.</param> /// <param name="activeAnimationClip">Active animation clip.</param> /// <param name="binding">Binding.</param> /// <param name="type">Type.</param> /// <param name="modification">Modification.</param> private static void AddKey(float time, GameObject rootGameObject, AnimationClip activeAnimationClip, EditorCurveBinding binding, Type type, PropertyModification modification) { object currentValue = GetCurrentValue (rootGameObject, binding); //Debug.Log (rootGameObject.transform.position + " " + binding.propertyName+"="+currentValue); object value = null; ObjectReferenceKeyframe[] keyframesCurveReferenced; bool isCurveReferenced = binding.isPPtrCurve; AnimationCurve curve; int frameCurrent = (int)(time * activeAnimationClip.frameRate); if (isCurveReferenced) { keyframesCurveReferenced = AnimationUtility.GetObjectReferenceCurve (activeAnimationClip, binding); if (keyframesCurveReferenced.Length == 0 && frameCurrent != 0) { if (!ValueFromPropertyModification (modification, binding, out value)) { value = currentValue; } AddKeyframeToObjectReferenceCurve (keyframesCurveReferenced, activeAnimationClip, binding, value, type, 0); } AddKeyframeToObjectReferenceCurve (keyframesCurveReferenced, activeAnimationClip, binding, currentValue, type, time); } else { curve = AnimationUtility.GetEditorCurve (activeAnimationClip, binding); if (curve == null) curve = new AnimationCurve (); if (curve.length == 0 && frameCurrent != 0) { if (!ValueFromPropertyModification (modification, binding, out value)) { value = currentValue; } AddKeyframeToCurve (curve, activeAnimationClip, binding, (float)value, type, 0); } AddKeyframeToCurve (curve, activeAnimationClip, binding, (float)currentValue, type, time); } }
public static extern System.Type PropertyModificationToEditorCurveBinding(PropertyModification modification, GameObject gameObject, out EditorCurveBinding binding);
private static void AddKey(AnimationWindowState state, EditorCurveBinding binding, System.Type type, PropertyModification modification) { GameObject activeRootGameObject = state.activeRootGameObject; AnimationClip activeAnimationClip = state.activeAnimationClip; if ((activeAnimationClip.hideFlags & HideFlags.NotEditable) != HideFlags.None) return; AnimationWindowCurve curve = new AnimationWindowCurve(activeAnimationClip, binding, type); object currentValue = CurveBindingUtility.GetCurrentValue(activeRootGameObject, binding); if (curve.length == 0) { object outObject = (object) null; if (!AnimationRecording.ValueFromPropertyModification(modification, binding, out outObject)) outObject = currentValue; if (state.frame != 0) AnimationWindowUtility.AddKeyframeToCurve(curve, outObject, type, AnimationKeyTime.Frame(0, activeAnimationClip.frameRate)); } AnimationWindowUtility.AddKeyframeToCurve(curve, currentValue, type, AnimationKeyTime.Frame(state.frame, activeAnimationClip.frameRate)); state.SaveCurve(curve); }
private static extern void INTERNAL_CALL_AddPropertyModification(ref EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
public static void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride) { AnimationMode.AddPropertyModification_Injected(ref binding, modification, keepPrefabOverride); }
public static void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride) { INTERNAL_CALL_AddPropertyModification(ref binding, modification, keepPrefabOverride); }
static bool ComparePropertyModifications(PropertyModification a, PropertyModification b) { return a.objectReference == b.objectReference && a.propertyPath == b.propertyPath && a.target == b.target && a.value == b.value; }
/* public static void ApplySpecificChanges (GameObject obj, PropertyModification[] changes) { } */ public static void RevertSpecificChanges(Object obj, PropertyModification[] changes) { var root = PrefabUtility.FindPrefabRoot(GetGameObject(obj)); var modsArray = PrefabUtility.GetPropertyModifications(root); var mods = new List<PropertyModification>(modsArray != null ? modsArray:new PropertyModification[0]); if(obj == root.transform) { var prefabTForm = (Transform)PrefabUtility.GetPrefabParent(root.transform); var baseMods = new PropertyModification[] { new PropertyModification() { propertyPath = "m_LocalPosition.x", target = prefabTForm, value=prefabTForm.localPosition.x.ToString() }, new PropertyModification() { propertyPath = "m_LocalPosition.y", target = prefabTForm, value=prefabTForm.localPosition.y.ToString() }, new PropertyModification() { propertyPath = "m_LocalPosition.z", target = prefabTForm, value=prefabTForm.localPosition.z.ToString() }, new PropertyModification() { propertyPath = "m_LocalRotation.x", target = prefabTForm, value=prefabTForm.localRotation.x.ToString() }, new PropertyModification() { propertyPath = "m_LocalRotation.y", target = prefabTForm, value=prefabTForm.localRotation.y.ToString() }, new PropertyModification() { propertyPath = "m_LocalRotation.z", target = prefabTForm, value=prefabTForm.localRotation.z.ToString() }, new PropertyModification() { propertyPath = "m_LocalRotation.w", target = prefabTForm, value=prefabTForm.localRotation.w.ToString() }, new PropertyModification() { propertyPath = "m_LocalScale.x", target = prefabTForm, value=prefabTForm.localScale.x.ToString() }, new PropertyModification() { propertyPath = "m_LocalScale.y", target = prefabTForm, value=prefabTForm.localScale.y.ToString() }, new PropertyModification() { propertyPath = "m_LocalScale.z", target = prefabTForm, value=prefabTForm.localScale.z.ToString() } }; mods = new List<PropertyModification>(baseMods); } else { foreach(var i in changes) { mods.RemoveAll((a) => ComparePropertyModifications(i,a)); } } var newChanges = mods.ToArray(); PrefabUtility.SetPropertyModifications(obj, newChanges); }
public static void AddInstanceComponentToPrefab(Component obj) { var gameObject = PrefabUtility.FindPrefabRoot(GetGameObject(obj)); var prefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject); foreach(var i in GetRequiredComponents(obj)) { if(i && PrefabUtility.GetPrefabParent(i) == null && prefab.GetComponent(i.GetType()) == null) AddInstanceComponentToPrefab(i); } // add the prefab to the target var prefabComp = prefab.AddComponent(obj.GetType()); if(prefabComp) { var mods = new List<PropertyModification>(PrefabUtility.GetPropertyModifications(gameObject)); // copy data EditorUtility.CopySerialized(obj, prefabComp); // fix up any references to their prefabs SerializedObject so = new SerializedObject(obj); SerializedObject prefabCompSo = new SerializedObject(prefabComp); prefabCompSo.Update(); so.Update(); var i = so.GetIterator(); while(i.Next(true)) { if(i.propertyType == SerializedPropertyType.ObjectReference) { if(i.propertyPath == "m_PrefabParentObject" || i.propertyPath == "m_PrefabInternal" || i.propertyPath == "m_GameObject" || i.propertyPath == "m_Script") continue; var prefabRef = PrefabUtility.GetPrefabParent(i.objectReferenceValue); var prefabRefRoot = PrefabUtility.GetPrefabParent(PrefabUtility.FindPrefabRoot(PrefabUtilityEx.GetGameObject(i.objectReferenceValue))); var prefabType = i.objectReferenceValue!= null ? PrefabUtility.GetPrefabType(i.objectReferenceValue):PrefabType.None; if(prefabType != PrefabType.Prefab && prefabType != PrefabType.ModelPrefab) { // link to an object in the scene. // we must add a modification for this. if(i.objectReferenceValue != null && (prefabRef == null || prefab != prefabRefRoot)) { var propertyMod = new PropertyModification(); propertyMod.objectReference = i.objectReferenceValue; propertyMod.target = prefabComp; propertyMod.propertyPath = i.propertyPath; mods.Add(propertyMod); prefabCompSo.FindProperty(i.propertyPath).objectReferenceValue = null; } else prefabCompSo.FindProperty(i.propertyPath).objectReferenceValue = prefabRef; } } } so = null; // save prefabCompSo.ApplyModifiedProperties(); EditorUtility.SetDirty(prefab); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(prefab)); // remove the applied value from our instance. UnityEngine.GameObject.DestroyImmediate(obj); // add property mods var components = gameObject.GetComponents(prefabComp.GetType()); Component newComponent = System.Array.Find(components, ((arg) => PrefabUtility.GetPrefabParent(arg)==prefabComp)); PrefabUtility.SetPropertyModifications(newComponent, mods.ToArray()); } else EditorUtility.DisplayDialog("Error", "Can't apply this component to the prefab as it cannot own more than one prefab of this type", "Ok"); }
private static extern void AddPropertyModification_Injected(ref EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
public static extern void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
private static void AddKey(AnimationWindowState state, EditorCurveBinding binding, Type type, PropertyModification modification) { GameObject rootGameObject = state.m_RootGameObject; AnimationClip activeAnimationClip = state.m_ActiveAnimationClip; AnimationWindowCurve animationWindowCurve = new AnimationWindowCurve(activeAnimationClip, binding, type); object currentValue = AnimationWindowUtility.GetCurrentValue(rootGameObject, binding); object value = null; if (animationWindowCurve.length == 0 && state.m_Frame != 0) { if (!AnimationRecording.ValueFromPropertyModification(modification, binding, out value)) { value = currentValue; } AnimationWindowUtility.AddKeyframeToCurve(animationWindowCurve, value, type, AnimationKeyTime.Frame(0, activeAnimationClip.frameRate)); } AnimationWindowUtility.AddKeyframeToCurve(animationWindowCurve, currentValue, type, AnimationKeyTime.Frame(state.m_Frame, activeAnimationClip.frameRate)); state.SaveCurve(animationWindowCurve); }
internal static void SaveCrossSceneReference( this SceneData instance, SerializedProperty property ) { Object objRef = property.objectReferenceValue; if ( !objRef ) throw new UnassignedReferenceException( "Cannot save a null cross-scene reference" ); if ( !(objRef is Component || objRef is GameObject) ) throw new UnityException( "You are only able to reference Components or GameObjects across scenes, not " + objRef.GetType() ); // Book keeping on the FROM side. Object fromObj = property.serializedObject.targetObject; SubScene fromSubScene = SubSceneEx.GetSubScene( fromObj ); SceneData fromSceneData = SceneDataEx.GetSceneData( fromSubScene ); string fromHash = fromSceneData.FindOrCreateHashCode( fromObj ); if ( fromObj is SceneData ) return; // Book keeping on the TO side. SubScene toSubScene = SubSceneEx.GetSubScene( objRef ); bool bIsDestinationUnlocked = !toSubScene || !toSubScene.IsLocked(); var toSceneData = SceneDataEx.GetSceneData( toSubScene, bIsDestinationUnlocked ); string toCompHash = null; if ( bIsDestinationUnlocked ) toCompHash = toSceneData.FindOrCreateHashCode( objRef ); else if ( toSceneData ) toCompHash = toSceneData.FindHashCodeForObject( objRef ); SceneData.CrossSceneReference entry = new SceneData.CrossSceneReference() { fromSubScene = fromSubScene, fromObjectHash = fromHash, fromPropertyPath = property.propertyPath, toSubScene = toSubScene, toObjectHash = toCompHash }; if ( !toSceneData ) throw new UnityException( string.Format("Cannot save cross-scene reference {0}. The SubScene '{1}' needs to be unlocked in order to record its referenced objects", entry, toSubScene) ); else if ( fromSubScene && fromSubScene.GetRuntimeLoadSettings() != SubScene.RuntimeLoadSettings.BakeIntoScene ) throw new UnityException( string.Format("Cannot save cross-scene reference {0}. The Source SubScene is not set to BakeIntoScene. See the documentation on 'Cross-Scene References'", entry) ); else if ( toSubScene && toSubScene.GetRuntimeLoadSettings() != SubScene.RuntimeLoadSettings.BakeIntoScene ) throw new UnityException( string.Format("Cannot save cross-scene reference {0}. The Destination SubScene is not set to BakeIntoScene. See the documentation on 'Cross-Scene References'", entry) ); instance.AddOrUpdateCrossSceneReference( entry ); EditorUtility.SetDirty( instance ); property.serializedObject.Update(); // Now reference the newly created component instead... Object placeHolder = GetPlaceholder( fromSubScene, objRef, toCompHash ); // Deal with Prefab issues in Unity 5.x by specifying this is definitely an override if ( property.isInstantiatedPrefab ) { var targetObject = property.serializedObject.targetObject; var prefabParent = PrefabUtility.GetPrefabParent(targetObject); var propMod = new PropertyModification() { objectReference = placeHolder, propertyPath = property.propertyPath, target = prefabParent }; // Create at least this change... var newMods = new List<PropertyModification>(); newMods.Add( propMod ); // Get the existing ones var existingMods = PrefabUtility.GetPropertyModifications(targetObject); if ( existingMods != null ) newMods.AddRange( existingMods ); // Now change all of the existing ones to match ours... foreach( var mod in newMods ) { if ( mod.propertyPath.Equals(propMod.propertyPath) ) mod.objectReference = propMod.objectReference; } // Tell the prefab this is an override PrefabUtility.SetPropertyModifications( targetObject, newMods.ToArray() ); } property.objectReferenceValue = placeHolder; property.serializedObject.ApplyModifiedProperties(); property.serializedObject.Update(); }
/// <summary> /// <para>Marks a property as currently being animated.</para> /// </summary> /// <param name="binding">Description of the animation clip curve being modified.</param> /// <param name="modification">Object property being modified.</param> /// <param name="keepPrefabOverride">Indicates whether to retain modifications when the targeted object is an instance of prefab.</param> public static void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride) { INTERNAL_CALL_AddPropertyModification(ref binding, modification, keepPrefabOverride); }
private static extern void INTERNAL_CALL_AddPropertyModification(ref EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
extern internal static void AddCandidate(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
/// <summary> /// Initializes a new instance of the /// <see cref="PropertyBackingFieldDrawer+HashableSerializedProperty"/> struct. /// </summary> /// <param name="mod">Property modification.</param> public HashableSerializedProperty(PropertyModification mod) : this(mod.propertyPath, mod.target) { }
public static extern void AddPropertyModification(EditorCurveBinding binding, PropertyModification modification, bool keepPrefabOverride);
private static bool TryExtractPropertyName(ISerializedObject obj, PropertyModification mod, out string keyName) { if (mod.propertyPath.StartsWith("_serializedStateValues.Array.data[")) { string text = mod.propertyPath.Remove(0, "_serializedStateValues.Array.data".Length + 1); string s = text.Substring(0, text.Length - 1); int num; if (int.TryParse(s, out num) && num >= 0 && num < obj.SerializedStateKeys.Count) { keyName = obj.SerializedStateKeys[num]; return true; } } keyName = string.Empty; return false; }
extern internal static void ApplyPropertyModificationToObject([NotNull("NullExceptionObject")] Object target, PropertyModification value);