목차

     

     


     

     

     

     
    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 추가

     


     

     

    실행화면