Exemple #1
0
        public override void Init(IAtomPlugin plugin)
        {
            base.Init(plugin);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            var keyframeCurrentPoseUI = prefabFactory.CreateButton("Keyframe pose (all on controllers)");

            keyframeCurrentPoseUI.button.onClick.AddListener(() => KeyframeCurrentPose(true));

            var keyframeCurrentPoseTrackedUI = prefabFactory.CreateButton("Keyframe pose (animated targets only)");

            keyframeCurrentPoseTrackedUI.button.onClick.AddListener(() => KeyframeCurrentPose(false));

            prefabFactory.CreateSpacer();

            _bakeUI = prefabFactory.CreateButton("Bake animation (arm & record)");
            _bakeUI.button.onClick.AddListener(() => Bake());

            prefabFactory.CreateSpacer();

            var removeAllKeyframesUI = prefabFactory.CreateButton("Remove all keyframes");

            removeAllKeyframesUI.button.onClick.AddListener(() => RemoveAllKeyframes());

            var reverseAnimationUI = prefabFactory.CreateButton("Reverse keyframes");

            reverseAnimationUI.button.onClick.AddListener(() => ReverseAnimation());
        }
Exemple #2
0
        public virtual void Bind(IAtomPlugin plugin, AtomAnimationClip clip, T target)
        {
            this.plugin = plugin;
            this.clip   = clip;
            this.target = target;

            CreateToggle(plugin);
            toggle.label = target.GetShortName();

            CreateCustom();

            valueText = CreateValueText();

            _expandButton = CreateExpandButton();
            var expandListener = _expandButton.AddComponent <Clickable>();

            expandListener.onClick.AddListener(pointerEvent => ToggleExpanded());

            this.plugin.animationEditContext.onTimeChanged.AddListener(OnTimeChanged);
            OnTimeChanged(this.plugin.animationEditContext.timeArgs);

            target.onAnimationKeyframesRebuilt.AddListener(OnAnimationKeyframesRebuilt);

            OnAnimationKeyframesRebuilt();
        }
Exemple #3
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            InitLockedUI();

            prefabFactory.CreateSpacer();

            InitDisableSync();
            if (!ReferenceEquals(plugin.containingAtom.containingSubScene, null))
            {
                InitSyncSubsceneOnly();
            }

            prefabFactory.CreateSpacer();

            InitSnapUI();

            prefabFactory.CreateSpacer();

            InitAutoKeyframeUI();

            prefabFactory.CreateSpacer();

            InitShowPathsUI();

            animationEditContext.onEditorSettingsChanged.AddListener(OnEditorSettingsChanged);
        }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            InitRenameLayer();
            InitRenameAnimation();

            prefabFactory.CreateHeader("Speed", 1);
            InitPlaybackUI();

            prefabFactory.CreateHeader("Options", 1);
            InitLoopUI();

            prefabFactory.CreateHeader("Length", 1);
            InitAnimationLengthUI();

            prefabFactory.CreateHeader("Advanced", 1);
            InitWeightUI();
            InitEnsureQuaternionContinuityUI();
            InitAnimationPatternLinkUI();

            current.onAnimationSettingsChanged.AddListener(OnAnimationSettingsChanged);
            current.onPlaybackSettingsChanged.AddListener(OnPlaybackSettingsChanged);
            animation.onSpeedChanged.AddListener(OnSpeedChanged);
            OnSpeedChanged();
            OnPlaybackSettingsChanged();
            UpdateValues();
        }
Exemple #5
0
        public void Bind(IAtomPlugin plugin, string defaultScreen = null)
        {
            _plugin = plugin;

            _leftPanelPrefabFactory        = leftPanel.AddComponent <VamPrefabFactory>();
            _leftPanelPrefabFactory.plugin = plugin;

            _controlPanel = CreateControlPanel(leftPanel);
            _controlPanel.Bind(plugin);

            InitClipboardUI();

            InitChangeCurveTypeUI();

            _curves = InitCurvesUI();

            tabs.Add(AnimationsScreen.ScreenName);
            tabs.Add(TargetsScreen.ScreenName);
            tabs.Add(EditAnimationScreen.ScreenName);
            tabs.Add(MoreScreen.ScreenName);
            _expandButton = tabs.Add("Collapse >");
            InitToggleRightPanelButton(_expandButton);
            tabs.onTabSelected.AddListener(screenName =>
            {
                screensManager.ChangeScreen(screenName);
                Expand(true);
            });

            screensManager = InitScreensManager(rightPanel);
            screensManager.onScreenChanged.AddListener(screenName => tabs.Select(screenName));
            screensManager.Bind(plugin, defaultScreen);
        }
