일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- toString
- 출처 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
- 출처 : https://webdir.tistory.com/506
- object
- http://jeonghwan-kim.github.io/dev/2019/06/25/react-ts.html
- https://velog.io/@velopert/create-typescript-react-component
- 게시판
- Today
- Total
Back Ground
Unity - Mathf.Cos(), Mathf.Sin() 시야함수 만들기 본문
위 큐브가 적이라고 치고 시선을 보고있는 방향을 구현하였다.
이렇게만 보면 뭔지 이해를 못할 것 같아서 현재 서비스운영중인 게임을 보자면,
[가디언 테일즈]게임에서 인베이더(적)들이 보는 탐색거리를 표현한것이다.
만들기 전에 삼각함수 공식에 대해서 먼저 설명하도록 하겠다.
(삼각함수 공식을 이용하여 코드로 작성해야하기 때문)
[삼각함수] ▼
삼각함수
Sin 사인, Cos 코사인,Tan 탄젠트[쉽게 외우는 방법]호도법60분법은
호도법(radian measure)이란 각도를 길이로 표현 하는 방법이다 즉, 라디안을 단위로 하여 중심각을 재는 방법 [라디안] 호의 길이가 반지름과 같게 되는 만큼의 각을 1 라디안이라고 정의한다. 라디안은 절대적인 각도이며 실제 1 라이안은 57.3도에 해당하는 값이다. 라디안의 표기는 rad라고 한다. 반지름과 호의 길이가 동일한 상태를 1 라디안이라고 부른다. [여기서 r은 반지름을 뜻한다.] 그런 식으로 늘어나게 되면 1 ~ 2 ~ 3 ~... 라디안이 된다. 그런데 반원이 되기에 3 라디안에서 약 0.147592.. 정도가 모자라게 되는데 원지름에 대한 길이의 비율 값을 3.14159265358979.. 가 되는데 이걸 파이(π, pi)라고 한다. 즉, 반원의 라디안은 파이 라디안이 된다 (원지름이 파이이기 때문) Gif설명 정리된 그림 [이미지 출처 : https://giverboy.tistory.com/42] π = 3.14159265358979... : 180º 반원 = πr (π: 파이 * r 반지름 ) [즉 180도 * 반지름으로 반원을 그린다고 생각하면 쉽다) 원주율 = 2πr 세타(theta)Θ 각도를 나타내는말 (x,y축 기준으로 양수음수로 나타낸다) |
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
Vector3[] CalualteSightPoint(float radius, float angle)
{
Vector3[] results = new Vector3[2];
// 우측 끝 점의 좌표를 구한다.
float theta = 90 - angle - transform.eulerAngles.y;
float posX = Mathf.Cos(theta * Mathf.Deg2Rad) * radius;
float posY = transform.position.y;
float posZ = Mathf.Sin(theta * Mathf.Deg2Rad) * radius;
results[0] = new Vector3(posX, posY, posZ);
// 좌측 끝 점의 좌표를 구한다.
theta = 90 + angle - transform.eulerAngles.y;
posX = Mathf.Cos(theta * Mathf.Deg2Rad) * radius;
posY = transform.position.y;
posZ = Mathf.Sin(theta * Mathf.Deg2Rad) * radius;
results[1] = new Vector3(posX, posY, posZ);
return results;
}
|
cs |
코드를 설명하기전 만들고자 하는 부분이 어디인지 설명 하자면
오른쪽 각도선를 먼저 설명할 것이다.
적당히 CalualteSightPoint라는 이름의 시선점 계산해주는 함수 정의 한 후
Mathf.Cos() 코사인 함수를 이용하여 길이를 구해준다.
1 2 |
float theta = 90 - angle; float posX = Mathf.Cos(theta * Mathf.Deg2Rad) * radius; |
cs |
theta각도를 구해준다. 90에서 뺀 이유는
적이 기준에서 x측이 0이기 때문에 /(오른쪽 대각선)을 구하기위해서 90기준에서
우리가 지정할 각도(매개변수 angle)를 빼준 것이다.
Mathf.Deg2Rad는 Degree(60분법 각도)에서 Radian(호의 길이)로 변경해준다.
밑변의 길이를 구해주기 위한 처리
Mathf.Cos(theta * Mathf.Deg2Rad) * radius; |
밑변 = cos(angle) * 빗면 |
그럼 이제 Z의 값도 구해준다.
(Y가 아니라 왜 Z??)
유니티에서 보면 쉽게 알 수 있는데 forward방향 Z가 되므로, X와 Z를 구해야 한다. |
Z축
1
|
float posZ = Mathf.Sin(theta * Mathf.Deg2Rad) * radius;
|
cs |
Mathf.Sin(theta * Mathf.Deg2Rad) * radius; |
높이 = sin(angle) * 빗면 |
1
|
results[0] = new Vector3(posX, posY, posZ);
|
cs |
Vector3를 통해서 (x위치 , y위치(본인 값), z위치)에 맞춰서 넣어주게 되면
위 그림의 현재 각도에 맞춰서 나타나게 된다.
(흰 선은 기즈모를 활용하여 시각화 했을뿐 이 코드만으로 저렇게 나오지 않는다.)
이와 같은 방식으로 좌측도 만들면 된다.
1
2
3
4
5
6
|
// 좌측 끝 점의 좌표를 구한다.
theta = 90 + angle - transform.eulerAngles.y; // 90도를 넘을 것이기 때문에 + 처리
posX = Mathf.Cos(theta * Mathf.Deg2Rad) * radius; //x 위치
posY = transform.position.y; //현재 큐브에 script를 추가했기 때문에 자기 자신의 y값
posZ = Mathf.Sin(theta * Mathf.Deg2Rad) * radius; //z 위치
results[1] = new Vector3(posX, posY, posZ);
|
cs |
다음으로는 기즈모를 그려보겠다.
[ 기즈모 그리는 함수 ]
https://backback.tistory.com/manage/posts/
기즈모 선그리기
1
2
3
4
5
6
7
8
9
10
11
12
|
void OnDrawGizmos()
{
Gizmos.color = Color.white;
// 시야 범위의 양쪽 끝 지점을 구한다.
Vector3[] sightPos = CalculateSightPoint(sightDistance, sightDegree);
for(int i=0; i < sightPos.Length; i++)
{
Gizmos.DrawLine(transform.position, transform.position + sightPos[i]);
}
}
|
cs |
코드 설명
기즈모를 하얀색으로 지정해주었다.
Gizmos.color = Color.white;
기즈모의 그려질 각 끝점을 구한다.
1
|
Vector3[] sightPos = CalculateSightPoint(sightDistance, sightDegree);
|
cs |
각도계산하는 함수로 원하는 각도를 통해서 거리와 각도를 구한다.
현재는 전역변수
float sightDistance = 10;
float sightDegree = 30;
로 지정하였다.
기즈모의 선을 그린다.
1
|
Gizmos.DrawLine(transform.position, transform.position + sightPos[i]);
|
cs |
DrawLine의 시작지점 (transform.position) ~ 끝지점 transform.position + sightPos[0]; 을 지정해줬는데
- 시작지점이 현재 script가 있는 큐브에서 부터 시작하므로 transform.position으로 지정
- 끝지점은 위에서 구한 sightPos의 각도를 구한 지점인데
현재 큐브에서 부터 각도가 나와야 하기때문에 transform.position + sightPos로 지정해줬다.
'Unity > 3D' 카테고리의 다른 글
Unity - OnDrawGizmos 기즈모 그리기 (0) | 2021.07.27 |
---|