Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ARFoundation Button在Unity上有哪些属性使其能够执行连续任务(与onClick不同)_C#_Unity3d_Augmented Reality - Fatal编程技术网

C# ARFoundation Button在Unity上有哪些属性使其能够执行连续任务(与onClick不同)

C# ARFoundation Button在Unity上有哪些属性使其能够执行连续任务(与onClick不同),c#,unity3d,augmented-reality,C#,Unity3d,Augmented Reality,我正在寻找一个属性,该属性允许UI触摸按钮执行连续任务,而不像onClick,当按下按钮时,onClick会触发一次操作。因为我试图制作一个按钮来移动对象,所以我需要像onPress这样的东西,但是这个属性没有定义 如果我正确理解了提供的答案,您应该编写两个脚本,一个用于ContinuousButton类,另一个用于所需操作。下面是我的实现,如下所示: using System.Collections; using System.Collections.Generic; using UnityE

我正在寻找一个属性,该属性允许UI触摸按钮执行连续任务,而不像onClick,当按下按钮时,onClick会触发一次操作。因为我试图制作一个按钮来移动对象,所以我需要像onPress这样的东西,但是这个属性没有定义

如果我正确理解了提供的答案,您应该编写两个脚本,一个用于ContinuousButton类,另一个用于所需操作。下面是我的实现,如下所示:

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

[RequireComponent(typeof(Button))]
public class ContinuousButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    [SerializeField] private Button _button;
    // This will be called every frame while the button stays pressed
    public UnityEvent whilePressed;

    private Coroutine routine;

    private void Awake()
    {
        if (!_button) _button = GetComponent<Button>();
    }

    public void OnPointerDown(PointerEventData pointerEventData)
    {
        if (!_button.interactable) return;

        routine = StartCoroutine(WhilePressedRoutine());
    }

    public void OnPinterUp(PointerEventData pointerEventData)
    {
        if (routine != null) StopCoroutine(routine);
        routine = null;
    }

    public void OnPinterExit(PointerEventData pointerEventData)
    {
        if (routine != null) StopCoroutine(routine);
        routine = null;
    }

    private IEnumerator WhilePressedRoutine()
    {
        while (true)
        {
            whilePressed.Invoke();

            yield return null;
        }
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        ((IPointerUpHandler)_button).OnPointerUp(eventData);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        ((IPointerExitHandler)_button).OnPointerExit(eventData);
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.Events;
使用UnityEngine.EventSystems;
使用UnityEngine.UI;
[要求组件(按钮类型))]
公共类ContinuousButton:MonoBehavior、IPInterDownHandler、IPInterUpHandler、IPInterexiThandler
{
[序列化字段]专用按钮\u按钮;
//当按钮保持按下时,每帧调用一次
受压迫的公共单位事件;
私人协同程序;
私人空间
{
如果(!\u按钮)\u按钮=GetComponent();
}
POINTERDOWN上的公共无效(PointerEventData PointerEventData)
{
如果(!\u按钮。可交互)返回;
例程=开始例程(whilepressedrootine());
}
PinterUp上的公共无效(PointerEventData PointerEventData)
{
如果(例程!=null)StopCorroutine(例程);
例程=空;
}
PinterExit上的公共无效(PointerEventData PointerEventData)
{
如果(例程!=null)StopCorroutine(例程);
例程=空;
}
私有IEnumerator whilepressedrootine()
{
while(true)
{
whilePressed.Invoke();
收益返回空;
}
}
POINTERUP上的公共无效(PointerEventData事件数据)
{
((IPInterupHandler)u按钮).OnPointerUp(eventData);
}
公共void OnPointerExit(pointereventdataeventdata)
{
((IPInterexitHandler)u按钮).OnPointerExit(事件数据);
}
}

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


public class ControlButtons : MonoBehaviour
{

    [SerializeField]
    private Button ClockwiseButton;
    [SerializeField]
    private Button ForwardButton;
    [SerializeField]
    private Button ReverseButton;
    [SerializeField]
    private Button AntiClockwiseButton;
    [SerializeField]
    private Button AscendButton;
    [SerializeField]
    private Button DescendButton;

    public GameObject objectToPlace;

    private void Awake()
    {
        ClockwiseButton.onClick.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, 20 * Time.deltaTime));
        //ForwardButton.onClick.AddListener(() => objectToPlace.transform.Translate(Vector3.forward * Time.deltaTime * 10));
        ForwardButton.GetComponent<ContinuousButton>().whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.forward * Time.deltaTime * 10)); //Breaking from this point.
        ReverseButton.onClick.AddListener(() => objectToPlace.transform.Translate(Vector3.back * Time.deltaTime * 10));
        AntiClockwiseButton.onClick.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, -20 * Time.deltaTime));
        AscendButton.onClick.AddListener(() => objectToPlace.transform.Translate(Vector3.up * Time.deltaTime * 10));
        DescendButton.onClick.AddListener(() => objectToPlace.transform.Translate(Vector3.down * Time.deltaTime * 10));
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.UI;
公共类控件按钮:MonoBehavior
{
[序列化字段]
私人按钮时钟按钮;
[序列化字段]
私人按钮转发按钮;
[序列化字段]
私人按钮反转按钮;
[序列化字段]
专用按钮防锁按钮;
[序列化字段]
私人按钮;
[序列化字段]
私人按钮;
公共游戏对象objectToPlace;
私人空间
{
ClockwiseButton.onClick.AddListener(()=>objectToPlace.transform.RotateAround(Vector3.zero,Vector3.up,20*Time.deltaTime));
//ForwardButton.onClick.AddListener(()=>objectToPlace.transform.Translate(Vector3.forward*Time.deltaTime*10));
ForwardButton.GetComponent().whilePressed.AddListener(()=>objectToPlace.transform.Translate(Vector3.forward*Time.deltaTime*10));//从此点中断。
ReverseButton.onClick.AddListener(()=>objectToPlace.transform.Translate(Vector3.back*Time.deltaTime*10));
AntiClockwiseButton.onClick.AddListener(()=>objectToPlace.transform.RotateAround(Vector3.zero,Vector3.up,-20*Time.deltaTime));
AscendButton.onClick.AddListener(()=>objectToPlace.transform.Translate(Vector3.up*Time.deltaTime*10));
DescentButton.onClick.AddListener(()=>objectToPlace.transform.Translate(Vector3.down*Time.deltaTime*10));
}
//在第一帧更新之前调用Start
void Start()
{
}
//每帧调用一次更新
无效更新()
{
}
}
但它也不起作用。这是我制作的一个视频:正如你所看到的,我每次移动都需要按下按钮,当我长按时,飞机不会一直移动。因为我计划上传我在Google Play商店的作品,我很想知道如何引入所需的行为。
好吧。。这样的事情根本不存在;)

