Unity 2D方法未达到Update方法。

huangapple go评论65阅读模式
英文:

Unity 2d method don't reach the Update method

问题

我尝试修改我的代码,以便能够使用UI按钮移动角色,因为我正在制作一个移动游戏。以前,代码看起来很棒并且能够正常工作,但自从我尝试添加在玩家释放按钮时停止的功能后,它不再起作用。没有错误,但角色不想跳跃和移动。我尝试使用ChatGPT解决这个问题,但他没有更多的想法,只是循环相同的代码。
以下是他最后编写的引起问题的代码:

using UnityEngine;
using UnityEngine.UI;

public class CharacterController : MonoBehaviour
{
    // 省略其他变量和方法

    private void Update()
    {
        if (isMovingLeft)
        {
            rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);
            spriteRenderer.flipX = true;
            isRunning = true;
            animator.SetBool("IsRunning", isRunning);
        }
        else if (isMovingRight)
        {
            rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
            spriteRenderer.flipX = false;
            isRunning = true;
            animator.SetBool("IsRunning", isRunning);
        }
        else
        {
            rb.velocity = new Vector2(0f, rb.velocity.y);
            isRunning = false;
            animator.SetBool("IsRunning", isRunning);
        }

        if (isJumpButtonPressed && !isJumping)
        {
            Jump();
        }

        isFalling = rb.velocity.y < 0f && !isJumping;
        animator.SetBool("IsFalling", isFalling);
        animator.SetBool("IsJumping", isJumping);
    }
    // 省略其他方法
}

我调试了这段代码并发现以下方法:

public void OnMoveLeftButtonDown()
{
    isMovingLeft = true;
}

public void OnMoveLeftButtonUp()
{
    isMovingLeft = false;
}

public void OnMoveRightButtonDown()
{
    isMovingRight = true;
}

public void OnMoveRightButtonUp()
{
    isMovingRight = false;
}

public void OnJumpButtonDown()
{
    isJumpButtonPressed = true;
}

public void OnJumpButtonUp()
{
    isJumpButtonPressed = false;
}

这些方法正在工作,但未在Update方法中使用。

有没有任何想法来重写这段代码,使其再次正常工作,并在玩家释放按钮时停止角色?感谢任何帮助!

英文:

I tried to modify my code for it to be able to move the character by using UI buttons as I am making a mobile game. Before, the code looked incredible and worked, but since I tried to add the stop when the player released the button, it no longer works. There are no errors, but the character doesn't want to jump and move. I tried using ChatGPT to solve this problem, but he ran out of ideas and cycled the same codes.
Here is his last written code that causes a problem:

using UnityEngine;
using UnityEngine.UI;

public class CharacterController : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 5f;
    private bool isJumping = false;
    private SpriteRenderer spriteRenderer;
    private Animator animator;
    private Rigidbody2D rb;
    private bool isFalling;
    private bool isRunning;

    public Button moveLeftButton;
    public Button moveRightButton;
    public Button jumpButton;

    private bool isMovingLeft = false;
    private bool isMovingRight = false;
    private bool isJumpButtonPressed = false;

    private void Start()
    {
        rb = GetComponent&lt;Rigidbody2D&gt;();
        spriteRenderer = GetComponent&lt;SpriteRenderer&gt;();
        animator = GetComponent&lt;Animator&gt;();

        moveLeftButton.onClick.AddListener(OnMoveLeftButtonDown);
        moveLeftButton.onClick.AddListener(OnMoveLeftButtonUp);
        moveRightButton.onClick.AddListener(OnMoveRightButtonDown);
        moveRightButton.onClick.AddListener(OnMoveRightButtonUp);
        jumpButton.onClick.AddListener(OnJumpButtonDown);
        jumpButton.onClick.AddListener(OnJumpButtonUp);
    }

    public void OnMoveLeftButtonDown()
    {
        isMovingLeft = true;
    }

    public void OnMoveLeftButtonUp()
    {
        isMovingLeft = false;
    }

    public void OnMoveRightButtonDown()
    {
        isMovingRight = true;
    }

    public void OnMoveRightButtonUp()
    {
        isMovingRight = false;
    }

    public void OnJumpButtonDown()
    {
        isJumpButtonPressed = true;
    }

    public void OnJumpButtonUp()
    {
        isJumpButtonPressed = false;
    }

    private void Update()
    {
        if (isMovingLeft)
        {
            rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);
            spriteRenderer.flipX = true;
            isRunning = true;
            animator.SetBool(&quot;IsRunning&quot;, isRunning);
        }
        else if (isMovingRight)
        {
            rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
            spriteRenderer.flipX = false;
            isRunning = true;
            animator.SetBool(&quot;IsRunning&quot;, isRunning);
        }
        else
        {
            rb.velocity = new Vector2(0f, rb.velocity.y);
            isRunning = false;
            animator.SetBool(&quot;IsRunning&quot;, isRunning);
        }

        if (isJumpButtonPressed &amp;&amp; !isJumping)
        {
            Jump();
        }

        isFalling = rb.velocity.y &lt; 0f &amp;&amp; !isJumping;
        animator.SetBool(&quot;IsFalling&quot;, isFalling);
        animator.SetBool(&quot;IsJumping&quot;, isJumping);
    }

    private void Jump()
    {
        rb.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
        isJumping = true;
        animator.SetTrigger(&quot;Jump&quot;);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag(&quot;Ground&quot;))
        {
            isJumping = false;
            animator.SetBool(&quot;IsJumping&quot;, isJumping);
        }
    }
}

