在不影响跳跃的情况下添加力的恒定速度

时间:2015-05-05 22:16:55

标签: c# unity3d

似乎有相当多的类似问题,但似乎都没有真正回答。我有一个游戏对象,只需点击一下按钮即可跳转并自动保持正确。

我需要正确的移动动作才能保持不变,但随着时间的推移它会越来越快地建立起来。如果我使用Velocity而不是AddForce,则运动是恒定的。但是,当我点击鼠标进行跳跃时,需要花费10秒才能回到地面。

我是否可以获得有关如何保持自动向右移动恒定并且仍能快速跳回并快速返回地面的帮助。以下是我的代码。谢谢。

编辑:

  

期望的结果

  • Gameobject不断向右移动相同的速度。当我跳跃时,游戏对象跳跃并在0.5秒内回到地面。 跳跃预计就像一个顺畅的流动,就像一个跳跃并顺利回归的球。
  

当前结果使用AddForce向右移动

  • Gameobject开始慢慢向右移动并随着时间的推移加快速度越来越快,因此无法保持恒定的相同速度。
  

当前结果使用Velocity向右移动

  • Gameobject能够保持恒定的速度,但是当我跳过Gameobject跳跃并花大约10秒钟回到地面时(它慢慢滑回)。
public float jumpSpeed = 300;
 public float maxSpeed = 15; 
 Rigidbody rb;

 void Start()
 {
     rb = GetComponent<Rigidbody>();
     rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxSpeed);
 }

 void Update()
 {
     if (Input.GetMouseButtonDown(0))
     {
         rb.AddForce(Vector3.up * jumpSpeed);
     }
 }

 void FixedUpdate()
 {
     rb.AddForce(Vector3.right * maxSpeed);
 }

//Trying to change velocity instead - Able to keep constant speed but when I jump, takes about 10 secs to get back down to ground. 

public float jumpSpeed = 2000;
public float maxSpeed = 5; 
Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();
    rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxSpeed);
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        rb.AddForce(Vector3.up * jumpSpeed);
    }
}

void FixedUpdate()
{
    rb.velocity = new Vector2(5, 0);
}

1 个答案:

答案 0 :(得分:2)

我认为这里有一些混淆点,所以我会回答一些我自己的澄清问题。

使用添加力时,为什么对象的速度无限制地增加?

每次应用时,AddForce命令都会增加对象的速度。在代码中,这意味着对FixedUpdate的每次调用都会增加速度。

我认为误解与你的Start方法中的这行代码有关:

rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxSpeed);

Vector2.ClampMagnitude不是持久的。也就是说,它并没有限制前进的幅度。你可能想要的是防止速度破坏“maxSpeed”,在这种情况下你应该在FixedUpdate中调用clamp方法。

但是,这可能会产生不同的效果,您可能不会这样做。当游戏对象仅沿一个轴移动时,速度的整个大小沿着该轴。一旦游戏对象开始沿第二轴移动,例如在跳跃时,速度的大小在两者之间被分开。这意味着当你的游戏对象正在跳跃(其速度为y分量)时,其水平速度(其速度的x分量)将会减小。换句话说,跳跃会减慢游戏对象向右移动的速度。

为什么我的物体在直接设定速度时会慢慢向下“浮动”?

使用AddForce的一个优点是它可以修改向量的目标轴而无需修改其他向量。直接设置速度有点棘手,因为你可能会意外地破坏物理引起的速度变化。

例如,在您的FixedUpdate代码中:

rb.velocity = new Vector2(5, 0);

将对象的x速度设置为5 - 创建所需的平滑水平移动 - 但同时将y速度设置为0.

这就是为什么你需要将jumpSpeed加速到2000以查看对象高度的任何影响:在FixedUpdate方法将其向上运动重置为0之前,它只有一秒钟向上移动。这也是你的对象的原因似乎是“漂浮”回到地球。内部物理引擎试图将重力应用于对象,但是被代码挫败,这会不断地重置对象的向下速度。

另一个评论

我注意到你的Update方法中有一些代码用于对象的物理 - 这是你的跳转代码。一个好的经验法则是将所有代码保存在FixedUpdate方法中的对象物理上,因为这是在物理引擎工作之前调用的,而Update方法是在渲染引擎完成其工作之前调用的。游戏。

一种可能的解决方案

在处理对象的速度时,通常建议使用AddForce技术,因为它通过加速创建自然的物理效果。直接设置对象速度可能会产生奇怪的效果,因为实际中的对象不能以这种方式工作。例如,想象看到一辆汽车在不到一秒的时间内从0mph变为60mph的情况。

如果您在Rigidbody.velocity上查看Unity的文档,您会看到他们提出同样的建议,但添加跳转可能是您想破坏此规则的情况。但是,正如我前面提到的,我们在明确设置y速度时要小心,以避免沿其他轴改变对象的速度。

public float jumpSpeed = 2;
public float maxSpeed = 1; 
Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{   
    var newVelocity = rb.velocity;
    if (Input.GetMouseButtonDown (0))
        newVelocity.y = jumpSpeed;

    newVelocity.x = maxSpeed;

    rb.velocity = newVelocity;
}