2015-01-04 6 views
0

3D 게임을하고 캐릭터 이동을 올바르게 설정하려고합니다. 상호 작용은 간단합니다. 화면에 하나의 모델이 있고, 사용자가 화면상의 한 점을 클릭하고, 클릭 한 점을 향하도록 모델이 회전합니다 (모델은 눈으로 약간의 유령이기 때문에 눈은 클릭 한 얼굴을 향하게됩니다). 포인트), 한 번 포인트를 마주, 모델은 거기로 이동합니다.유니버설 트윈 엔진/LibGDX : 트윈 사이에서 트위닝 간의 회전 및 변환이 손실되는 모델

내가 작성한 코드로이 작업을했지만 애니메이션이 부드럽지 않고 모델이 종종 대상을 오버 슛/언더 슛 (undershoot/undershoot) 한 다음 뒤로 또는 앞으로 움직여 자리를 잡습니다. 나는 2 차원 애니메이션에 대한 유니버설 트윈 엔진으로 만 작업 했었지만 시도해보기로했습니다. 그것은 jerkiness 문제를 해결하고 두 가지를 모두 잘 돌아가며 회전시키고 변형 시키지만 순서대로 함께 작업 할 수는 없습니다.

모델을 회전시키는 코드 만 활성화하면 잘 동작합니다 (잘 돌면 거의 괜찮습니다. 특정 각도에서 시계 방향 또는 시계 반대 방향 회전을 결정할 때 이상한 점이 있지만 나중에 다른 문제가 있습니다). 위치를 선택하면 모델이 회전하여 다음 클릭까지 새 회전을 유지 한 다음 해당 위치를 향하게됩니다. 번역 만 사용 가능 : 지점을 클릭하면 모형이 이동하고 다시 클릭 할 때까지 새로운 번역이 유지 된 다음 해당 위치로 이동합니다.

번역 및 회전이 모두 활성화되면 실행됩니다. 문제. 모델은 먼저 클릭 한 점을 향하도록 회전 한 다음 초기 회전으로 다시 설정 한 다음 클릭 된 점으로 이동합니다. 이후의 클릭에서 모델은 처음에 초기 변환으로 돌아간 다음 클릭 한 점 (실제로 다시 초기화 된 위치를 기준으로 클릭 한 점의 위치)을 향하도록 회전 한 다음 클릭 된 점으로 이동합니다.

콜백을 사용하여 코드 재 배열을 시도하고 게임 모델 클래스의 멤버에게 새 번역 및 회전을 캐시 한 다음 트위터를 시작하기 전에 set()에 값을 사용했지만 아무 것도 작동하지 않았습니다. 여기

TweenAccessor에서 관련 코드 :

public class GameModelTweenAccessor implements TweenAccessor<DynamicModel> {  
    public int getValues(DynamicModel target, int tweenType, float[] returnValues) { 
     trans = target.model.transform.getTranslation(trans); 
     switch (tweenType) { 
      ... 
      case POSITION_XYZ: 
       returnValues[0] = trans.x; 
       returnValues[1] = trans.y; 
       returnValues[2] = trans.z; 
       return 3; 
      case ROTATION: 
       axisVec = new Vector3(); 
       angle = target.model.transform.getRotation(new Quaternion()).getAxisAngle(axisVec) * axisVec.nor().y; 
       returnValues[0] = angle; 
       return 1; 
      ... 
     } 

    } 

    public void setValues(DynamicModel target, int tweenType, float[] newValues) { 
     trans = target.model.transform.getTranslation(trans); 
     switch (tweenType) { 
      ... 
      case POSITION_XYZ: 
       target.model.transform.setToTranslation(newValues[0], newValues[1], newValues[2]); 
       break; 
      case ROTATION: 
       target.model.transform.setToRotation(Vector3.Y, newValues[0]); 
       break; 
      ... 
     } 
    } 
} 

그리고 여기에 타임 라인 트윈 (이 this file에서의) 시작 코드 :

