A.1 삼각함수란?

직각삼감형의 각도에 따른 변 길이의 비율을 반환하는 함수 입니다. 

삼각함수로 사인, 코사인, 탄젠트라는 단어를 들어본 적이 있을 겁니다.

 

A.2 각도로 좌표 구하기 

플레이어가 적 캐릭터에게 사격을 하기위해 적과의 각도를 알면 다음과 같이 계산할수 있습니다.

float x = Mathf.Cos(라디안)
float y = Mathf.Sin(라디안)
Vector3 v = new Vector3(x,y) * shootSpeed;

유니티가 제공하는 삼각함수.

Mathf.cos, Mathf.sin Mathf.Tan

유니티가 제공하는 삼각함수는 각도를 매개변수로 사용하지 않고 라디안(호도법)을 사용합니다.

각도 = 라디안 x(180/원주율)

라디안=각도x(원주율/180)입니다.

유니티는 계산을 편하게 하기위해 Mathf.Deg2Rad, Mathf.Rad2Deg를 마련해 놨습니다.

 

라디안

아래 그림은 각도는 한바퀴를 360도라고 정의했을때 비율이다.

라디안은 반지름1인 원이 한바퀴 도는 둘레가 2πr인데 반지름이 1이름로 2π=360도 이다.

라디안은 결국 쉽게 말하면 한바퀴도는데 2π니까 1도 = 2π/360 = π/180 임.

역으로하면 360도 = 2π 니까 π=180도 뭐 그닥 와닫지는 않지만.

어려운건 아님.  각도는 바퀴고 라디안은 굴러간거리라고 생각하면 편함.

가만 생각해보면 원이 한바퀴도는건 파이=3.141592아니었나 생각되지만 그건 지름이 1일 경우이고 라디안은 반지름이1 지름이 2일 경우이다. ㅠㅠ

삼각함수도 반지름이 1일경우로 원을 그려 생각하면 엄청 쉬움

cosθ+sinθ=1 이게 원을 뜻한다.

x*x+y*y=1 도 원이지만. 

[네이버 지식백과]라디안[Radian] (물리학백과)

 

A.3 좌표에서 각도 구하기 

플레이어의 애니메이션을 선택하기 위해 플레이어의 이동각도를 알아야 할 때가 있습니다.

플레이어가 점 p1에서 p2로 이동할때 각도는 다음과 같습니다.

float dx = p2.x - p1.x;
float dy = p2.y - p1.y;
float angle = Mathf.Atan2(dy,dx)*Mathf.Rad2Deg;

Atan2는 좌표를 입력하면 각도를 구해주는 함수입니다.

 

A.4 자주쓰는 삼각함수 메서드

특정 게임 오브젝트 추적하기

Vector2 GetToVector(Vector2 pos) {
	float dx = pos.x-transform.position.x;
    float dy = pos.y-transform.position.y;
    float rad = Mathf.Atan2(dy,dx);
    //벡터만들기
    float x = Mathf.Cos(rad);
    float y = Mathf.Sin(rad);
    Vector2 v = new Vector2(x,y);  //방향
    return v;
}

특정 게임 오브젝트를 향하도록 회전시키기

GetAngle(Vector2 from, Vector2 to) {
	float dx = to.x-from.x;
    float dy = to.y-from.y;
    float rad = Mathf.Atan2(dy,dx);
    return rad * Mathf.Rad2Deg;
}

위함수를 Update()에서 호출해서 게임오브젝트을 로테이션 시킵니다.

Update(){
	float angle = GetAngle(transform.position, 이동 위치의 position);
    transform.rotation = Quaternion.Euler(0,0,angle);
}

다음 메소드는 이동속도를 회전각도로 반환합니다.

float velocityToAngle(){
	float r = 0;
    Rigidbody2D body = GetComponent<Rigidbody2D>();
    if(body !=null) {
    	Vector2 v = body.velocity;
        r = Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
    }
    retur r;
}

Update()에서 다음같이 사용됩니다.

Update() {
	float angle = velocityToAngle();
    transform.rotation = Quaternion.Euler(0,0,angle);
}

'유니티스크립팅 > 게임수학' 카테고리의 다른 글

벡터  (0) 2023.04.25

https://terms.naver.com/entry.naver?docId=3405101&cid=47324&categoryId=47324 

 

벡터

물체에 힘을 가할 때는 어느 방향으로 얼마만큼 세게 미는지를 같이 이야기한다. 속도라는 개념도 어느 방향으로 얼마나 빠르게 가는지를 동시에 이야기한다. 이와 같이 크기와 방향을 동시에

terms.naver.com

일반적인 벡터의 정의는 이미 대략은 알고 계실것이다.

유니티도 벡터를 많이 이용하고 툴을 제공한다.

1. 두 지점사이의 거리

현재위치 curPos와 목적지인 destPos가 있다면 현재위치에서 목적지로 가는 벡터는 delta = destPos-curPos 이다.

2지점의 거리는 delta.magnitude이다. Vector3.Distance(curpos,destPos)로도 구할 수 있다.

 

2. 단위거리 이동

목적지로 10만큼의 거리를 가고 싶을때는 정규화후 이동하면된다.

newPos = curPos;

newPos += delta.normalized * 10f

 

3. 쿼터니언

인스펙터뷰의 transform의 rotation은 Vector3로 보이지만 스크립트에서 수정하고자 하면 에러가 난다. 왜냐하면 내부적으로는 짐벌락의 문제로 쿼터니언으로 처리하기 때문이다. 

오일러각으로 읽어오기 위해서는 rotation.eulerAngles로 읽어와야하고 변경할때는

유니티는 오일러각을 Quaternion으로 변환해주는 함수를 제공한다.

rotation = Quaternion.Euler(Vector3);처럼 변경해야 한다.

 

현재 회전 상태에서 더 회전하기

현재 rotation1 = Quaternion(30,0,0)상태에서 rotation2 = Quaternion(0.60,0) 만큼 더 회전시키려면 rotation1+rotation2가 아니고 rotation1*rotation2이다. 쿼터니언 사이의 연산은 행렬을 사용하기 때문입니다.

 

4.벡터의 내적 : vector3.Dot(a,b) 벡터b를 벡터a로 투영한 길이를 구합니다. 수직일 경우 0이 됩니다.

5. 벡터의 외적 : Vector3.Cross(a,b) 두 벡터 모두에 수직인 벡터를 구합니다. 앞뒤가 있습니다.

 

'유니티스크립팅 > 게임수학' 카테고리의 다른 글

게임에서 사용되는 삼각함수  (2) 2023.05.25

+ Recent posts