Actor class가 사용할 수 있는 몇가지 함수 정리
객체의 위치를 지정된 location으로 설정함
물리 시뮬레이션을 고려함
매개변수로 전달받는 값은 좌표
Blueprint에서 SetActorLocation 사용법
- Target
SetActorLocation을 적용시킬 target
New Location
Actor의 Location 지정- Sweap
객체를 이동시킬 때 충돌을 감지하고 반응하는 기능. 추후 Collision때 추가기술- Teleport
객체를 즉시 이동시켜야 할 때 사용
c++에서 SetActorLocation 사용법
/** Actor명 = Item */ void AItem::BeginPlay() { ... // 해당 actor의 location을 지정 SetActorLocation(FVector(0.f, 0.f, 50.f)); ... }
객체의 회전을 지정된 Rotation으로 설정함
전역 좌표계를 기준으로 회전을 지정하므로, 월드 공간에서의 회전을 의미
Blueprint에서 SetActorLocation 사용법
- Target
SetActorLocation을 적용시킬 target- New Rotation
축에 대한 회전량 설정- Teleport Physics
객체가 회전하는 동안 물리시뮬레이션이 적용되지 않고, 텔레포트된 후 새로운 위치에서 물리 시뮬레이션이 다시 시작되도록 함
c++에서 SetActorLocation 사용법
/** Actor명 = Item */ void AItem::BeginPlay() { ... SetActorRotation(FRotator(0.f, 45.f, 0.f)); ... }
객체의 현재위치에서 world 좌표계 기준 상대적인 이동
물리 시뮬레이션을 고려하지 않음
매개변수로 전달받는 것은 벡터
Blueprint에서 AddActorWorldOffset 사용법
- Target
AddActorWorldOffset을 적용시킬 target- Delta Location
각 축에 대한 이동값 설정- Sweap
객체를 이동시킬 때 충돌을 감지하고 반응하는 기능. 추후 Collision때 추가기술- Teleport
객체를 즉시 이동시켜야 할 때 사용
c++에서 AddActorWorldOffset 사용법
/** Actor명 = Item */ void AItem::BeginPlay() { ... // 해당 위치에서 world 좌표계 기준인 y축으로 45.f만큼 이동 AddActorWorldOffset(FVector(0.f, 45.f, 0.f)); ... }
AddActorWorldRotation
객체의 현재회전상태에서 world 좌표계 기준 회전
객체의 현재 회전값에 기반한 회전이므로, 현재 상태에서 추가적인 회전을 의미Blueprint에서 AddActorWorldOffset 사용법
- Target
AddActorWorldRotation을 적용시킬 target- Delta Location
각 축에 대한 회전값 설정
c++에서 AddActorWorldRotation 사용법
/** Actor명 = Item */ void AItem::BeginPlay() { ... // 해당 회전상태에서 world 좌표계 기준인 pitch 기준 45.f만큼 회전 AddActorWorldRotation(FRotator(0.f, 45.f, 0.f)); ... }
프레임 속도에 따라 Tick함수 내에 있는 코드들의 동작이 달라질 수 있음.
그러므로 프레임 속도에 관계없이 동작할 수 있도록 DeltaTime을 이용해 이를 보정해주어야 함.
우선 Debug관련 매크로를 추가한다.
#define DRAW_SPHERE_SINGLEFRAME(Location) if(GetWorld()) DrawDebugSphere(GetWorld(), Location, 25.f, 24, FColor::Red, false, -1.f) #define DRAW_LINE_SINGLEFRAME(StartLocation, EndLocation) if(GetWorld()) DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Red, false, -1.f, 0, 1.f); #define DRAW_POINT_SINGLEFRAME(Location) if(GetWorld()) DrawDebugPoint(GetWorld(), Location, 30.f, FColor::Red, false, -1.f); #define DRAW_VECTOR_SINGLEFRAME(StartLocation, EndLocation) if(GetWorld()) \ { \ DrawDebugLine(GetWorld(), StartLocation, EndLocation, FColor::Red, false, -1.f, 0, 1.f); \ DrawDebugPoint(GetWorld(), EndLocation, 30.f, FColor::Red, false, -1.f); \ }
이어서 cpp파일에 이동관련 코드를 추가해준다.
void AItem::Tick(DeltaTime) { ... float MovementRate = 50.f; float RorationRate = 45.f; // MovementRate = 거리/시간, Deltatime = 시간/프레임 // 그러므로 MovementRate * Deltatime = 거리/프레임 // 위의 계산을 통해 프레임이 달라도 전제적으로 동일한 움직임 가능 // 회전도 동일 AddActorWorldOffset(FVector(MovementRate * DeltaTime, 0.f, 0.f)); AddActorWorldRotation(FRotator(0.f, RotationRate * DeltaTime, 0.f)); DRAW_SPHERE_SINGLEFRAME(GetActorLocation()); DRAW_VECTOR_SINGLEFRAME(GetActorLocation(), GetActorRotation() + GetActorForwardVector() * 100.f); }
Tick함수를 통한 Actor의 이동과 회전(Sin,Cos)
sin과 cos을 이용하면 Item이 둥둥 떠있는 상태를 구현할 수 있다.
Blueprint에서 구현
- 먼저 components탭에서 TestValue라는 float타입 변수 하나를 생성
- node 연결
TestValue에 DeltaTime을 합한 것을 Setter를 통해 할당하고, 10배(radian)하여 진동을 빠르게, 0.25배(진폭)해서 진폭을 짧게, AddActorWorldOffset함수를 통해 z축으로 해당 값만큼 움직이도록 설정(Delta Loctaion을 우클릭해 Split Struct Pin을 선택하면 각 축에 할당 가능하도록 분리가능).
c++에서 구현
우선 헤더파일의 private 섹션에 radian값을 할당하기 위한 변수를 추가한다.
... private: // DebugSphere, DebugLine, DebugPoint를 움직이기 위해 필요한 radian값 float Radian; // DebugSphere, DebugLine, DebugPoint가 움직일때의 진폭 UPROPERTY(EditDefaultsOnly) float Amplitude; // DebugSphere, DebugLine, DebugPoint가 움직일때의 주기 UPROPERTY(EditInstanceOnly) float Period; ...
이어서 cpp파일에 관련 코드를 추가한다.
/** Actor명 = Item */ AItem::AItem() : Amplitude(0.25f), TimeConstant(5.f) ... void AItem::Tick(float DeltaTime) { // Radian값이 DeltaTime에 의해 계속 증가 Radian += DeltaTime; // 진동주기는 10배로 빠르게, 진폭은 0.25배로 더 작게 float DeltaZ = Amplitude * FMath::Sin(DeltaTime * TimeConstant); // DeltaZ에 의해 DebugSphere와 DebugVector가 움직이도록 함 AddActorWorldOffset(FVector(0.f, 0.f, DeltaZ)); DRAW_SPHERE_SINGLEFRAME(GetActorLocation()); DRAW_VECTOR_SINGLEFRAME(GetActorLocation(), GetActorForwardVector() * 100.f); }
Blueprint에서 구현
- 좌측 상단의 Components 패널에서 우클릭후 StaticMesh 생성
- 우측 Details 패널에서 StaticMesh 설정
c++에서 구현
우선 헤더파일에 UStaticMeshComponent type의 변수를 선언한다
private: // ItemMeshComponent UPROPERTY(VisibleAnywhere) UStaticMeshComponent* ItemMesh;
이어서 cpp 파일에 관련 코드를 추가한다.
/** Actor명 = Item */ AItem::AItem() { ... ItemMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ItemMesh")); RootComponent = ItemMesh; }