Getting "Search stopped: found a playable with multiple outputs"

Hi, I am trying to build a FSM editor with Playable and Timeline.
I’ve modify how timeline asset creates playable graph quite a bit. At some point I started to get this compile error “Search stopped: found a playable with multiple outputs”. There is no stack trace .
What does it mean? Aren’t playables suppose to support multiple outputs?

I can’t check the code right now for this error, but Playables the framework allows for multiple outputs, but there are no Playables besides Timeline that really support multiple outputs. And even then, on Timeline each input is only connected to 0 or 1 output.

Hello David! Thanks for your reply!

I post a thread a few weeks ago and got zero responses so I wasn’t expecting any this time. I’ll try to describe the situation a little better.

What I am trying to do: A FSM based ability editor using NodeCanvas’s FSM module and Timeline. Here’s a breakdown of the design:

  1. MotionGraph: the FSM, holds several MotionStates and their transition relations.
  2. MotionState: states in the FSM, each holds a timeline asset.
  3. MotionGraphPlayableCtrl: manipulates the playable graph when the FSM’s active state changes, connecting the unplugging the subgraph of the existing state and connect the entering state to outputs, or blending in/out of the state subgraphs.
  4. PlayableGraph Compile:
    a. When editing a MotionState, the editor feed the state’s timelineAsset to PlayableDirector, and created a PlayableGraph only for preview.
    b. In play mode, MotionGraph will create a temporary MotionGraphPlayableAsset for PlayableDirector to compile PlaybleGraph, which contains all states’ timeline assets.

I tried as hard as I could to keep the timeline package intact but it’s difficult for what I’m trying to do. I end up moving the whole timeline package out, creating PlayableAssetCompiler classes to pack compiling stuff together, and used assembly reference to gain access to some internal stuff (so that I can use the IntPtr of the PlayableHandle as a key for indexing, setting tracking name of a playable, etc.)

I created an AnimatorControllerTrack, an AnimationRetargetTrack using AnimationScriptPlayable for IKStuff (because AnimatorControllerPlayable does not have SetIKPosition). Also created a AnimationGroupTrack, which excepts child track of type: AnimationClipTrack, AnimatorControllerTrack, and AnimationRetargetingTrack, and blends child tracks with a AnimationLayerMixerPlayable.

I also modified the PlayableGraphVisualizerWindow(or recreated it) to give myself a better idea of whats going on.
So a TimelineAsset like this:
7192195--863155--upload_2021-5-31_13-19-42.png

, produces a PlayableGraph like this:
7192195--863158--upload_2021-5-31_13-33-48.png

Problems I encountered so far:

  1. The AnimationTrackGroup and AnimatorControllerTrack works find in play mode. However, in edit mode, the AnimatorControllerPlayable only produces output when I hit the “play” button in the timeline editor, dragging the cursor does not progress the AnimatorControllerPlayable. I tried adding RuntimeElement to control the AnimatorControllerPlayable but that does not help either.

2.I incorporate the compile process of AnimationTrack into my custom compiler. I found that the MotionXtoDeltaPlayable can cause the application to crash sometime, removing the MotionXtoDeltaPlayable sovles that crashing and does not seemed to effect anything. The AnimationMotionXToDeltaPlayable is not documented and there’s no comments in its script. What does it do? It is only required for preview?

3.Getting “Search stopped: found a playable with multiple outputs”
At first, this only shows up when the I set the PlayableAsset of the PlayableDirector in edit mode. At some point (I ignored this for a while and did some other stuff), it gets printed every time the PlayableDirector evaluated, both in edit and play mode. The weird part is the asset still plays normally in both edit mode and play mode.
For the example provided above, I check every playable and only the StatePlayable has more than one output. So I am guessing the log it self was shorthanding some keywords. It is possible to use AnimatorControllerPlayable like this at all?

Thanks.

Well first thing first, congratulations, you did a great job with the playable graph visualization, and yours is also the first example of passthrough playable I see in the wild.

