using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace RimWorldAnimationStudio { public class KeyframeSlider : Slider, IPointerClickHandler, IBeginDragHandler, IEndDragHandler { public AnimationTimeline timeline; public Transform ghostSliders; public Slider ghostSliderPrefab; public int maxGhosts = 4; public int actorID; public int keyframeID; private PawnAnimationClip clip; private PawnKeyframe keyframe; public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID) { this.timeline = timeline; this.clip = Workspace.Instance.GetPawnAnimationClip(actorID); this.keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID); this.actorID = actorID; this.keyframeID = keyframeID; PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID); maxValue = Workspace.StageWindowSize; value = keyframe.atTick.Value; OnValueChanged(); onValueChanged.AddListener(delegate (float value) { OnValueChanged(); }); } public void OnValueChanged() { keyframe.atTick = (int)value; UpdateGhostFrames(); clip.BuildSimpleCurves(); AnimationController.Instance.stageTick = keyframe.atTick.Value; } // Ghost sliders are non-interactable slider handle public void UpdateGhostFrames() { if (maxGhosts == 0) { return; } int nGhosts = GetGhostFramesRequired(); for (int i = 0; i < Mathf.Max(nGhosts, ghostSliders.childCount); i++) { if ((i - 1) * clip.duration + keyframe.atTick <= Workspace.StageWindowSize) { if (ghostSliders.childCount <= i) { Instantiate(ghostSliderPrefab, ghostSliders); } GameObject ghostSliderObject = ghostSliders.GetChild(i).gameObject; Debug.Log(ghostSliderObject); ghostSliderObject.SetActive(true); Slider ghostSlider = ghostSliderObject.GetComponent(); Debug.Log(ghostSlider); ghostSlider.value = (int)((i + 1) * clip.duration + keyframe.atTick); float mult = 1f - Mathf.Pow((float)i / maxGhosts, 2); ghostSlider.transform.FindDeepChild("Handle").GetComponent().color = new Color(0, 0.5f, 0.5f, 0.5f * mult); } if (i >= nGhosts) { transform.GetChild(i).gameObject.SetActive(false); } } } public int GetGhostFramesRequired() { if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false) { return 0; } if (clip.duration <= 1) { return 0; } return Math.Min(Mathf.CeilToInt((float)Workspace.StageWindowSize / clip.duration), maxGhosts); } public void OnPointerClick(PointerEventData eventData) { Activate(); } public void OnBeginDrag(PointerEventData eventData) { Activate(); if (keyframe.atTick == 1) { return; } interactable = true; } public override void OnDrag(PointerEventData eventData) { base.OnDrag(eventData); Activate(); } public void OnEndDrag(PointerEventData eventData) { interactable = false; } public void Activate() { AnimationController.Instance.stageTick = keyframe.atTick.Value; Workspace.keyframeID = keyframeID; foreach (AnimationTimeline _timeline in AnimationController.Instance.animationTimelines.GetComponentsInChildren()) { foreach (KeyframeSlider keyframeSlider in _timeline.GetComponentsInChildren()) { if (keyframeSlider.keyframe.atTick.Value == keyframe.atTick.Value) { keyframeSlider.transform.FindDeepChild("Handle").GetComponent().color = new Color(0f, 1f, 0f); } else { keyframeSlider.transform.FindDeepChild("Handle").GetComponent().color = new Color(1f, 1f, 1f); } } } } } }