点击跳转问题

Tap to jump problems

问题

所以我在 iOS 和 Android 应用商店发布了这款名为 Jumpol 的游戏,它运行良好。唯一的问题是跳跃机制有点古怪。有时当我和其他玩家点击时,我的玩家有时会跳,有时不会跳。此外,当您点击靠近两侧的屏幕时,它有时不会跳转。有人有什么建议吗?

Link到游戏(如果你想自己看的话)

Android Link

iOS Link

C#代码

using UnityEngine;

public class Player : MonoBehaviour {

    Rigidbody rb;

    float speed = 640;              // Speed of player.
    float thrust = 40;              // Jump force.
    float gravity = -6.18f;         // Gravity force.

    bool isGrounded = false;        // If on ground or not.

    private void Start () {

        rb = GetComponent<Rigidbody> ();

    }

    private void Update () {

        if (Application.platform == RuntimePlatform.WindowsEditor) DesktopControls ();

        if (Application.platform == RuntimePlatform.IPhonePlayer ||
            Application.platform == RuntimePlatform.Android) MobileControls ();

    }

    private void FixedUpdate () {

        if (GameManager.Instance.started) {

            Move ();
            Gravity ();

        }

    }

    private void OnCollisionEnter (Collision collision) {

        if (collision.gameObject.tag == "Ground") {
            isGrounded = true;
        }

    }

    private void OnCollisionExit (Collision collision) {

        if (collision.gameObject.tag == "Ground") {
            isGrounded = false;
        }

    }

    /// <summary>
    /// Controls for mobile devices.
    /// </summary>
    private void MobileControls () {

        if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Began) Jump ();

    }

    /// <summary>
    /// Controls for desktops.
    /// </summary>
    private void DesktopControls () {

        if (Input.GetMouseButtonDown (0)) Jump ();

    }

    /// <summary>
    /// Makes player jump.
    /// </summary>
    private void Jump () {

        if (instructions.activeSelf) {
            instructions.SetActive (false);
        }

        if (isGrounded) {
            rb.velocity += new Vector3 (0, thrust, 0);

            SoundManager.Instance.PlayOneShot (SoundManager.Instance.jump);
        }

    }

    /// <summary>
    /// Adds gravity.
    /// </summary>
    private void Gravity () {

        rb.velocity += new Vector3 (0, gravity, 0);

    }

    /// <summary>
    /// Moves player.
    /// </summary>
    private void Move () {

        rb.velocity = new Vector3 (rb.velocity.x, rb.velocity.y, speed * Time.deltaTime);

    }

}

Sometimes when I and other players tap, my player sometimes jumps and other times doesn't jump.

您的代码在很大程度上依赖于碰撞事件来实现您的 isGrounded 状态。不要误会我的意思,Unity Physics 系统是一个功能强大且功能强大的系统,但是,在 Unity 物理引擎中,Rigidbody 对象和在运行时模拟的碰撞有时会给出不完美的结果。它更像是实践中的近似值,因此这些近似值并不总是准确的。

    private void OnCollisionEnter (Collision collision) {

    if (collision.gameObject.tag == "Ground") {
        isGrounded = true;
    }

}

private void OnCollisionExit (Collision collision) {

    if (collision.gameObject.tag == "Ground") {
        isGrounded = false;
    }

}

我建议不要在 OnCollisionEnterOnCollisionExit 中更改 isGrounded 状态,而是进行简短的 Raycast 检查。你的玩家刚体对象可以很容易地从 OnCollisionEnterOnCollisionExit 移动,导致你的 isGround bool 在沿着 ground 移动时从 true 移动到 false当您希望它始终接地时标记的对象,导致您的 jump 调用被忽略,认为您在空中。我建议 实施更可靠的地面检查系统。

有关如何实施 Raycast based platformer system here is an example from Unity themselves with video and code in the link and all:

的示例
void Update () 
{
    grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));

    if (Input.GetButtonDown("Jump") && grounded)
    {
        jump = true;
    }
}

它最初是为 2D 设计的,因此有 Physics2D 函数调用,但是,逻辑是相同的,您需要将 2D 调用换成它们的 3D 等效函数。 (例如 Physics.Raycast 而不是 Physics2D.Linecast

Also when you tap the screen near the sides, it sometimes doesn't jump.

至于这个,我会说它与我上面解决的问题有关。查看您 iOS 应用程序产品页面上的屏幕截图,我没有看到任何 UI 侧面可能会专门阻止触摸输入事件。