관리 메뉴

기억을 위한 기록들

Youtube /CPP- FootPlaceAlgorithm - Character 본문

UnrealEngine/Foot-Place IK 관련

Youtube /CPP- FootPlaceAlgorithm - Character

에드윈H 2020. 6. 30. 20:27

https://www.youtube.com/watch?v=jJNXhmMyk-U

 

우선 글쓰기에 앞서 해당 영상을 학습하며, 작성한 글입니다.

 

 

(해당 영상을 보면 진행 순서가 나옵니다. 해당 영상을 다 본 후에 작성하는 글입니다.)

 

우선 기본적으로 기존 3인칭 캐릭터 클래스와 애님인스턴스 클래스를 추가해준다.

 

캐릭터 클래스 부분 헤더파일 :

 

 

 

6개의 변수를 추가 해주었다.

 

왼발/오른발 BoneName을 가져오는 변수 2개,

- LeftFootBoneName/RightFootBoneName

 

 

왼발/오른발 각각 본의 실제 위치를 갖고 있는 변수 ,

- LeftFootBoneRelativeLocation/RightFootBoneRelativeLocation

 

캐릭터 클래스의 상속 되어 있는 캐릭터 메시를 조정해주기 위한 위치값 저장 변수

- InitialMeshRelativeLocation

 

FootPlaceAnimInatance 라는 애니메이션 인스턴스를 추가해 가져오는 애님 인스턴스 변수

- FootPlaceAnimInatance

 

캐릭터 클래스 부분 cpp파일 :

 

생성자 부분에 초기화 해준 변수로

위의 영상에서는 해당 변수를 레벨에 배치되어 있는 부분에 작성해주었지만, 우선은 언리얼에서 기본적으로 제공해주는 마네킹 캐릭터로만 사용하기에, 위처럼 초기화 해주었다.

 

 

레벨에 배치 되어 해당 변수가 적용되어 있는 모습
해당 본의 위치 foot_l , 반대로 foot_r은 오른쪽 발에 위치해 있다.

그 다음 BeginPlay 부분

 

- 선언한 변수 애님 인스턴스에 현재 캐릭터 애님인스턴스로 초기화 해준다.

 

- 현재 캐릭터 메시에 스켈레탈 메시가 정상적으로 있다면, 현재 왼발 위치 World값을 가져 온뒤, const FVector LeftFootBoneWorldLocation 변수에 초기화 해주고,  구해진 왼발의 World Location 위치를  

RelativeLocation값으로 변환하여  LeftFootBoneRelativeLocation에 초기화 시켜준다. (오른발도 동일하게)

 

- InitialMeshRelativeLocation에 현재 캐릭터 Mesh의 Relative값으로 초기화 시켜준다.

 

 

 

* Foot Place의 IK에서 중요한점 World Location & Relative Location

 

 

이건 따로 작성 해주어야겠다. 

 

 

Tick 함수 부분

 

 

 

- 애님 인스턴스 유효성 검사

 

- GetVelocity.Size()=0 은 움직임이 없을 때만, 즉  실행하도록 즉 걷는 중, 점프 중 일때는 연산 안하도록 처리

 

- 움직임 이 있을때에는 

 

GetMesh()->SetRelativeLocation(InitialMeshRelativeLocation);  //원래 기본 Mesh 위치에 설정 
FPAnimInstance->SetLeftFootAlpha(0.f);  //뒤에서 알아보자
FPAnimInstance->SetRightFootAlpha(0.f);

 

 

- Trace 함수사용을 위한 Hit결과 저장을 위한  FHitResult LeftTraceHit; 변수 선언

 

- 현재 LeftBone의 RelativeLocation 위치 저장 즉 'foot_l 본'을 위한 const FVector LeftFootLocation 변수 선언 후 초기화

 

- bool bLeftFootTraceHit 변수에  UKismetSystemLibrary::SphereTraceSingle(..) 함수 사용 하여,

  Start location (RightFootLocation + FVector(0.0f, 0.f, 50.f)) 부터  End location(RightFootLocation + FVector(0.f, 0.f,     -100.f)) 까지의 범위를 탐색 해주고 결과를 LeftTraceHit에 전달 (부연 설명 제외)

 

 

- 오른발도 동일하게 진행

 

 

 


- float ZOffset=0.f; //Z 값 기준 비교를 위한(각 발의 편차에 대한 캐릭터 메시 조절을 위한 값 ) Offset 0으로 초기화

 

 

- if (LeftTraceHit.ImpactPoint.Z < RightTraceHit.ImpactPoint.Z) 왼발의 Hit Location Z와  오른발의 Hit Location 위치의 Z값을 비교한다.

 

 

- 비교 후, 왼발이 더 낮을때에는 

ZOffset= LeftFootLocation.Z-LeftTraceHit.ImpactPoint.Z;  //현재 왼발의 위치 LeftFootLocation Z에서 LeftTraceHit Z의 차이를 구해준다. 

FPAnimInstance->SetRightEffectorLocation(RightTraceHit.ImpactPoint+FVector(0.f,0.f,14.f));  //뒤에서 알아보자 
FPAnimInstance->SetLeftFootAlpha(0.f); 
FPAnimInstance->SetRightFootAlpha(1.f);

 

 

- 반대로 오른발이 더 낮게 있다면 

 

ZOffset = RightFootLocation.Z - RightTraceHit.ImpactPoint.Z;
FPAnimInstance->SetLeftEffectorLocation(LeftTraceHit.ImpactPoint + FVector(0.f, 0.f, 14.f));
FPAnimInstance->SetLeftFootAlpha(1.f);
FPAnimInstance->SetRightFootAlpha(0.f);

 

 

-그리고 나온 ZOffset을 가지고 캐릭터 SkeletalMesh의 위치를 변경해준다.

GetMesh()->SetRelativeLocation(InitialMeshRelativeLocation + FVector(0.f,0.f,-ZOffset+14.f));

 

오른발이 더 낮게 있다면 오른발 기준으로 캐릭터 메시가  내려간다.
마찬가지로 왼발이 더 낮게 있으면 왼발 기준으로 캐릭터 메시 Z 값 조절

캡슐은 그대로 유지 Mesh만 내려온 모습을 확인할 수 있다.

 

 

 

우선 캐릭터 클래스는 여기까지이다.

 

포인트는

 

- 시작시 FootBoneRelativeLocation 위치 구하는것

 

- 왼발 오른발 높낮이 차이에 따라 캐릭터 Mesh RelativeLocation Z값에 Offset값을 할당해준다는 것이다.

 

 

다음으로 발 위치를 바꿔주기 위한  애님 인스턴스에 대해 알아보자