Timeline.createSequence() 
    .push(Tween.to(screen.ghost, GameModelTweenAccessor.ROTATION, Math.abs(angle - newRotation)/200) 
     .target(newRotation) 
     .ease(TweenEquations.easeNone)) 
    .push(Tween.to(screen.ghost, GameModelTweenAccessor.POSITION_XYZ, duration). 
     target(intersection.x, intersection.y, intersection.z) 
     .ease(TweenEquations.easeNone)) 
    .start(screen.ghostManager); 

사람이 방향으로 날 포인트를 해결책?

편집 : 다른 트윈이 완료되면 각 트윈의 완료에 의해 설정된 변환이 0으로 재설정 된 것으로 보입니다. 이들은 TweenAccessorgetValuessetValues 기능에서 해당 값의 로그를 다음과 같습니다 트위닝이 시작되기 전에

Get Rot: 0.0 

Get Trans: x: 0.0   y: 0.0   z: 0.0 

Get Rot: 0.0 

Get Trans: x: 0.0   y: 0.0   z: 0.0 

Get Rot: 0.0 

Set Rot: 9.598349 
Set Rot: 9.814415 
Set Rot: 10.052449 
... 
Set Rot: 39.99417 
Set Rot: 43.397423 
Set Rot: 46.62333 

Get Trans: x: 0.0   y: 0.0   z: 0.0 

Set Trans: x: 0.0012489144 y: 0.0   z: 0.001180494 
Set Trans: x: 0.024489587 y: 0.0   z: 0.023147952 
Set Trans: x: 0.04921494 y: 0.0   z: 0.04651875 
... 
Set Trans: x: 6.4197707 y: 0.0   z: 6.06807 
Set Trans: x: 6.444479  y: 0.0   z: 6.091425 
Set Trans: x: 6.453598  y: 0.0   z: 6.1000443 

Get Rot: 0.0 

Get Trans: x: 6.453598  y: 0.0   z: 6.1000443 

Get Rot: 0.0 

Get Trans: x: 6.453598  y: 0.0   z: 6.1000443 

Get Rot: 0.0 

Set Rot: 3.4318955 
Set Rot: 6.795984 
Set Rot: 10.0074415 
... 
Set Rot: 156.79567 
Set Rot: 159.99591 
Set Rot: 162.38742 

Get Trans: x: 0.0   y: 0.0   z: 0.0 

Set Trans: x: 0.03550978 y: 3.836017E-8 z: 0.021066409 
Set Trans: x: 0.15527377 y: 1.6773768E-7 z: 0.092117175 
... 
Set Trans: x: 6.848614  y: 7.3983565E-6 z: 4.062985 
Set Trans: x: 6.961268  y: 7.5200533E-6 z: 4.129818 
Set Trans: x: 7.0624847 y: 7.6293945E-6 z: 4.189865 

Get Rot: 0.0 

Get Trans: x: 7.0624847 y: 7.6293945E-6 z: 4.189865 

Get Rot: 0.0 

Get Trans: x: 7.0624847 y: 7.6293945E-6 z: 4.189865 

Get Rot: 0.0 

Set Rot: -3.2620814 
Set Rot: -6.8205137 
Set Rot: -9.834579 
... 
Set Rot: -76.57533 
Set Rot: -79.91388 
Set Rot: -80.610855 

Get Trans: x: 0.0   y: 0.0   z: 0.0 

Set Trans: x: 0.01940876 y: 0.0   z: 0.033669088 
Set Trans: x: 0.04174851 y: 0.0   z: 0.07242267 
Set Trans: x: 0.06332677 y: 0.0   z: 0.109855264 
... 
Set Trans: x: 2.7853239 y: 0.0   z: 4.8318033 
Set Trans: x: 2.808029  y: 0.0   z: 4.8711905 
Set Trans: x: 2.827034  y: 0.0   z: 4.9041595 

getValues는 트윈 (번역 및 회전)의 각 유형에 대해 두 번 호출되고있다. 이 시점에서 변환 값은 마지막 번역 트위닝이 끝날 때 설정 한 값입니다. 회전에 대한 값은 0으로 설정되었지만 (나는 다음 번에 setValues을 호출하는 결과로 추측됩니다).

은 목표 회전에 도달 할 때까지 회전을 위해 여러 번 호출됩니다. 이것은 (회전 재설정을 제외하고) 내가 기대하고 희망하는대로 작동합니다. getRotation이 호출 된 후 변환은 0,0,0으로 다시 설정되지만 setValues에 대한 호출로 설정되지 않습니다 (로그가 없습니다).그런 다음 여러 번의 setValues 호출로 번역이 대상에 애니메이션으로 표시됩니다.

