Timeline custom signal, the receiver still needs 'normal' signal receiver attached too

I’ve set up a custom signal, with an emitter and a receiver and it works just fine to pass a string.
However the endpoint receiving object not only requires the custom receiver (as expected) but also needs the default Signal Receiver on it which doesn’t even get ‘used’ as it can’t work with custom data.
However, without the latter the timeline loses it’s reference to the target object.

My emitter inherits from SignalEmitter and my receiver from MonoBehaviour, INotificationReceiver

public class ParameterizedEmitter<T> : SignalEmitter
{
    public T parameter;
}

public class SignalEmitterWithString : ParameterizedEmitter<string> { }


public class SignalReceiverWithString : MonoBehaviour, INotificationReceiver
{
    public SignalAssetEventPair[] signalAssetEventPairs;

    [Serializable]
    public class SignalAssetEventPair
    {
        public SignalAsset signalAsset;
        public ParameterizedEvent events;

        [Serializable]
        public class ParameterizedEvent : UnityEvent<string> { }
    }

    public void OnNotify(Playable origin, INotification notification, object context)
    {
        if (notification is ParameterizedEmitter<string> stringEmitter)
        {
            var matches = signalAssetEventPairs.Where(x => ReferenceEquals(x.signalAsset, stringEmitter.asset));
            foreach (var m in matches)
            {
                m.events.Invoke(stringEmitter.parameter);
            }
        }
    }
}

What am I missing?

    [TrackClipType(typeof(SignalReceiverWithString ))]
    [TrackBindingType(typeof(SignalReceiverWithString ))]
    public class SignalReceiverWithString : TrackAsset {}

This seems to add it to the track and works with the binding.

So dump inheriting from MonoBehaviour, INotificationReceiver? Just that even the official examples use those?

Oops my bad! Should be a new class

[TrackClipType(typeof(SignalReceiverWithString ))]
    [TrackBindingType(typeof(SignalReceiverWithString ))]
    public class SignalReceiverWithStringTrack : TrackAsset {}

Ok, what happens with this new class? Unity will just automatically use it when creating a new track of the ‘WithString’ types?

Yeah - Unity seems to pick up any extension of the TrackAsset as an option for a new track. You can bind the matching type to the track then.

2 Likes

Thanks. I’ll try this out.

Guys, I just wanted to say THANK YOU!! … this has made my day. I’ve wanted to pass parameters through signals for an age now … I’m so glad it works.

Do you know what the limitations are for the parameter types? I guess it is basic types. Can you pass structs?

Thank you again.

WARNING!! Unity 6 Timeline doesn’t seem to like the TrackAsset … when you set it up, it works, but then, sometime later, and for no apparent reason, the track is disabled and has a warning symbol on it. The signals you added will also be gone. The solution is to just use a normal Signal Track but make sure you also add a Signal Receiver component to the binded object that also has your custom receiver on it.

A side-effect of using the standard Signal Track is that it throws an error:

SerializedObjectNotCreatableException: Object at index 0 is null
UnityEditor.Editor.CreateSerializedObject () (at <1f8babe234e540299e4f7387cdc20cd8>:0)
UnityEditor.Editor.GetSerializedObjectInternal () (at <1f8babe234e540299e4f7387cdc20cd8>:0)
UnityEditor.Editor.get_serializedObject () (at <1f8babe234e540299e4f7387cdc20cd8>:0)
UnityEditor.Timeline.Signals.SignalReceiverInspector.OnEnable () (at ./Library/PackageCache/com.unity.timeline/Editor/Signals/SignalReceiverInspector.cs:26)

However, it doesn’t seem to stop you using the custom signals. Is this something to do with having the empty Signal Receiver on the bound object?

I spoke too soon.

The signals are suddenly being removed from the track. Any ideas?

Gutted. This seems too buggy to use.
The error is an editor error when it tries to add the custom signals to the track. They don’t show, but if you run the scene they appear in play mode. If you then stop playing the scene, they are there on the track again.
Unfortunately, this sometimes just happens randomly when you are loading scenes.
Can you guys confirm that you have been using this successfully? I think my code is slightly different to yours. Here it is:

using System.Linq;
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Playables;
using UnityEngine.Timeline;


public class SignalReceiverWithString : MonoBehaviour, INotificationReceiver
{
    public SignalAssetEventPair[] signalAssetEventPairs;

    [Serializable]
    public class SignalAssetEventPair
    {
        public SignalAsset signalAsset;
        public ParameterizedEvent events;

        [Serializable]
        public class ParameterizedEvent : UnityEvent<string> { }
    }

    public void OnNotify(Playable origin, INotification notification, object context)
    {
        Debug.Log("OnNotify called with notification: " + notification.GetType().Name);
        if (notification is ParameterizedEmitter<string> stringEmitter)
        {
            var matches = signalAssetEventPairs.Where(x => ReferenceEquals(x.signalAsset, stringEmitter.asset));
            foreach (var m in matches)
            {
                m.events.Invoke(stringEmitter.parameter);
            }
        }
    }
}

public class ParameterizedEmitter<T> : SignalEmitter
{
    public T parameter;
}

public class SignalEmitterWithString : ParameterizedEmitter<string>
{
}

[TrackClipType(typeof(SignalReceiverWithString))]
[TrackBindingType(typeof(SignalReceiverWithString))]
public class SignalReceiverWithStringTrack : TrackAsset { }

Sorry - hadn’t used Unity forums since they ported over to this new format.

I’m still on 2021; not used Unity 6.

Quick glance of your code seems similar to mine. Are the classes in separate class files? that might impact how serialization is handled with stuff?

No worries. I think this is a bug with Unity 6. Would love to get an engineer involved to see if we can resolve this. Custom Signals are SOOO useful, and they could really make a feature out of this.