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


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. 당신을 곱 DirectionSpeed와 함께 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.