滑块代码,不能用作洗涤器,向下时不会移动?

Slider code, doesn't work as scrubber, won't move when down?

擦洗滑块坏了,它可以识别点击,但不会移动。我有可交互的启用。

我必须重新导入所有资产才能让它再次工作,但即使是现在也不确定它会修复它。

大约一周前这段代码运行良好,此后我几乎没有对其进行任何更改。

其中的很多内容都有注释,因此我可以了解代码的不同部分。如有不便,请随时删除。

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

public class NewAnimController : MonoBehaviour {


public Slider scrubSlider;    //This is the slider that controls the current position of the animation. Values have to be 0 to 1 for normalized time of the animation, called later in the script
public Slider speedSlider;       //This is the slider that controls the playback speed of the animation
public Animator animator;        //Animator that is attached to the model that we are looking to control the animation of
public float playbackSpeedAdjustment = 0.5f;  //This is a variable that can be easily adjusted to change the total playback speed of the animation. If it's too fast make smaller and vice versa
public Text currentDateText;
public int monthsInProject;

private float rememberTheSpeedBecauseWeMightNeedIt;  //Float needed to keep the speed of the animation between pausing and playing

public void Update()
{
    float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;   //float a new value animationTime that is equal to the animators animation state then converted to normalized time
    //Debug.Log("animationTime (normalized) is " + animationTime);   //logging the normalized time to be able to store it for the scrubbing slider. Doesn't need to be logged for this to work, good to log it to make sure that it's working
    scrubSlider.value = animationTime;  //making the slider value equal to the now logged normalized time of the animation state

}


public void ScrubSliderChanged(float ScrubSliderchangedValue)  // this value has to be floated so that the scrubbing slider can be attached to in the inspector to be able to change the current frame of the animation
{
    animator.Play("Take 001", -1, scrubSlider.normalizedValue);

}


public void SpeedSliderChanged(float SpeedSliderchangedValue)  //value is floated to be able to change the speed of the animation playback
{
    animator.speed = speedSlider.normalizedValue * playbackSpeedAdjustment;  // here the speed is multiplied by the adjustment value set in the editor just in case the playback speed needs to be changed outside of normalized values
}


public void UserClickedPauseButton()
{
    if (animator.speed > 0f)
    {
        // we need to pause animator.speed
        rememberTheSpeedBecauseWeMightNeedIt = animator.speed;
        animator.speed = 0f;
    }
    else
    {
        // we need to "unpause"
        animator.speed = rememberTheSpeedBecauseWeMightNeedIt;
    }
}

public void UserClickedBackButton()
{
    scrubSlider.value = scrubSlider.value - (1f / monthsInProject);
}

public void UserClickedForwardButton()
{
    scrubSlider.value = scrubSlider.value + (1f / monthsInProject);
}

public void UserClickedStartButton()
{
    scrubSlider.value = 0;
}

public void UserClickedEndButton()
{
    scrubSlider.value = 1;
}
}

非常感谢您的帮助。

我很确定是这个问题。在 Update 你正在做这样的事情:

scrubSlider.value = animationTime

这意味着每一帧,"NO MATTER WHAT",您都在将滑块位置设置到动画所在的位置。如果用户试图移动滑块 - 你正在向后移动它,同一帧!

解决这个问题并不容易。 Unity 没有为此包含一个简单的内置函数。您需要一个单独的脚本,该脚本位于滑块上,用于确定手柄是否被按住。您必须使用 OnPointerDownOnPointerUp 处理程序。

如何在现代 Unity 中使用指针处理程序:

第一步,制作这个名为Teste.cs

的小脚本
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;

public class Teste:MonoBehaviour, IPointerDownHandler, IPointerUpHandler
    {
    public Slider theSlider;
    public bool sliderIsBeingHeldDown;

    public void OnPointerDown(PointerEventData data)
        {
        sliderIsBeingHeldDown = true;
        Debug.Log("holding down!");
        }
    public void OnPointerUp(PointerEventData data)
        {
        sliderIsBeingHeldDown = false;
        Debug.Log("holding up!");
        }
    }

不要忘记声明...

Teste:MonoBehaviour, IPointerDownHandler, IPointerUpHandler

而不是通常的 MonoBehavior.

将该脚本拖到您的UI.Slider

请注意,通常这些仅在 "on" 有问题的情况下才有效。

运行,并尝试在滑块按钮上单击上下 - 检查控制台。它工作正常吗?现在你必须在 NewAnimController

中使用那个变量

(1) 添加一个public变量到NewAnimController,

public Teste teste;

(2) 务必在 Inspector 中拖动以连接该变量

(3) 现在您可以参考 teste.sliderIsBeingHeldDown 查看该滑块是否被按住。所以不是每帧都这样做...

scrubSlider.value = animationTime;

你必须每一帧都这样做...

if (teste.sliderIsBeingHeldDown)
  Debug.Log("don't try to work against the user!");
else
  scrubSlider.value = animationTime;

希望有用!我认为这是了解滑块何时被按下的最简单方法。

你的第一个项目真的选了一个高难度的项目!见鬼!

值得注意的是,您还可以放置滑块调整代码(我的意思是说您的洗涤器的实际代码)"inside" 实际位于滑块上的脚本 -- 但我不会暂时担心这个。你的解决方案很好。

注意 根据您的实现方式,您可能需要在按住滑块手柄时更优雅地暂停,但在移动滑块手柄之前。为实现这一点,一种方法是安排调用 UserClickedPauseButton() 或类似的概念,此时调用 "Teste" 中显示的 Down/Up 例程。相反,您可以不理会 ScrubSliderChanged,而是在句柄为 "down".

时运行的代码中完成整个工作

(一般来说,您几乎肯定会在此处使用 UnityEvent 来为像这样的滑块制作可靠的可重复使用解决方案,以便与洗涤器之类的东西一起使用。)