但是,您可以通过使用、
ipinteruphandler
和evtl以及
ipinterexithandler
接口轻松实现自己的功能:

[RequireComponent(typeof(Button))]
public class ContinuousButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    [SerializeField] private Button _button;
    // This will be called every frame while the button stays pressed
    public UnityEvent whilePressed;

    private Coroutine routine;

    private void Awake()
    {
        if(!_button) _button = GetComponent<Button>();
    }

    public void OnPointerDown(PointerEventData pointerEventData)
    {
        if(!_button.interactable) return;

        routine = StartCoroutine (WhilePressedRoutine());
    }  
    
    public void OnPointerUp(PointerEventData pointerEventData)
    {
        if(routine != null) StopCoroutine (routine);
        routine = null;
    }

    public void OnPointerExit(PointerEventData pointerEventData)
    {
        if(routine != null) StopCoroutine (routine);
        routine = null;
    }

    private IEnumerator WhilePressedRoutine ()
    {
        while(true)
        {
            whilePressed.Invoke();

            yield return null;
        }
    }
}

更新

由于您现在已将代码添加到问题中:

  • 你有一些打字错误。。我的坏消息是,我的代码中也有它们:它应该始终是
    OnPointerXY
    ,而不是
    OnPinterXY

  • 只保留我原来的那些!无需将调用转发到
    按钮
    组件。只要您不主动地将传递的事件设置为“使用”,每个处理程序都将自己处理它

  • 如前所述,您仍在将侦听器添加到
    onClick
    。。为了连接到新的连续呼叫,它应该看起来像

     public class ControlButtons : MonoBehaviour
     {
         [SerializeField]  private ContinuousButton ClockwiseButton;
         [SerializeField] private ContinuousButton ForwardButton;
         [SerializeField] private ContinuousButton ReverseButton;
         [SerializeField] private ContinuousButton AntiClockwiseButton;
         [SerializeField] private ContinuousButton AscendButton;
         [SerializeField] private ContinuousButton DescendButton;
    
         public GameObject objectToPlace;
    
         private void Awake()
         {
             ClockwiseButton.whilePressed.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, 20 * Time.deltaTime));
             ForwardButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.forward * Time.deltaTime * 10));
             ReverseButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.back * Time.deltaTime * 10));
             AntiClockwiseButton.whilePressed.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, -20 * Time.deltaTime));
             AscendButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.up * Time.deltaTime * 10));
             DescendButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.down * Time.deltaTime * 10));
         }
     }
    

  • 不,我的意思是,就像你用
    onClick
    一样。。通过拖放并在Inspector中选择一个方法,或者通过codeWell使用
    AddListener
    ,然后如前所述简单地将其更改为
    ForwardButton.GetComponent()。whilePressed.AddListener(()=>objectToPlace.transform.Translate(Vector3.forward*Time.deltaTime*10))应该可以it@user13305980不您只能分配回调一次。从其他脚本或通过检查器。。不一样。如前所述,基本上与您使用的方法完全相同。。分配回调一次,然后在每次调用事件时自动调用它;)调用是上面的脚本处理的部分,因此您只需分配回调,并在按钮保持按下的同时观察它在每一帧被调用。Hi I使用您的代码更新了我的答案。“它断裂”到底是什么意思?您是否有任何错误?是的,但通常在这种情况下,“问题行”会抛出错误。。不知道这一点就有点难以帮助;)你好
    
     public class ControlButtons : MonoBehaviour
     {
         [SerializeField]  private ContinuousButton ClockwiseButton;
         [SerializeField] private ContinuousButton ForwardButton;
         [SerializeField] private ContinuousButton ReverseButton;
         [SerializeField] private ContinuousButton AntiClockwiseButton;
         [SerializeField] private ContinuousButton AscendButton;
         [SerializeField] private ContinuousButton DescendButton;
    
         public GameObject objectToPlace;
    
         private void Awake()
         {
             ClockwiseButton.whilePressed.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, 20 * Time.deltaTime));
             ForwardButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.forward * Time.deltaTime * 10));
             ReverseButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.back * Time.deltaTime * 10));
             AntiClockwiseButton.whilePressed.AddListener(() => objectToPlace.transform.RotateAround(Vector3.zero, Vector3.up, -20 * Time.deltaTime));
             AscendButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.up * Time.deltaTime * 10));
             DescendButton.whilePressed.AddListener(() => objectToPlace.transform.Translate(Vector3.down * Time.deltaTime * 10));
         }
     }