You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
7.4 KiB
226 lines
7.4 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using UnityEngine; |
|
using UnityEngine.Playables; |
|
using UnityEngine.Timeline; |
|
using Object = UnityEngine.Object; |
|
|
|
namespace UnityEditor.Timeline |
|
{ |
|
class PropertyCollector : IPropertyCollector |
|
{ |
|
readonly Stack<GameObject> m_ObjectStack = new Stack<GameObject>(); |
|
|
|
// Call immediately before use |
|
public void Reset() |
|
{ |
|
m_ObjectStack.Clear(); |
|
} |
|
|
|
// call to reset caches. should be called when switching master timelines |
|
public void Clear() |
|
{ |
|
m_ObjectStack.Clear(); |
|
AnimationPreviewUtilities.ClearCaches(); |
|
} |
|
|
|
public void PushActiveGameObject(GameObject gameObject) |
|
{ |
|
m_ObjectStack.Push(gameObject); |
|
} |
|
|
|
public void PopActiveGameObject() |
|
{ |
|
m_ObjectStack.Pop(); |
|
} |
|
|
|
public void AddFromClip(AnimationClip clip) |
|
{ |
|
var go = m_ObjectStack.Peek(); // allow it to throw if empty |
|
if (go != null && clip != null) // null game object is allowed for calls to be ignored |
|
AddFromClip(go, clip); |
|
} |
|
|
|
public void AddFromClips(IEnumerable<AnimationClip> clips) |
|
{ |
|
var go = m_ObjectStack.Peek(); |
|
if (go != null) |
|
AddFromClips(go, clips); |
|
} |
|
|
|
public void AddFromName<T>(string name) where T : Component |
|
{ |
|
var go = m_ObjectStack.Peek(); // allow it to throw if empty |
|
if (go != null) // null game object is allowed for calls to be ignored |
|
AddFromName<T>(go, name); |
|
} |
|
|
|
public void AddFromName(string name) |
|
{ |
|
var go = m_ObjectStack.Peek(); // allow it to throw if empty |
|
if (go != null) // null game object is allowed for calls to be ignored |
|
AddFromName(go, name); |
|
} |
|
|
|
public void AddFromClip(GameObject obj, AnimationClip clip) |
|
{ |
|
if (!Application.isPlaying) |
|
AddPropertiesFromClip(obj, clip); |
|
} |
|
|
|
public void AddFromClips(GameObject animatorRoot, IEnumerable<AnimationClip> clips) |
|
{ |
|
if (Application.isPlaying) |
|
return; |
|
|
|
AnimationPreviewUtilities.PreviewFromCurves(animatorRoot, AnimationPreviewUtilities.GetBindings(animatorRoot, clips)); |
|
} |
|
|
|
public void AddFromName<T>(GameObject obj, string name) where T : Component |
|
{ |
|
if (!Application.isPlaying) |
|
AddPropertiesFromName(obj, typeof(T), name); |
|
} |
|
|
|
public void AddFromName(GameObject obj, string name) |
|
{ |
|
if (!Application.isPlaying) |
|
AddPropertiesFromName(obj, name); |
|
} |
|
|
|
public void AddFromName(Component component, string name) |
|
{ |
|
if (!Application.isPlaying) |
|
AddPropertyModification(component, name); |
|
} |
|
|
|
public void AddFromComponent(GameObject obj, Component component) |
|
{ |
|
if (Application.isPlaying) |
|
return; |
|
|
|
if (obj == null || component == null) |
|
return; |
|
|
|
var serializedObject = new SerializedObject(component); |
|
SerializedProperty property = serializedObject.GetIterator(); |
|
|
|
while (property.NextVisible(true)) |
|
{ |
|
if (property.hasVisibleChildren || !AnimatedParameterUtility.IsTypeAnimatable(property.propertyType)) |
|
continue; |
|
|
|
AddPropertyModification(component, property.propertyPath); |
|
} |
|
} |
|
|
|
void AddPropertiesFromClip(GameObject go, AnimationClip clip) |
|
{ |
|
if (go != null && clip != null) |
|
{ |
|
AnimationMode.InitializePropertyModificationForGameObject(go, clip); |
|
} |
|
} |
|
|
|
static void AddPropertiesFromName(GameObject go, string property) |
|
{ |
|
if (go == null) |
|
return; |
|
|
|
AddPropertyModification(go, property); |
|
} |
|
|
|
static void AddPropertiesFromName(GameObject go, Type compType, string property) |
|
{ |
|
if (go == null) |
|
return; |
|
var comp = go.GetComponent(compType); |
|
if (comp == null) |
|
return; |
|
|
|
AddPropertyModification(comp, property); |
|
} |
|
|
|
public void AddObjectProperties(Object obj, AnimationClip clip) |
|
{ |
|
if (obj == null || clip == null) |
|
return; |
|
|
|
IPlayableAsset asset = obj as IPlayableAsset; |
|
IPlayableBehaviour playable = obj as IPlayableBehaviour; |
|
|
|
// special case for assets that contain animated script playables. |
|
// The paths in the clip start from the field with the templated playable |
|
if (asset != null) |
|
{ |
|
if (playable == null) |
|
{ |
|
AddSerializedPlayableModifications(asset, clip); |
|
} |
|
else |
|
{ |
|
// in this case the asset is the playable. The clip applies directly |
|
AnimationMode.InitializePropertyModificationForObject(obj, clip); |
|
} |
|
} |
|
} |
|
|
|
void AddSerializedPlayableModifications(IPlayableAsset asset, AnimationClip clip) |
|
{ |
|
var obj = asset as Object; |
|
if (obj == null) |
|
return; |
|
|
|
var driver = WindowState.previewDriver; |
|
if (driver == null || !AnimationMode.InAnimationMode(driver)) |
|
return; |
|
|
|
var serializedObj = new SerializedObject(obj); |
|
var bindings = AnimationClipCurveCache.Instance.GetCurveInfo(clip).bindings; |
|
var fields = AnimatedParameterUtility.GetScriptPlayableFields(asset); |
|
|
|
// go through each binding and offset using the field name |
|
// so the modification system can find the particle object using the asset as a root |
|
foreach (var b in bindings) |
|
{ |
|
foreach (var f in fields) |
|
{ |
|
var propertyPath = f.Name + "." + b.propertyName; |
|
if (serializedObj.FindProperty(propertyPath) != null) |
|
{ |
|
DrivenPropertyManager.RegisterProperty(driver, obj, propertyPath); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
private static void AddPropertyModification(GameObject obj, string propertyName) |
|
{ |
|
var driver = WindowState.previewDriver; |
|
if (driver == null || !AnimationMode.InAnimationMode(driver)) |
|
return; |
|
|
|
DrivenPropertyManager.RegisterProperty(driver, obj, propertyName); |
|
} |
|
|
|
private static void AddPropertyModification(Component comp, string name) |
|
{ |
|
if (comp == null) |
|
return; |
|
|
|
var driver = WindowState.previewDriver; |
|
if (driver == null || !AnimationMode.InAnimationMode(driver)) |
|
return; |
|
|
|
// Register Property will display an error if a property doesn't exist (wanted behaviour) |
|
// However, it also displays an error on Monobehaviour m_Script property, since it can't be driven. (not wanted behaviour) |
|
// case 967026 |
|
if (name == "m_Script" && (comp as MonoBehaviour) != null) |
|
return; |
|
|
|
DrivenPropertyManager.RegisterProperty(driver, comp, name); |
|
} |
|
} |
|
}
|
|
|