알고 있자! (본수업에서 사용했던 것에서는 다른) - 나중에 중요하게 쓰임

Rotation이 외적식으로 3개축을 구하는 방식 공간을 만드는 것 (decal은 공간이 없는데.)

FRotator FVector4::ToOrientationRotator() const
{
	FRotator R;

	// Find yaw.
	R.Yaw = FMath::Atan2(Y,X) * (180.f / PI);

	// Find pitch.
	R.Pitch = FMath::Atan2(Z,FMath::Sqrt(X*X+Y*Y)) * (180.f / PI);

	// Find roll.
	R.Roll = 0;

Arctan2 사용해 볼것이다.

FT_2022-06-19 00_52_48.052.png

2벡터를 알 수 있다면 내각을 구하는 것은 문제가 되지 않는다.

평면상의 직선을 하나 알고 있고, 수직이 되는 방향을 하나 알고 있는 것이다. (x 하고 y만 알고있는 상태)

내각 cos 세타를 구할려면. x하고 y 값이 있다면 그곳테 tan 가 있다. tan를 가지고 내각을 구하는 방법이 있는데, tan에 대비되는 값 arctan 이 있다. 아크탄젠트를 이용해서 코사인 각을 구할 수 있다.

atan : 파라미터 1개를 받는다

atan2 : 파라미터 2개를 받는다.(보통 이걸 많이 쓴다)

그러면 roll이라는 것은 어떻게 방향이 생성이 되나?

위에서 오른쪽으로 가니까 (y, z)으로 간다 - x 가 먼저 시작해야하니까 회전축이

Yaw.

정면에서 오른쪽 (y, x)

Pitch

(X,Z) 이건 주의 해야한다.

//사용했던 

float roll = UKismetMathLibarary::DeAtan2(Hit.ImpactNormal.Y, Hit.ImpactNormal.Z);
float pitch = - UKismetMathLibarary::DeAtan2(Hit.ImpactNormal.X, Hit.ImpactNormal.Z);
float yaw = UKismetMathLibarary::DeAtan2(Hit.ImpactNormal.Y, Hit.ImpactNormal.X);

CBullet.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CBullet.generated.h"

UCLASS()
class U2110_03_API ACBullet : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(EditDefaultsOnly, Category = "Impact")
		class UMaterialInstanceConstant* Decal;

	UPROPERTY(EditDefaultsOnly, Category = "Impact")
		class UParticleSystem* Particle;

private:
	UPROPERTY(VisibleDefaultsOnly)
		class UCapsuleComponent* Capsule;

	UPROPERTY(VisibleDefaultsOnly)
		class UStaticMeshComponent* Mesh;

	UPROPERTY(VisibleDefaultsOnly)
		class UProjectileMovementComponent* Projectile;

public:	
	ACBullet();

	void Shoot(const FVector& InDirection);

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};

이런 충돌체에 대한 오류를 주의하자. 이펙트 텍스쳐 메터리얼등 위치가 이상하게잡히면. 이런식으로 나오지 않는 경우가 생긴다. 지금. 충돌체가. 중간에 있어서. 앞에 붙어야 나오는데 생기지 않았던 것 , 충돌이 시작된 지점이 아니라. 정확히 닿아야 한다.

Untitled

CBullet.cpp

#include "CBullet.h"
#include "Global.h"
#include "Components/CapsuleComponent.h"
#include "Components/StaticMeshComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Materials/MaterialInstanceConstant.h"
#include "Particles/ParticleSystem.h"
#include "Components/DecalComponent.h"

ACBullet::ACBullet()
{
	CHelpers::CreateComponent<UCapsuleComponent>(this, &Capsule, "Capsule");
	CHelpers::CreateComponent<UStaticMeshComponent>(this, &Mesh, "Mesh", Capsule);
	CHelpers::CreateActorComponent<UProjectileMovementComponent>(this, &Projectile, "Projectile");

	Capsule->SetRelativeRotation(FRotator(90, 0, 0));
	Capsule->SetCapsuleHalfHeight(50);
	Capsule->SetCapsuleRadius(2);
	Capsule->SetCollisionProfileName("BlockAllDynamic");

	UStaticMesh* mesh;
	CHelpers::GetAsset<UStaticMesh>(&mesh, "StaticMesh'/Game/Meshes/Sphere.Sphere'");
	Mesh->SetStaticMesh(mesh);
	Mesh->SetRelativeScale3D(FVector(1, 0.025f, 0.05f));
	Mesh->SetRelativeRotation(FRotator(90, 0, 0));

	Projectile->InitialSpeed = 2e+4f; //2 * 10 ^ 4
	Projectile->MaxSpeed = 2e+4f; //2 * 10 ^ 4
	Projectile->ProjectileGravityScale = 0;

	CHelpers::GetAsset<UMaterialInstanceConstant>(&Decal, "MaterialInstanceConstant'/Game/Weapons/M_Decal_Inst.M_Decal_Inst'");
	CHelpers::GetAsset<UParticleSystem>(&Particle, "ParticleSystem'/Game/Weapons/Particle/VFX_Impact_Default.VFX_Impact_Default'");
}

void ACBullet::BeginPlay()
{
	Super::BeginPlay();

	Capsule->OnComponentHit.AddDynamic(this, &ACBullet::OnHit);
}

void ACBullet::Shoot(const FVector& InDirection)
{
	Projectile->Velocity = InDirection * Projectile->InitialSpeed;
}

void ACBullet::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	FRotator rotation = Hit.ImpactNormal.Rotation();

	if (!!Decal)
	{
		UDecalComponent* decal = UGameplayStatics::SpawnDecalAtLocation(GetWorld(), Decal, FVector(5), Hit.ImpactPoint, rotation, 10);
		decal->SetFadeScreenSize(0);
	}
	
	if (!!Particle)
	{
		UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particle, Hit.ImpactPoint, rotation);
	}

	Destroy();
}