2

我正在尝试在 Unity 中制作一个简单的 2D 自上而下的射击游戏。我有鼠标的基本移动和跟随,但移动存在问题。

每当你同时按下 Up 和 Right 时,它会像你期望的那样沿对角线移动,但是当你松开 Up 键时,它会一直沿对角线移动到我希望它向右移动的位置。我处理运动的代码是:

private void Update () 
{
    if (Input.GetKey(Up)) {
        Debug.Log("UP");
        Vector3 velUp = rigidbody2D.velocity;
        velUp.y = walkSpeed;
        rigidbody2D.velocity = velUp;
    }
    else if (Input.GetKey(Down)) {
        Vector3 velDown = rigidbody2D.velocity;
        velDown.y = walkSpeed*-1;
        rigidbody2D.velocity = velDown;
    }
    else if (Input.GetKey(Left)) {
        Vector3 velLeft = rigidbody2D.velocity;
        velLeft.x = walkSpeed*-1;
        rigidbody2D.velocity = velLeft;

    }
    else if (Input.GetKey(Right)) {
        Vector3 velRight = rigidbody2D.velocity;
        velRight.x = walkSpeed;
        rigidbody2D.velocity = velRight;
    }
    else {
        Vector3 velStop = rigidbody2D.velocity;
        velStop.x = 0;
        velStop.y = 0;
        rigidbody2D.velocity = velStop;
    }

    //rotation
    Vector3 mousePos = Input.mousePosition;

    Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
    mousePos.x = mousePos.x - objectPos.x;
    mousePos.y = mousePos.y - objectPos.y;

    float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}

我怎样才能让运动像我提到的那样表现?像这样沿对角线移动会使运动看起来不正常。

任何帮助是极大的赞赏。谢谢。

4

2 回答 2

6

您从 0 的速度开始,然后将您拥有的所有运动方向相加。然后你对向量进行归一化并将其缩放到你的移动速度。否则玩家移动得更快,如果走对角线。

我还没有检查代码,但这样的事情会做:

void Update () {
    Vector3 vel = new Vector3();

    if(Input.GetKey(Up)){
        Debug.Log("UP");
        Vector3 velUp = new Vector3();
        // just use 1 to set the direction.
        velUp.y = 1;
        vel += velUp;
    }
    else if(Input.GetKey(Down)){
        Vector3 velDown = new Vector3();
        velDown.y = -1;
        vel += velDown;
    }

    // no else here. Combinations of up/down and left/right are fine.
    if(Input.GetKey(Left)){
        Vector3 velLeft = new Vector3();
        velLeft.x = -1;
        vel += velLeft;
    }
    else if(Input.GetKey(Right)){
        Vector3 velRight = new Vector3();
        velRight.x = 1;
        vel += velRight;
    }

    // check if player wants to move at all. Don't check exactly for 0 to avoid rounding errors
    // (magnitude will be 0, 1 or sqrt(2) here)
    if (vel.magnitude > 0.001) {
      Vector3.Normalize(vel);
      vel *= walkSpeed;
      rigidbody2D.velocity = vel;
    }

    //rotation
    Vector3 mousePos = Input.mousePosition;

    Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
    mousePos.x = mousePos.x - objectPos.x;
    mousePos.y = mousePos.y - objectPos.y;

    float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}

关于Normalize看看这张图片。

向量加法

如果你只向上或向右走,你会以速度 1 移动(我们稍后会乘以你想要的速度)。但是如果你走对角线,你会以大约 1.4 倍的所需速度行走(绿色矢量)。Normalize保持向量的方向不变,但给你一个长度(也称为“大小”)1(红色向量)。

在较老的射击游戏中,您可能会发现一个叫做“兔子跳”的错误。我不确定这是否是问题的根源,但我猜它是。

关于vel.magnitude > 0.001

我们实际上想知道vel.magnitude > 0. Butvel.magnitude是计算的结果,因此可能包含舍入误差。如果您使用浮点值,请始终牢记这一点。检查本身已完成,因为该Normalize方法需要除以幅度,而除以零是邪恶的。不确定是否Normalize检查这个本身。

于 2014-07-09T23:02:12.740 回答
0

似乎你唯一一次强迫你的速度为零是没有任何键被按下。

我可能会建议添加一些检查以查看何时Input.GetKeyUptrue,并将rigidbody2D.velocity'sxy值设置为0,也许是这样的:

void Update () {

    if (Input.GetKeyUp(Up) || Input.GetKeyUp(Down)) {
        rigidbody2D.velocity.y = 0;
    }

    if (Input.GetKeyUp(Left) || Input.GetKeyUp(Right)) {
        rigidbody2D.velocity.x = 0;
    }

    ...
于 2014-07-09T23:05:01.750 回答