【问题标题】:Continuously run code while UI button pressed按下 UI 按钮时连续运行代码
【发布时间】:2019-09-15 04:45:38
【问题描述】:

我正在 Unity 中制作一个平台游戏,其中球通过三个按钮移动:

  • 向右移动
  • 向左移动
  • 跳跃

我已经拥有了现在可以使用的所有功能,但是要移动角色我需要继续发送一个按钮,而不是像我想要的那样按住它。我尝试了一些在教程中找到的方法,但由于我还是个初学者,我没能成功。

这是我的 Move2D 脚本附加到角色的代码:

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

public class Move2D : MonoBehaviour
{
    public float moveSpeed = 5f;
    public bool isGrounded = false;

    [SerializeField] private Rigidbody2D rigidbody;

    private void Awake()
    {
        if (!rigidbody) rigidbody = GetComponent<Rigidbody2D>();
    }

    public void Jump()
    {
        if (isGrounded)
        {
            rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
        }
    }

    public void Move(float value)
    {
        Vector3 movement = new Vector3(value, 0f, 0f);
        transform.position += movement * Time.deltaTime * moveSpeed;
    }
}

而这是第二个脚本,主要控制所有的运动:

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

public class ContinuesButton : MonoBehaviour, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
    [SerializeField] private Button button;

    [SerializeField] private UnityEvent whilePressed;

    private readonly bool isHover;

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

    public void OnPointerDown(PointerEventData eventData)
    {
        StartCoroutine(WhilePressed());
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        StopAllCoroutines();
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        StopAllCoroutines();
    }

    private IEnumerator WhilePressed()
    {
        while (true)
        {
            whilePressed?.Invoke();
            yield return null;
        }
    }
}

非常感谢任何信息或解释,因为这部分对我的游戏非常重要! :)

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    由于您的玩家有一个刚体,您可以通过刚体的速度而不是通过它的变换来移动玩家。
    (这也使它更加一致,因为您的跳转实现使用刚体)

    速度由DirectionSpeed 组成;由于速度是恒定的,您可以让按钮设置移动的方向。
    并且由于您希望玩家按住按钮才能移动,您可以设置移动的方向OnPointerDown,并且当OnPointerUp 发生时重置它,如下所示:

    Move2D.cs

    public class Move2D : MonoBehaviour {
        // ...
    
        [SerializeField]
        private float speed;
    
        private Rigidbody2D rigidBody;
    
        private Vector2 currentMoveDirection;
    
        private void Awake() {
            rigidBody = GetComponent<Rigidbody2D>();
            currentMoveDirection = Vector2.zero;
        }
    
        // ...
    
        private void FixedUpdate() {
            rigidBody.velocity = (currentMoveDirection + new Vector2(0f, rigidBody.velocity.y)).normalized * speed;
        }
    
        public void TriggerMoveLeft() {
            currentMoveDirection += Vector2.left;
        }
    
        public void StopMoveLeft() {
            currentMoveDirection -= Vector2.left;
        }
    
        public void TriggerMoveRight() {
            currentMoveDirection += Vector2.right;
        }
    
        public void StopMoveRight() {
            currentMoveDirection -= Vector2.right;
        }
    }
    

    PlayerMoveButton.cs

    (或你的ContinuesButton.cs

    public class PlayerMoveButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
        [SerializeField]
        private Button targetButton;
    
        [SerializeField, Tooltip("The targeted player's movement component")]
        private Move2D playerMovement;
    
        [SerializeField, Tooltip("True if this button moves the player to the left")]
        private bool movesLeft;
    
        // ...
    
        public void OnPointerDown(PointerEventData eventData) {
            if (movesLeft) {
                playerMovement.TriggerMoveLeft();
            } else {
                playerMovement.TriggerMoveRight();
            }
        }
    
        public void OnPointerUp(PointerEventData eventData) {
            if (movesLeft) {
                playerMovement.StopMoveLeft();
            } else {
                playerMovement.StopMoveRight();
            }
        }
    }
    

    示例:

    现在点击LeftButton (OnPointerDown),currentMoveDirection 设置为Left (-1, 0)
    松开按钮的那一刻(OnPointerUp),currentMoveDirection 重置为正常@ 987654334@

    玩家通过currentMoveDirection * speed设置速度来不断移动

    编辑

    为了保留jump 运动,而不是简单地执行currentMoveDirection * speed,您需要将当前向上的方向添加到它,如下所示:

    private void FixedUpdate() {
        rigidBody.velocity = (currentMoveDirection + new Vector2(0f, rigidBody.velocity.y)).normalized * speed;
    }
    

    【讨论】:

    • 非常感谢!但现在它产生了两个问题。点击跳跃按钮,球不能再跳跃了,而且有一种很奇怪的低重力。我没有改变重力比例(设置为 1),球向下移动非常非常缓慢。我如何解决这两个问题?非常感谢!
    • @EnricoCortinovis 我的错没有考虑跳跃动作;编辑了我的答案,希望它可以工作,因为我目前无法对其进行测试。
    • 我在代码中保留了 jump() 函数,并更改了 FixedUpdate(),但编译器指示我无法添加 vector2D 和浮点数。 (我应该在 Jump() 中修改一些内容还是只在 fixedUpdate 中修改?)非常感谢!
    • @EnricoCortinovis 再次编辑;我试图将当前的向上运动添加到currentMoveDirection,所以它应该是new Vector2(0f, rigidBody.velocity.y)
    • 重力现在恢复正常。有一个新问题:现在,看起来当球因任何原因(跟随平台或跳跃)上升时,它一直在上升,我认为它之后不会停止。我们该如何解决这个问题?
    猜你喜欢
    • 2014-03-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多