这实际上是两个问题。
1。长按按钮
Unity UI.Button 本身没有长按的方法,但您可以使用IPointerXHandler 接口自行实现:
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
// RequireComponent makes sure there is Button on the GameObject
[RequireComponent(typeof(Button))]
public class LongPressButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
private void Awake()
{
ResetButton();
}
// set the long press duration in the editor (in seconds)
public float LongPressDuration = 0.5f;
// Here you reference method just like in onClick
public UnityEvent onLongPress;
private float _timer;
private bool _isPressed;
private bool _pressInvoked;
private void Update()
{
// prevent multiple calls if button stays pressed
if (_pressInvoked) return;
// if button is not pressed do nothing
if (!_isPressed) return;
// reduce the timer by the time passed since last frame
_timer -= Time.deltaTime;
// if timeout not reached do nothing
if (!(_timer <= 0)) return;
// Invoke the onLongPress event -> call all referenced callback methods
onLongPress.Invoke();
_pressInvoked = true;
}
// reset all flags and timer
private void ResetButton()
{
_isPressed = false;
_timer = LongPressDuration;
_pressInvoked = false;
}
/* IPointer Callbacks */
// enable the timer
public void OnPointerDown(PointerEventData eventData)
{
_isPressed = true;
}
// reset if button is released before timeout
public void OnPointerUp(PointerEventData eventData)
{
ResetButton()
}
// reset if cursor leaves button before timeout
public void OnPointerExit(PointerEventData eventData)
{
ResetButton();
}
}
这个脚本必须放在Button 组件旁边。
您没有引用Button 中的回调方法
onClick 而是在这个LongPressButton 的onLongPress 中
别忘了在检查器中调整LongPressDuration。
例子
2。致电CarController 的Update
我不知道你为什么想要这个(我猜你禁用了该组件但还是想调用Update)
解决方案 A
为了能够在 Inspector 中引用该方法,有几个选项:
-
只需让你的Update方法public
public void Update()
{
rotation = Input.GetAxisRaw("Horizontal");
movement = -Input.GetAxisRaw("Vertical") * speed;
}
-
将Update 的内容包装在另一个public 方法中,并改用那个方法:
private void Update()
{
DoUpdateStuff();
}
public void DoUpdateStuff()
{
rotation = Input.GetAxisRaw("Horizontal");
movement = -Input.GetAxisRaw("Vertical") * speed;
}
-
反过来(您如何请求)- 从另一个 public 方法调用 Update:
private void Update()
{
rotation = Input.GetAxisRaw("Horizontal");
movement = -Input.GetAxisRaw("Vertical") * speed;
}
public void DoUpdateStuff()
{
Update();
}
所以剩下的就是在LongPressButton 的onLongPress 事件中引用CarController 的Update 或DoUpdateStuff 方法。
解决方案 B
或者,您可以直接在运行时添加该回调,无需引用任何内容,也无需创建回调方法 public,因此您可以直接使用 private void Update 而无需包装方法。
缺点:对于这种方法,您必须以某种方式在您的 CarController 脚本中获取对 LongPressButton 的引用
public class CarController : MonoBehaviour
{
// Somehow get the reference for this either by referencing it or finding it on runtime etc
// I will asume this is already set
public LongPressButton longPressButton;
private void Awake()
{
// make sure listener is only added once
longPressButton.onLongPress.RemoveListener(Update);
longPressButton.onLongPress.AddListener(Update);
}
private void Update()
{
rotation = Input.GetAxisRaw("Horizontal");
movement = -Input.GetAxisRaw("Vertical") * speed;
}
private void OnDestroy()
{
// clean up the listener
longPressButton.onLongPress.RemoveListener(Update);
}
//...
}