KDT Unity 2주차~4주차 - new team!
23-11-24 TIL
알고리즘 문제
오늘의 알고리즘 문제 : 제일 작은 수 제거하기
정수를 저장한 배열, arr 에서 가장 작은 수를 제거한 배열을 리턴하는 함수, solution을 완성해주세요. 단, 리턴하려는 배열이 빈 배열인 경우엔 배열에 -1을 채워 리턴하세요. 예를들어 arr이 [4,3,2,1]인 경우는 [4,3,2]를 리턴 하고, [10]면 [-1]을 리턴 합니다.
1
2
3
4
5
6
public class Solution {
public int[] solution(int[] arr) {
int[] answer = new int[] {};
return answer;
}
}
해결
1
2
3
4
5
6
7
8
9
10
11
public int[] solution(int[] arr)
{
int[] answer = new int[] { -1 };
int index = Array.IndexOf(arr, arr.Min());
List<int> list = new List<int>(arr);
list.RemoveAt(index);
if(arr.Length > 1) answer = list.ToArray();
return answer;
}
일단은 해당 배열의 길이가 1일 경우를 디폴트로 생각합니다.
그래서 int[] answer = new int[] { -1 };를 기본으로 잡고
int index = Array.IndexOf(arr, arr.Min());배열의 가장 작은 값의 인덱스 번호를 찾습니다.
List<int> list = new List<int>(arr); 해당 코드를 이용하여 배열을 리스트로 변환해줍니다. list.RemoveAt(index);을 사용하여 제일 작은 수의 인덱스를 없애줍니다.
그 후 if(arr.Length > 1) answer = list.ToArray(); 배열의 길이가 1보다 크다면 answer은 list를 배열화한 값이 됩니다.
새로운 팀 새로운 과제
저번 팀플이 끝나고 새로운 팀과 함께하게 되었습니다.
저번과 마찬가지로 개인 프로젝트부터 시작하였습니다.
개인 프로젝트 탑뷰 만들기! - 현재 진행사항
이동은 전포스팅에 적었던 뉴 인풋 시스템을 사용하였습니다!
이동과 애니메이션이 잘 나오고 마우스 포인터에 따라 좌우 반전도 잘됩니다!
얘 머리 왜 돌아가요?
희망편인 진행상황이 되기전 크게 문제되는 부분이 있었습니다.
마우스 포인터에 따라 좌우가 반전되야하지만 현재 문제는 마우스가 움질일 때 프레임마다 머리를 흔드는 일이 발생헀습니다.
1
2
3
4
5
6
7
8
9
10
11
12
void RotationAim(Vector2 direction)
{
float rotZ = MathF.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (Mathf.Abs(rotZ) > 90f) player.localScale = new Vector3(player.localScale.x * -1, player.localScale.y, player.localScale.z) ;
else player.localScale = new Vector3(player.localScale.x * -1, player.localScale.y, player.localScale.z) ;
}
현재 목이 부러질 듯 돌아가는 코드 상황입니다.
마우스의 인풋시스템으로 받은 벡터값인 direction을 기준으로 해당 각도가 일정 수준이 넘어가면 오브젝트의 스케일의 X값을 음수로 바꿔 반전을 주려고 했습니다!
-1을 곱하는 상황이기에 해당 함수는 마우스의 위치가 일정수준을 넘어가면 다시 -1을 곱해 양수에서 음수로 음수에서 양수로 바꿀 이론이였습니다.
하지만 여기서 랜더러 플립을 쓰면 되지 왜 스케일을 바꾸냐 하시는 분들이 있으실겁니다!
하지만 그 이유는 해당 객체는 하나의 오브젝트가 아닌 여러 오브젝트에 랜더러를 붙인 방식이기 때문입니다
그래서 스케일을 바꾸는 방법을 선택하였습니다!
본론으로 돌아와 해당 객체가 머리를 많이 흔드는 이유는 마우스가 움직일때 해당하는 if문 또는 else문이 반복적으로 돌기 때문입니다.
머리를 계속 흔드는 이유는 마우스가 움직일때마다 -1을 곱해주었기 때문입니다.
해결
이걸 어떻게 하면 잘 바꿧다고 소문이 날까라는 생각을 하면서 한번 다시 정리를 해보았습니다.
그때 문뜩 생각이 났습니다.
매개변수로 들어오는 벡터값 direction은 해당 객체의 오른쪽일 때 +, 왼쪽일때 -의 값을 가지는구나!
유니티는 해당 객체의 오른쪽을 1 왼쪽을 -1로 나타냅니다.
그럼 양수인지 음수인지만 확인하면 되겠다!
고친 코드입니다.
1
2
3
4
5
6
7
8
9
void RotationAim(Vector2 direction)
{
float rotZ = MathF.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (direction.x > 0) transform.localScale = new Vector3(transform.localScale.x * direction.x, transform.localScale.y, transform.localScale.z);
else if(direction.x < 0) transform.localScale = new Vector3(transform.localScale.x * direction.x, transform.localScale.y, transform.localScale.z);
}
어 이렇게 하니까 머리가 위치에 따라 돌아가네?라고 잠시 느꼇지만 그건 큰 오산이였습니다.
왜냐면 direction으로 들어오는 값은 완전한 1,-1이 아니기 때문입니다.
그래서 저는 한번더 생각을 해보았습니다.
그럼 new Vector3의 X값에 transform.localScale.x과 -transform.localScale.x을 넣어보자고 말입니다
그랬더니 왠걸? transform.localScale.x은 정상작동을 합니다. 하지만 -transform.localScale.x은 위와 마찬가지로 프레임당 -1을 곱해주는 것과 같은 반응을 보이기 시작합니다.
그래서 그냥 해당객체의 스케일 값을 양수값, 음수값을 넣어줬습니다.
정상 작동을 하였습니다.
하지만 이렇게 되면 특수한 상황(캐릭터의 크기가 커지거나 작아지거나)에는 고정값으로 인해 플립이 될때 크기가 줄어들거나 커지는 경우가 생길수 있습니다.
그래서 한번더 생각했습니다.
변수를 하나더 만들자 해당 스케일의 값을 가지고 있는 값인 float flipX;을 만들었습니다.
그후 Awake함수에서 한번 초기화를 해줍니다.
1
2
3
4
5
6
7
float flipX;
private void Awake()
{
flipX = transform.localScale.x;
}
해당 값을 넣어 만든 최종 메서드입니다.
1
2
3
4
5
6
void RotationAim(Vector2 direction)
{
float rotZ = MathF.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (direction.x > 0) transform.localScale = new Vector3(-flipX, transform.localScale.y, transform.localScale.z);
else if(direction.x < 0) transform.localScale = new Vector3(flipX, transform.localScale.y, transform.localScale.z);
}
이렇게 되면 해당 캐릭터의 스케일이 변했을 시 flipX의 값만 바꿔주면 플립과 크기가 정상적으로 작동하게 됩니다.
오늘의 정리
코드를 짤때는 해당 객체의 문제점을 잘 확인해봐야 한다.
또한 항상 고정된 값이 아닌 것은 변수처리를 해 나중을 대비하는 편이 좋다.
무언가 오류가 났을 시 해당 문제를 여러가지 측면에서 접근을 하는 습관을 들이는게 좋다.