Exemple #6
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            InitSelectionUI();

            InitBulkClipboardUI();

            InitChangeCurveUI();

            InitOffsetUI();

            // Init

            _startJSON.valNoCallback = _lastStart == -1f ? 0f : Mathf.Min(_lastStart, current.animationLength);
            _endJSON.valNoCallback   = _lastEnd == -1f ? current.animationLength : Mathf.Min(_lastEnd, current.animationLength);
            if (_endJSON.val <= _startJSON.val || _lastAnim != current.animationName || _lastLength != current.animationLength)
            {
                _startJSON.valNoCallback = 0f;
                _endJSON.valNoCallback   = current.animationLength;
            }
            animationEditContext.onTargetsSelectionChanged.AddListener(OnTargetsSelectionChanged);
            OnTargetsSelectionChanged();
        }
Exemple #7
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            _resizeAnimationJSON = new JSONStorableBool("Resize animation to mocap length", current.targetControllers.Count == 0 || _lastResizeAnimation, val => _lastResizeAnimation = val);
            prefabFactory.CreateToggle(_resizeAnimationJSON);

            _importRecordedUI = prefabFactory.CreateButton("Import recorded animation (mocap)");
            _importRecordedUI.button.onClick.AddListener(ImportRecorded);

            prefabFactory.CreateSpacer();

            _playAndRecordControllersUI = prefabFactory.CreateButton(_recordingControllersCoroutine != null ? _recordingLabel : _startRecordControllersLabel);
            _playAndRecordControllersUI.button.onClick.AddListener(PlayAndRecordControllers);

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("<i>Go to <b>reduce</b> screen...</i>", ReduceScreen.ScreenName);

            prefabFactory.CreateSpacer();

            var clearMocapUI = prefabFactory.CreateButton("Clear atom's mocap");

            clearMocapUI.button.onClick.AddListener(ClearMocapData);
            clearMocapUI.buttonColor = Color.yellow;

            animationEditContext.onTargetsSelectionChanged.AddListener(OnTargetsSelectionChanged);
            OnTargetsSelectionChanged();
        }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            prefabFactory.CreateHeader("Options", 1);
            InitSequenceMasterUI();
            InitAutoPlayUI();

            prefabFactory.CreateHeader("Sequencing", 1);
            InitSequenceUI();
            InitUninterruptibleUI();
            InitBlendUI();
            InitRandomizeLengthUI();
            InitPreviewUI();

            prefabFactory.CreateHeader("Transition (auto keyframes)", 1);
            InitLoopUI();
            InitTransitionUI();

            // To allow selecting in the popup
            prefabFactory.CreateSpacer().height = 200f;

            current.onAnimationSettingsChanged.AddListener(OnAnimationSettingsChanged);

            UpdateValues();
        }
Exemple #9
0
        public override void Init(IAtomPlugin plugin)
        {
            base.Init(plugin);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", TargetsScreen.ScreenName);

            prefabFactory.CreateSpacer();

            InitTriggersUI();

            prefabFactory.CreateSpacer();

            InitControllersUI();

            prefabFactory.CreateSpacer();

            InitFloatParamsUI();

            InitFixMissingUI();

            prefabFactory.CreateSpacer();

            InitRemoveUI();

            UpdateRemoveUI();

            current.onTargetsListChanged.AddListener(OnTargetsListChanged);
            current.onTargetsSelectionChanged.AddListener(UpdateRemoveUI);
        }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", AnimationsScreen.ScreenName);

            InitAnimationsListUI();

            prefabFactory.CreateSpacer();

            InitReorderAnimationsUI();

            prefabFactory.CreateSpacer();

            InitDeleteAnimationsUI();
            InitDeleteLayerUI();

            prefabFactory.CreateSpacer();

            InitSyncInAllAtomsUI();

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("<i><b>Add</b> animations/layers...</i>", AddAnimationScreen.ScreenName);

            RefreshAnimationsList();

            animation.onClipsListChanged.AddListener(RefreshAnimationsList);
        }
Exemple #11
0
 public virtual void Init(IAtomPlugin plugin, object arg)
 {
     this.plugin          = plugin;
     prefabFactory        = gameObject.AddComponent <VamPrefabFactory>();
     prefabFactory.plugin = plugin;
     plugin.animationEditContext.onCurrentAnimationChanged.AddListener(OnCurrentAnimationChanged);
 }
