Android滑动和addforce统一

标签 android unity3d swipe

我正在研究 2D 无限赛跑者。我有下面的代码来从屏幕滑动获取输入以快速跳跃、滑动和运行。我从编辑器中提供了 jumpHeight,值为 500,帧率为 30。代码通常工作正常,但有时玩家跳得太高而无法向上滑动。如果输入来自键盘,类似的代码将按预期工作。为什么会发生这种情况超出了我对团结的理解。非常感谢任何帮助。

using UnityEngine;
public class PlayerControl : MonoBehaviour
{

    public float ForwardSpeed = 3.7f; //moves player in forward direction
    public float speedOffset = 0.0f; //offset speed of player
    public float JumpHeight = 250; //moves player in verticle direction
    bool grounded = false; //checks if player is grounded or not
    public Transform groundCheck;
    float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool
    public LayerMask groundLayer;
    Vector2 fingerStart;
    Vector2 fingerEnd;

    void Update()
    {
        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Began)
            {
                fingerStart = touch.position;
                fingerEnd = touch.position;
            }

            if (touch.phase == TouchPhase.Moved)
            {
                fingerEnd = touch.position;
                if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
                {
                    if (fingerEnd.y - fingerStart.y > 50)//up swipe
                    {
                        Jump();
                    }
                    else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
                    {
                        //Slide();
                    }
                    fingerStart = touch.position;
                }
            }
            if (touch.phase == TouchPhase.Stationary)
            {
                RunFast();
            }
            if (touch.phase == TouchPhase.Ended)
            {
                fingerEnd = touch.position;
                if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
                {
                    if (fingerEnd.y - fingerStart.y > 50)//up swipe
                    {
                        Jump();
                    }
                    else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
                    {
                        //Slide();
                    }
                }
            }
        }



        if (Input.GetButton("Fire1"))
        {
            speedOffset = 2.5f;
        }
        else
        {
            speedOffset = 0.0f;
        }


        if (grounded && Input.GetKeyDown(KeyCode.UpArrow))
        {
            grounded = false;
            GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight));
        }

        //check if circle overlaps with ground layer
        grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
        //Debug.Log(grounded);


    }



    void FixedUpdate()
    {
        //set players forward velocityto forward speed variable
        Vector2 PlayerForwardvelocity = GetComponent<Rigidbody2D>().velocity;
        // Vector2 PlayerJumpHeight = GetComponent<Rigidbody2D>().AddForce()
        PlayerForwardvelocity.x = ForwardSpeed + speedOffset;
        GetComponent<Rigidbody2D>().velocity = PlayerForwardvelocity;
    }

    void Jump()
    {
        if (grounded)
        {
            GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight));
            speedOffset = 0.0f;
        }

    }

    void RunFast()
    {
        if (Input.GetButton("Fire1"))
        {
            speedOffset = 2.5f;
        }
        else
        {
            speedOffset = 0.0f;
        }
    }
}

最佳答案

您的代码有 2 个问题。

您的第一个问题出在这行代码中:

 grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);

这行代码失败了。 grounded 始终为 true。正因为如此,当玩家没有接地时,跳转被调用了太多次。

将这行代码替换为

 Collider2D playerCollider = gameObject.GetComponent<Collider2D>();
 grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer); 

Collider2D playerCollider = gameObject.GetComponent<Collider2D>();
grounded = playerCollider.IsTouchingLayers(groundLayer.value);

您的代码的另一个问题是报告false。有时,collider overlapping 返回true,即使它是false。我尝试将那部分代码移至 LateUpdate 函数,但这并没有解决问题。

您可以通过实现计时器来修复它。每当玩家跳跃时,计时器重置为 0 并开始计数至 0.5。当计时器未达到它正在计数的值时不要跳转。 .5 to 1 是一个完美的值。使用 Time.deltaTime 增加计时器。下面是带有计时器和修复程序的完整代码。

public class PlayerControl : MonoBehaviour
{

