public override void Init() { try { if (containingAtom == null) { return; } PATH_WHEN_LOADED = SuperController.singleton.currentLoadDir; SuperController.singleton.currentSaveDir = PATH_WHEN_LOADED; uiVisible = new JSONStorableBool("uiVisible", false, (bool on) => { ui.canvas.enabled = on; keyUI.canvas.enabled = on; }); RegisterBool(uiVisible); #region Animation Pattern Init animationPattern = containingAtom.GetStorableByID("AnimationPattern") as AnimationPattern; if (animationPattern == null) { SuperController.LogError("You must add this plugin to an AnimationPattern"); return; } animationPattern.Pause(); animationPattern.containingAtom.GetStorableByID("scale").SetFloatParamValue("scale", 0); #endregion CreatePeopleChooser((atom) => { if (atom == null) { return; } person = atom; }); saveStore = new JSONStorableString("keyframes", ""); RegisterString(saveStore); #region World UI float UISCALE = 0.001f; ui = new UI(this, UISCALE); ui.canvas.transform.SetParent(animationPattern.containingAtom.mainController.transform, false); UIDynamicToggle onToggle = ui.CreateToggle("On", 120, 60); JSONStorableBool onStorable = animationPattern.GetBoolJSONParam("on"); onStorable.toggleAlt = onToggle.toggle; onToggle.transform.localPosition = new Vector3(-575 + 35, 160, 0); UIDynamicToggle loopToggle = ui.CreateToggle("Loop", 140, 60); JSONStorableBool loopStorable = animationPattern.GetBoolJSONParam("loop"); loopStorable.toggleAlt = loopToggle.toggle; loopToggle.transform.localPosition = new Vector3(-575 + 180, 160, 0); UIDynamicButton doneEditingButton = ui.CreateButton("Done Editing", 200, 60); doneEditingButton.transform.localPosition = new Vector3(-575 + 75, -300, 0); doneEditingButton.buttonColor = new Color(0.45f, 0.8f, 0.3f); doneEditingButton.textColor = new Color(1, 1, 1); doneEditingButton.button.onClick.AddListener(() => { uiVisible.SetVal(false); ClearEditingKey(); if (SuperController.singleton.GetSelectedAtom() == animationPattern.containingAtom) { SuperController.singleton.ClearSelection(); } }); timeSlider = ui.CreateSlider("Time", 500, 110); timeSlider.transform.localPosition = new Vector3(-350, 55, 0); timeSlider.slider.maxValue = animationPattern.GetTotalTime(); time = animationPattern.GetFloatJSONParam("currentTime"); time.sliderAlt = timeSlider.slider; UIDynamicButton playButton = ui.CreateButton("▶", 50, 60); playButton.transform.localPosition = new Vector3(-575, -30, 0); playButton.button.onClick.AddListener(() => { ClearEditingKey(); if (animationPattern.GetCurrentTimeCounter() == animationPattern.GetTotalTime()) { animationPattern.ResetAndPlay(); } else { animationPattern.Play(); } }); UIDynamicButton pauseButton = ui.CreateButton("||", 50, 60); pauseButton.transform.localPosition = new Vector3(-525, -30, 0); pauseButton.button.onClick.AddListener(() => { ClearEditingKey(); animationPattern.Pause(); }); UIDynamicButton rewindButton = ui.CreateButton("«", 50, 60); rewindButton.transform.localPosition = new Vector3(-475, -30, 0); rewindButton.button.onClick.AddListener(() => { ClearEditingKey(); animationPattern.ResetAnimation(); }); UIDynamicButton addKeyButton = ui.CreateButton("+Key", 100, 60); addKeyButton.textColor = new Color(0.984f, 0.917f, 0.972f); addKeyButton.buttonColor = new Color(0.474f, 0.023f, 0.4f); addKeyButton.transform.localPosition = new Vector3(-550, -200, 0); addKeyButton.button.onClick.AddListener(AddKey); UIDynamicButton insertKeyButton = ui.CreateButton("Insert Key", 140, 60); insertKeyButton.textColor = new Color(0.984f, 0.917f, 0.972f); insertKeyButton.buttonColor = new Color(0.474f, 0.023f, 0.4f); insertKeyButton.transform.localPosition = new Vector3(-420, -200, 0); insertKeyButton.button.onClick.AddListener(InsertKey); UIDynamicButton nextKeyButton = ui.CreateButton("Next Key", 140, 60); nextKeyButton.transform.localPosition = new Vector3(-390, -100, 0); nextKeyButton.button.onClick.AddListener(() => { if (keyframes.Count <= 0) { return; } int index = keyframes.IndexOf(GetNearestKeyToTime(time.val)); int nextIndex = index + 1; if (nextIndex >= keyframes.Count) { nextIndex = 0; } SuperController.singleton.SelectController(keyframes[nextIndex].step.containingAtom.mainController); }); UIDynamicButton previousKeyButton = ui.CreateButton("Prev Key", 140, 60); previousKeyButton.transform.localPosition = new Vector3(-530, -100, 0); previousKeyButton.button.onClick.AddListener(() => { if (keyframes.Count <= 0) { return; } int index = keyframes.IndexOf(GetNearestKeyToTime(time.val)); int prevIndex = index - 1; if (prevIndex < 0) { prevIndex = keyframes.Count - 1; } SuperController.singleton.SelectController(keyframes[prevIndex].step.containingAtom.mainController); }); #endregion #region Keyframe UI keyUI = new UI(this, UISCALE * 0.8f); undoPoseButton = keyUI.CreateButton("Undo", 300, 90); undoPoseButton.buttonText.fontSize = 40; undoPoseButton.transform.localPosition = new Vector3(0, 120, 0); undoPoseButton.textColor = new Color(1, 1, 1); undoPoseButton.buttonColor = new Color(0.650f, 0.027f, 0.027f); undoPoseButton.button.onClick.AddListener(() => { if (editingKeyframe == null) { return; } editingKeyframe.pose = lastPose; SetToPose(lastPose, true); }); setDurationSlider = keyUI.CreateSlider("Duration To Key", 500, 110); setDurationSlider.defaultButtonEnabled = true; setDurationSlider.quickButtonsEnabled = true; setDurationSlider.rangeAdjustEnabled = true; setDurationSlider.transform.localPosition = new Vector3(0, -270, 0); tweenSelection = keyUI.CreatePopup("Tween", 500, 110); tweenSelection.transform.localPosition = new Vector3(0, -350, 0); UIDynamicButton copyPoseButton = keyUI.CreateButton("Copy Pose", 200, 60); copyPoseButton.transform.localPosition = new Vector3(-150, -170, 0); copyPoseButton.button.onClick.AddListener(() => { if (editingKeyframe == null) { return; } copiedPose = editingKeyframe.pose; }); UIDynamicButton pastePoseButton = keyUI.CreateButton("Paste Pose", 200, 60); pastePoseButton.transform.localPosition = new Vector3(50, -170, 0); pastePoseButton.button.onClick.AddListener(() => { if (editingKeyframe == null) { return; } if (copiedPose == null) { return; } editingKeyframe.pose = copiedPose; SetToPose(editingKeyframe.pose, true); }); UIDynamicButton copyControllerButton = keyUI.CreateButton("Copy Control", 200, 60); copyControllerButton.transform.localPosition = new Vector3(-150, -120, 0); copyControllerButton.button.onClick.AddListener(() => { if (editingKeyframe == null) { return; } FreeControllerV3 selectedController = SuperController.singleton.GetSelectedController(); if (selectedController == null) { return; } copiedPosition = selectedController.transform.position; copiedRotation = selectedController.transform.rotation; }); UIDynamicButton pasteControllerButton = keyUI.CreateButton("Paste Control", 200, 60); pasteControllerButton.transform.localPosition = new Vector3(50, -120, 0); pasteControllerButton.button.onClick.AddListener(() => { if (editingKeyframe == null) { return; } FreeControllerV3 selectedController = SuperController.singleton.GetSelectedController(); if (selectedController == null) { return; } selectedController.transform.position = copiedPosition; selectedController.transform.rotation = copiedRotation; }); #endregion #region Plugin (Debug) UI #region Experimental Save and Load Pose UIDynamicButton loadPoseButton = CreateButton("Load Pose"); loadPoseButton.transform.localPosition = new Vector3(-520, -150, 0); loadPoseButton.button.onClick.AddListener(() => { if (person == null) { return; } Vector3 position = person.mainController.transform.position; Quaternion rotation = person.mainController.transform.rotation; person.LoadPhysicalPresetDialog(); person.mainController.transform.SetPositionAndRotation(position, rotation); }); UIDynamicButton savePoseButton = CreateButton("Save Pose"); savePoseButton.transform.localPosition = new Vector3(-360, -150, 0); savePoseButton.button.onClick.AddListener(() => { if (person == null) { return; } person.SavePresetDialog(true, false); }); #endregion #endregion timeSlider.slider.onValueChanged.AddListener((value) => { }); UIDynamicToggle snapToggle = ui.CreateToggle("Snap To Keyframe", 340, 60); snapToggle.transform.localPosition = new Vector3(-270, -30); EventTrigger timeSliderET = timeSlider.slider.gameObject.AddComponent <EventTrigger>(); EventTrigger.Entry entry = new EventTrigger.Entry(); entry.eventID = EventTriggerType.Drag; entry.callback.AddListener((data) => { if (keyframes.Count == 0) { return; } if (snapToggle.toggle.isOn) { Keyframe nearestToTime = null; keyframes.ForEach((key) => { float timeDelta = Mathf.Abs(key.step.timeStep - time.val); if (timeDelta <= 0.01f && nearestToTime == null) { nearestToTime = key; } }); if (nearestToTime != null) { SuperController.singleton.SelectController(nearestToTime.step.containingAtom.mainController); } else { SuperController.singleton.ClearSelection(); ClearEditingKey(); } } else { ClearEditingKey(); } }); timeSliderET.triggers.Add(entry); Transform thickTimelineTransform = new GameObject().transform; thickTimelineTransform.SetParent(animationPattern.containingAtom.mainController.transform, false); thickTimeline = thickTimelineTransform.gameObject.AddComponent <LineRenderer>(); thickTimeline.positionCount = 0; thickTimeline.startWidth = 0.02f; thickTimeline.endWidth = 0.02f; thickTimeline.material = animationPattern.rootLineDrawerMaterial; thickTimeline.material.color = new Color(0.15f, 0.66f, 0.0f); thickTimeline.useWorldSpace = false; thickTimeline.numCornerVertices = 6; thickTimeline.alignment = LineAlignment.View; updateKeyframeLoop = StartCoroutine(UpdateEditingKeyframeLoop()); lookAtCamera = new JSONStorableBool("UILookAtCamera", true, (bool on) => { ui.lookAtCamera = on; keyUI.lookAtCamera = on; }); RegisterBool(lookAtCamera); CreateToggle(lookAtCamera); person.freeControllers.ToList().ForEach((fc) => { JSONStorableBool animateControl = new JSONStorableBool(fc.name, true); RegisterBool(animateControl); CreateToggle(animateControl, true); }); CreateButton("Reverse Animation").button.onClick.AddListener(() => { List <AnimationStep> reversedSteps = animationPattern.steps.ToList(); reversedSteps.Reverse(); animationPattern.steps = reversedSteps.ToArray(); animationPattern.RecalculateTimeSteps(); keyframes.Reverse(); }); maxKeyframesPerRow = new JSONStorableFloat("max keyframes per row", 6, (float value) => { }, 2, 20, true); CreateSlider(maxKeyframesPerRow); RegisterFloat(maxKeyframesPerRow); } catch (Exception e) { SuperController.LogError("Exception caught: " + e); } }
void ClearEditingKey() { editingKeyframe = null; keyUI.canvas.gameObject.SetActive(false); }
void OnKeyframeDeselected(Keyframe keyframe) { }