Exemple #12
0
        public override void Init(IAtomPlugin plugin)
        {
            base.Init(plugin);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            InitSelectionUI();

            prefabFactory.CreateSpacer();

            InitBulkClipboardUI();

            prefabFactory.CreateSpacer();

            InitChangeCurveUI();

            prefabFactory.CreateSpacer();

            InitDeleteUI();

            prefabFactory.CreateSpacer();

            _offsetControllerUI = prefabFactory.CreateButton(_offsetting ? _offsetControllerUIOfsettingLabel : _offsetControllerUILabel);
            _offsetControllerUI.button.onClick.AddListener(() => OffsetController());

            // Init

            _startJSON.valNoCallback = 0f;
            _endJSON.valNoCallback   = current.animationLength;
            current.onTargetsSelectionChanged.AddListener(OnTargetsSelectionChanged);
            OnTargetsSelectionChanged();
        }
        public override void Init(IAtomPlugin plugin)
        {
            base.Init(plugin);

            CreateHeader("Playback", 1);
            InitPlaybackUI();

            CreateHeader("Name", 1);
            InitRenameLayer();
            InitRenameAnimation();

            CreateHeader("Options", 1);
            InitLoopUI();
            InitEnsureQuaternionContinuityUI();
            InitAutoPlayUI();

            CreateHeader("Length", 1);
            InitAnimationLengthUI();

            CreateHeader("Sequencing", 1);
            InitSequenceUI();
            InitTransitionUI();
            InitPreviewUI();

            CreateHeader("Links", 1);
            InitAnimationPatternLinkUI();

            current.onAnimationSettingsChanged.AddListener(OnAnimationSettingsChanged);
            current.onPlaybackSettingsChanged.AddListener(OnPlaybackSettingsChanged);
            animation.onSpeedChanged.AddListener(OnSpeedChanged);
            UpdateValues();
        }
Exemple #14
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            if (arg == null)
            {
                arg = _lastArg;
            }
            else
            {
                _lastArg = (string)arg;
            }
            _target = current.targetControllers.FirstOrDefault(t => t.name == (string)arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", TargetsScreen.ScreenName);

            prefabFactory.CreateHeader("Controller settings", 1);

            if (_target == null)
            {
                prefabFactory.CreateTextField(new JSONStorableString("", "Cannot show the selected target settings.\nPlease go back and re-enter this screen."));
                return;
            }
            prefabFactory.CreateHeader(_target.name, 2);

            prefabFactory.CreateHeader("Parenting", 1);

            InitParentUI();

            prefabFactory.CreateHeader("Options", 1);

            InitControlUI();
            InitWeightUI();
        }
Exemple #15
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            _backupUI = prefabFactory.CreateButton("Backup");
            _backupUI.button.onClick.AddListener(TakeBackup);
            _restoreUI = prefabFactory.CreateButton("Restore");
            _restoreUI.button.onClick.AddListener(RestoreBackup);

            prefabFactory.CreateSpacer();
            prefabFactory.CreateSlider(_reduceMaxFramesPerSecondJSON).valueFormat = "F1";
            prefabFactory.CreateToggle(_averageToSnapJSON);
            prefabFactory.CreateToggle(_removeFlatSectionsKeyframes);
            prefabFactory.CreateToggle(_simplifyKeyframes);
            prefabFactory.CreateSlider(_reduceMinDistanceJSON).valueFormat             = "F3";
            prefabFactory.CreateSlider(_reduceMinRotationJSON).valueFormat             = "F2";
            prefabFactory.CreateSlider(_reduceMinFloatParamRangeRatioJSON).valueFormat = "F3";

            _reduceUI = prefabFactory.CreateButton("Reduce");
            _reduceUI.button.onClick.AddListener(Reduce);

            _restoreUI.button.interactable = _backup != null;
            if (_backup != null)
            {
                _restoreUI.label = $"Restore [{_backupTime}]";
            }
        }
