Esempio n. 1
0
        /// <summary>
        /// Draw the UI controls for animation playback, e.g.
        /// the drop-down menu for selecting the active
        /// animation clip. These UI controls are only shown
        /// when the currently glTF model has one or more
        /// animations.
        /// </summary>
        public void AnimationControlsOnGui()
        {
            Animation anim = ModelManager.Instance.Animation;

            var clipKeys  = ModelManager.Instance.AnimationClipKeys;
            var clipNames = ModelManager.Instance.AnimationClipNames;

            var animationControlsAreaHeight = _styles.DropDownButton.CalcSize(
                new GUIContent("Dummy Text")).y;

            var dropdownWidth = ScaleInt(300);

            GUILayout.BeginHorizontal(GUILayout.Height(animationControlsAreaHeight));

            // Get a reference to the currently selected animation clip.
            // We use a value of null to indicate that the special
            // "Static Pose" clip is currently selected.

            AnimationState selectedClip = null;

            if (_dropDownState.selectedIndex != STATIC_POSE_INDEX)
            {
                selectedClip = anim[clipKeys[_dropDownState.selectedIndex]];
            }

            // play/pause button

            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();

            var playButtonRect = GUILayoutUtility.GetRect(
                new GUIContent(""), _styles.PlayButton,
                GUILayout.Width(animationControlsAreaHeight),
                GUILayout.Height(animationControlsAreaHeight));

            if (GUI.Button(playButtonRect, "", _styles.PlayButton) && selectedClip != null)
            {
                selectedClip.speed = selectedClip.speed == 0f ? 1f : 0f;
            }

            var origColor = GUI.color;

            GUI.color = selectedClip != null ? Color.black : Color.gray;

            float playIconMargin = ScaleInt(10);

            var playIconRect = new Rect(
                playButtonRect.x + playIconMargin,
                playButtonRect.y + playIconMargin,
                playButtonRect.width - 2 * playIconMargin,
                playButtonRect.width - 2 * playIconMargin);

            GUI.DrawTexture(playIconRect,
                            selectedClip != null && selectedClip.speed > 0f ? _pauseIcon : _playIcon,
                            ScaleMode.ScaleToFit);

            GUI.color = origColor;

            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();

            // timeline slider

            GUILayout.FlexibleSpace();

            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();

            var time   = 0f;
            var length = 0f;

            if (selectedClip != null)
            {
                length = selectedClip.length;
                time   = selectedClip.time % length;
            }

            // Workaround: GUI.LayoutSlider does not expand
            // its width to fill the available space, so we must manually
            // calculate the available width here. I'm pretty sure this is a
            // bug, since other GUI elements (e.g. GUILayout.Label)
            // are capable of automatically expanding their width.

            var sliderWidth = Screen.width
                              - _screenMargin.left
                              - animationControlsAreaHeight
                              - _styles.PlayButton.margin.right
                              - _styles.DropDownButton.margin.left
                              - dropdownWidth
                              - _screenMargin.right;

            var prevTime = time;

            time = GUILayout.HorizontalSlider(time, 0f, length,
                                              GUILayout.Width(sliderWidth));

            // if the user clicked on the slider, set the time to
            // the clicked location and pause playback
            if (selectedClip != null && time != prevTime)
            {
                selectedClip.time  = time;
                selectedClip.speed = 0f;
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();

            GUILayout.FlexibleSpace();

            // drop-down menu for selecting animation clip

            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();

            var dropdownRect = GUILayoutUtility.GetRect(
                new GUIContent(""), _styles.DropDownButton,
                GUILayout.Width(dropdownWidth),
                GUILayout.Height(animationControlsAreaHeight));

            var prevSelectedIndex = _dropDownState.selectedIndex;

            _dropDownState = GuiEx.DropDownMenu(
                dropdownRect,
                clipNames,
                _dropDownState,
                _dropDownIcon,
                _styles.DropDownButton,
                _styles.DropDownListBackground,
                _styles.DropDownListForeground,
                _styles.DropDownListItem);

            // if a new animation clip has been selected, stop the
            // current clip and start playing the new one

            if (_dropDownState.selectedIndex != prevSelectedIndex)
            {
                anim.Stop();

                if (selectedClip != null)
                {
                    selectedClip.speed = 1f;
                    selectedClip.time  = 0f;
                }

                // Restore the static pose before we start playing the
                // new animation clip. This is necessary because
                // an animation clip will not necessarily reset
                // all position/rotation/scale values for
                // all game objects in the model. Any unspecified
                // transform values are assumed to come from the
                // default static pose.

                anim.Play(clipKeys[STATIC_POSE_INDEX]);
                anim.Sample();

                // start playing the new clip

                var newClipKey = clipKeys[_dropDownState.selectedIndex];
                var newClip    = anim[newClipKey];

                newClip.time  = 0f;
                newClip.speed = 1f;

                anim.Play(newClipKey);
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();

            GUILayout.EndHorizontal();
        }
Esempio n. 2
0
        /// <summary>
        /// Draw the UI controls for animation playback, e.g.
        /// the drop-down menu for selecting the active
        /// animation clip. These UI controls are only shown
        /// when the currently glTF model has one or more
        /// animations.
        /// </summary>
        public void AnimationControlsOnGui()
        {
            Animation anim = ModelManager.Instance.Animation;

            var clipKeys  = ModelManager.Instance.AnimationClipKeys;
            var clipNames = ModelManager.Instance.AnimationClipNames;

            const float animationControlsAreaHeight = 75;

            // Get a reference to the currently selected animation clip.
            // We use a value of null to indicate that the special
            // "Static Pose" clip is currently selected.

            AnimationState selectedClip = null;

            if (_dropDownState.selectedIndex != STATIC_POSE_INDEX)
            {
                selectedClip = anim[clipKeys[_dropDownState.selectedIndex]];
            }

            // play/pause button

            const float playButtonSize = 50;

            var playButtonRect = new Rect(
                _screenEdgePadding,
                Screen.height - animationControlsAreaHeight
                + (animationControlsAreaHeight - playButtonSize) / 2,
                playButtonSize,
                playButtonSize);

            if (GUI.Button(playButtonRect, "", _styles.PlayButton) && selectedClip != null)
            {
                selectedClip.speed = selectedClip.speed == 0f ? 1f : 0f;
            }

            var origColor = GUI.color;

            GUI.color = selectedClip != null ? Color.black : Color.gray;

            const float playIconMargin = 10;
            var         playIconRect   = new Rect(
                playButtonRect.x + playIconMargin,
                playButtonRect.y + playIconMargin,
                playButtonRect.width - 2 * playIconMargin,
                playButtonRect.width - 2 * playIconMargin);

            GUI.DrawTexture(playIconRect,
                            selectedClip != null && selectedClip.speed > 0f ? _pauseIcon : _playIcon,
                            ScaleMode.ScaleToFit);

            GUI.color = origColor;

            // drop-down menu for selecting animation clip

            const float buttonWidth  = 300;
            var         buttonHeight = _styles.DropDownButton.CalcSize(
                new GUIContent("Dummy Text")).y;

            var buttonRect = new Rect(
                Screen.width - _screenEdgePadding - buttonWidth,
                Screen.height - animationControlsAreaHeight
                + (animationControlsAreaHeight - buttonHeight) / 2,
                buttonWidth, buttonHeight);

            var prevSelectedIndex = _dropDownState.selectedIndex;

            _dropDownState = GuiEx.DropDownMenu(
                buttonRect,
                clipNames,
                _dropDownState,
                _dropDownIcon,
                _styles.DropDownButton,
                _styles.DropDownListBackground,
                _styles.DropDownListForeground,
                _styles.DropDownListItem);

            // if a new animation clip has been selected, stop the
            // current clip and start playing the new one

            if (_dropDownState.selectedIndex != prevSelectedIndex)
            {
                anim.Stop();

                if (selectedClip != null)
                {
                    selectedClip.speed = 1f;
                    selectedClip.time  = 0f;
                }

                // Restore the static pose before we start playing the
                // new animation clip. This is necessary because
                // an animation clip will not necessarily reset
                // all position/rotation/scale values for
                // all game objects in the model. Any unspecified
                // transform values are assumed to come from the
                // default static pose.

                anim.Play(clipKeys[STATIC_POSE_INDEX]);
                anim.Sample();

                // start playing the new clip

                var newClipKey = clipKeys[_dropDownState.selectedIndex];
                var newClip    = anim[newClipKey];

                newClip.time  = 0f;
                newClip.speed = 1f;

                anim.Play(newClipKey);
            }

            // timeline slider

            const float sliderMargin = 20;
            const float sliderHeight = 10;

            var sliderX1 = playButtonRect.x + playButtonRect.width + sliderMargin;
            var sliderX2 = buttonRect.x - sliderMargin;

            var sliderRect = new Rect(
                sliderX1,
                Screen.height - animationControlsAreaHeight
                + (animationControlsAreaHeight - sliderHeight) / 2,
                sliderX2 - sliderX1,
                sliderHeight);

            var time   = 0f;
            var length = 0f;

            if (selectedClip != null)
            {
                length = selectedClip.length;
                time   = selectedClip.time % length;
            }

            var prevTime = time;

            time = GUI.HorizontalSlider(sliderRect, time, 0f, length);

            // if the user clicked on the slider, set the time to
            // the clicked location and pause playback
            if (selectedClip != null && time != prevTime)
            {
                selectedClip.time  = time;
                selectedClip.speed = 0f;
            }
        }