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