Exemple #16
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton($"<b><</b> <i>Back to {AnimationsScreen.ScreenName}</i>", AnimationsScreen.ScreenName);

            prefabFactory.CreateHeader("Add animations", 1);

            prefabFactory.CreateSpacer();

            prefabFactory.CreateHeader("Animations", 2);

            InitCreateAnimationUI();

            prefabFactory.CreateSpacer();

            prefabFactory.CreateHeader("Layers", 2);

            InitCreateLayerUI();
            InitSplitLayerUI();

            prefabFactory.CreateSpacer();

            prefabFactory.CreateHeader("More", 2);

            CreateChangeScreenButton("<i><b>Import</b> from file...</i>", ImportExportScreen.ScreenName);
            CreateChangeScreenButton("<i><b>Manage</b> animations list...</i>", ManageAnimationsScreen.ScreenName);
        }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            InitLockedUI();

            prefabFactory.CreateSpacer();

            InitSnapUI();

            prefabFactory.CreateSpacer();

            InitAutoKeyframeUI();

            prefabFactory.CreateSpacer();

            InitShowPathsUI();

            animationEditContext.onEditorSettingsChanged.AddListener(OnEditorSettingsChanged);
        }
Exemple #18
0
        public void Bind(IAtomPlugin plugin, AtomAnimationClip clip, T target)
        {
            this.plugin = plugin;
            this.clip   = clip;
            this.target = target;

            CreateToggle(plugin);
            toggle.label = target.name;

            CreateCustom();

            valueText = CreateValueText();

            _expandButton = CreateExpandButton();
            var expandListener = _expandButton.AddComponent <Clickable>();

            expandListener.onClick.AddListener(pointerEvent => ToggleExpanded());

            this.plugin.animation.TimeChanged.AddListener(this.OnTimeChanged);
            OnTimeChanged(this.plugin.animation.Time);

            target.onAnimationKeyframesModified.AddListener(OnAnimationKeyframesModified);

            OnAnimationKeyframesModified();
        }
 public void Bind(IAtomPlugin plugin)
 {
     _animationsJSON = InitAnimationSelectorUI(plugin.manager.configurableScrollablePopupPrefab);
     _scrubber       = InitScrubber();
     InitFrameNav(plugin.manager.configurableButtonPrefab);
     InitPlaybackButtons(plugin.manager.configurableButtonPrefab);
     _dopeSheet = InitDopeSheet();
 }
Exemple #20
0
        public override void Init(IAtomPlugin plugin)
        {
            base.Init(plugin);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            InitExplanation();
        }
Exemple #21
0
 public virtual void Init(IAtomPlugin plugin)
 {
     this.plugin          = plugin;
     prefabFactory        = gameObject.AddComponent <VamPrefabFactory>();
     prefabFactory.plugin = plugin;
     plugin.animation.onCurrentAnimationChanged.AddListener(OnCurrentAnimationChanged);
     current = plugin.animation?.current;
 }
 public void Bind(IAtomPlugin plugin, string defaultScreen)
 {
     _plugin        = plugin;
     _currentScreen = defaultScreen;
     if (enabled && plugin.animation != null)
     {
         ChangeScreen(GetDefaultScreen());
     }
 }
Exemple #23
0
 public void Bind(IAtomPlugin plugin)
 {
     _prefabFactory        = gameObject.AddComponent <VamPrefabFactory>();
     _prefabFactory.plugin = plugin;
     _animationsJSON       = InitAnimationSelectorUI();
     _scrubber             = InitScrubber();
     InitFrameNav(plugin.manager.configurableButtonPrefab);
     InitPlaybackButtons(plugin.manager.configurableButtonPrefab);
     _dopeSheet = InitDopeSheet();
 }
 public void Bind(IAtomPlugin plugin)
 {
     _scrubber = InitScrubber(plugin.scrubberJSON, plugin.snapJSON);
     InitSpacer();
     // TODO: Make the JSON use animation features instead of the other way around
     InitFrameNav(plugin.manager.configurableButtonPrefab, plugin.previousFrameJSON, plugin.nextFrameJSON);
     InitSpacer();
     InitPlaybackButtons(plugin.manager.configurableButtonPrefab, plugin.playJSON, plugin.stopJSON);
     InitSpacer();
     _dopeSheet = InitDopeSheet();
     InitSpacer();
 }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            InitImportUI();

            prefabFactory.CreateSpacer();

            InitExportUI();
        }
