public ExpressionAnimationUI(ExpressionBank script, string name, ExpressionAnimation animation, Action onRemove = null) { this.script = script; this.animation = animation; testButton = script.CreateButton("Play " + name); testButton.button.onClick.AddListener(() => { script.PlayExpression(animation); }); this.onRemove = onRemove; removeButton = script.CreateButton("Remove " + name, true); removeButton.button.onClick.AddListener(Remove); }
public void PlayExpression(ExpressionAnimation animation) { ExpressionAnimation lastAnimation = currentAnimation; currentAnimation = animation; currentAnimation.Start(); if (animation.nac != null) { headAudioSource.PlayNow(animation.nac); } if (lastAnimation != null && currentAnimation != null && lastAnimation != currentAnimation) { transitionAnimation = new ExpressionAnimation(morphControl, lastAnimation, currentAnimation); transitionAnimation.StartFadeOut(); } }
void Start() { // this allows other atoms to target expressionChooser = new JSONStorableStringChooser("expression", new List <string>(), "", "expression", (string choice) => { ExpressionAnimation animation = animationLookup[choice]; PlayExpression(animation); }); RegisterStringChooser(expressionChooser); // load storables as animations storeList.storables.ForEach((storable) => { if (storable.val != storable.defaultVal) { CreateUIFromExpressionPath(storable.val, storable); } }); }
public ExpressionAnimation(GenerateDAZMorphsControlUI morphControl, ExpressionAnimation stopping, ExpressionAnimation starting) { this.morphControl = morphControl; ExpressionKeyframe stoppingFrame = stopping.keyframes[0]; ExpressionKeyframe startingFrame = starting.keyframes[0]; List <string> stoppingMorphs = stoppingFrame.morphValues.Keys.ToList(); List <string> startingMorphs = startingFrame.morphValues.Keys.ToList(); List <string> notInStarting = stoppingMorphs.Where((stoppingName) => { return(startingMorphs.Contains(stoppingName) == false); }).ToList(); ExpressionKeyframe startFrame = new ExpressionKeyframe() { time = 0 }; ExpressionKeyframe endFrame = new ExpressionKeyframe() { time = 1 }; notInStarting.ForEach((morphName) => { DAZMorph morph = morphControl.GetMorphByDisplayName(morphName); startFrame.morphValues[morphName] = morph.appliedValue; endFrame.morphValues[morphName] = morph.startValue; }); keyframes.Add(startFrame); keyframes.Add(endFrame); duration = TRANSITION_ANIMATION_DURATION; }
public override void Init() { try { lastLoadPath = PATH_WHEN_LOADED = SuperController.singleton.currentLoadDir; sc = SuperController.singleton; DAZCharacterSelector dcs = containingAtom.GetStorableByID("geometry") as DAZCharacterSelector; morphControl = dcs.morphsControlUI; // Fix tongue morph... morphControl.GetMorphByDisplayName("Tongue In-Out").startValue = 0.0f; headAudioSource = containingAtom.GetStorableByID("HeadAudioSource") as AudioSourceControl; JSONStorableAction playRandomAction = new JSONStorableAction("Play Random Expression", () => { if (currentAnimation != null) { currentAnimation.Stop(); } if (animationLookup.Count == 0) { return; } ExpressionAnimation selectedAnimation = currentAnimation; do { int randomIndex = UnityEngine.Random.Range(0, animationLookup.Count); string key = animationLookup.Keys.ToList()[randomIndex]; selectedAnimation = animationLookup[key]; if (animationLookup.Count <= 1) { break; } }while (currentAnimation == selectedAnimation); PlayExpression(selectedAnimation); }); RegisterAction(playRandomAction); JSONStorableAction playRandomWhenReadyAction = new JSONStorableAction("Play Random Expression When Ready", () => { if (currentAnimation != null) { return; } if (animationLookup.Count == 0) { return; } ExpressionAnimation selectedAnimation = currentAnimation; do { int randomIndex = UnityEngine.Random.Range(0, animationLookup.Count); string key = animationLookup.Keys.ToList()[randomIndex]; selectedAnimation = animationLookup[key]; if (animationLookup.Count <= 1) { break; } }while (currentAnimation == selectedAnimation); PlayExpression(selectedAnimation); }); RegisterAction(playRandomWhenReadyAction); CreateButton("Load Expression").button.onClick.AddListener(() => { sc.fileBrowserUI.defaultPath = PATH_WHEN_LOADED; sc.fileBrowserUI.SetTextEntry(false); sc.fileBrowserUI.Show((path) => { if (string.IsNullOrEmpty(path)) { return; } JSONStorableString store = storeList.GetNext(); if (store == null) { return; } CreateUIFromExpressionPath(path, store); lastLoadPath = path; }); }); CreateButton("Load Expression (Folder)").button.onClick.AddListener(() => { sc.GetDirectoryPathDialog((path) => { if (string.IsNullOrEmpty(path)) { return; } sc.GetFilesAtPath(path).ToList().ForEach((filePath) => { if (filePath.ToLower().Contains(".json") == false) { return; } JSONStorableString store = storeList.GetNext(); if (store == null) { return; } Debug.Log("loading " + filePath); CreateUIFromExpressionPath(filePath, store); }); lastLoadPath = path; }, lastLoadPath); }); CreateButton("Secret Button", true); CreateButton("Clear All", true).button.onClick.AddListener(() => { uiList.GetRange(0, uiList.Count).ForEach((ui) => { ui.Remove(); }); }); CreateSpacer(false).height = 50; CreateSpacer(true).height = 50; // do this last so it shows up at the bottom... storeList = new StorableStringList(this, "expression_"); } catch (Exception e) { SuperController.LogError("Exception caught: " + e); } }
public override void Init() { try { PATH_WHEN_LOADED = SuperController.singleton.currentLoadDir; SuperController sc = SuperController.singleton; CreateButton("New").button.onClick.AddListener(() => { audioChoice.SetVal(""); RemoveAllSteps(); RemoveAllSelectors(); CreateStep(0); CreateStep(1); playback.SetVal(0); totalDuration.SetVal(totalDuration.defaultVal); }); CreateButton("Save").button.onClick.AddListener(() => { if (steps.Count <= 0) { return; } List <ExpressionKeyframe> keyframes = steps.Select((step) => step.ToKeyFrame()).ToList(); string audioUID = ""; if (currentClip != null) { audioUID = currentClip.uid; } ExpressionAnimation animation = new ExpressionAnimation() { audio = audioUID, duration = totalDuration.val, keyframes = keyframes }; JSONNode json = animation.GetJSON(); //Debug.Log(json.ToString()); //sc.activeUI = SuperController.ActiveUI.None; sc.fileBrowserUI.defaultPath = PATH_WHEN_LOADED; sc.fileBrowserUI.SetTextEntry(true); sc.fileBrowserUI.Show((path) => { // cancel or invalid if (string.IsNullOrEmpty(path)) { return; } // ensure extension if (!path.EndsWith(".json")) { path += ".json"; } sc.SaveStringIntoFile(path, json.ToString("")); SuperController.LogMessage("Wrote expression file: " + path); }); // set default filename if (sc.fileBrowserUI.fileEntryField != null) { sc.fileBrowserUI.fileEntryField.text = currentClip.uid + ".json"; sc.fileBrowserUI.ActivateFileNameField(); } }); CreateSpacer().height = 12; CreateButton("Load", true).button.onClick.AddListener(() => { sc.fileBrowserUI.defaultPath = PATH_WHEN_LOADED; sc.fileBrowserUI.SetTextEntry(false); sc.fileBrowserUI.Show((path) => { if (string.IsNullOrEmpty(path)) { return; } string jsonString = sc.ReadFileIntoString(path); /* * Example: * * { * "audio" : "holding it 1.mp3", * "keyframes" : [ * { * "time" : "0", * "Brow Down" : "0" * }, * { * "time" : "1", * "Brow Down" : "1" * } * ] * } * */ JSONClass jsc = JSON.Parse(jsonString).AsObject; string clipId = jsc["audio"].Value; // validate this audio clip exists NamedAudioClip nac = URLAudioClipManager.singleton.GetClip(clipId); if (nac == null) { //SuperController.LogError("Clip " + clipId + " is not loaded to scene. Add it first."); //return; } audioChoice.SetVal(jsc["audio"].Value); totalDuration.SetVal(jsc["duration"].AsFloat); RemoveAllSteps(); RemoveAllSelectors(); JSONArray keyframes = jsc["keyframes"].AsArray; HashSet <DAZMorph> morphSet = new HashSet <DAZMorph>(); GenerateDAZMorphsControlUI morphControl = GetMorphControl(); for (int i = 0; i < keyframes.Count; i++) { JSONClass keyframe = keyframes[i].AsObject; float time = keyframe["time"].AsFloat; ExpressionStep step = CreateStep(time); keyframe.Keys.ToList().ForEach((key => { if (key == "time") { return; } string morphName = key; DAZMorph morph = morphControl.GetMorphByDisplayName(morphName); if (morph == null) { SuperController.LogError("Expression has a morph not imported: " + morphName); return; } if (morphSet.Contains(morph) == false) { morphSet.Add(morph); MorphSelectUI selector = CreateMorphSelector(); selector.morphString.SetVal(morphName); selector.SetCollapse(morphsCollapsed); } float value = keyframe[morphName].AsFloat; step.morphKeyframe[morph] = value; })); } playback.SetVal(0); }); }); CreateSpacer(true).height = 12; totalDuration = new JSONStorableFloat("duration", 2.0f, (float newDuration) => { }, 0.0f, 10.0f, false); UIDynamicSlider slider = CreateSlider(totalDuration); slider.label = "Duration (based on audio clip if selected)"; audioChoice = new JSONStorableStringChooser("clip", GetAudioClipIds(), "", "Audio Clip", (string clipId) => { NamedAudioClip nac = URLAudioClipManager.singleton.GetClip(clipId); if (nac == null) { currentClip = null; return; } currentClip = nac; PlayAudioClipAtT(nac, 0); totalDuration.SetVal(nac.sourceClip.length); }); //RegisterStringChooser(audioChoice); UIDynamicPopup popup = CreateScrollablePopup(audioChoice); popup.popup.onOpenPopupHandlers += () => { audioChoice.choices = GetAudioClipIds(); }; playback = new JSONStorableFloat("time", 0, (float t) => { if (isTesting == false) { if (currentClip != null) { SampleAudioClipAtT(currentClip, t); } SetMorphAtT(t); } createKeyButton.label = "Key At " + t; CancelDeleteConfirmation(); }, 0, 1, true, true); UIDynamicSlider playbackSlider = CreateSlider(playback); playbackSlider.quickButtonsEnabled = false; playbackSlider.rangeAdjustEnabled = false; playbackSlider.defaultButtonEnabled = false; CreateButton("Test").button.onClick.AddListener(() => { if (isTesting == true) { isTesting = false; return; } isTesting = true; testStartTime = Time.time; if (currentClip != null) { PlayAudioClipAtT(currentClip, 0); } CancelDeleteConfirmation(); }); createKeyButton = CreateButton("Key At 0"); createKeyButton.button.onClick.AddListener(() => { CreateStep(playback.val); }); CreateSpacer(); UIDynamicButton addMorphButton = CreateButton("Add Morph", true); addMorphButton.button.onClick.AddListener(() => { CreateMorphSelector(); }); UIDynamicButton minimizeViewButton = CreateButton("Minimize Morph Controls", true); minimizeViewButton.button.onClick.AddListener(() => { morphsCollapsed = !morphsCollapsed; morphSelectors.ForEach((selector) => { selector.SetCollapse(morphsCollapsed); }); CancelDeleteConfirmation(); minimizeViewButton.label = morphsCollapsed ? "Maximize Morph Controls" : "Minimize Morph Controls"; }); deleteButton = CreateButton("Delete Selected", false); deleteButton.button.onClick.AddListener(() => { if (selectedStep == null) { return; } if (deleteConfirmation == false) { BeginDeleteConfirmation(); return; } else { RemoveStep(selectedStep); CancelDeleteConfirmation(); } }); CreateStep(0); CreateStep(1); playback.SetVal(0); } catch (Exception e) { SuperController.LogError("Exception caught: " + e); } }