애니메이션 도중, 다른 애니메이션으로 전환할 때
CurFrame으로 현재 애니메이션의 프레임을 가져와서,
다른 애니메이션에서 해당 프레임부터 재생을 시작하는 기능을 만들었습니다.
하지만 종종 CurFrame으로 마지막 프레임을 가져와 재생할 경우
해당 애니메이션의 처음 프레임이 노출되는 경우가 발생하는데
어제부터 원인을 도저히 찾을 수 가 없네요...
위 Gif의 초반 부분을 보시면 그냥 애니메이션을 실행시키면 잘 진행됩니다.
하지만 지금 재생중인 메시그룹과 다른 메시그룹으로 이루어진 애니메이션을
(메시 그룹은 Side, Front, Back 3가지로 이루어져 있고 좌우는 Flip으로 처리합니다)
PlayAt으로 실행 시킬 시 애니메이션의 첫 프레임의 모습이 잠깐씩 보입니다.
(첫 프레임 - 지면에 서있는 모습)
원래는 상 하 때도 문제가 보이고 더 많이 보여야 하는데 gif 녹화 툴이 좋지 않아서
많이 생략되어 보이네요.
(공중에서 좌우 전환은 Flip으로 처리되는 부분이라 오류가 발생하지 않습니다)
위 점프 애니메이션을 사용할 때의 코드입니다.
실험을 위해
jumpingAnimeData = portrait.PlayAt(_animeName, currentframe);
윗줄에 portrait.StopAll(); 이나 portrait.PauseAll(); 를 사용해봤지만 반응은 같았습니다.
위에 설명했지만
애니메이션들은 Back, Side_Right, Front
그룹인 총 3가지 그룹으로 이루어진 애니메이션들이고
각각 애니메이션들은 반복 재생이 비 활성화 되어 있으며
시작 프레임과 종료 프레임, FPS가 같은 상태들입니다.
혹시 키 입력 시 코드상 오류로
점프가 아닌 다른 애니메이션이 시작되는게 아닐까도 생각하여
(당연히 jump중일땐 다른부분이 막혀서 안되는게 당연하지만)
다른 애니메이션 실행부분에 모두 디버그 출력을 입력하여
일일히 노가다로 체크해봤지만
점프 애니메이션 도중 다른 애니메이션이 출력되는 경우는 없었습니다...
혹시 윗부분에 써놓은 코드가 문제인지
아니면 다른 설정부분의 문제가 있는것 인지 알 수 가 없네요 ㅠㅠ
* 추가
게시글 올리려고 gif 파일들을 보면서 분석을 해봤는데
왼쪽 방향키, 위쪽 방향키 를 반복적으로 누르는 경우
왼쪽을 누르면 위족방향을 보는 애니메이션의 잔상이,
위쪽 방향을 누르면 왼쪽 애니메이션의 잔상이 보입니다.
즉, PlayAt을 사용하여 다른 메시그룹의 애니메이션을 마지막 프레임에서 실행할 경우
(ex : PlayAt("다른애니메이션", 15);)
현재 진행 중이었던 애니메이션의 첫 프레임이 출력되고
다른 메시그룹의 애니메이션이 요청받은 프레임부터 정상적으로 출력되는 것으로 생각됩니다.
1 - 애니메이션 정상 실행 후 종료
2 - CurFrame으로 마지막 프레임을 받아옴
3 - 다른 메시 그룹의 애니메이션을 PlayAt으로 요청
4 - 현재 실행되던 애니메이션의 0프레임 출력
5 - 다른 메시 그룹의 마지막 프레임 애니메이션 정상 출력
이번에도 Gif에는 상당히 생략되어 있지만
실제로는 한 50프로 확률로 발동되는 것 같네요.
100프로 발동되는 것 도 아니고...
버그 수정 감사합니다!
잘 해결되었습니다!
안녕하세요!
버그를 수정한 파일을 공유드립니다.
아래의 링크에서 UnityPackage 파일을 다운로드한 후, 해당 프로젝트에 임포트하시면 스크립트 파일 하나(apAnimPlayUnit.cs)가 업데이트될 것입니다.
https://drive.google.com/file/d/14_TduF3Xwrg1yDPiCNTWEgEIZFlhTMy7/view?usp=sharing
이 파일은 AnyPortrait v1.2.6에서 동작되며, 그 외의 버전을 사용하고 계시다면 다시 저희에게 알려주세요.
코드를 확인한 결과, 버그의 내용은 애니메이션에 의해서 루트 유닛이 전환될 때, 1프레임 늦게 전환되는 것이었습니다.
따라서 PlayAt을 포함한 다른 Play 함수에서도 동일한 현상이 나타났으며, 만약 루트 유닛이 전환되는 것이 아니라면 문제는 없었습니다.
그래서 Play 혹은 PlayAt 함수가 호출되는 시점에 맞게 루트 유닛이 전환되도록 만드는 것으로서 이 문제를 해결할 수 있었습니다.
저희의 테스트에서는 버그가 해결된 것으로 나타났으며, 이 버그는 곧 업데이트될 정식 버전에도 반영될 예정입니다.
만약 문제가 해결되지 않는다면 글을 남겨주세요!
감사합니다.
Eng)
Q. When the root unit is switched with animation playback, the previous root unit's appearance is displayed one more frame.
A. This is a bug, and an improved version will be applied in the update. Please use the temporarily attached file of the link.
포기하고 다른 방향을 해야 될까 고민하고 있었는데
수정 해주신다니 감사합니다!
첨부해주신 GIF 파일을 프레임마다 하나씩 확인을 해보았습니다.
말씀해주신 대로 첫 프레임이 나오는 것이 아니라 메시 그룹이 전환될 때, 이전 메시 그룹의 기본 모습이 순간적으로 나타나는 것으로 보입니다.
그 정보를 중심으로 테스트를 진행하였으며, 버그로 보이는 현상을 실제로 확인하였습니다.
코드 상에서 아직 문제의 원인을 찾지는 못했지만, 테스트를 더 진행하고 코드를 검토하여 문제를 찾아낼 수 있을 것 같습니다.
이 문제는 저희가 해결하여 다시 답변을 드리겠습니다.
애니메이션 시스템이 복잡하여 문제를 해결하는데 다소 시간이 걸릴 수도 있으니 양해 부탁드립니다.
다시한번 빠르게 문제를 해결해드리지 못한 점에 대해서 사과의 말씀을 드립니다.
문제를 찾기위해 실험좀 해보느라 좀 늦었습니다.
우선 말씀 주신데로 메시그룹을 다 최상위로 바꿨지만
아쉽게도 증상은 같았습니다.
아직 문제를 해결하진 못했지만
실험의 결과만 말씀드리면,
제가 PlayAt을 사용하는 경우,
대체 어느 애니메이션이 출력되는건가 싶어서
Back 메시 그룹과 관련된
모든 애니메이션들의 첫 프레임과 마지막 프레임에서
캐릭터의 두 팔을 때어 버렸습니다.
이런식으로요...
하지만 실험한 결과
뒷모습이 나올 때 팔은 다 정상적으로 붙어있었습니다.
아무래도 메시그룹의 기본 모습이 나오는건가 싶은
생각이 들고 있긴한데... 혼란하네요...
헐... 이렇게 하면 안 되는 거였군요.
일단 제 경우에는 자식 메시 그룹도 루트 유닛으로 지정하니
애니메이션이 재생 되었던 것 같습니다.
우선은 링크를 주신 자식 메시그룹 데이터 이전이랑
애니메이션 파일로 내보내기 기능을 섞어서
애니메이션들을 살리면서
메시 그룹들을 최상위 그룹으로 바꿔보겠습니다...
답변 작성을 하느라 추가 내용을 늦게 확인하였습니다.
마침 저희도 첨부해주신 이미지중 애니메이션 "Front_Jumping"이 최상위 메시 그룹인 "Full"이 아닌 자식 메시 그룹인 "Front"에 연결된 것을 확인하고 이 점에 대해서 생각하는 중이었습니다.
원칙적으로는 자식 메시 그룹엔 애니메이션이 연결 될 수 없으며, 오직 루트 유닛이 되는 "최상위 메시 그룹"만 애니메이션의 재생 대상이 될 수 있습니다.
그래서 일반적으로는 자식 메시 그룹에 애니메이션을 연결하더라도 게임 실행시 에러가 발생하거나 정상적으로 동작하지 않습니다.
저희도 이점 때문에 자식 메시 그룹에 대해 각각 애니메이션을 만들고 비슷하게 재생하는 테스트를 하였는데, 저희의 예상대로 에러가 발생하여 애니메이션을 재생할 수 없었습니다.
자식 메시 그룹에 애니메이션을 연결하면 아예 재생이 불가능한 것이 맞는데, (약간의 프레임 문제를 가진 상태로라도) 실행이 되는 것이 저희의 생각으로는 오히려 이상한 상황입니다.
AnyPortrait의 스펙대로 원래는 최상위 메시 그룹에 대해서 모든 애니메이션이 작성되어야 하며, 따라서 Morph (Animation) 모디파이어, Transform (Animation) 모디파이어는 자식 메시 그룹에 생성되면 안됩니다.
만약 자식 메시 그룹에 애니메이션을 작성했다면, "데이터 이전 기능"을 이용하여 부모 메시 그룹에 연결되도록 만들 수 있습니다.
애니메이션의 대상 메시 그룹 변경과 데이터 이전 방법에 대해서는 아래의 링크를 확인해주세요.
https://rainyrizzle.github.io/kr/AdvancedManual/AD_AnimationIssueChild.html
다만 이 과정은 복구가 어려울 수 있으므로, 백업용으로 해당 캐릭터의 GameObject를 복사해두는 것을 권장해드립니다.
다만, 이 방식을 사용하면 모든 방향의 캐릭터에 대해서 모든 애니메이션을 수정할 필요가 있습니다.
(예: Front에 대한 애니메이션에서도 Back이나 Side_Right 메시 그룹에 대한 타임라인 레이어를 작성해야합니다.)
따라서 필요에 따라서는 각각의 방향에 해당하는 메시 그룹을 Full로 묶지마시고, 모두 최상위 메시 그룹으로 만들고, 여러개의 루트 유닛(Root Unit)이 되도록 만드는 것도 좋을 것 같습니다.
즉, "Full(루트 유닛) > Front / Back / Side_Right"에서 "Front(루트 유닛), Back(루트 유닛), Side_Right(루트 유닛)"로 분리하는 것이 좋은 방법일 수도 있습니다.
마찬가지로 이 경우에도 복구가 어려울 수 있으니 백업용 캐릭터를 만드는 것을 권장해드립니다.
이것이 프레임 문제의 직접적인 원인인지는 확인이 되지 않습니다만, 일단 저희가 권장하는 애니메이션과 메시 그룹의 구조와는 차이가 있어서 변경하는 것이 좋을 것 같습니다.
위 내용을 확인해보시고 다시 알려주시면 계속해서 도움을 드리겠습니다.
감사합니다.
비슷한 상황까지 만들어 주시면서 실험해주셔서 감사합니다.
저도 작성하신 부분의 오류를 겪어봤기 때문에
점프 애니메이션이 끝난 경우
public void JumpEnd()
{
print("Jump End");
jumpingAnimeData = null;
}
따로 null 값으로 초기화 해주는 기능이 있습니다.
그 부분에 대해서는 지금 겪고있는 문제와
크게 연관이 없어서 까먹고 글에 따로 안적었네요.
문제가 없다는 것을 실험해주셨으니
제 다른 코드들을 하나하나 다시 까보며 디버깅 해봐야겠는데,
한가지 궁금한게 실험하실 때 사용하신
애니메이션 Anim1, Anim2, Anim3 혹은 Idle 애니메이션 중
다른 메시그룹의 애니메이션이 있나요?
다름이 아니라 그냥 가능성으로 생각 들었던 것이
PlayAt으로 다른 메시그룹의 애니메이션을 불러오는 경우
해당 문제가 생기는 것이 아닐까 싶어서 질문 글을 올렸던것이었습니다.
제가 여러 메시그룹들을 이용한 애니메이션들은
일반 Play로 잘 사용하고 있는데
PlayAt 저기서만 문제가 일어나서요..
일단 문제를 좀 더 찾아보고 안되면 다른 방법을 강구해봐야겠네요.
안녕하세요, RainyRizzle 팀입니다.
문의 주신 내용을 검토해보고 저희가 비슷한 상황을 테스트해보았습니다.
다만, 전체 스크립트를 알지 못한 상태에서 진행하였으므로, 결과나 원인이 다소 다를 수 있다는 점 양해 부탁드립니다.
Loop가 아닌 애니메이션만 있는 조건에서는, 즉 이 경우엔 "점프 애니메이션"만 있는 경우엔 애니메이션 프레임이 잘못 가져오거나 잘못 입력되는 경우는 없었습니다.
반면, Loop 애니메이션이나 다른 애니메이션, 즉 "점프가 아닌 애니메이션이 이어서 재생되는 경우"에서 문제가 발생했습니다.
저희의 경우엔 프레임을 공유할 수 있는 3개의 Loop가 아닌 애니메이션과 Idle 애니메이션 1개를 만들고, 항상 점프 이후엔 Idle 애니메이션이 실행되도록 PlayQueued() 함수를 이용하였습니다.
Idle 애니메이션이 실행되는 동안엔 문의주셨던 코드의 변수인 "jumpingAnimeData"가 null로 초기화되어야 하는데, 만약 그렇지 않는다면 잘못된 프레임을 가져올 수 있습니다.
저희는 위와 같이 코드를 작성했습니다.
특히, 붉은색 박스에 다음과 같은 코드를 추가로 작성하여 점프 애니메이션이 재생되지 않는 경우인데도 jumpingAnimeData 변수가 null이 아닌 경우엔 null로 초기화될 수 있도록 만들었습니다.
if ( jumpingAnimeData != null && jumpingAnimeData.PlaybackStatus != apAnimPlayData.AnimationPlaybackStatus.Playing )
{
jumpingAnimeData = null;
}
이렇게 하여 "점프 애니메이션 재생이 끝난 이후에도 jumpingAnimeData에서 프레임을 가져오는 경우"를 방지할 수 있었습니다.
PlayQueued를 이용한 저희의 테스트 도중엔 Idle 애니메이션이 잠시 나타나서 제보해주신 것과 유사하게 이상하게 보여진 경우도 있었습니다만,
디버그를 통하여 다른 애니메이션은 재생되지 않았음을 확인하셨다고 하셨으므로 이 경우엔 해당되지 않는 듯 합니다.
저희가 현재 정확하게 원인과 현상을 파악하지는 못했습니다.
위 내용을 확인해보시고 저희에게 추가적인 정보를 주신다면 다시 도움을 드리겠습니다.
감사합니다.