Exemple #26
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            var keyframeCurrentPoseUI = prefabFactory.CreateButton("Keyframe pose (all on controllers)");

            keyframeCurrentPoseUI.button.onClick.AddListener(() => KeyframeCurrentPose(true));

            var keyframeCurrentPoseTrackedUI = prefabFactory.CreateButton("Keyframe pose (animated targets only)");

            keyframeCurrentPoseTrackedUI.button.onClick.AddListener(() => KeyframeCurrentPose(false));

            prefabFactory.CreateSpacer();

            _bakeUI = prefabFactory.CreateButton("Bake animation (arm & record)");
            _bakeUI.button.onClick.AddListener(Bake);

            prefabFactory.CreateSpacer();

            var reverseAnimationUI = prefabFactory.CreateButton("Reverse keyframes");

            reverseAnimationUI.button.onClick.AddListener(ReverseAnimation);

            prefabFactory.CreateSpacer();

            var rebuildAnimationsUI = prefabFactory.CreateButton("Rebuild & realign all animations");

            rebuildAnimationsUI.button.onClick.AddListener(RebuildAnimations);

            prefabFactory.CreateSpacer();

            var removeAllKeyframesUI = prefabFactory.CreateButton("Remove all keyframes");

            removeAllKeyframesUI.buttonColor = Color.yellow;
            removeAllKeyframesUI.button.onClick.AddListener(RemoveAllKeyframes);

            prefabFactory.CreateSpacer();

            var clearAllUI = prefabFactory.CreateButton("Delete all animations (reset)");

            clearAllUI.buttonColor = new Color(1f, 0f, 0f);
            clearAllUI.textColor   = new Color(1f, 1f, 1f);
            clearAllUI.button.onClick.AddListener(ClearAll);
        }
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            // Right side

            CreateChangeScreenButton("<b><</b> <i>Back</i>", MoreScreen.ScreenName);

            prefabFactory.CreateSpacer();

            _resultJSON = new JSONStorableString("Result", "Analyzing...");
            prefabFactory.CreateTextField(_resultJSON).height = 1200f;

            DoAnalysis();
        }
Exemple #28
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            prefabFactory.CreateHeader("Animations", 1);

            InitClipsUI();

            prefabFactory.CreateSpacer();

            prefabFactory.CreateHeader("Operations", 1);

            CreateChangeScreenButton("<i><b>Add</b> animations/layers...</i>", AddAnimationScreen.ScreenName);
            CreateChangeScreenButton("<i><b>Manage</b> animations list...</i>", ManageAnimationsScreen.ScreenName);
        }
Exemple #29
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            prefabFactory.CreateHeader("More options", 1);

            CreateChangeScreenButton("<b>Import / export</b> animations...", ImportExportScreen.ScreenName);

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("<b>Mocap</b> import...", MocapScreen.ScreenName);
            CreateChangeScreenButton("<b>Record</b> animation...", RecordScreen.ScreenName);
            CreateChangeScreenButton("<b>Reduce</b> keyframes...", ReduceScreen.ScreenName);

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("<b>Bulk</b> changes...", BulkScreen.ScreenName);
            CreateChangeScreenButton("<b>Advanced</b> keyframe tools...", AdvancedKeyframeToolsScreen.ScreenName);

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("<b>Diagnostics</b> and scene analysis...", DiagnosticsScreen.ScreenName);
            CreateChangeScreenButton("<b>Options</b>...", OptionsScreen.ScreenName);

            prefabFactory.CreateSpacer();

            CreateChangeScreenButton("Help", HelpScreen.ScreenName);

            prefabFactory.CreateSpacer();

            var helpButton = prefabFactory.CreateButton("[Browser] Online help");

            helpButton.button.onClick.AddListener(() => Application.OpenURL("https://github.com/acidbubbles/vam-timeline/wiki"));

            var hubButton = prefabFactory.CreateButton("[Browser] Virt-A-Mate Hub");

            hubButton.button.onClick.AddListener(() => Application.OpenURL("https://hub.virtamate.com/resources/timeline.94/"));

            prefabFactory.CreateSpacer();

            var patreonBtn = prefabFactory.CreateButton("[Browser] Support me on Patreon!");

            patreonBtn.textColor   = new Color(0.97647f, 0.40784f, 0.32941f);
            patreonBtn.buttonColor = Color.white;
            patreonBtn.button.onClick.AddListener(() => Application.OpenURL("https://www.patreon.com/acidbubbles"));
        }
Exemple #30
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            _filterJSON = new JSONStorableBool("Filter unselected targets", _lastFilterVal, val => { _lastFilterVal = val; OnSelectionChanged(); });

            animationEditContext.onTargetsSelectionChanged.AddListener(OnSelectionChanged);

            if (animation.IsEmpty())
            {
                InitExplanation();
                CreateAddRemoveTargetsButton(true);
            }
            else
            {
                OnSelectionChanged();
            }
        }