[UE] AnimNotify, DoAction
목차
Source | ||
Characters | ||
CAnimInstance.h .cpp CEnemy.h .cpp 생성 CPlayer.h .cpp ICharacter.h .cpp |
||
Components | ||
CMontagesComponent.h .cpp CMovementComponent.h .cpp CStateComponent.h .cpp CWeaponComponent.h .cpp |
||
Notifies | ||
CAnimNotifyState_BeginAction.h .cpp 생성 CAnimNotifyState_EndAction.h .cpp 생성 CAnimNotify_EndState.h .cpp CAnimNotifyState_Collision.h .cpp 생성 CAnimNotifyState_Combo.h .cpp 생성 CAnimNotifyState_Equip.h .cpp |
||
Utilities | ||
CHelper.h CLog.h .cpp |
||
Weapons | ||
CDoAction_Combo.h .cpp CAttachment.h .cpp CDoAction.h .cpp CEquipment.h .cpp CWeaponAsset.h .cpp CWeaponStructures.h .cpp |
||
Global.h CGameMode.h .cpp U2212_06.Build.cs |
||
U2212_06.uproject | ||
Combo 공격 구현
CAnimNotify_BeginAction 생성
새 C++ 클래스 - AnimNotify - CAnimNotify_BeginAction 생성
CAnimNotify_BeginAction.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotify.h"
#include "CAnimNotify_BeginAction.generated.h"
UCLASS()
class U2212_06_API UCAnimNotify_BeginAction : public UAnimNotify
{
GENERATED_BODY()
public:
FString GetNotifyName_Implementation() const override;//Notify 이름을 지어주는 함수.
void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
CAnimNotify_BeginAction.cpp
#include "Notifies/CAnimNotify_BeginAction.h"
#include "Global.h"
#include "Components/CWeaponComponent.h"
#include "Weapons/CDoAction.h"
FString UCAnimNotify_BeginAction::GetNotifyName_Implementation() const
{
return "Begin_DoAction";//Notify이름을 Begin_DoAction으로 설정.
}
void UCAnimNotify_BeginAction::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
Super::Notify(MeshComp, Animation);
CheckNull(MeshComp);//MeshComp 있는지 체크
CheckNull(MeshComp->GetOwner());//MeshComp->GetOwner() 있는지 체크
UCWeaponComponent* weapon = CHelpers::GetComponent<UCWeaponComponent>(MeshComp->GetOwner());
CheckNull(weapon);//weapon이 있는지 체크
CheckNull(weapon->GetDoAction());//weapon 내에 GetDoAction()함수가 있는지 체크
weapon->GetDoAction()->Begin_DoAction();//Begin_DoAction 실행
}
CAnimNotify_EndAction 생성
새 C++ 클래스 - AnimNotify - CAnimNotify_EndAction 생성
CAnimNotify_EndAction.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotify.h"
#include "CAnimNotify_EndAction.generated.h"
UCLASS()
class U2212_06_API UCAnimNotify_EndAction : public UAnimNotify
{
GENERATED_BODY()
public:
FString GetNotifyName_Implementation() const override;
void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
CAnimNotify_EndAction.cpp
#include "Notifies/CAnimNotify_EndAction.h"
#include "Global.h"
#include "Components/CWeaponComponent.h"
#include "Weapons/CDoAction.h"
FString UCAnimNotify_EndAction::GetNotifyName_Implementation() const
{
return "End_DoAction";
}
void UCAnimNotify_EndAction::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
Super::Notify(MeshComp, Animation);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCWeaponComponent* weapon = CHelpers::GetComponent<UCWeaponComponent>(MeshComp->GetOwner());
CheckNull(weapon);
CheckNull(weapon->GetDoAction());
weapon->GetDoAction()->End_DoAction();//End_DoAction 실행
}
CAnimNotifyState_Combo 생성
새 C++ 클래스 - AnimNotifyState - CAnimNotifyState_Combo 생성
CAnimNotifyState_Combo.h
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotifyState.h"
#include "CAnimNotifyState_Combo.generated.h"
UCLASS()
class U2212_06_API UCAnimNotifyState_Combo : public UAnimNotifyState
{
GENERATED_BODY()
public:
FString GetNotifyName_Implementation() const override;
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration) override;
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
CAnimNotifyState_Combo.cpp
#include "Notifies/CAnimNotifyState_Combo.h"
#include "Global.h"
#include "Components/CWeaponComponent.h"
#include "Weapons/DoActions/CDoAction_Combo.h"
FString UCAnimNotifyState_Combo::GetNotifyName_Implementation() const
{
return "Combo"; //Notify이름 설정.
}
void UCAnimNotifyState_Combo::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration)
{
Super::NotifyBegin(MeshComp, Animation, TotalDuration);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCWeaponComponent* weapon = CHelpers::GetComponent<UCWeaponComponent>(MeshComp->GetOwner());
CheckNull(weapon);
CheckNull(weapon->GetDoAction());
UCDoAction_Combo* combo = Cast<UCDoAction_Combo>(weapon->GetDoAction());
CheckNull(combo);
combo->EnableCombo();//콤보 on
}
void UCAnimNotifyState_Combo::NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
Super::NotifyEnd(MeshComp, Animation);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());
UCWeaponComponent* weapon = CHelpers::GetComponent<UCWeaponComponent>(MeshComp->GetOwner());
CheckNull(weapon);
CheckNull(weapon->GetDoAction());
UCDoAction_Combo* combo = Cast<UCDoAction_Combo>(weapon->GetDoAction());
CheckNull(combo);
combo->DisableCombo();//콤보 off
}
Montage 작업
DA_Sword에 DoAction Datas 할당
실행화면
Collision 구현하
ICharacter
ICharacter.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ICharacter.generated.h"
UINTERFACE(MinimalAPI) //직렬화를 위한 부분
class UICharacter : public UInterface
{
GENERATED_BODY()
};
class U2212_06_API IICharacter
{
GENERATED_BODY()
public:
virtual void End_BackStep() { }
public:
void Create_DynamicMaterial(class ACharacter* InCharacter);
void Change_Color(class ACharacter* InCharacter, FLinearColor InColor);
};
함수 추가
- void Create_DynamicMaterial(class ACharacter* InCharacter);
- void Change_Color(class ACharacter* InCharacter, FLinearColor InColor);
※참고)
추상 클래스는 직렬화 할 수 없다. 인터페이스는 직렬화 할 수 있다.
추상클래스나 인터페이스 모두 객체를 못 만든다. 인터페이스의 경우 자식클래스에서 구현될 때 직렬화 될 수 있다.
ICharacter.cpp
#include "Characters/ICharacter.h"
#include "Global.h"
#include "GameFramework/Character.h"
#include "Components/SkeletalMeshComponent.h"
#include "Materials/MaterialInstanceDynamic.h"
void IICharacter::Create_DynamicMaterial(ACharacter* InCharacter)
{
for (int32 i = 0; i< InCharacter->GetMesh()->GetMaterials().Num(); i++)
{
UMaterialInterface* material = InCharacter->GetMesh()->GetMaterials()[i];
InCharacter->GetMesh()->SetMaterial(i, UMaterialInstanceDynamic::Create(material, InCharacter));
}
}
void IICharacter::Change_Color(ACharacter* InCharacter, FLinearColor InColor)
{
for(UMaterialInterface* material : InCharacter->GetMesh()->GetMaterials())
{
UMaterialInstanceDynamic* instance = Cast<UMaterialInstanceDynamic>(material);
if (!!instance)
instance->SetVectorParameterValue("BodyColor", InColor);
}
}
CEnemy 생성
새 C++ 클래스 - Character - CEnemy 생성
CEnemy.h
#pragma once
#include "CoreMinimal.h"
#include "Characters/ICharacter.h"
#include "Components/CStateComponent.h"
#include "GameFramework/Character.h"
#include "CEnemy.generated.h"
UCLASS()
class U2212_06_API ACEnemy : public ACharacter, public IICharacter //다중상속
{
GENERATED_BODY()
private:
UPROPERTY(EditAnywhere, Category = "Color")
FLinearColor OriginColor = FLinearColor::White;//색상 설정.
private:
UPROPERTY(VisibleAnywhere)
class UCWeaponComponent* Weapon;
UPROPERTY(VisibleAnywhere)
class UCMontagesComponent* Montages;
UPROPERTY(VisibleAnywhere)
class UCMovementComponent* Movement;
UPROPERTY(VisibleAnywhere)
class UCStateComponent* State;
public:
ACEnemy();
public:
float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;//TakeDamage 오버라이드하여 재정의.
protected:
virtual void BeginPlay() override;
private:
UFUNCTION()
void OnStateTypeChanged(EStateType InPrevType, EStateType InNewType);
};
CEnemy.cpp
#include "Characters/CEnemy.h"
#include "Global.h"
#include "CAnimInstance.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/CMontagesComponent.h"
#include "Components/CMovementComponent.h"
#include "Components/CWeaponComponent.h"
ACEnemy::ACEnemy()
{
CHelpers::CreateActorComponent<UCWeaponComponent>(this, &Weapon, "Weapon");
CHelpers::CreateActorComponent<UCMontagesComponent>(this, &Montages, "Montage");
CHelpers::CreateActorComponent<UCMovementComponent>(this, &Movement, "Movement");
CHelpers::CreateActorComponent<UCStateComponent>(this, &State, "State");
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);
TSubclassOf<UCAnimInstance> animInstance;
CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
GetMesh()->SetAnimClass(animInstance);
GetCharacterMovement()->RotationRate = FRotator(0, 720, 0);
}
void ACEnemy::BeginPlay()
{
Super::BeginPlay();
Movement->OnWalk();//기본값 설정.
Create_DynamicMaterial(this);//IICharacter의 함수 사용. 색이 적용되는 객체를 this(여기서는 Enemy)로 설정.
Change_Color(this, OriginColor);//색상 할당.
State->OnStateTypeChanged.AddDynamic(this, &ACEnemy::OnStateTypeChanged);
}
void ACEnemy::OnStateTypeChanged(EStateType InPrevType, EStateType InNewType)
{
}
float ACEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
float damage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
CLog::Print(damage);
return damage;
}
CEnemy 기반 BP - BP_CEnemy 생성
CAttachment
CAttachment.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CAttachment.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAttachmentBeginCollision);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FAttachmentEndCollision);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttachmentBeginOverlap, class ACharacter*, InAttacker, AActor*, InAttackCuaser, class ACharacter*, InOther);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAttachmentEndOverlap, class ACharacter*, InAttacker, class ACharacter*, InOther);
UCLASS()
class U2212_06_API ACAttachment : public AActor
{
GENERATED_BODY()
protected:
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
class USceneComponent* Root;
public:
ACAttachment();
protected:
virtual void BeginPlay() override;
public:
UFUNCTION(BlueprintImplementableEvent)
void OnBeginEquip();
UFUNCTION(BlueprintImplementableEvent)
void OnUnequip();
public:
void OnCollisions(); //Collision 켜기
void OffCollisions();//Collision 끄기
private:
UFUNCTION()
void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
void OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
protected:
UFUNCTION(BlueprintCallable, Category = "Attach")
void AttachTo(FName InSocketName);
public:
FAttachmentBeginCollision OnAttachmentBeginCollision;
FAttachmentEndCollision OnAttachmentEndCollision;
FAttachmentBeginOverlap OnAttachmentBeginOverlap;
FAttachmentEndOverlap OnAttachmentEndOverlap;
protected:
UPROPERTY(BlueprintReadOnly, Category = "Game")
class ACharacter* OwnerCharacter;
//UShapeComponent는 UBox,Capsule,SphereComponent의 상위클래스
UPROPERTY(BlueprintReadOnly, Category = "Game")
TArray<class UShapeComponent*> Collisions;
};
함수 추가
- void OnCollisions(); //Collision 켜기
- void OffCollisions(); //Collision 끄기
구조체 추가
- FAttachmentBeginCollision OnAttachmentBeginCollision;
- FAttachmentEndCollision OnAttachmentEndCollision;
- FAttachmentBeginOverlap OnAttachmentBeginOverlap;
- FAttachmentEndOverlap OnAttachmentEndOverlap;
변수 추가
- UPROPERTY(BlueprintReadOnly, Category = "Game")
TArray<class UShapeComponent*> Collisions;- UShapeComponent는 UBoxComponent, UCapsuleComponent, USphereComponent의 상위클래스다.
CAttachment.cpp
#include "Weapons/CAttachment.h"
#include "Global.h"
#include "GameFramework/Character.h"
#include "Components/SceneComponent.h"
#include "Components/ShapeComponent.h"
ACAttachment::ACAttachment()
{
CHelpers::CreateComponent(this, &Root, "Root");
}
void ACAttachment::BeginPlay()
{
OwnerCharacter = Cast<ACharacter>(GetOwner());
TArray<USceneComponent*> children;//최종 부모는 SceneComponent다.
Root->GetChildrenComponents(true, children);
for (USceneComponent* child : children)
{
UShapeComponent* shape = Cast<UShapeComponent>(child);
if(!!shape)//shape이 있다면
{
//충돌 이벤트 연결
shape->OnComponentBeginOverlap.AddDynamic(this, &ACAttachment::OnComponentBeginOverlap);
shape->OnComponentEndOverlap.AddDynamic(this, &ACAttachment::OnComponentEndOverlap);
Collisions.Add(shape);//Collsions배열에 shape 추가
}
}
//ACharacter를 먼저 Cast 한 후에 Super::BeginPlay() 호출.
Super::BeginPlay();
}
void ACAttachment::OnCollisions()
{
//Pre (충돌체가 켜지기 전에 작업)
if (OnAttachmentBeginCollision.IsBound())
OnAttachmentBeginCollision.Broadcast();//연결되어 있는것 이벤트콜
for (UShapeComponent* shape : Collisions)//Collisions배열의 for문
shape->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);//Collision을 QueryAndPhysics 설정.
}
void ACAttachment::OffCollisions()
{
//Pre (충돌체가 꺼지기 전에 작업)
if (OnAttachmentBeginCollision.IsBound())
OnAttachmentBeginCollision.Broadcast();//연결되어 있는것 이벤트콜
for (UShapeComponent* shape : Collisions)
shape->SetCollisionEnabled(ECollisionEnabled::NoCollision);//Collision을 NoCollision 설정.
}
void ACAttachment::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
CheckTrue(OwnerCharacter == OtherActor);//자기 자신
CheckTrue(OwnerCharacter->GetClass() == OtherActor->GetClass());//GetClass()가 같다는 것은 아군이라는 의미
if (OnAttachmentBeginOverlap.IsBound())
OnAttachmentBeginOverlap.Broadcast(OwnerCharacter, this, Cast<ACharacter>(OtherActor));
}
void ACAttachment::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
CheckTrue(OwnerCharacter == OtherActor);//자기 자신
CheckTrue(OwnerCharacter->GetClass() == OtherActor->GetClass());//GetClass()가 같다는 것은 아군이라는 의미
if (OnAttachmentEndOverlap.IsBound())
OnAttachmentEndOverlap.Broadcast(OwnerCharacter, Cast<ACharacter>(OtherActor));
}
void ACAttachment::AttachTo(FName InSocketName)
{
AttachToComponent(OwnerCharacter->GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), InSocketName);
}
Collision - TakeDamage 설명
Blueprint의 Any와 Apply는 C++에서는 TakeDamage다.
Sword Enemy
Any Apply
Enemy->TakeDamage TakeDamage
Actor.h 내의 ReceiveAnyDamage, TakeDamage 선언
Actor.cpp 내의 ReceiveAnyDamage 정의
OnTakeAnyDamage는 AnyDamage 콜 될 때 Delegate.
UCDoAction_Combo에서 TakeDamage 적용되는 예시.
CDoAction
CDoAction.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Weapons/CWeaponStructures.h"
#include "CDoAction.generated.h"
UCLASS(Abstract)//DoAction 그 자체로는 객체화되면 안 되기 때문에 Abstract을 붙여준다.
class U2212_06_API UCDoAction : public UObject
{
GENERATED_BODY()
public:
UCDoAction();
virtual void BeginPlay //재정의 할 수 있도록 virtual로 만든다.
(
class ACAttachment* InAttachment,
class UCEquipment* InEquipment,
class ACharacter* InOwner,
const TArray<FDoActionData>& InDoActionDatas
);
public:
//재정의 할 수 있도록 virtual로 만든다.
virtual void DoAction();
virtual void Begin_DoAction();
virtual void End_DoAction();
public:
UFUNCTION()
virtual void OnAttachmentBeginCollision() {}
UFUNCTION()
virtual void OnAttachmentEndCollision() {}
UFUNCTION()
virtual void OnAttachmentBeginOverlap(class ACharacter* InAttacker, AActor* InAttackCauser, class ACharacter* InOther) { }
UFUNCTION()
virtual void OnAttachmentEndOverlap(class ACharacter* InAttacker, class ACharacter* InOther) { }
protected:
bool bBeginAction;
class ACharacter* OwnerCharacter;
class UWorld* World;
class UCMovementComponent* Movement;
class UCStateComponent* State;
TArray<FDoActionData> DoActionDatas;
};
가상함수 생성
- virtual void OnAttachmentBeginOverlap(class ACharacter* InAttacker, AActor* InAttackCauser, class ACharacter* InOther) { }
- virtual void OnAttachmentEndOverlap(class ACharacter* InAttacker, class ACharacter* InOther) { }
- 위의 2개의 가상함수는 CDoAction_Combo에서 오버라이드된다!
※ 언리얼C++에서 직렬화 코드(ex. UFUNCTION)도 상속된다.
CDoAction.cpp
#include "Weapons/CDoAction.h"
#include "Global.h"
#include "CAttachment.h"
#include "CEquipment.h"
#include "GameFramework/Character.h"
#include "Components/CStateComponent.h"
#include "Components/CMovementComponent.h"
UCDoAction::UCDoAction()
{
}
void UCDoAction::BeginPlay(ACAttachment* InAttachment, UCEquipment* InEquipment, ACharacter* InOwner, const TArray<FDoActionData>& InDoActionDatas)
{
OwnerCharacter = InOwner;
World = OwnerCharacter->GetWorld();
State = CHelpers::GetComponent<UCStateComponent>(OwnerCharacter);
Movement = CHelpers::GetComponent<UCMovementComponent>(OwnerCharacter);
DoActionDatas = InDoActionDatas;
}
void UCDoAction::DoAction()
{
State->SetActionMode();
}
void UCDoAction::Begin_DoAction()
{
bBeginAction = true;
}
void UCDoAction::End_DoAction()
{
bBeginAction = false;
State->SetIdleMode();
Movement->Move();
Movement->DisableFixedCamera();
}
변경사항 없음.
CWeaponAsset
CWeaponAsset.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "Weapons/CWeaponStructures.h"
#include "CWeaponAsset.generated.h"
UCLASS()
class U2212_06_API UCWeaponAsset : public UDataAsset
{
GENERATED_BODY()
private:
UPROPERTY(EditAnywhere)
TSubclassOf<class ACAttachment> AttachmentClass;
UPROPERTY(EditAnywhere)
FEquipmentData EquipmentData;
UPROPERTY(EditAnywhere)
TSubclassOf<class UCEquipment> EquipmentClass;
UPROPERTY(EditAnywhere)
TSubclassOf<class UCDoAction> DoActionClass;
UPROPERTY(EditAnywhere)
TArray<FDoActionData> DoActionDatas;
public:
FORCEINLINE class ACAttachment* GetAttachment() { return Attachment; }//외부에 생성된 것을 리턴해줌.
FORCEINLINE class UCEquipment* GetEquipment() { return Equipment; }//외부에 생성된 것을 리턴해줌.
FORCEINLINE class UCDoAction* GetDoAction() { return DoAction; }//외부에 생성된 것을 리턴해줌.
public:
UCWeaponAsset();
void BeginPlay(class ACharacter* InOwner);
private:
//UPROPERTY를 붙여 가비지 콜렉터가 제거하기 전까지 물고 있게 만든다.
//UWeaponAsset은 UObject로부터 상속받아 Actor의 생성주기에 영향을 받지 않아 가비지 콜렉터에 영향을 받는다.
UPROPERTY()
class ACAttachment* Attachment;
UPROPERTY()
class UCEquipment* Equipment;
UPROPERTY()
class UCDoAction* DoAction;
};
변경사항 없음.
CWeaponAsset.cpp
#include "Weapons/CWeaponAsset.h"
#include "Global.h"
#include "CAttachment.h"
#include "CEquipment.h"
#include "CDoAction.h"
#include "GameFramework/Character.h"
UCWeaponAsset::UCWeaponAsset()
{
AttachmentClass = ACAttachment::StaticClass();//기본값
EquipmentClass = UCEquipment::StaticClass();//기본값
DoActionClass = UCDoAction::StaticClass();//기본값
}
void UCWeaponAsset::BeginPlay(ACharacter* InOwner)
{
if (!!AttachmentClass)//AttachmentClass가 선택되어 있다면
{
FActorSpawnParameters params;
params.Owner = InOwner;
Attachment = InOwner->GetWorld()->SpawnActor<ACAttachment>(AttachmentClass, params);
}
if (!!EquipmentClass)//EquipmentClass가 선택되어 있다면
{
Equipment = NewObject<UCEquipment>(this, EquipmentClass);
Equipment->BeginPlay(InOwner, EquipmentData);
if (!!Attachment)//Attachment가 있다면
{
Equipment->OnEquipmentBeginEquip.AddDynamic(Attachment, &ACAttachment::OnBeginEquip);
Equipment->OnEquipmentUnequip.AddDynamic(Attachment, &ACAttachment::OnUnequip);
}
}
if(!!DoActionClass)
{
DoAction = NewObject<UCDoAction>(this, DoActionClass);
DoAction->BeginPlay(Attachment, Equipment, InOwner, DoActionDatas);
if (!!Attachment)
{
Attachment->OnAttachmentBeginCollision.AddDynamic(DoAction, &UCDoAction::OnAttachmentBeginCollision);
Attachment->OnAttachmentEndCollision.AddDynamic(DoAction, &UCDoAction::OnAttachmentEndCollision);
Attachment->OnAttachmentBeginOverlap.AddDynamic(DoAction, &UCDoAction::OnAttachmentBeginOverlap);
Attachment->OnAttachmentEndOverlap.AddDynamic(DoAction, &UCDoAction::OnAttachmentEndOverlap);
}
}
}
DoAction 부분에 AddDynamic으로 Collision을 넣어준다.
- if (!!Attachment) {
Attachment->OnAttachmentBeginCollision.AddDynamic(DoAction, &UCDoAction::OnAttachmentBeginCollision);
Attachment->OnAttachmentEndCollision.AddDynamic(DoAction, &UCDoAction::OnAttachmentEndCollision);
Attachment->OnAttachmentBeginOverlap.AddDynamic(DoAction, &UCDoAction::OnAttachmentBeginOverlap);
Attachment->OnAttachmentEndOverlap.AddDynamic(DoAction, &UCDoAction::OnAttachmentEndOverlap);
}
BP_CAttachment_Sword - Collision용 Capsule 추가
실행화면
'⭐ Unreal Engine > UE RPG Weapon System' 카테고리의 다른 글
[UE] Hit Effect 구현, Status Component, Hammer 공격 구현 (0) | 2023.05.10 |
---|---|
[UE] Hit Data, Effect, Object Pooling(오브젝트 풀링) (0) | 2023.05.09 |
[UE] 무기 장착 및 기본 공격하기 (0) | 2023.05.02 |
[UE] 무기 시스템 설계하기 (0) | 2023.05.01 |
[UE] Interface, AnimNotify, Backstep 구현하기 (0) | 2023.04.28 |
댓글
이 글 공유하기
다른 글
-
[UE] Hit Effect 구현, Status Component, Hammer 공격 구현
[UE] Hit Effect 구현, Status Component, Hammer 공격 구현
2023.05.10 -
[UE] Hit Data, Effect, Object Pooling(오브젝트 풀링)
[UE] Hit Data, Effect, Object Pooling(오브젝트 풀링)
2023.05.09 -
[UE] 무기 장착 및 기본 공격하기
[UE] 무기 장착 및 기본 공격하기
2023.05.02 -
[UE] 무기 시스템 설계하기
[UE] 무기 시스템 설계하기
2023.05.01