【问题标题】:horizontal movement in UnityUnity 中的水平移动
【发布时间】:2015-11-03 16:10:46
【问题描述】:

我是 Unity 的新手,我正在尝试在经典 2D 地图(超级马里奥之类)上移动一个简单的方块。

我用addForce跳转,按计划进行。 但现在,我正在尝试水平移动我的角色。

首先,我尝试使用tramsform.translation(),我很快注意到这不是正确的方法,因为这种方法会“传送”角色,如果它移动得太快,它可以传送到墙后面。我也尝试使用addForce,但我希望我的角色具有恒定的速度,并且它会产生惯性,所以当我释放键时它不会立即停止。我也尝试使用.MovePosition(),但使用这种方法时角色会颤抖(显然,由于重力)。

那么,水平移动角色(Rigidbody2D)的正确方法是什么?

这是我尝试不同的代码:

using UnityEngine;
using System.Collections;
public class test : MonoBehaviour {
    private Rigidbody2D rb;
    public Vector2 velocity;
    public float jumpforce;
    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody2D>();
    }

// Update is called once per frame
void Update () {
    Debug.Log(velocity);
    if (Input.GetKeyDown("space")){
        rb.AddForce(new Vector2(0, jumpforce), ForceMode2D.Impulse);
    }
    if (Input.GetKey("a")){ // move to the left
        rb.AddForce(-velocity * Time.deltaTime, ForceMode2D.Impulse);
        //rb.MovePosition(rb.position - velocity * Time.fixedDeltaTime);
        //transform.Translate(-velocity);
    }
    if (Input.GetKey("d")){ // move to the right
            rb.AddForce(velocity * Time.deltaTime, ForceMode2D.Impulse);
            //rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
            //transform.Translate(velocity);
        }
    }
}

【问题讨论】:

  • 您可能会研究角色控制器脚本——它们旨在模仿刚体等物理行为,同时还支持倾向于产生角色移动的自定义逻辑。

标签: c# unity3d


【解决方案1】:

就个人而言,我使用这样的设置:

Rigidbody2D rb;
[SerializeField] [Range(0, 1)] float LerpConstant;
//Other stuff here
FixedUpdate() {
    float h = Input.GetAxisRaw("Horizontal");
    Vector2 movement = new Vector2(h, rb.velocity.y);
    rb.velocity = Vector2.Lerp(rb.velocity, movement, LerpConstant);
}

Lerp 简单的意思是“从 A 到 B 取一个 'x' 数量的 Vector2,然后返回它”。因此,代码创建了一个运动矢量,它是您的水平运动(用户输入)、垂直运动(刚体已经具有的垂直运动),然后将当前速度调整为它。通过直接修改速度,只要您知道如何正确操作,它就可以确保您的运动保持平稳和恒定。

【讨论】:

  • 关于直接修改速度的好建议:)
【解决方案2】:

如果你想要一个基于“物理”的运动,那么你应该对Rigidbody 施加力。作用于刚体的一个好处是它会考虑与物体(如墙壁)的碰撞。

Here 是一个很棒的介绍教程(它是 3D,但同样的概念也适用于 2D)。这是该教程中的代码,经过一些修改以使其成为 2D:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

    public float speed;    // Here we set a float variable to hold our speed value

    private Rigidbody2D rb;  // This is to hold the rigidbody component

    // Start is called as you start the game, we use it to initially give values to things
    void Start ()
    {
        rb = GetComponent<Rigidbody2D>();  // Here we actually reference the rigidbody.
    }

    void FixedUpdate ()
    {
        // We assign values based on our input here:
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        // Here we assign those values to a Vector2 variable.
        Vector2 movement = new Vector2 (moveHorizontal, moveVertical);

        rb.AddForce (movement * speed);    // Finally we apply the forces to the rigidbody
    }
}

我们可以通过更改AddForce.ForceMode2D 参数来改变力作用在刚体上的方式。例如,ForceMode2D.Force

使用刚体的质量向刚体添加一个力。

ForceMode2D.Impulse

使用它的质量向rigidbody2D 添加一个瞬时力脉冲。

这更适合跳跃之类的事情。

  • 注意 - 最好将基于物理的方法调用放在 FixedUpdate 中,而不是 Update 中,因为存在帧速率依赖性。
  • 另请注意 - 当你对一个物体施加一个力时,它会加速,因为你作用在一个质量(刚体)上,并根据其他力减速(friction 等)如果你想让你的玩家放慢速度停止而不是停止死亡,想想作用在玩家身上的力量。此外,如果您在每次 FixedUpdate 对刚体施加一次力,如果您选择 ForceMode2D.Force,这将导致您想要的恒定速度,因为其他作用在相反方向的力将平衡它(见下图 - 归功于 @987654325 @ 图片)。


编辑: 关于上面 rutter 的评论,here 是关于 2D 角色控制器的介绍性教程。

【讨论】:

    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多