【问题标题】:Question about Double Jump and Collision in Unity关于Unity中的二段跳和碰撞问题
【发布时间】:2019-02-02 05:50:40
【问题描述】:

我刚刚开始学习如何在 Unity 中制作一个简单的 2D 平台游戏,并且我观看了 Blackthornprod 2D Platformer movement video 以学习如何让角色移动和跳跃。到目前为止,我能够理解大部分视频,但是,我在跳跃部分遇到了一些问题。

现在,据我在他的视频中了解,要让角色跳跃,我需要检测角色是否接触地面。为此,我需要在玩家脚下创建一个小圆圈,看看它是否与地面重叠,like this

所以,这里是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float JumpForce;       // jumping force

    private bool isGrounded;      //if the player is touching the ground
    public Transform GroundCheck; //object that contains the position of the 
                                  //"circle"
    public LayerMask GroundLayer; //the layer that the "circle" collide with
    public float radius;          //radius of the circle
    public float BaseNumOfJumps;  //maximum number of jumps
    private float NumOfJumps;     //current number of jumps


    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        NumOfJumps = BaseNumOfJumps;
    }

    void FixedUpdate()
    {
        //check the collision between the "circle" and the ground
        isGrounded = Physics2D.OverlapCircle(GroundCheck.position, 
        radius,GroundLayer);

       //here is the horizontal movement update part, but they are 
       //irrelevant so I cut them off

    }

    void Update()
    {
        //if the player touches the ground, reset the number of jumps
        if (isGrounded)
        {
            NumOfJumps = BaseNumOfJumps;
        }

        //when jumping, decrease the number of jumps
        if (Input.GetKeyDown(KeyCode.UpArrow) && NumOfJumps > 0)
        {
            rb.velocity = Vector2.up * JumpForce;
            NumOfJumps--;
        }
    }

}

问题就从这里开始,实际的最大跳跃次数总是高于我输入的值。例如,如果我设置 BaseNumOfJumps = 2,那么我可以跳 3 次而不是 2 次,类似地,如果 BaseNumOfJumps = 1 则我可以跳 2 次,依此类推。

过了一会儿,我发现因为圆圈的大小总是比实际玩家的脚大一点,所以当我跳跃时,玩家的脚在空中的那一刻,但是圆圈仍然与地面重叠,这会重置当前的跳跃次数(在我的代码中也称为 NumOfJumps),并使我的角色能够比在 BaseNumOfJumps 中输入的次数多跳一次。 不知道是真是假but here was what I imaginedThis comment under the video also described the same problem.

虽然 Blackthornprod 已经将这些值称为“额外跳跃”,所以如果我在该值中输入“1”,我会跳两次,“2”我会跳 3 次,等等。我在制作时遇到了一些困难跳跃次数一致。如果我的角色只是滑离地面而不跳like this怎么办?圆圈不会与地面发生碰撞,我将能够跳出我在 BaseNumOfJumps 中输入的确切跳跃次数,简而言之:

如果我输入的最大跳跃次数为 2,我将能够(再次重申,这只是我的猜测,所以我可能错了):

这当然会造成一些不一致。我已经搜索过其他关于跳跃和碰撞的教程,但其中大多数要么使用其他形式的检查碰撞(如 OnCollisionStay、OnCollisionEnter),要么使用我使用的相同方法但没有深入解释它(所以基本上它们是相同的就像在 Blackthornprod 的视频中一样)

那么我该如何解决这个问题,如何改变“圆”的半径,使其在玩家跳跃时脚离开地面的同一时刻离开地面?或者我应该像之前提到的那样使用其他形式的碰撞检查,如果是,它们有什么区别,哪种最有效?

这是我在这里的第一个问题,由于我不熟悉英语,我知道这有点长且令人困惑,但如果有人能提供帮助,我将不胜感激。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    让我们从概念上理解我们想要做什么。我们希望玩家有相同的跳跃次数,无论他们是先跳(使用一跳)还是跌倒(不使用一跳)。然而,一个简单的事实是肯定的:如果我们不在地面上,我们的接地跳跃就无法使用。我们可以通过分别跟踪接地跳跃和空中跳跃来实现这一点。

    现在,要允许使用接地跳跃,我们需要问的唯一问题是玩家是否在地面上。为了允许使用额外跳跃,我们需要问的唯一问题是玩家是否在空中以及玩家是否还有剩余的跳跃。

    剩下的就是确定玩家是否有剩余的跳跃。如果他们摔倒了,我们可以计算他们总跳跃次数中的跳跃次数。如果他们跳了,我们可以计算他们的总跳数中有多少跳减一。

    所有这些都为我们提供了以下逻辑:

    int numberOfJumps = 1; //Or however many you want.
    bool initiallyJumped = false; // jump checking
    
    //Other stuff
    void Update()
    {
        //Reset jumps BEFORE considering allowing jumps
        if(isGrounded)
        {
            initiallyJumped = false;
            resetJumpCounter();
        }
        
        if(Input.GetKeyDown(KeyCode.UpArrow))
        {
            if(!initiallyJumped && isGrounded)
            {
                jump();
                initallyJumped = true;
            }
            else
            {
                int jumpsRemaining = numberOfJumps;
                if(initiallyJumped)
                {
                    jumpsRemaining--;
                }
                
                if(numberOfJumps > jumpsRemaining)
                {
                    jump();
                    numberOfJumps--;
                }
            }
        }
    }
    

    现在,只有在未使用且玩家在地面上时才使用初始跳跃。奖金跳跃用于任何其他场景。但是,如果我们最初跳跃,奖励跳跃的次数会减少 1。

    【讨论】:

    • 非常感谢,但我仍然不明白如果角色不从地面开始跳跃,初始跳跃将如何工作。所以通常玩家可以通过从地面跳到半空中,但如果平台只是……突然掉下来怎么办?玩家只能在半空中进行奖励跳跃,但不能进行初始地面跳跃,并且如果他开始从地面跳跃,则只能跳跃两次而不是 3 次,因为正如您所说,只有奖励如果玩家在半空中,可以使用跳跃。
    • 如果平台刚刚从播放器下方滑出,'if(Input.GetKeyDown(KeyCode.UpArrow))' 将为真,但 'isGrounded' 将为假。因此,玩家将只使用奖励跳跃。我以为这就是你要找的。我误会你了吗?
    • 另外,我注意到我提出的系统中存在一个错误,如果玩家在着陆后由于某种原因按住跳跃按钮然后从某物上掉下来,就会阻止他们获得奖励跳跃。我将做一个真正的快速编辑来解决这个问题。
    • 编辑完成。从技术上讲,我会在玩家起身时返回初始跳跃,但我也会明确检查他们是否在地面上使用初始跳跃,所以它是安全的——除非他们按下跳跃按钮两次非常非常快。即使他们确实做到了这一几乎不可能的壮举,跳跃高度的差异也几乎不可能被注意到。但如果还是有问题,我们可以将跳跃圈向上移动一点点,使跳跃圈的底部,而不是圈的中心,位于玩家的脚底。
    • 再次,非常感谢您对我的帮助,我实际上重新观看了视频并找到了一些其他视频,他们实际上使用了与您类似的解决方案。现在我能够理解问题的一部分,但是,我在之前的评论中的意思是,我希望我的玩家能够在不落地的情况下进行初始跳跃。因此,如果平台刚刚从玩家的脚上滑落,我希望他能够像在地面上一样进行初始跳跃,因此即使 isGrounded == false,他仍然可以进行初始跳跃。对不起,如果我试图使事情复杂化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2011-01-05
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多