I debugged this code using Debug.Log and discovered that the

    public void OnMoveLeftButtonDown()
    {
        isMovingLeft = true;
    }

    public void OnMoveLeftButtonUp()
    {
        isMovingLeft = false;
    }

    public void OnMoveRightButtonDown()
    {
        isMovingRight = true;
    }

    public void OnMoveRightButtonUp()
    {
        isMovingRight = false;
    }

    public void OnJumpButtonDown()
    {
        isJumpButtonPressed = true;
    }

    public void OnJumpButtonUp()
    {
        isJumpButtonPressed = false;
    }

Methods are working but not used in the Update method.

Are there any ideas to rewrite this code to work again and add a stop for a character when the player releases it? Thanks for any help!

答案1

得分: 1

问题

你面临的问题是因为在你的 Start 函数中两次注册了相同事件:

    private void Start()
    {
        //code
        moveLeftButton.onClick.AddListener(OnMoveLeftButtonDown);
        moveLeftButton.onClick.AddListener(OnMoveLeftButtonUp);
        //More code
    }

这会导致在按钮按下时两个方法都会触发,从而始终将 isMovingLeft(例如)设置为 false。

解决

对于所请求的行为,我建议您不要使用 UI 的 Button 类,因为它的主要目的是触发 'onClick' 事件,而您正在寻找类似 IPointerUpHandlerIPointerDownHandler 的东西。要实现 EventSystem 接口非常简单:

  1. 确保有一个活动的 GraphicsRaycaster 组件。
  2. 确保有一个活动的 EventSystem 游戏对象(要创建它,右键单击场景/层次结构,然后转到 UI -> Event System,它将被正确添加)。

*这两者也可以通过在场景中创建一个 Canvas 来添加,所以如果您已经有一个 Canvas,那么您可能已经设置好了(但值得检查)。

然后,这些接口应该在您的 UI 脚本上实现,这样您就可以管理自定义 UI,比如操纵杆。

英文:

Issue

The issue you are facing is because you are registering on the same event twice in your Start function:

    private void Start()
    {
        //code
        moveLeftButton.onClick.AddListener(OnMoveLeftButtonDown);
        moveLeftButton.onClick.AddListener(OnMoveLeftButtonUp);
        //More code
    }

This will cause both methods to be triggered right as the button is pressed, causing then the reaction of always setting the isMovingLeft (for instance) to be false.

Solving

For the requested behaviour, I'd recommend you to not use the Button class from UI due to its limitation of reading its state as its main purpose is to fire 'onClick' events, whereas you're looking for something like IPointerUpHandler and IPointerDownHandler. To implement EventSystem interfaces is quite easy:

  1. Be sure to have an active GraphicsRaycaster component
  2. Be sure to have an active EventSystem GameObject (to create it, right-click on the Scene/Hierarchy then go to UI -&gt; Event System and it shall be added properly)

Both can also be added by creating a Canvas on the scene, so if you have one, you'll probably be set (but worth to check).

Those interfaces shall then be implemented on an UI script of yours, this way you can manage custom UI such as joysticks

huangapple
  • 本文由 发表于 2023年7月11日 02:29:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76656391.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定