As for your questions:

  1. I’m not sure exactly why the controller is not outputting, but it may have something to do with deltaTime. Playback updates the PlayableGraph with a deltaTime, whereas preview does an Evaluate call, which doesn’t have a deltaTime. If your Animator is set to ApplyRootMotion, with no deltaTime, you won’t get any delta in Root Motion, which means no displacement (on the Root joint at least).

  2. Mixing a Timeline with an already existing Animator is complicated. You probably want your Timeline to be in absolute positioning, but there’s a good chance that you want your character in relative positioning (through ApplyRootMotion). In order to be able to blend together an Animator with a controller and a Timeline, we introduced the MotionXToDeltaPlayable (MXTDP) in the Timeline graph. What it does is: everything in the graph that is a child of the MXTDP evaluates the motion of the Root joint as an absolute displacement. When the MXTDP is evaluated, it either does nothing (if the Animator has ApplyRootMotion off), or converts the absolute displacement to a relative displacement (if ApplyRootMotion is ON).

Since it’s not public, and it’s only used by Timeline, it’s quite possible that it’s causing issues if you try to use it elsewhere. But… if you don’t add it, it’s possible that this is causing preview issues at least on the Root joint. It should not really affect other joints.

3- Timeline uses another Playable to fake scene values during preview so that if a track’s weight goes below 1, it’s not blending with nothing. That may be it. If the graph doesn’t have the expected topology, it may be connecting or modifying the wrong Playable.

Oh Thank you! That playable visualizer borrowed a lot of stuff from Node Canvas, especially the GUIStyles, can’t take all the credits.:smile:

  1. The AnimatorControllerPlayable and its subgraph do not produce any animation outputs, (including root motions output) when scrubbing the timeline cursor. But I think we can live with that.

  2. Thanks for explaining MXTDP. I haven’t delved into animating transforms (scene interaction stuff) in timeline yet. At the moment we only want root motion output from AnimationClipPlayable and AnimatorControllerPlayable to output normally, and it does, so I think I’ll leave out MXTDP for now.

  3. The message gets printed in play mode too, so it’s not a preview only issue. And I am pretty sure it has nothing to do with timeline because the whole playable graph is created or compiled with custom script, the playable compiler classes I mentioned. I am guessing it is from the playable director component.
    Everything looks and works as expected but that message just keep flooding the console. I can’t hand this stuff to my team like this.
    It is possible for you to locate the error message? That will be a life saver! Thanks.

Oh, I just realized I logged in with a different account.

I will take a look today, but it should be easier to tell you how to fix it if I had the exact code that produces it. If you can report a bug with your code, I’ll be able to debug it and maybe figure out why don’t things don’t produce a pose in preview

Found it.

AnimationPlayables don’t support multiple outputs, because they need to have a unique path to a unique player (the Animator in this context) to know how to allocate bindings (the list of properties to animate).

Check all your AnimationPlayables, and make sure they don’t have multiple outputs, and that you only connect on output 0.

Thank you David! I’ll go try fix it right now.

@aquacoon2049 Sorry to revive such an old thread but I must ask you this:

How were you able to properly rendering multiple outputs in your visualizer? I cannot see any way to query the exact connections between nodes in a PlayableGraph to determine what input ports on a node connect to what output ports on some other node.

This is in spite of the fact that PlayableGraph.Connect requires all of this data to establish a connection. If you happen to be able to clear this up it would be awesome!

@DavidGeoffroy Quick API question:

Is it really the case that with the current Playables / PlayableGraph API there is no way to query the system to ask “for node A input n connected to node B what port on b is it connected to?”

This seems like a completely fundamental query to the system.

After all, the API to create a connection is PlayableGraph.Connect(source, sourceport, dest, destport)

Without this API, it is currently not possible to visualize or even query the data structure of your graph correctly which is a real problem for those of us using the system “in anger”.

Any clarification would be very much appreciated.