- Home /
extending timeline GatherProperties, changing objects Parent
Hi everyone.
I'm trying to write my own type of playable, as much as I have learned, in writing needed scripts, there should be a part in track script which tells unity not to listen to some properties driven by timeline.
In my case I want objects transform to be driven by timeline and be only on preview, but I also want something more which I don't know how to achieve.
My own type of playable, gets its binding object and not only change it's transforms but also it's parent, for example it makes it's Parent to null which makes it global.
how can I change the Transform.parent of my track binding object in timeline preview and as soon as the timeline lose focus this object parent gets to it's previous status, I mean make it child of same object, which it has been before starting timeline Preview?
this is the code I use for my Track scrip, and at the end of it previewing and changing transform in preview mode is handled.
[TrackColor(0.87450f, 0.2155f, 0.87450f)]
[TrackClipType(typeof(MagneticTweenClip))]
[TrackBindingType(typeof(Transform))]
public class MagneticTweenTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
track = ScriptPlayable<MagneticTweenMixerBehaviour>.Create(graph, inputCount);
return track;
}
public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
{
#if UNITY_EDITOR
var comp = director.GetGenericBinding(this) as Transform;
if (comp == null)
return;
var so = new SerializedObject(comp);
var iter = so.GetIterator();
while (iter.NextVisible(true))
{
if (iter.hasVisibleChildren)
continue;
driver.AddFromName<Transform>(comp.gameObject, iter.propertyPath);
#endif
base.GatherProperties(director, driver);
}
}
}
but I don't know how to do same thing for changing this specific object parent temporary and only in preview.
I want the transform.Parent be intact even if it is changed in mixer in timeline preview time.
I hope I have told what I meant correctly.
my simple version of Mixer script :
public class MagneticTweenMixerBehaviour : PlayableBehaviour
{
public override void OnPlayableDestroy(Playable playable)
{
m_FirstFrameHappened = false;
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Transform trackBinding = playerData as Transform;
if (trackBinding == null)
return;
trackBinding.parent=null;
// more code
}
}
thanks in advance.
Answer by seant_unity · Jun 05, 2018 at 12:35 PM
I haven't tried to put the transform parent in preview using the gather properties, so I'm not sure if this would work. What you could try is drive the child references (under the m_Children property of the parent), as well as parent (under the m_Father property) of the source Transform.
driver.AddFromName<Transform>(comp.gameObject, "m_Father");
driver.AddFromName<Transform>(comp.parent.gameObject, "m_Children");
However, I suspect that this will still cause the scene to be dirtied. In your mixer behaviour, if you store the previous parent and restore it on OnGraphStop(), that should also return the scene to it's previous hierarchy. However, that would affect both preview and play mode.
Thanks. I tried OnGraphStop() and OnGraphStart as you said, and it's exactly what I wanted, I didn't they exist and after some experiments is figure out how it works and It was exactly what I needed. I was worried about what if the developer for example decide to change the scene in the middle of timeline and his hierarchy got messed up because of my playable type, but the good Point is OnGraphStop is called before Unloading a scene and loading another one, so I can be sure that everything gets to it's normal status, as the developer would expect.
I also checked the two line code you have written but I got some errors which I don't understand completely , I will attach the image of them, but any way I could do what I needed with your help and with OnGraphStop and OnGraphStart.
Thanks a lot once again.
Sorry for delayed response. I was able to dig in to this a bit more, and you can't put those properties in to preview mode - which partly explains the errors. The alternate is to ignore the preview and just restore the parent in OnGraphStop()
Here's an example:
public class ParentBehaviour : PlayableBehaviour
{
private Transform binding = null;
private Transform parent = null;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
var transform = playerData as Transform;
if (transform == null)
return;
if (binding == null)
binding = transform;
if (transform.parent != null)
{
parent = transform.parent;
transform.parent = null;
}
}
public override void OnGraphStop(Playable playable)
{
if (binding != null && parent != null)
binding.parent = parent;
}
}
The drawback with (just) this approach is that using timeline will constantly dirty the scene.
Your answer
Follow this Question
Related Questions
Is there any way to make a timeline feature in editor scripting? 1 Answer
How to refresh timeline after update to AnimationClip 1 Answer
How To Set Layer Collisons in Physics Manager Via Script 0 Answers
Port Project Setting TO Another Project 0 Answers
Auto switch max size of a selected texture in Project window 0 Answers