【问题标题】:Slider isn't moving smoothly. (Unity3d)滑块移动不顺畅。 (Unity3d)
【发布时间】:2020-09-23 15:59:25
【问题描述】:

我有一个音频剪辑和一个滑块。滑块充当音频剪辑的进度条(时间线)。我可以暂停和播放音频,也可以跳过曲目。一切正常。问题是滑块移动不顺畅,有点紧张。如果有人可以,请编辑它。提前致谢。

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MusicPlayer : MonoBehaviour
{
    AudioSource audioSource;
    Slider slider;
    public AudioClip track;

    // Start is called before the first frame update
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        slider = GetComponent<Slider>();

        audioSource.clip = track;
        audioSource.Play();

        slider.minValue = 0;
        slider.maxValue = track.length;
    }

    // Update is called once per frame
    void Update()
    {
        slider.value = audioSource.time;
        
    } 

    public void MovePoition()
    {
        audioSource.time = slider.value;
    }

    public void play()
    {
        audioSource.Play();
    }

    public void pause()
    {
        audioSource.Pause();
    }

}

【问题讨论】:

    标签: c# unity3d slider unity-ui


    【解决方案1】:

    Update 上,如果正在播放,请使用Time.deltaTime 更新滑块的值来确保平滑度。否则,同样在playpause 中,将位置与播放时间重新同步。

    但是,设置值时需要避免回调。在Start 创建一个空事件,并在更新值时将其分配给滑块。

    最后,添加一个标志来跟踪是否应该播放曲目。这可以防止源在播放剪辑结尾然后拖动滑块时停止。

    MovePoition 中设置源时间后,根据剪辑的压缩,它可能无法设置为滑块的确切值。因此,您应该使用音频源决定使用的时间重新更新滑块值。

    总共:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class MusicPlayer : MonoBehaviour
    {
        AudioSource audioSource;
        Slider slider;
        Slider.SliderEvent emptyEvent;
        public AudioClip track;
        private bool isPaused;
        private bool needSync;
    
        // Start is called before the first frame update
        void Start()
        {
            audioSource = GetComponent<AudioSource>();
            slider = GetComponent<Slider>();
    
            audioSource.clip = track;
            audioSource.Play();
    
            slider.minValue = 0;
            slider.maxValue = track.length;
    
            emptyEvent = new Slider.SliderEvent();
        }
    
        void SetSliderWithoutCallback(float time) 
        {
            Slider.SliderEvent temp = slider.onValueChanged;
            slider.onValueChanged = emptyEvent;
            slider.value = time;
            slider.onValueChanged = temp;
        }
    
        // Update is called once per frame
        void Update()
        {
            if (audioSource.isPlaying) 
            {
                float newTime = Mathf.Min(slider.value + Time.deltaTime, slider.maxValue);
                SetSliderWithoutCallback(newTime);
            } 
            else if (!isPaused)
            {
                SetSliderWithoutCallback(slider.maxValue);
                isPaused = true;
            }
        } 
    
        public void MovePoition()
        {
            audioSource.time = slider.value;
            if (!isPaused) 
            {
                audioSource.Play();
                SetSliderWithoutCallback(audioSource.time);
            }
        }
    
        public void play()
        {
            audioSource.Play();
            isPaused = false;
            SetSliderWithoutCallback(audioSource.time);
        }
    
        public void pause()
        {
            isPaused = true;
            audioSource.Pause();
            SetSliderWithoutCallback(audioSource.time);
        }
    
    }
    

    【讨论】:

    • 现在仍然很紧张,而且进展很快。现在音频也不清楚。
    • @MirzaZeeshan 我更改了Updateplaypause。看看这是否适合你。
    • 我收到此错误。 Assets\Scripts\MusicPlayer.cs(31,20): error CS0122: 'Slider.Set(float, bool)' 由于其保护级别而无法访问
    • @MirzaZeeshan 又一个更新。我在我的系统上对此进行了测试,它似乎工作得很好。
    • 滑块移动平稳,但是当您使用滑块播放几次时,我的意思是在运行时如果您向后播放音乐 2 或 3 次,那么它不会完全播放音频剪辑,它会丢失剪辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2016-06-21
    • 2015-06-21
    相关资源
    最近更新 更多