이 후 다른 클릭으로 순환이 다시 시작되고 getValues이 순환 및 변환을 위해 두 번 다시 호출됩니다. 변환은 마지막 Timeline에있는 setValues의 마지막 호출에서 설정된 값을 갖지만 회전 (0으로 돌아 가기)이 트윈을 통과 할 때까지만 변환됩니다.

getValues에 대한 4 건의 통화가 가능할 수 있습니다. 내 설정에서 Timeline이 밀어 넣을 때 순차적으로 실행될 예정인 경우 해당 트윈이 시작되기 전에 번역의 값을 가져 오는 것이 무엇인지 확신 할 수 없습니다. 또한 각 트윈에 대해 왜 getValues이 두 번 호출되는지 잘 모르겠지만 트윈 엔진이 트윈 과정에서 두 번 호출하는 것은 불가능하지 않습니다.

저는 사용하고있는 LibGDX의 번역/회전 기능이 모델에 고정되어 있으며 트위닝 엔진이 아닌 다른 버전과 마찬가지로 번역을 위해 사용했습니다. 회전은 비슷하지만 같은 기능은 아닙니다.

두 번째 변환 중에 Y 값이 바뀌면 조사 할 항목이 있습니다.

+0

주의 할 점은 코드가 게임 루프의 어딘가에있는 트윈 엔진 외부에서 이러한 속성을 수정했을 가능성이 있다는 것입니다. 그것이 일어나는 것과 같이 보인다. – Barodapride

+0

감사합니다. 위치와 회전을 변경하는 다른 것을 제거하기 위해 이전 코드를 살펴 보았습니다. 나는 그것을 모두 가지고 있다고 생각하지만, 다른 모습은 상처를 줄 수 없다. – nils

+0

getter 및 setter를 통해 값을 변경하면 값이 나오는 경우입니다. breakpoint 또는 sysout을 넣는 것은 쉽습니다 (위와 동일). getter 또는 setter에서 특성의 모든 변경 사항을 모니터하십시오. getter 및 setter없이 공용 변수를 사용하는 경우 해당 값이 언제 변경되는지 쉽게 알 수 없습니다. 어쩌면 디버거와 함께 할 수있는 방법이 있지만 익숙하지 않습니다. 내 생각 엔 당신이 속성을 비공개로 설정하려고 시도 할 수 있었고 IDE가 getter/setter없이 설정 한 모든 장소를 가리켜 야합니다. – Barodapride

답변

1

그래서이 솔루션은 Universal Tween Engine과 관련이 없으며 구현 방법도 없습니다. LibGDX의 행렬 변환 함수를 제대로 이해하지 못했습니다. setToRotation에 대한 호출은 변환 행렬을 재설정하고 회전을 적용하여 이전 변환의 영점 조정을 적용합니다. setToTranslation은 회전을 상실한 동일한 작업을 수행합니다.

번역을 위해 대신 setTranslation을 사용했으며 회전이 손실되지 않습니다. 나는 회전을위한 비교 가능한 함수가 있다고 생각하지 않는다. (rotate을 사용하면 모든 종류의 이슈가 발생한다.) 따라서 모델의 위치가 저장된 Vector3을 새로 얻고 setToRotation을 적용한 다음 변환을 새 벡터로 설정한다. TweenAccessor의 업데이트 된 코드는 다음과 같습니다.

public void setValues(DynamicModel target, int tweenType, float[] newValues) { 
    trans = target.model.transform.getTranslation(trans); 
    switch (tweenType) { 
     ... 
     case POSITION_XYZ: 
      target.model.transform.setTranslation(newValues[0], newValues[1], newValues[2]); 
      break; 
     case ROTATION: 
      // store the position 
      Vector3 position = target.model.transform.getTranslation(new Vector3()); 
      // then set the rotation and reset the translation 
      target.model.transform.setToRotation(Vector3.Y, newValues[0]).setTranslation(position); 
      break; 
     default: 
      assert false; 
      break; 
    } 
}