언리얼이나 유니티를 사용하다보면
Vector.GetSafeNormal();
과 같은 FVector에서 사용하는 함수가 있다
float speed = 100.0f;
FVector normalizedDirection = direction.GetSafeNormal();
FVector movement = normalizedDirection * speed * DeltaTime;
같이 사용되는데
이걸 왜 사용하는 지 드디어 알아 보게 되었다.
왜 사용하는가?
벡터의 방향을 유지하기 위해서가 가장 크다고 생각된다.
이것 말고도 계산 단수화 , 각도 계산 코사인값 등 아직은 넘어가야 될 내용이 많지만
가장 크게는 방향이라고 생각되었다.
#pragma
#include <iostream>
#include <cmath>
using namespace std;
struct FVector2D {
public:
double x, y;
FVector2D(double x = 0, double y = 0) : x(x), y(y)
{
}
const void SetVector(const double& x, const double& y)
{
this->x = x;
this->y = y;
}
FVector2D operator+ (const FVector2D& other) const {
return FVector2D(x + other.x, y + other.y);
}
FVector2D operator- (const FVector2D& other) const {
return FVector2D(x - other.x, y - other.y);
}
// 스칼라 곱
FVector2D operator*(double scalar) const {
return FVector2D(x * scalar, y * scalar);
}
//벡터의 크기를 계산하고
double magnitude() const {
return sqrt(x * x + y * y);
}
//여기서는 벡터의 방향을 계산한다.
FVector2D Normalized() const {
double mag = magnitude();
return (mag == 0) ? FVector2D() : FVector2D(x / mag, y / mag);
}
void CaluateAvoidanceDirection(const FVector2D& currentDirection)
{
/*x -= currentDirection.x;
y -= currentDirection.y;*/
x += 3;
}
void ZeroVector(){
x = 0; y = 0;
}
void SetLocation(FVector2D location)
{
x = location.x;
y = location.y;
}
double Distance(const FVector2D& other) const
{
return sqrt(pow(x - other.x,2) + pow(y - other.y,2));
}
};
bool IsOverlapBegin(const FVector2D& ThisVector, const FVector2D& target, double collisionDistance = 2.5) {
double distance = (ThisVector - target).magnitude();
return distance <= collisionDistance;
}
class Unit
{
protected :
FVector2D Vector;
public:
double speed;
// 벡터 초기화
Unit(double x = 0, double y = 0) {
Vector.SetVector(x, y);
speed = 3.0;
}
//아하 좋은 방식은아니겠지만 해당 값을 변경하려면 참조값을 주면된다
FVector2D& GetPoint() {
return Vector;
}
FVector2D Move(const FVector2D& Distance)
{
Vector = Vector + Distance;
return Distance;
//FVector2D(Vector.x + Distance.x, Vector.y + Distance.y);
}
const void Print(const string& text = "") {
cout << text << "FVector (x = " << Vector.x << " y = " << Vector.y << " )" << endl;
}
};
class EnemyUnit : public Unit
{
public:
EnemyUnit(double x = 0, double y =0) : Unit(x,y)
{
speed = 5.0;
}
void NextTurn()
{
speed += 3.0;
}
void Follow(Unit player, double deltitime)
{
FVector2D targetPoint = player.GetPoint();
FVector2D currentPoint = GetPoint();
// 플레이어를 향한 방향 벡터 계산
FVector2D direction = (targetPoint - currentPoint).Normalized();
FVector2D movement = (player.GetPoint() - GetPoint()).Normalized() * (speed / deltitime);
Move(movement);
double distance = currentPoint.Distance(targetPoint);
if (IsOverlapBegin(currentPoint, targetPoint, distance))
{
if (Vector.x > player.GetPoint().x)
{
Vector.SetLocation(FVector2D(targetPoint.x, Vector.y));
}
if (Vector.y > player.GetPoint().y)
{
Vector.SetLocation(FVector2D(Vector.x, targetPoint.y));
}
}
}
};
int main() {
Unit* Player = new Unit(5.0, 5.0);
EnemyUnit* Enemy = new EnemyUnit(10, 10);
FVector2D MoveDirection;
FVector2D MovePoint = FVector2D(2, 2);
double speed = 5.0; //이동 속도
double enemyspeed = 3.0;//적 이동속도
double deltaTime = 1.5; //이동 시간
double Radius = 2.5; //충돌 반경
//10번 반복
int turn = 10;
while (turn > 0)
{
turn--;
MoveDirection = Player->Move(MovePoint * (speed / deltaTime)); // 여기서 괄호로 한 이유를 생각중 예로들면 2 , 3 , 4 였다면 2* 3 * 4 = 24일테고 2 * (3* 4)면 6* 8 = 48값이 두배나 차이날텐데
Player->Print("Player Point :");
//cout << MoveDirection.x << " " << MoveDirection.y << endl;
Enemy->Follow(*Player, deltaTime);
Enemy->Print("Enemy Point :");
if (IsOverlapBegin(Player->GetPoint(), Enemy->GetPoint(), Radius))
{
cout << "Collision hit!!"<< endl;
//방향 전환
Player->GetPoint().CaluateAvoidanceDirection(MoveDirection);
Player->Print();
cout << endl;
}
Enemy->NextTurn();
}
}
방향으로 바꾸는 이유를 생각해보면
저 위치로 순간이동하는 거라면 정규화는 필요 없지만,
이동하는 과정에서는 특정 방향으로 일정한 속도로 움직여야 하고
그럴 때 계산을 쉽게 하기 위해 방향을 정규화하는 것이라고 생각된다.
만약 정규화를 하지않았다면 이동속도가 들쭉 날쭉 했을 것 같다.
'TIL' 카테고리의 다른 글
2025 - 02- 07 기록 (프로그래머스 코딩테스트 연습 - 체육복 ) (0) | 2025.02.07 |
---|---|
2025 - 02 - 06 기록 (0) | 2025.02.06 |
2025 02 04 - 공부내용 (언리얼 충돌 감지) (0) | 2025.02.04 |
2025 - 02 - 03 Unreal Input MappingContext 우선순위 (1) | 2025.02.03 |
2025 - 01- 31 언리얼 에서 객채 움직이기 (c++) (0) | 2025.01.31 |