【问题标题】:Unity: Diagonal movement issueUnity:对角线运动问题
【发布时间】:2018-02-11 21:09:19
【问题描述】:

我有一个测试 2D 游戏,我的玩家从左到右移动,当他到达屏幕的尽头时,它只会在另一侧变换。我改变了主意,让我的球员斜着走。它确实有效,但我不知道如何让播放器在到达屏幕末端时停止。我不希望它在另一边发生变化,而只是停下来。到目前为止,我所有的结果要么是边缘出现了一些故障,要么根本没有停止。我提供了我的 PlayerController 脚本。现在我的球员沿对角线移动,他将在屏幕边缘后继续前进。如果有人可以帮助我,我将不胜感激。我从没想过我会处理对角线运动,但我真的很想学习如何去做。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class PlayerController : MonoBehaviour {

    public float speed = 7;
    public float speedy = 7;

    public event System.Action OnPlayerDeath;
    float screenHalfWidthInWorldUnits;
    Rigidbody2D rb;

    void Start () {
        rb = GetComponent<Rigidbody2D>();
        float halfPlayerWidth = transform.localScale.x / 2f;
        screenHalfWidthInWorldUnits = Camera.main.aspect * Camera.main.orthographicSize;
    }

    void Update()
    {
        float inputX = Input.GetAxisRaw("Horizontal");
        float velocity = inputX * speed;
        transform.Translate(Vector2.right * velocity * Time.deltaTime); 
    }


    public void MoveRight()
    {
        rb.velocity = new Vector2(speed, speedy);
    }

    public void MoveLeft()
    {
        rb.velocity = new Vector2(-speed, -speedy);
    }


    public void Stop()
    {
        rb.velocity =  Vector2.zero;
    }

    void OnTriggerEnter2D(Collider2D triggerCollider)
    {
        if (triggerCollider.tag =="Box")
        {
            if (OnPlayerDeath != null)
            {
                OnPlayerDeath();
            }
            Destroy(gameObject);
        }
    }
}

【问题讨论】:

  • 你想在到达边缘时摧毁玩家吗?
  • 为什么不在你想限制玩家的地方创建碰撞器?
  • @MGDroid 不,我只是想让他停下来。当它向左或向右时它工作得很好,但是对角线,我错过了一些东西。
  • 快速提问,为什么要使用transform.Translate 移动播放器,而不是使用MoveRight()MoveLeft() 方法? (目前这将忽略物理对象,例如对撞机。)
  • 是否可以添加有关情况和问题的短视频/gif?我有点难以想象发生了什么。

标签: unity3d unity5 unity3d-2dtools


【解决方案1】:

您可以检查玩家是否在您定义的地图边界处。

如果您分别检查 x 和 y 轴,则可以将他的 x 或 y 轴锁定到边界,而不是进一步。

这是我之前编写的一个脚本示例。

如果我理解正确,您希望能够沿对角线移动。在我下面的示例脚本中,您可以直线和对角线移动,也可以在边缘之间弯曲或在边缘停止,就像您所说的那样。

这个脚本可能比你需要的要高级一些,所以如果它有什么让你困惑的地方,请告诉我。

请注意,如果您将布尔值 _ShouldWarp 设置为 false,他将在边界处停止,否则他会在地图的边缘从边缘扭曲到边缘。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{

    public float _Speed = 5f;
    public WorldBounds _WorldBounds;
    public bool _ShouldWarp; //If _ShouldWarp is false, will block players movement instead.

    void Update()
    {
        Move();
        WarpIfAtBoundary();
    }

    void Move()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
        transform.Translate(Vector3.up * Time.deltaTime * _Speed * vertical);
    }

    void WarpIfAtBoundary()
    {
        //X Axis
        //If player is at positive X boundary
        if (transform.position.x > (_WorldBounds.xPlus + _WorldBounds.xBuffer))
        {
            if (_ShouldWarp) //Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(_WorldBounds.xMinus, transform.position.y, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(_WorldBounds.xPlus + _WorldBounds.xBuffer, transform.position.y, transform.position.z);
            }
        }
        //Else if player is at negative X boundary
        else if (transform.position.x < (_WorldBounds.xMinus - _WorldBounds.xBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(_WorldBounds.xPlus, transform.position.y, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(_WorldBounds.xMinus - _WorldBounds.xBuffer, transform.position.y, transform.position.z);
            }
        }

        //Y Axis
        //If player is at positive Y boundary
        if (transform.position.y > (_WorldBounds.yPlus + _WorldBounds.yBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus + _WorldBounds.yBuffer, transform.position.z);
            }
        }
        //Else if player is at negative Y boundary
        else if (transform.position.y < (_WorldBounds.yMinus - _WorldBounds.yBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            { 
                transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus - _WorldBounds.yBuffer, transform.position.z);
            }
        }
    }
}

//Set as serializable so it displays correctly in Unity's inspector window.
[System.Serializable]
public class WorldBounds
{
    [Header("Bounds")]
    public float xMinus = -9.4f;
    public float xPlus = 9.4f;
    public float yMinus = -9.4f;
    public float yPlus = 9.4f;
    [Header("BufferZone")]
    public float xBuffer = 1f;
    public float yBuffer = 1f;
}

编辑:

通过您的添加,我可以将移动分配给我的两个按钮。一个上下左右,一个上下左右。

        void Move()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
        transform.Translate(Vector3.up * Time.deltaTime * _Speed * horizontal);
    }

这应该可以左右对角线左右移动。

我所做的更改是对 X 和 Y 移动使用水平输入。

我不需要经线。只是为了踏上定义的边界

您可以将 Warp 布尔值设置为 false 或从代码中删除扭曲部分然后 :-),应该可以工作。

【讨论】:

  • 在我尝试实现它之前唯一要做的事情。通过您的添加,我将能够将运动分配给我的两个按钮。一个在上和右,另一个在下和左。只是一个一般性的问题,因为我很有能力把事情搞砸。
  • 据我所见。我不需要经线。只是为了踏上定义的边界。我不确定如何,但我会尝试。将界限添加到我的 x 和 y 位置。也只是要注意。我不希望它直接移动。就在右上对角线和左下对角线。
  • 请查看我刚刚对原始答案底部所做的编辑,我会尝试解决您的问题。
  • 两个小问题。我不确定如何将 Move() 函数分配给检查器中的上/右和下/左两个按钮。现在它适用于键盘。其次,你能给我一个关于扩展边界的提示吗?现在我的玩家确实碰到了边界,但它太大了,如果我改变缓冲区或边界上的某些东西,我的玩家的生成位置会移动,所以我永远无法正确调整边界。谢谢!
  • 我在代码中用于输入的是 Unity 的输入系统,在本例中称为水平轴。这通常可以通过 A 和 D 按钮或左右箭头键进行控制。关于输入的文档页面:docs.unity3d.com/ScriptReference/Input.html 要缩放边界,请将玩家移动到靠近边界的位置,查看他的坐标是什么,然后将该坐标应用于 Bounds 变量。不知道你所说的生成位置变化是什么意思,它不应该对生成位置产生影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
相关资源
最近更新 更多