2014-07-09 2 views
2

Unity에서 간단한 2D 하향식 슈터를 만들려고합니다. 나는 기본적인 움직임과 마우스의 추종을 가지고 있지만 운동에 문제가있다. Up과 Right를 동시에 말할 때마다 예상대로 대각선으로 움직이지만, Up 키를 놓으면 대각선 방향으로 계속 움직여서 오른쪽으로 이동합니다. 움직임을 처리하기위한 코드는 다음과 같습니다.Unity 2D Top Shooter 동작 문제 C#

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)); 
} 

내가 언급 한대로 동작하도록하려면 어떻게해야합니까? 그것이 대각선으로 움직이면 움직임이 보이지 않게됩니다. 도움을 주시면 대단히 감사하겠습니다. 감사.

답변

6

속도를 0으로 시작한 다음 이동 방향을 모두 추가합니다. 그런 다음 벡터를 정규화하고 이동 속도로 크기를 조정합니다. 그렇지 않으면 대각선 걷는 경우 플레이어가 더 빠르게 움직입니다.

나는 코드를 확인하지 않은,하지만이 같은 것을 할 것입니다 : Normalize에 대해서는

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)); 
} 

이 이미지를 보라.

Vector addition

만 위쪽이나 오른쪽에는 속도 1로 움직일 것입니다 걸 으면 (이 우리 나중에 곱 원하는 속도). 그러나 당신이 대각선으로 걸 으면 원하는 속도 (녹색 벡터)의 약 1.4 배를 걸어갑니다. Normalize은 벡터 방향을 그대로 유지하지만 길이 ("크기"라고도 함)는 1 (빨간색 벡터)입니다.

나이가 많은 저격수의 경우 "bunny hopping"이라는 버그가있을 수 있습니다. 이것이 문제의 근원인지 확실하지 않지만 그것이 맞을 것이라고 추측 할 수 있습니다. vel.magnitude > 0.001에 관한

는 :

우리는 실제로 vel.magnitude > 0 경우를 알고 싶어요. 그러나 vel.magnitude은 계산 결과이므로 반올림 오류가 포함될 수 있습니다. 부동 소수점 값을 사용하는 경우 항상 염두에 두어야합니다. 체크 자체는 Normalize 메소드가 절대 값으로 나눌 필요가 있고 0으로 나눈 값이 나쁘기 때문에 수행됩니다. Normalize가이 자체를 검사하는지 확실하지 않습니다.

+0

완벽하게 일했다! 고맙습니다. 마지막 부분을 설명하면 괜찮겠습니까? 나는 화합과 C#을 처음 접했고'vel.magnitude'와'Normalize' Parts를 이해하지 못했습니다. –

+0

'vel.magnitude'는 속도의 "크기"를 얻습니다. 속도가 (1,1)이면 'magnitude'는 ~ 1.4입니다 (Mene이 "토끼 호핑"문제에 대해 말했듯이) 이것은 기본 삼각법 (Sin (ang) = 1/hyp)에서 작동합니다. 'Normalize'는 벡터를 줄여서 최대 성분이 1이되도록합니다. (2,4)는 (0.5,1) – anothershrubery

+0

으로 정규화됩니다. 올바르지 않습니다. 'Normalize'는 크기가 1 인 벡터를 줄 것입니다. – Mene

0

키를 누르지 않았을 때 속도를 강제로 강요하는 유일한 경우 인 것 같습니다.

내가 Input.GetKeyUptrue 때보고 몇 가지 검사를 추가 제안 및 0rigidbody2D.velocityx 또는 y 값을 설정할 수 있습니다,이 같은 아마 뭔가 :

void Update() { 

    if (Input.GetKeyUp(Up) || Input.GetKeyUp(Down)) { 
     rigidbody2D.velocity.y = 0; 
    } 

    if (Input.GetKeyUp(Left) || Input.GetKeyUp(Right)) { 
     rigidbody2D.velocity.x = 0; 
    } 

    ...