2017-03-15 17 views
0

一日中、ハードコーディングなしでオフスクリーンにならないようにするための良い解決策を見つけようとしていました。Unityで完全にオフスクリーンにならないようにするにはどうすればいいですか?

私はplayer controllerというスクリプトを持っています。これまでのところ、プレーヤーは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); 
    } 
} 

残念ながら、このコードは良くありません。実際には、プレーヤーが画面外に出るのを止めることはないので、さらに悪化します。

この時点で、私は岩と堅い場所の間にこだわっています。どんな提案も大いに評価されるだろう。

+0

スプライトの中心をスプライトの端にクランプしていますが、2番目の例ではスプライトの画面の端にエッジを固定していません。クランプポジションの代わりにposMinとposMaxを0と1の間で締め付けてみてください。正しい計算を理解することができます(答えが出ていないので今すぐ調べてください) –

+0

@ScottChamberlain posMinとposMaxの両方をMathf.clamp01でクランプし、その後に 'pos.x = Mathf.Clamp(pos.x、posMin.x、posMax.x);'?なぜなら、そのベクトルはtransform.positionに割り当てられるものなので、私はまだposをクランプする必要があるからです。 –

+0

いいえ、オフセットを削除した後にそれぞれ1つずつposを更新した後に2つのクランプを実行する必要があることを意味します。今日の仕事の後、私は戻って基本的な構造で答えを書きます。 –

答えて

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位置?

関連する問題