【问题标题】:Unity 2D Top Down Shooter movement issue C#Unity 2D Top Down Shooter 运动问题 C#
【发布时间】:2014-08-31 03:23:38
【问题描述】:

我正在尝试在 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));
}

我怎样才能让运动按照我提到的方式进行?像这样沿对角线移动会使移动看起来不正常。

非常感谢任何帮助。谢谢。

【问题讨论】:

    标签: c# unity3d game-physics topdown


    【解决方案1】:

    您以 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(红色向量)。

    在较早的射击游戏中,您可能会发现一个名为 "bunny hopping" 的错误。我不确定这是否是问题的根源,但我猜是。

    关于vel.magnitude > 0.001

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

    【讨论】:

    • 效果很好!谢谢你。如果你解释最后一部分可以吗?我是 Unity 和 C# 的新手,我不太了解 vel.magnitudeNormalize 部分。
    • vel.magnitude 获取速度的“大小”。如果您的速度为 (1,1),那么 magnitude 将约为 1.4(正如 Mene 所说的“兔子跳”问题)这是从基本三角函数(Sin(ang)= 1/hyp)开始的。 Normalize 减少一个向量,使其最大分量为 1。即。 (2,4) 将归一化为 (0.5,1)
    • 这是不正确的。 Normalize 会给你一个大小为 1 的向量。
    【解决方案2】:

    似乎只有在没有按下任何键的情况下才能将速度强制为空。

    我可能建议添加一些检查以查看Input.GetKeyUp 何时为true,并将rigidbody2D.velocityxy 值设置为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;
        }
    
        ...
    

    【讨论】:

      猜你喜欢
      • 2019-03-21
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多