    public float ForwardSpeed = 3.7f; //moves player in forward direction
    public float speedOffset = 0.0f; //offset speed of player
    public float JumpHeight = 250; //moves player in verticle direction
    bool grounded = false; //checks if player is grounded or not
    public Transform groundCheck;
    float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool
    public LayerMask groundLayer;
    Vector2 fingerStart;
    Vector2 fingerEnd;

    public float resetTimer = 0.5f; //.5 second
    float timerCounter = 0;
    Collider2D playerCollider = null;

    Rigidbody2D playerRigidBody;


    void Start()
    {
        playerRigidBody = GetComponent<Rigidbody2D>();
        playerCollider = gameObject.GetComponent<Collider2D>();
    }

    void Update()
    {

        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Began)
            {
                fingerStart = touch.position;
                fingerEnd = touch.position;
            }

            if (touch.phase == TouchPhase.Moved)
            {
                fingerEnd = touch.position;
                if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
                {
                    if (fingerEnd.y - fingerStart.y > 50)//up swipe
                    {
                        Jump();
                    }
                    else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
                    {
                        //Slide();
                    }
                    fingerStart = touch.position;
                }
            }
            if (touch.phase == TouchPhase.Stationary)
            {
                RunFast();
            }
            if (touch.phase == TouchPhase.Ended)
            {
                fingerEnd = touch.position;
                if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe
                {
                    if (fingerEnd.y - fingerStart.y > 50)//up swipe
                    {
                        Jump();
                    }
                    else if (fingerEnd.y - fingerStart.y < -50)//Down swipe
                    {
                        //Slide();
                    }
                }
            }
        }



        if (Input.GetButton("Fire1"))
        {
            speedOffset = 2.5f;
        }
        else
        {
            speedOffset = 0.0f;
        }


        if (grounded && Input.GetKeyDown(KeyCode.UpArrow))
        {
            grounded = false;
            playerRigidBody.AddForce(new Vector2(0, JumpHeight));
        }

        //check if circle overlaps with ground layer
        grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer);
        //OR Use grounded = playerCollider.IsTouchingLayers(groundLayer.value);

        //Increment Timer if it is still less than resetTimer
        if (timerCounter < resetTimer)
        {
            timerCounter += Time.deltaTime;
        }
    }


    void FixedUpdate()
    {
        //set players forward velocityto forward speed variable
        Vector2 PlayerForwardvelocity = playerRigidBody.velocity;
        // Vector2 PlayerJumpHeight = playerRigidBody.AddForce()
        PlayerForwardvelocity.x = ForwardSpeed + speedOffset;
        playerRigidBody.velocity = PlayerForwardvelocity;
    }

    void Jump()
    {
        if (grounded)
        {
            //Exit if timer has not reached the required value to jump again
            if (timerCounter < resetTimer)
            {
                Debug.Log("Failed To Jump because timer has not yet reached");
                return; //Exit
            }

            timerCounter = 0; //Reset Timer

            playerRigidBody.AddForce(new Vector2(0, JumpHeight));
            speedOffset = 0.0f;
            Debug.Log("Jumped");
        }
        else
        {
            Debug.Log("Not on the Ground");
        }

    }

    void RunFast()
    {
        if (Input.GetButton("Fire1"))
        {
            speedOffset = 2.5f;
        }
        else
        {
            speedOffset = 0.0f;
        }
    }
}

关于Android滑动和addforce统一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36683028/

相关文章:

android - 如何连接 CameraUpdate 动画

java - android java中 '^'(插入符号)的 key 代码?

android - 如何获取原生自定义模板广告的点击URL

java - 我们可以使用 SharedPreference 将数据从一个 Activity 共享或传输到另一个 Activity 吗?

unity3d - 欧拉角约定变换

java - 如何使用幻灯片在布局(如 ICS+ 计算器之类)之间切换?

c# - Unity 5 上的 OnLevelWasLoaded 在哪里?

c# - unity WaitForSeconds 等待时间超过预期

css - 将触摸/滑动命令添加到 CSS 转换/动画

android - 如何在底部滑动后继续阅读ListView中的内容?