如何完全阻止玩家在Unity中离开屏幕?

时间:2017-03-15 03:34:42

标签: c# unity5 clamp

整整一天,我一直试图找到一个很好的解决方案来完全阻止播放器在没有硬编码的情况下离开屏幕。

我有一个名为播放器控制器的脚本,它到目前为止所做的只是允许播放器沿x轴移动。它还有一个额外的功能,可以锁定玩家在x轴上的移动。在这里。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public const float MAX_SPEED = 5.0f;

    // Update is called once per frame
    void Update()
    {
        transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
        clampPlayerMovement();
    }

    void clampPlayerMovement()
    {
        Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
        pos.x = Mathf.Clamp01(pos.x);
        transform.position = Camera.main.ViewportToWorldPoint(pos);
    }
}

这个剧本的问题在于它并没有完全阻止玩家离开屏幕(玩家身体的一半仍然在屏幕外)。

所以这就是我接下来要尝试的。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public const float MAX_SPEED = 5.0f;

    private float xLeft;
    private float xRight;

    void Start()
    {
        float pivotX = GetComponent<SpriteRenderer>().sprite.pivot.x;
        float pixelsPerunit = GetComponent<SpriteRenderer>().sprite.pixelsPerUnit;
        float textureWidth = GetComponent<SpriteRenderer>().sprite.texture.width;

        //Units on the left from the sprite's pivot.
        xLeft = pivotX / pixelsPerunit;

        //Units on the right from the sprite's pivot.
        xRight = (textureWidth - pivotX) / pixelsPerunit;
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
        clampPlayersMovement();
    }


    void clampPlayersMovement()
    {
        Vector3 pos = transform.position;
        Vector3 posMin = transform.position;
        Vector3 posMax = transform.position;

        posMin.x = posMin.x - xLeft;
        posMax.x = posMax.x + xRight;

        pos = Camera.main.WorldToViewportPoint(pos);
        posMin = Camera.main.WorldToViewportPoint(posMin);
        posMax = Camera.main.WorldToViewportPoint(posMax);

        pos.x = Mathf.Clamp(pos.x, posMin.x, posMax.x);
        transform.position = Camera.main.ViewportToWorldPoint(pos);
    }
}

不幸的是,这段代码并不好。事实上,情况更糟,因为它并没有阻止玩家离开屏幕。

所以在这一点上,我被困在一块岩石和一块坚硬的地方之间。任何建议都会受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

经过长时间的搜索,我终于找到了答案。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public const float MAX_SPEED = 5.0f;

    private float halfPlayerSizeX;

    void Start()
    {
        halfPlayerSizeX = GetComponent<SpriteRenderer>().bounds.size.x / 2;
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
        clampPlayerMovement();
    }

    void clampPlayerMovement()
    {
        Vector3 position = transform.position;

        float distance = transform.position.z - Camera.main.transform.position.z;

        float leftBorder = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance)).x + halfPlayerSizeX;
        float rightBorder = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, distance)).x - halfPlayerSizeX;

        position.x = Mathf.Clamp(position.x, leftBorder, rightBorder);
        transform.position = position;
    }
}

我唯一没有得到的是为什么我需要从游戏对象和相机中减去z位置?为什么不是x位置?