На самом деле это два вопроса.
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
Чтобы иметь возможность ссылаться на этот метод в Инспекторе, есть несколько опций:
Просто сделайте ваш 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;
}
наоборот (как вы это просили) - позвоните Update
из другого public
метода:
private void Update()
{
rotation = Input.GetAxisRaw("Horizontal");
movement = -Input.GetAxisRaw("Vertical") * speed;
}
public void DoUpdateStuff()
{
Update();
}
Так что все, что осталось, - это ссылка на CarController
Update
или DoUpdateStuff
метод в событии LongPressButton
onLongPress
.
Решение B
В качестве альтернативы вы можете добавить этот обратный вызов непосредственно во время выполненияне ссылаясь ни на что, ни делая метод обратного вызова public
, чтобы вы могли напрямую использовать private void Update
без метода-оболочки.
недостаток : для этого метода у вас как-то естьчтобы получить ссылку на этот LongPressButton
в вашем CarController
скрипте вместо
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);
}
//...
}