首页 > 解决方案 > 滑块移动不顺畅。(Unity3d)

问题描述

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

这是代码:

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#unity3dsliderunity-ui

解决方案


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

但是,设置值时需要避免回调。在更新值时创建一个空事件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);
    }

}

推荐阅读