Android刷卡和addforce统一

时间:2016-04-17 22:41:36

标签: android unity3d swipe

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

<include android:id="@+id/action_back"
    layout="@layout/action_back"
    android:layout_height="match_parent"
    android:layout_width="wrap_content" />

<LinearLayout
    android:layout_toRightOf="@id/action_back"
    android:gravity="center_horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textSize="17sp"
        android:textStyle="bold"/>
</LinearLayout>

</RelativeLayout>

1 个答案:

答案 0 :(得分:1)

您的代码有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报告。有时,对等重叠会返回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;
        }
    }
}