본문 바로가기

분류 전체보기50

게임 개발 - AI(4) 나도 모르게 저녁을 내리 자서 간단하게만 수정한다. 시야각과 객체상의 거리를 구하였으니 우리는 이제 몬스터의 회전을 생각해봐야 한다. move to는 움직임이 없으면 방향의 변화가 일어나지 않기 때문이다. 따라서 Attack Range 내에 타겟을 발견할 시에는 Attack Range 내부에서는 회전을 필연적으로 넣어야 한다는 것이다. 커스텀 데코레이터로 간단하게 구현해보려고 했는데 생각보다 각도에 따라 속도가 달라지는 현상이 있었고, 또 분기마다 이동되는 노드를 제어하기 위해선 tick 을 이용해야한다는 점에서 위 노드랑 달라지는 것이 하나도 없기 때문에 위 데코레이터를 사용했다. 위의 회전 외에도 이제 공격을 만들어 봐야 하는데 공격은 몽타주를 이용할 것이고, 평타와 강타 or 물기를 고려해볼 생각이.. 2022. 2. 5.
게임 개발 - AI(3) 객체 사이의 거리를 구한다. 객체 사이의 거리를 구하는 방법은 GetDistanceTo 메소드를 이용한다. but, 이 메소드는 객체의 중심점, 즉 transform으로부터 데이터를 받아온다. 따라서 공격거리를 가늠할 경우에는 캡슐컴포넌트(겉으로 보이는 캐릭터 영역)의 반경을 더해주어야 제대로 된 거리가 나온다. 객체 사이의 거리를 가늠하면, 이제 시야각에 들어오는지 판별한다. 시야각에 들어와 있다면 공격을 하고, 들어오지 않는다면 회전한다. but 공격이 진행되고 있을 때 공격이 멈추면 안되므로 이후 데코레이터 위치를 조정할 필요성이 있을 것이다. or 데코레이터가 아닌 태스크노드를 통해 회전할 수도 있을 것이다. 회전각은 DotProduct를 이용한다. DotProduct는 벡터 사이즈가 1이어야 하.. 2022. 2. 5.
언리얼 엔진 - 벡터 내적(스칼라곱) 두 벡터의 내적을 통해 우리는 두 벡터의 사이각을 구할 수 있다. 벡터 내적의 원래 이름은 스칼라곱으로, 유클리드 상의 두 벡터를 통해 스칼라값을 얻는 수치다. 이것을 본래 두 벡터를 알고 있고 사이각이 미지수일 때 그 사이각을 구할 수 있는 것이다. https://www.youtube.com/watch?v=IOf1o72aKDc Actor->GetForwardVector() 와 Target->GetActorLocation() - GetActorLocation() 이라는 두 벡터를 통해서 사이각을 구할 수 있다. 이러한 사이각은 Sight Angle을 계산할 때 쓰인다. 2022. 2. 5.
게임 개발 - AI(2) 좀비는 실시간으로 어그로 영역을 통해 캐릭터를 탐지한다. 탐지 후에는 타겟에게 다가가며, 타겟이 전방의 영역에 존재할 경우에 공격을 시행한다. 전방에 없지만 일정 거리 내에 존재한다면 그 방향으로 이동하여 공격한다. 좀비의 이동에는, 평상 이동(매우 느림), 타겟팅 이동(조금 느림), 달리기(빠름), 광폭화(매우 빠름) 타겟팅 이동은 타겟, 즉 인기척을 느꼈을 경우에 살며시 이동하는 느낌이다. 달리기는 타겟팅된 존재가 가까이 느껴질 때 더욱 빨라지는 느낌이다. 광폭화는 피가 줄어든 상태(즉 타격을 심하게 받았을 경우) 마지막 발악으로 매우 빨라진다. 따라서 몬스터에게 AttackRange, DetectRange 두 가지 변수를 추가했다. 우선적으로 정찰의 기본을 구현해보자. DetectEnemy를 서비스.. 2022. 2. 4.
게임 개발 - 몬스터, AI(1) 전체적인 방향은 영상과 같다. Monster-> AI -> BT,BB로 데이터 관리의 형태로 몬스터를 스폰할 예정이고 몬스터는 일반 몬스터, 정예 몬스터, 보스 몬스터로 존재할 것이고 보스 몬스터는 크기가 조금 클 예정이다. #include "MonsterController.h" #include "BehaviorTree/BlackboardData.h" #include "BehaviorTree/BlackboardComponent.h" #include "BehaviorTree/BehaviorTree.h" AMonsterController::AMonsterController() { static ConstructorHelpers::FObjectFinder ABT(TEXT("/Game/Resource/Charac.. 2022. 2. 4.
게임 개발 - UI(4) 원래는 진도를 확확 나가버릴 생각이었는데 가정사로 인해서 어제 만든 아이콘을 적용시켜보았다. 갈수록 짧아지는 개발 분량에 대해서 스스로 자괴감이 들 정도지만 내일부터는 좀 더 분발해보도록 할 예정. 간단하게 아이콘을 받아서 그대로 적용하는 역할이다. class THEZOMBIES_API UUIWidget : public UUserWidget { GENERATED_BODY() UPROPERTY(Meta = (WidgetBind)) class UProgressBar* HPbar; UPROPERTY(Meta = (WidgetBind)) class UProgressBar* SPbar; UPROPERTY(Meta = (WidgetBind)) class UTextBlock* HP; UPROPERTY(Meta = (.. 2022. 2. 4.
언리얼 엔진 - Object를 통해서 Texture 추출하기 처음으로 적어보는 문장형 주제... 실제로 저것 외에는 뭐라고 설명을 해야할 지 모르겠다. 오늘은 UI에 필요한 Icon을 어떻게 해야할까 고민했다가 검색을 오랜시간 거쳤음에도 마음에 드는 Icon이 없어서 SceneCapture2D를 이용해서 만들 생각으로 바꿔먹었다. 애니메이터나 아트쪽 지인이 없다면 그냥 나처럼 날로 해먹자. 외국에 많은 라이브러리 + 에셋 판매를 보면 이것을 이용하여 데이터를 뽑는 것이 많다. 일단 그것을 구매하거나 라이브러리 전체적으로 데이터를 뽑을 수는 없고, 리얼타임으로 작동하는 SceneCapture를 이용하여 모습을 이리저리 이동해보고 이것을 텍스쳐로 뽑아볼 생각이다. 전체적인 구현 루트는 다음의 영상으로 대체. 요약형태로 보여주자면 3d 에셋(스태틱 메시) + 빛이 없다.. 2022. 2. 4.
게임 개발 - UI(3) UI 값을 캐릭터와 연동시킴으로써 유동적인 제어가 가능할 수 있도록 했다. 맵이 전환될 때마다 초기화가 될 예정이므로, 데이터의 유지성은 크게 고려하지 않았다. //HUD의 UI 생성 중에 AddDynamic void ACurrentUseWidget::ShowUIWidget(class UPlayerStatus* PlayerStatus) { if (CrossHair) CrossHair->RemoveFromViewport(); CrossHair = CreateWidget(GetWorld(), CrossHairClass); CrossHair->AddToViewport(); if (StateUI) StateUI->RemoveFromViewport(); StateUI = CreateWidget(GetWorld().. 2022. 2. 4.
게임 개발 - UI(2), HP/SP UE에서는 HUD라는 UI 관리 객체 클래스를 제공한다. HUD 또한 일종의 위젯처럼 구현할 수 있지만 UserWidget이라는 블루프린트의 시각적 효과가 매우 좋기 때문에 HUD C++ 자체의 구현보다는 블루프린트의 변수를 C++로 바인딩하여 HUD 클래스 내부에서 Widget을 관리하는 방법을 주로 사용한다. HUD는 PlayerController에 내장되어 있으며, HUD를 확인하기 위해서는 PlayerController를 참조할 필요가 있다. 오늘은 간단하게 UI를 PlayerController로부터 참조하여 연동되는 것에 대한 부분까지 구현해보았다.(생각보다 오류없는 참조로 구현하고자 시간을 많이 앗아먹었다.) 우측 하단은 현재 들고 있는 CurWeapon에 대한 정보를 담을 생각인데 아직 UI.. 2022. 2. 4.