분류 전체보기
#13 3번째 스프린트 수립
지난 스프린트 회고 지난 스프린트는 일주일간 진행됐고, 주로 메인 캐릭터의 전투 시스템 개선에 목적을 두었다. 의도했던 정도로 업데이트하는 데에 전혀 차질이 없었다. 사실 생각보다 빨리 끝났는데, 언리얼 엔진을 계속 쓰다보니 아무래도 헤매는 시간이 줄어든 것 같다. 그래서 기능이나 함수를 찾지 못해 허비하는 시간이 줄어들었고, 이로 인해 진짜로 신경써야 하는 부분에 빠르게 접근할 수 있었다. 이번 스프린트 계획 이번 스프린트의 목표는 "흥미로운 적 AI 개발"이다. 이를 위해 4가지 세부 목표로 나누었다. AI가 Player와 비슷한 수준의 Animation을 가지고 있다. AI가 패트롤할 수 있다. AI가 시야가 있고 이에 따른 행동을 취한다. (현재는 무조건 적대) AI 공격 시 저마다의 행동 패턴을..
#12 연속 공격 시스템 구현
연속 공격 시스템 연속 공격 시스템이 작동하는 방식은 간소화했다. 일정 타이밍, 정확히는 CombatStatus가 Recovery일 때, 다시 공격하면 다른 공격모션이 발동한다. 약공격은 3연속, 강공격은 2연속 공격을 할 수 있다. 타이밍이 정확해서 구현하는 데에 어려움이 없었다. 구현은 빠르게 했는데, 다른 곳에서 발생한 다른 버그가 있어서 그런 부분들을 남은 시간에 해결했다. 메가 스캔을 써보면서 퀵셀 에셋을 둘러봤는데, 아직 애매하다. 결과
#11 Strafe Movement with Evade
Root motion in blend space 이 작업에서 가장 헤맸던 부분은 Evade 애니메이션을 Root Motion으로 재생해야 하는데, 4방향 밖에 없다는 것이었다. 45도나 135도는 물론, 패드까지 지원하려면 Blend Space를 써야한다. 문제는 Blend Space에 애니메이션을 넣어도 Root Motion이 적용되지 않는 것이었다. 정확히 말하면 애니메이션은 재생되는데, 위치는 움직일 수 없는 상태였다. 문제는 AnimInstance의 Root Motion Mode 였다. Root Motion Mode는 다음 4가지다. No Root Motion Extraction 루트 모션 추출 없음 - 루트 모션은 그대로 놔둡니다 (루트 본에 적용됩니다). Ignore Root Motion 루트..
#10 lock on일 때, strafe movement 구현
Lock on, Strafe Movement Lock on 상태일 때, strafe movement(게다리 걸음)가 되려면 아래 세가지가 적용돼야 한다. Lock on Target을 카메라(여기선 컨트롤러와 동일)가 바라봐야한다. 그 카메라가 바라보는 방향으로 캐릭터도 바라봐야 한다. 이후 움직임에 대해서 방향을 계산하고 이에 따라 적절한 애니메이션을 재생해야 한다. (Blendspace) 카메라 회전은 #8에서 구현했다. 그 다음으로, 카메라 방향에 따라 캐릭터의 Rotation을 업데이트해야 한다. 간단한 코드인데, Character에서 바로 SetActorRotation에 접근하지 못해서 애먹었다. void AMainCharacter::LookAtTarget (float DeltaSeconds) c..
#9 스프린트 계획
지난 주 스프린트를 끝내고 이번 주 스프린트 계획을 새로 세웠다. 이번주의 목표는 크게 Strafe Movement 구현 연속 공격 시스템 구현 이다. 생각대로 빠르게 구현할 수만 있으면 좀 빠르게 끝날 수도 있겠다.
#8 타게팅 시스템 구현
레이트레이스 타겟을 찾는 방식을 아래와 같이 단순화했다. 타게팅 버튼을 누르면 120도에 걸쳐 원뿔 모양으로 레이를 쏜다. 그 중 가장 가까운 타겟을 찾아 락온타겟으로 레퍼런스를 저장한다. 만약 타겟이 이미 있으면 타게팅을 그만한다. 언리얼에서는 Raytrace가 KismetSystemLibrary에 모여있다. 그냥 레이를 쓰면 운이 안좋으면 레이에 안맞을수도 있어서 Sphere모양으로 쏘게끔 했다. void AMainCharacter::LockTarget() { if (bHasLockTarget == false) { // 120도의 부채꼴 모양으로 레이트레이싱을 실행한다. FVector CameraForwardVector = GetFollowCamera()->GetForwardVector().Rotat..
#7 기본 모드일 때, 회피 구현
회피 타게팅이 되어있지 않은 상태에서 회피를 구현했다. 이 때, 회피는 앞 방향과 뒤 방향만 구현한다. 구현 방식은 다음과 같다. 방향키를 누르지 않은 채로 회피 -> 뒤로 회피 방향키를 누른 채로 회피 -> 해당 방향을 보면서 회피 이전에 Movement Status를 설정해놔서 구현하는데에 적은 시간이 걸렸다. 회피 애니메이션도 Root Motion으로 해서 따로 코드를 더할 필요가 없었다. 결과
#6 메인 캐릭터와 적 캐릭터의 죽음 구현
죽음 애니메이션 구현 죽음 애니메이션을 구현할 때, 두가지 문제가 있었다. 죽으면 딱 애니메이션이 정지되어야 한다. 죽고 일정 시간 후 액터가 사라져야 한다. 먼저 애니메이션 정지가 생각보다 구글링으로 찾기 힘들었는데, 간단히 해결 할 수 있었다. GetMesh()->bPauseAnims = true; 액터가 몇초후에 사라지게 하려면 이를 위한 타이머가 필요한데, 이번 경우엔 월드타이머매니저를 불러왔다. 함수 형태가 요상하다. // RepeatingFunction 을 초당 1 회, 지금부터 2 초간 호출합니다. GetWorldTimerManager().SetTimer(MemberTimerHandle, this, &AMyActor::RepeatingFunction, 1.0f, true, 2.0f);