【问题标题】:Unity 5: Rigidbody 2d sticking to ceiling while velocity is moving upwardsUnity 5:刚体 2d 在速度向上移动时粘在天花板上
【发布时间】:2017-08-30 04:03:18
【问题描述】:

我正在制作一个 2d 游戏。我的问题是,在玩的时候,如果玩家保持跳跃并且在 BoxCollider2D 下,玩家在释放跳跃之前不会跌倒。

我的玩家游戏对象由一个 sprite 渲染器、一个带有重力的动态刚体 2d 和一个 boxcollider2d 组成。

这是我的动作脚本:

1:

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

public class JumpScript : MonoBehaviour {

    [Range(1, 10)]
    public float jumpVelocity;

    [Range(0,10)]
    public float speed;
    private bool jumpQueue = false;
    private bool boolin=false;
    void Update()
    {

        //Friggin fall, loser

        //Jumping
        ///*
        if (Input.GetButton("Jump")&& GetComponent<Rigidbody2D>                ().velocity.y==0)
        {
            GetComponent<Rigidbody2D>().velocity = Vector2.up *     jumpVelocity;
        }
        //*/
        //jumpQueue?
        /*
        if(Input.GetButtonDown("Jump"))
        {
            jumpQueue = true;
        }*/
        //Right Movement
        if (Input.GetKey(KeyCode.D))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(1*speed,         GetComponent<Rigidbody2D>().velocity.y);
            boolin = true;
        }
        if(Input.GetKeyUp(KeyCode.D))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(0,     GetComponent<Rigidbody2D>().velocity.y);
            boolin = false;
        }
        //Left Movement
        if (Input.GetKey(KeyCode.A))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(-1*speed,     GetComponent<Rigidbody2D>().velocity.y);
            boolin = true;
        }
        if (Input.GetKeyUp(KeyCode.A))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(0,     GetComponent<Rigidbody2D>().velocity.y);
            boolin = false;
        }
        //No movement?
        if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.A))
        {
            GetComponent<Rigidbody2D>().velocity = new Vector2(0,     GetComponent<Rigidbody2D>().velocity.y);
            boolin = false;

        }

        //Time to handle animation, boios.
        Rigidbody2D rb = GetComponent<Rigidbody2D>();

        bool schwomp = false;
        bool schwift = false;
        if(rb.velocity.y>0)
        {
            schwomp = true;
        }
        if(rb.velocity.y<0)
        {
            schwift = true;
        }
        Animator anim = GetComponent<Animator>();
        if (boolin)
        {
            anim.SetInteger("Boolin", 1);
            /*if (!anim.GetBool("expand"))
            {
                anim.SetBool("expand", true);
                anim.Play("running");
            }*/
        }
        else
        {
            anim.SetInteger("Boolin", 0);
            /*
            if(anim.GetBool("expand"))
            {
                anim.SetBool("expand", false);
                anim.Play("Idle");
            }*/
        }
        if(schwomp)
        {
            //anim.SetInteger("Boolin", 2);
        }
        if(schwift)
        {
            //anim.SetInteger("Boolin", 3);
        }
    }
}

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

公共类 BetterJumper : MonoBehaviour {

public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;

Rigidbody2D rb;

void Awake()
{
    rb = GetComponent<Rigidbody2D>();

}

void Update()
{
    if(rb.velocity.y<0)
    {
        rb.velocity += Vector2.up*Physics2D.gravity.y*(fallMultiplier-1)*Time.deltaTime;

    }
    else if(rb.velocity.y>0&&!Input.GetButton("Jump"))
    {
        rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
    }
}
}

非常感谢您!

【问题讨论】:

  • 请花点时间正确格式化您的代码。
  • 您写出了问题所在,但没有提供预期的结果......

标签: c# unity3d collision


【解决方案1】:

您正在使用Input.GetKey(),它将每帧轮询密钥。这意味着你保持跳跃的时间越长,速度就越快。你有效地构建了一个喷气背包而不是一个跳跃力量。

您应该使用Input.GetKeyDown(),它只会在按下某个键时触发一次,然后必须松开并再次按下才能重新触发。然后你需要使用RigidBody.AddForce() 施加一个足够强的垂直力来使角色跳跃,而不是连续增加速度。

此外,您真的应该在脚本唤醒或启动时缓存GetComponent&lt;Rigidbody2D&gt;() 调用的结果,这样您就不会连续调用它;这些调用中的每一个都需要处理时间。此外,您应该使用FixedUpdate() 进行物理学。

public class ExampleClass : MonoBehaviour {
    public float thrust;
    public Rigidbody rb; // make the rigidbody variable available anywhere in the class

    void Start() {
        // cache the rigidbody component to the variable once on start
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate() {
        // use the variable reference from now on rather than making GetComponent calls
        rb.AddForce(transform.up * thrust);
    }
}

【讨论】:

  • 感谢您的帮助!如果可以的话,我一定会尝试的!
【解决方案2】:

Soviut 的回答很好地解释了这一点,但您还需要了解更多信息。您直接操纵速度,它会覆盖任何力的影响,包括重力(尽管您是手动应用它)。请参阅documentation

如 Soviut 的回答所示,您应该施加力和冲量,让物理引擎确定速度。您应该直接设置速度的唯一时间是当您构建一个故意具有不切实际物理的模拟时(即复古平台游戏)。即使在这种情况下,请记住这样做会产生更多的工作,因为您需要考虑每一个产生运动的小事情。这意味着您实际上是在重新发明物理引擎。

【讨论】:

  • 很有趣,我正在尝试创建一个复古的平台游戏,哈哈。
  • 哇,多么讽刺。在任何情况下,如果您限制最大速度并且不要过度使用您所施加的力量,您就可以获得复古平台游戏的大部分感觉。祝你好运。
  • 这更像是一种解决方法,而不是我可以应用于其他情况的解决方案。但是,我确实使用了光线投射来确定播放器是否接地。那样的话,他现在只有在地上时才会跳。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多