简体   繁体   English

Unity 2D Top Down Shooter运动问题C#

[英]Unity 2D Top Down Shooter movement issue C#

I am trying to make a simple 2D Top-Down Shooter in Unity. 我正在尝试在Unity中制作一个简单的2D自顶向下射击游戏。 I have the basic movement and following of the mouse, but there is an issue in the movement. 我掌握了鼠标的基本动作和跟随方式,但是动作有问题。

Whenever you press say Up and Right at the same time, it moves diagonally as you would expect, but when you let go of the Up key, it keeps going diagonally where I want it to move Right. 每当您同时按下说上移和右移时,它都会按预期的那样沿对角线移动,但是当您松开上移键时,它会一直沿对角线移动到我希望其向右移动的位置。 My code for handling the movement is: 我处理运动的代码是:

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));
}

How can I get the movement to behave as I mentioned? 如何使运动表现出我所说的? With it moving diagonally like this makes the movement seem off. 这样,它沿对角线移动,使运动看起来不明显。

Any help is greatly appreciated. 任何帮助是极大的赞赏。 Thanks. 谢谢。

You start with a velocity of 0, then you add up all the movements directions you have. 您从速度0开始,然后将所有运动方向加起来。 Then you normalize the vector and scale it to your movement speed. 然后,您可以对向量进行归一化并将其缩放为您的移动速度。 Otherwise the player moves faster, if walking diagonal. 否则,如果走对角线,则玩家移动得更快。

I haven't checked the code, but something like this will do: 我还没有检查代码,但是可以这样做:

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));
}

Regarding Normalize have a look at this image. 关于Normalize看看这个图像。

向量加法

If you walk only upwards or right you would move with speed 1 (which we later multiply with your desired speed). 如果您只向上走或向右走,您将以速度1移动(我们随后将其乘以您想要的速度)。 But if you walk diagonal you walk with about 1.4 times the desired speed (green vector). 但是,如果您对角行走,则行走的速度约为所需速度的1.4倍(绿色矢量)。 Normalize keeps the direction of the vector intact, but gives you a length (also called "magnitude") of 1 (red vector). Normalize可保持向量的方向不变,但长度为1(红色向量)(也称为“幅值”)。

In older shooters you may find a bug called "bunny hopping" . 在较老的射击游戏中,您可能会发现一个称为“兔子跳”的错误。 I'm not sure if this is the source of the problem, but I would guess it is. 我不确定这是否是问题的根源,但我想是这样的。

Regarding vel.magnitude > 0.001 : 关于vel.magnitude > 0.001

We actually want to know if vel.magnitude > 0 . 我们实际上想知道vel.magnitude > 0 But vel.magnitude is the result of a calculation and thus may contain rounding errors. 但是vel.magnitude是计算的结果,因此可能包含舍入误差。 If you work with floating-point values always keep that in mind. 如果使用浮点值,请始终牢记这一点。 The check itself is done because the Normalize method needs to divide by the magnitude and division by zero is evil. 进行检查本身是因为Normalize方法需要除以大小,而除以零是邪恶的。 Not sure if Normalize checks for this itself. 不知道是否Normalize检查本身。

It seems the only time you force your velocity to nothing is when there isn't any key being pressed. 似乎只有在没有按下任何键的情况下,才迫使速度达到零。

I might suggest adding some checks to see when Input.GetKeyUp is true , and set the rigidbody2D.velocity 's x or y values to 0 , maybe something like this: 我可能会建议增加一些检查时看到Input.GetKeyUptrue ,并设置rigidbody2D.velocityxy0 ,也许是这样的:

void Update () {

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

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

    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM