简体   繁体   English

我的角色有时无法跳跃-Unity2D

[英]My character sometimes fails to jump - Unity2D

So, I've set up a basic script in Unity to move around a 2D sprite, and it works pretty well, except for the fact that occasionally the player-character will not jump when told to. 因此,我在Unity中设置了一个基本脚本来在2D精灵周围移动,并且效果很好,除了以下事实之外:有时玩家角色在被告知时不会跳动。 It seems to only happen while or shortly after the character moves horizontally. 它似乎只发生在角色水平移动的同时或之后不久。 I really have no idea why this is happening. 我真的不知道为什么会这样。 Hopefully someone else can shed some light on this. 希望其他人可以对此有所启发。 Here is the controller script. 这是控制器脚本。 Any feedback is helpful, even if it's unrelated to the question, I'm doing this as a learning exercise. 任何反馈都是有帮助的,即使与问题无关,我也是在进行学习。

using UnityEngine;
using System.Collections;

public class PlayerControlsCs : MonoBehaviour {

public KeyCode walkLeft;
public KeyCode walkRight;
public KeyCode jumpUp;

public float speed = 5;
public float jumpForce = 750;
public int jumpCapacity = 1;
public int extraJumps = 0;

public bool facingRight = true;
public bool grounded = false;
private Transform groundCheck;
private Animator anim;

void Awake () {
    groundCheck = transform.Find("GroundCheck");
    anim = GetComponent<Animator>();
}

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

    if(grounded){
        anim.SetTrigger("Grounded");
        anim.ResetTrigger("Falling");
        extraJumps = jumpCapacity;
    }
    else {
        anim.ResetTrigger("Grounded");
        anim.SetTrigger("Falling");
    }

}

void FixedUpdate () {
    anim.SetFloat("Speed", Mathf.Abs(rigidbody2D.velocity.x));
    anim.SetFloat("Ascent", rigidbody2D.velocity.y);

    if(Input.GetKey(walkLeft))
    {
        if(facingRight){
            Flip();
        }
        rigidbody2D.velocity = new Vector2(-speed, rigidbody2D.velocity.y); 
    }
    else if(Input.GetKey(walkRight))
    {
        if(!facingRight){
            Flip();
        }
        rigidbody2D.velocity = new Vector2(speed, rigidbody2D.velocity.y);  
    }
    else
    {
        rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);  
    }

    if(Input.GetKeyDown(jumpUp) && grounded)
    {
        anim.SetTrigger("Jump");

        rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, 0);

        rigidbody2D.AddForce(new Vector2(0f, jumpForce));
    }
    else if(Input.GetKeyDown(jumpUp) && extraJumps > 0) 
    {
        anim.SetTrigger("Jump");

        rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, 0);

        rigidbody2D.AddForce(new Vector2(0f, jumpForce));

        extraJumps -= 1;
    }

}

void Flip ()
{
    // Switch the way the player is labelled as facing.
    facingRight = !facingRight;

    // Multiply the player's x local scale by -1.
    Vector3 theScale = transform.localScale;
    theScale.x *= -1;
    transform.localScale = theScale;
}
}

If it helps at all, here is what I have made: 如果有帮助,这就是我所做的:

https://www.dropbox.com/s/ka4vgc0s0205sbd/test.html https://www.dropbox.com/s/ka4vgc0s0205sbd/test.html

https://www.dropbox.com/s/40i8kltwfz1jgyu/test.unity3d https://www.dropbox.com/s/40i8kltwfz1jgyu/test.unity3d

Update and FixedUpdate aren't guaranteed to happen every time one after another. 不能保证Update和FixedUpdate每次都发生。 I haven't ran into this kind of bugs, so I can't say for sure, but you may experience a situation where your grounded state is incorrect. 我还没有遇到过此类错误,所以不能肯定地说,但是您可能会遇到一种情况,即您的接地状态不正确。 Instead of saving this value as a field, try checking for it every time you need it — at least a separate check in Update and FixedUpdate. 不用每次将此值保存为字段,而是尝试在每次需要时都对其进行检查-至少在Update和FixedUpdate中进行单独检查。

Building on Max's answer... 以Max的答案为基础...

You should use FixedUpdate() for physics stuff like applying a force to a RigidBody as it runs 50 times a second regardless of how fast the game is running. 您应该将FixedUpdate()用于物理操作,例如对RigidBody施加力,使其RigidBody运行50次,而不管游戏的运行速度如何。 This makes it frame rate independent . 这使其独立于帧速率

See the documentation . 请参阅文档

Update() runs once per frame, so is frame rate dependent . Update()每帧运行一次,因此取决于帧速率 In here is where most of your non-physics stuff should go, checking for inputs for example. 大多数非物理学的东西都应该放在这里,例如检查输入。

This video is a good explanation of the difference. 该视频很好地解释了两者之间的差异。

The link in the comment is also correct: 评论中的链接也正确:

You need to call this function from the Update function, since the state gets reset each frame 您需要从Update函数中调用此函数,因为状态会在每帧中重置

So check if is grounded only when the player presses jump as ray/linecasts are computationally expensive, apply the physics in FixedUpdate() , and check for input in Update() . 因此,仅当玩家按下跳转时才检查是否接地,因为射线/线路广播的计算量FixedUpdate() ,请在FixedUpdate()应用物理FixedUpdate() ,并在Update()检查输入。

Input should be handeled in Update, because update runs every frame, while fixed update isn't like update and it doesn't run every frame so when input is handeled in fixed update it might miss the input and it won't jump ! 输入应该在Update中处理,因为update运行在每一帧,而固定更新不像update一样,它也不是运行在每一帧,所以当在固定更新中处理输入时,它可能会错过输入并且不会跳转! I suggest you cut and paste all the input code from fixed update to update ! 我建议您剪切并粘贴所有从固定更新到更新的输入代码!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM