userWidget을 부모로 Itemshop이라는 클라스를 만들자
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "MyUserWidget.h"
#include "ItemShop.generated.h"
/**
*
*/
UCLASS()
class TEAM_ISLAND_MASTER_API UItemShop : public UMyUserWidget
{
GENERATED_BODY()
public :
UPROPERTY(EditAnyWhere, BlueprintReadWrite,Category = "Shop")
class AMyTable* ownerTable;
UPROPERTY(EditAnyWhere, BlueprintReadWrite, Category = "Shop")
FText ctextId;
UPROPERTY(EditAnyWhere, BlueprintReadWrite, Category = "Shop")
FText ctextPos;
UFUNCTION( BlueprintCallable, Category = "Shop")
void SetTextID(FText value);
UFUNCTION(BlueprintCallable, Category = "Shop")
void SetTextPosition(FText value);
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "ItemShop.h"
void UItemShop::SetTextID(FText value)
{
ctextId = value;
}
void UItemShop::SetTextPosition(FText value)
{
ctextPos = value;
}
텍스트를 윗젯클래스의 변수와 직접 연결 나중에 알은건데 이러면 NPC쪽에서 계속 업데이트를 해줘야해서 개선할 필요 있음.
위젯을달 NPC를 하나 만들자
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "NPC.generated.h"
UCLASS()
class TEAM_ISLAND_MASTER_API ANPC : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ANPC();
UPROPERTY(EditDefaultsOnly, Category = FSM)
float idleDelayTime = 2;
// 경과시간
float currentTime = 0;
// 타겟
UPROPERTY(VisibleAnywhere, Category = FSM)
class AMyPlayer* target;
// 소유액터
UPROPERTY()
class ANPC* me;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawn)
FString npcid;
//이동속도
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawn)
float moveSpeed;
UPROPERTY(EditAnywhere, Category = FSM)
float attackRange = 150.0f;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = FSM)
FVector destination;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = FSM)
FVector dir;
// 사용중인 애니메이션 블루프린트
UPROPERTY()
class UEnemyAnim* anim;
UPROPERTY(EditAnywhere, Category = Animation)
class UAnimMontage* damageAnim;
UPROPERTY(EditAnywhere)
TSubclassOf<class UItemShop> widgetRef;
UPROPERTY()
class UItemShop* hpBar;
UPROPERTY()
class UWidgetComponent* widgetComp;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION()
void move(float DeltaTime);
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "NPC.h"
#include "EnemyFSM.h"
#include "MyPlayer.h"
#include "UnrealWidget.h"
#include "Animation/AnimMontage.h"
#include <Kismet/GameplayStatics.h>
#include <Kismet/KismetMathLibrary.h>
#include <Components/WidgetComponent.h>
#include <Components/CapsuleComponent.h>
#include "EnemyAnim.h"
#include "ItemShop.h"
// Sets default values
ANPC::ANPC()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
ConstructorHelpers::FObjectFinder<USkeletalMesh> tempMesh(TEXT("/Game/BG/CityofBrass_Enemies/Meshes/Enemy/Archer/Archer.Archer"));
// 1-1. 데이터 로드 성공하면
if (tempMesh.Succeeded())
{
UE_LOG(LogTemp, Warning, TEXT("Enemy Skeletal Mesh Loading"));
// 1-2. 데이터 할당
GetMesh()->SetSkeletalMesh(tempMesh.Object);
// 1-3. 메쉬 위치 및 회전 설정
GetMesh()->SetRelativeLocationAndRotation(FVector(0, 0, -88), FRotator(0, 0, 0));
// 1-4. 메쉬 크기 수정
GetMesh()->SetRelativeScale3D(FVector(0.84f));
}
widgetComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("HPWidget"));
widgetComp->SetupAttachment(GetMesh());
widgetComp->SetRelativeLocation(FVector(0, 0, 300.0f));
UClass* WidgetCompClass = LoadClass<UUserWidget>(NULL, TEXT("/Game/UI/WBP_HPBarTest.WBP_HPBarTest_C"));
if (WidgetCompClass) {
widgetComp->SetWidgetClass(WidgetCompClass);
widgetComp->SetWidgetSpace(EWidgetSpace::World);
}
moveSpeed = 1.f;
}
// Called when the game starts or when spawned
void ANPC::BeginPlay()
{
Super::BeginPlay();
auto actor = UGameplayStatics::GetActorOfClass(GetWorld(), AMyPlayer::StaticClass());
// ATPSPlayer 타입으로 캐스팅
target = Cast<AMyPlayer>(actor);
// 소유객체 가져오기
//me = Cast<ANPC>(GetOwner());
me = this;
widgetComp->InitWidget();
hpBar = Cast<UItemShop>(widgetComp->GetUserWidgetObject());
if (IsValid(hpBar)) {
//FText idText = FText::FromString(FString::FromInt(12));
FVector _pos = target->GetActorLocation();
hpBar->ctextId = GetClass()->GetDisplayNameText();
hpBar->ctextPos = FText::FromString(FString::Printf(TEXT("%f %f %f"), _pos.X, _pos.Y, _pos.Z));
}
}
// Called every frame
void ANPC::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//1.타겟 목적지가 필요하다.
move(DeltaTime);
}
void ANPC::move(float DeltaTime)
{
destination = target->GetActorLocation();
// 2.방향이 필요하다.
dir = destination - GetActorLocation();
// 3.방향으로 이동하고 싶다.
moveSpeed = 10;
float _speed = DeltaTime * moveSpeed;
FRotator _dirRot = UKismetMathLibrary::FindLookAtRotation(GetActorLocation(), target->GetActorLocation());
SetActorRotation(FRotator(0, _dirRot.Yaw, 0));
////dir = FVector(dir.X, dir.Y, 0).GetSafeNormal();
////float _speed = dir.Length() * moveSpeed * 0.1;
double _distance = dir.Length();
if (_distance > 150.f) {
AddMovementInput(me->GetActorForwardVector() * _speed); //* _speed
}
if (IsValid(hpBar)) {
hpBar->ctextId = GetClass()->GetDisplayNameText();
hpBar->ctextPos = FText::FromString(FString::Printf(TEXT("%d"), (int) _distance));
}
}
// Called to bind functionality to input
void ANPC::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
스포너를 하나 만들자;
웃긴건 스폰한 캐릭터가 움직이지 않는다 결국 알아낸건데 default pawn character를 연결해줘야하는데 아직 c++클래스를 찾지 못했다.
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NPCSpawner.generated.h"
UCLASS()
class TEAM_ISLAND_MASTER_API ANPCSpawner : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ANPCSpawner();
void SpawnEnemy(int id);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere, Category = Spawn)
class UArrowComponent* spawnPoint;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawn)
float minDelay = 5.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawn)
float maxDelay = 10.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Time)
float delayTime = 5.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawn)
TArray<TSubclassOf<class ANPC>> enemyClass;
private:
float currentTime = 0;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "NPCSpawner.h"
#include "Components/ArrowComponent.h"
#include "NPC.h"
// Sets default values
ANPCSpawner::ANPCSpawner()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
spawnPoint = CreateDefaultSubobject<UArrowComponent>(TEXT("Spawn Pointer"));
spawnPoint->SetRelativeLocation(FVector(0, 0, 100));
spawnPoint->SetRelativeRotation(FRotator(0, -90, 0));
//spawnPoint->SetupAttachment(RootComponent);
}
void ANPCSpawner::SpawnEnemy(int id)
{
if (enemyClass.Num() > 0) {
FActorSpawnParameters Param;
Param.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
auto _actor = GetWorld()->SpawnActor<ANPC>(enemyClass[0], spawnPoint->GetComponentLocation(),
spawnPoint->GetComponentRotation(), Param);
//GetWorld()->AddController();
}
}
// Called when the game starts or when spawned
void ANPCSpawner::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ANPCSpawner::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
currentTime += DeltaTime;
if (currentTime > delayTime) {
int _id = FMath::RandRange(0, enemyClass.Num() - 1);
SpawnEnemy(_id);
currentTime = 0;
}
}
'언리얼엔진 > ThirdPersonTemplete' 카테고리의 다른 글
캐릭터만들기 정리 (0) | 2023.12.04 |
---|---|
스폰한 캐릭터 안움직이는 이유 (0) | 2023.12.04 |
AnimNotify (0) | 2023.11.16 |
언리얼 Animation Montage (0) | 2023.11.14 |
캐릭터 메시 지정하기 (0) | 2023.11.13 |