여러 키를 눌렀을 때 이동 속도 스태킹을 피하는 방법은 무엇입니까?


17

마우스가 필요없는 새로운 게임을 시작하여 키보드까지 움직임을 남깁니다. 나는 8 방향을 통합하려고 노력했다; 위, 왼쪽, 오른쪽, 위 오른쪽 등. 그러나 두 개 이상의 화살표 키를 누르면 이동 속도가 쌓입니다 ( http://gfycat.com/CircularBewitchedBarebirdbat ). 이 문제를 어떻게 해결할 수 있습니까?

내 코드의 관련 부분은 다음과 같습니다.

var speed : int = 5;

function Update () {
    if (Input.GetKey(KeyCode.UpArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.RightArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftArrow)) {
        transform.rotation = Quaternion.AngleAxis(315, Vector3.up);
    }
    if (Input.GetKey(KeyCode.DownArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}

3
탄젠트 : 코드의 들여 쓰기가 약간 엉망이되어 처음에는 알지 못했지만 코드의 조건으로 인해 대부분의 코드가 실행되지 않습니다. 마찬가지로 if (UpArrow) else if (UpArrow && RightArrow)는 'else'분기를 실행하지 않습니다.
— jhocking

답변:


13

방향 선택 코드를 실제 이동 코드와 분리하십시오.

  1. Direction어떤 키를 눌렀는지 확인하여 선택하십시오 . 단위 (정규화 된) 벡터로 저장하십시오.
  2. 당신을 곱 Direction과 Speed와 함께 DeltaTime.
  3. 결과 변환을 오브젝트 / 카메라에 적용하십시오.

27

방향의 합계를 가져 와서 정규화 한 다음 속도를 곱해야합니다.

대각선 움직임 방지에 대한 응답의 일부로 이것을 접선으로 대답했습니다.

구체적으로 특별히:

velX = 0;
velY = 0;

if(keyLeft) velX += -1;
if(keyRight) velX += 1;
if(keyUp) velY += -1;
if(keyDown) velY += 1;

// Normalize to prevent high speed diagonals
length = sqrt((velX * velX ) + (velY * velY ));
if (length != 0)
{
    velX /= length;
    velY /= length;
}

velX *= speed;
velY *= speed;

3
Heheh, Larry는 자랑스러워 할 것입니다! c2.com/cgi/wiki?LazinessImpatienceHubris
— jzx

3
Unity는 이미 Vector 의 크기 와 제곱 크기 를 얻는 방법을 제공합니다 .
— Selali Adobor

1
아무 키도 누르지 않으면 NaN이 생성됩니다.
— CodeInChaos

1
@jzx 사실, 우리는 전설적인 Hobbits처럼되기 위해 노력합니다. youtube.com/watch?v=G49RUPv5-NU
— Pharap

11

"정규화 된 방향 벡터"는이 작업에 일반적으로 접근하는 방법과 자주 수행하는 방법이지만 최근에는 결과 이동 벡터를 고정하고 있습니다. 일반적으로 동일한 최종 결과를 달성하며 코드가 훨씬 간단합니다.

var moveSpeed = 6.0f;
function Update() {
  var movement = Vector3.zero;
  movement.x = Input.GetAxis("Horizontal") * moveSpeed;
  movement.z = Input.GetAxis("Vertical") * moveSpeed;
  movement = Vector3.ClampMagnitude(movement, moveSpeed);
  movement *= Time.deltaTime;
  transform.Translate(movement);
}

간단한 코드가 거의 항상 좋습니다.


무엇 을 하는가? ClampMagnitude그것은 Normalize * Constantdisquise에서 와 같은 코드 가 아닌가?
— 크롬 스터, 모니카

2
좀 빠지는. 값을 "클램핑"하면 값이 일정 범위 내로 유지되고 최대 값 미만으로 유지됩니다. 적어도 Unity에서는 GetAxis ()가 약간 가속하는 값을 반환하여 부드럽게 움직입니다. 벡터를 정규화하면 가속도가 무시되고 클램핑으로 가속이 발생합니다. 미묘하지만 멋지게 보입니다. 그러나 최종 효과는 거의 동일합니다.
— jhocking

1
Unity의 맥락에서 직접 작성된 유일한 답변 인 +1. API는 이러한 상황을 염두에두고 모든 종류의 유용한 Vector / Quaternion 수학 메서드를 제공합니다.
— Selali Adobor

나는 1로 moveSpeed고정하고 클램핑 후 만 곱하고 곱셈과 병합 할 수 있습니다 deltaTime.
— 코드 InChaos

그 변화가 단지 하나의 곱셈 연산을 제거하는 것 이상을 얻습니까? 마찬가지로, 클램핑 1이 클램핑 6과 다르게 작동합니까? 당신의 변화가 무엇인지 궁금해 ...
— jhocking
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.