Now this is my first time in posting on Unity’s forum so forgive me if Im not being clear. I am trying to code a playableasset and playablebehaviour script pair to allow my game to enable and disable several gameobjects during a timeline. Here are the scripts in question.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class TimelineGameObjectOnOff : PlayableAsset, ITimelineClipAsset
{
public GameObjectOnOffPlayableBehaviour template = new GameObjectOnOffPlayableBehaviour();
public List<ExposedReferenceEnabledObject> exposedReferenceEnabledObjects;
public List<ExposedReferenceDisabledObject> exposedReferenceDisabledObjects;
[Tooltip("When set to true, it will match the gameobjects from the exposed enable and disable gameobjects lists to the lists in gameObjectsEnabled and gameObjectsDisabled in the GameObjectOnOffPlayableBehaviour script")]
public bool matchItems;
private bool matchEnabledSize;
private bool matchDisabledSize;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
ScriptPlayable<GameObjectOnOffPlayableBehaviour> playable = ScriptPlayable<GameObjectOnOffPlayableBehaviour>.Create(graph, template);
GameObjectOnOffPlayableBehaviour gameObjectOnOffPlayableBehaviour = playable.GetBehaviour();
//This will make the size of the enable and disable lists be the same in the gameObjectOnOffPlayableBehaviour script
if (gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Count > exposedReferenceEnabledObjects.Count)
{
gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Clear();
matchEnabledSize = true;
}
while (gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Count < exposedReferenceEnabledObjects.Count || matchEnabledSize)
{
gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Add(null);
if (gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Count >= exposedReferenceEnabledObjects.Count)
{
matchEnabledSize = false;
}
}
if (gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Count > exposedReferenceDisabledObjects.Count)
{
gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Clear();
matchDisabledSize = true;
}
while (gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Count < exposedReferenceDisabledObjects.Count || matchEnabledSize)
{
gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Add(null);
if (gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Count >= exposedReferenceDisabledObjects.Count)
{
matchDisabledSize = false;
}
}
//When matchItems is set to true, it will go and match the enabled and disabled lists of the exposed gameobjects to the gameobject lists from the GameObjectsOnOffPlayableBehaviour script.
while (matchItems)
{
//Go throught the whole list of enabling gameobjects on this script and transfer them to the GameObjectsOnOffPlayableBehaviour script.
for (int a = 0; gameObjectOnOffPlayableBehaviour.gameObjectsEnabled.Count > a; a++)
{
gameObjectOnOffPlayableBehaviour.gameObjectsEnabled[a] = exposedReferenceEnabledObjects[a].exposedEnabledGameObject.Resolve(graph.GetResolver()) as GameObject;
}
//Go throught the whole list of disabling gameobjects on this script and transfer them to the GameObjectsOnOffPlayableBehaviour script.
for (int a = 0; gameObjectOnOffPlayableBehaviour.gameObjectsDisabled.Count > a; a++)
{
gameObjectOnOffPlayableBehaviour.gameObjectsDisabled[a] = exposedReferenceDisabledObjects[a].exposedDisabledGameObject.Resolve(graph.GetResolver()) as GameObject;
}
//Once we've matched everything, we make sure to exit the statement.
matchItems = false;
}
return playable;
}
public ClipCaps clipCaps
{
get { return ClipCaps.None; }
}
}
//This is a workaround from not being able to expose a list of gameObjects.
[Serializable]
public class ExposedReferenceEnabledObject
{
[SerializeField]
public ExposedReference<GameObject> exposedEnabledGameObject;
}
[Serializable]
public class ExposedReferenceDisabledObject
{
[SerializeField]
public ExposedReference<GameObject> exposedDisabledGameObject;
}
Here is the behavior script.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class GameObjectOnOffPlayableBehaviour : PlayableBehaviour
{
public List<GameObject> gameObjectsEnabled;
public List<GameObject> gameObjectsDisabled;
public bool clipPlayed = false;
private PlayableDirector director;
public override void OnPlayableCreate(Playable playable)
{
director = (playable.GetGraph().GetResolver() as PlayableDirector);
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
if (!clipPlayed
&& info.weight > 0f)
{
if (Application.isPlaying)
{
foreach (GameObject gameObject in gameObjectsEnabled)
{
if (gameObject != null)
{
if (!gameObject.activeSelf)
gameObject.SetActive(true);
}
}
foreach (GameObject gameObject in gameObjectsDisabled)
{
if(gameObject != null)
if(gameObject.activeSelf)
gameObject.SetActive(false);
}
}
clipPlayed = true;
}
}
public override void OnGraphStart(Playable playable)
{
base.OnGraphStart(playable);
}
}
I’m able to define the variables by checking true to the matching items variable in the inspector, but the problem is that the gameobjects don’t stay defined.
If I open another scene and come back to this scene, the variables for the GameObjectOnOffPlayableBehaviour script is missing. (See inspector on right.)
So that means that during runtime, the script might as well not even be there. Is there a way to define these variables during runtime without setting matchItems to true in the inspector?
And again, I’m sorry if some parts aren’t clear. I’ve been working on this for days and don’t seem to be getting anywhere.


