2017-03-15 2 views
0

하루 종일 하드 코딩없이 화면을 벗어나지 못하게하는 좋은 해결책을 찾으려고 노력했습니다.Unity에서 플레이어가 화면에서 벗어나는 것을 완전히 막는 방법은 무엇입니까?

나는 플레이어 컨트롤러라는이 스크립트를 가지고 있으며 지금까지 플레이어가 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

두 번째 예제에서 스프라이트 가장자리가 스프라이트 가장자리가 아니라 화면 가장자리까지 스프라이트 중심을 고정시키고 있습니다. 클램핑 포지션 대신 posMin과 posMax를 0에서 1 사이로 클램프하는 것을 살펴보십시오. 정확한 수학을 알아낼 수 있습니다 (대답을 게시하지 않으려 고 너무 졸려서). –

+0

@ScottChamberlain 그래서 여러분이 말하는 것은 다음과 같습니다. posMin과 posMax를 모두 Mathf.clamp01로 클램프하고 그 후에'pos.x = Mathf.Clamp (pos.x, posMin.x, posMax.x);'? 왜냐하면 그 벡터가 transform.position에 할당되면 무엇이든지 상관없이 여전히 pos를 고정해야하기 때문입니다. –

+0

아니, 오프셋을 제거한 후 각 하나가 pos를 업데이트 한 후에 두 개의 클램프를 수행해야한다는 뜻입니다. 오늘 일을 마치고 돌아와서 기본 구조로 답을 쓸 것입니다. –

답변

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 위치가 아닌가?

관련 문제