내일배움캠프 35일차 TIL : 이동 Vector3와 ?. 대한 의문점 정리

woollim·2024년 11월 11일
0

내일배움캠프TIL

목록 보기
32/36
post-thumbnail

■ 학습 개요

오늘 계획

  • 09:00~10:00 : 아침 회의
  • 10:00~11:00 : 11강 ~ 13강
  • 11:00~12:00 : 14강
  • 12:00~13:00 : 꾸준실습
  • 13:00~14:00 : 점심😁
  • 14:00~15:00 : 15강
  • 15:00~16:00 : 16강 ~ 18강
  • 16:00~17:00 : 19강 ~ 20강
  • 17:00~18:00 : 21강
  • 18:00~19:00 : 저녁 😁
  • 19:00~20:00 : 22강
  • 20:00~21:00 : 23강~24강
  • 22:00~23:00 : TIL작성, 알고리즘
  • 23:00~ : 강의 복습


■ 학습중 의문사항

○ 이동 Vector3

  • 코드
private Vector3 GetMovementDirection()
    {
        Vector3 forward = stateMachine.MainCamTransform.forward;
        Vector3 right = stateMachine.MainCamTransform.right;

        forward.y = 0;
        right.y = 0;

        forward.Normalize();
        right.Normalize();

        return forward * stateMachine.MovementInput.y + right * stateMachine.MovementInput.x;
    }
}
  • 내 의문사항
    forward * stateMachine.MovementInput.y + right * stateMachine.MovementInput.x;
    Vector3에서 항상 의문이었던점.
    앞으로가기 위한 값이니까 forward에는 z축을 곱해야하는거 아닌가? 유니티의 transform에선 앞뒤 이동이 z축이니까.

  • GPT 답변

    • 현재 GetMovementDirection() 메서드는 forward와 right 벡터를 사용하여 이동 방향을 계산하고 있습니다. 여기서 forward에 대해 z 축을 곱해야 하는 것이 아닌지에 대한 의문이 있는데, 이 방식은 Unity에서 흔히 사용하는 카메라의 상대적인 이동 방식이므로 다음 설명을 참고해보세요.
    • Unity에서 Vector3.forward(0, 0, 1)이며, MainCamTransform.forward카메라가 향하는 전방 벡터로, 월드 공간에서 카메라의 전방을 의미합니다.
      이 방향은 y축 방향을 제외하고 xy 평면에서 움직이는 것으로 y = 0 설정을 통해 수직 축의 영향을 제거합니다. 즉, forward에 z 축을 곱할 필요 없이 카메라 기준 방향으로 이동합니다.
    • 이 코드에서 MovementInput.y와 MovementInput.x 값이 각각 전방과 우측 이동을 제어하므로 forward * MovementInput.yright * MovementInput.x 방식으로 입력에 따라 방향이 설정됩니다.

  • MovementInput.y와 MovementInput.x

    • MovementInput.y : 앞뒤 방향의 입력 값입니다.
      • 일반적으로 W 키를 누르면 y 값이 양수(보통 1), S 키를 누르면 음수(보통 -1)로 설정됩니다.
      • 이 값은 캐릭터가 앞쪽으로 움직이게 하는지, 아니면 뒤쪽으로 움직이게 하는지를 결정합니다.
    • MovementInput.x : 좌우 방향의 입력 값입니다.
      • A 키를 누르면 x 값이 음수(왼쪽 이동), D 키를 누르면 양수(오른쪽 이동)로 설정됩니다.
      • 이 값은 캐릭터가 좌측으로 움직이는지, 아니면 우측으로 움직이는지를 결정합니다.

  • MainCamTransform.forward

    • MainCamTransform.forward는 카메라가 바라보는 방향을 나타내는 전방 벡터입니다.
    • 이 벡터는 Vector3 타입이며, (x, y, z) 값으로 현재 카메라의 월드 공간에서의 방향을 가리킵니다.

  • 깨달은 결론

    • input값이 vector2이기 때문에 vector3값인 MainCamTransform.forward에 input의 y가 곱해진것이다.
    • MovementInput의 값이 Vector2 타입이므로 Vector3 벡터와 계산할 때 y값이 forward에 곱해지고, x값이 right에 곱해짐
    • 여기서 Vector2의 y가 forward 방향으로 이동하는 양을 결정하고, x가 right 방향으로 이동하는 양을 결정함
    • MovementInput.y는 forward 벡터의 크기를 조절해주고, MovementInput.x는 right 벡터의 크기를 조절하여 이 두 방향을 조합한 최종 이동 방향이 반환됨
    • 이 방식 덕분에 입력이 Vector2라 하더라도 Vector3 방향으로 캐릭터가 자연스럽게 이동하게 됨

  • 만약에 input이 Vector3값이었다면?

    • 만약 MovementInput이 Vector3였다면 z 값이 추가적인 축으로 고려될 수 있음
    • MovementInput.z 값이 forward 벡터와 곱해져 이동에 영향을 주었을 가능성이 큼
    • 이렇게 하면 y는 수직(점프 또는 하강) 방향에, x는 좌우 방향에, z는 전후 방향에 사용될 수 있음
    • 예시
      return forward * stateMachine.MovementInput.z + right * stateMachine.MovementInput.x;
      • 이렇게 되면 z 값이 전진이나 후진을 제어하게 됨

○ ?.

  • 코드
public void ChangeState(IState state)
{
    currentState?.Exit();
    currentState = state;
    currentState?.Enter();
}
  • 내 의문사항
    델리게이트를 Invoke()할때만 쓰이는줄 알았는데 함수에도 쓰이네?

  • GPT 답변
    Unity에서 ?(물음표)는 nullable 타입을 만들거나 null 조건부 연산자로 사용하는 두 가지 경우가 있음

    1. nullable 타입
      • int?, float?와 같이 사용하면 해당 기본 타입을 null을 허용하는 타입으로 변환합니다.
      • 이때 ?는 변수에 null 값을 가질 수 있도록 허용합니다.
      • 예시 : int? nullableInt = null;
    2. null 조건부 연산자
      • 메서드 호출이나 델리게이트 실행, 속성 접근 등에서 ?. 형식으로 사용하면, 해당 객체가 null인지 확인 후 null이 아니면 그 뒤의 메서드나 속성을 실행합니다.
      • 이를 통해 null 참조 예외를 방지할 수 있습니다.
      • 이처럼 ?. 연산자는 null 검사를 간편하게 하기 위해 함수 호출이나 델리게이트 실행 시에도 자주 쓰입니다.
      • 예시 :
      Action myDelegate = null;
      myDelegate?.Invoke(); // 델리게이트가 null이면 실행하지 않음
  • 깨달은 결론
    • 델리게이트, 함수에 모두 쓰인다

■ 일일 알고리즘

○ 모의고사(하)

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 정답 체크 함수, 맞은 갯수 돌려줌
int UserTest(vector<int> answers, vector<int> user)
{
    int temp = 0;
    int index = 0;

    for (int i = 0; i < answers.size(); i++)
    {
        if (user[index] == answers[i])
        {
            temp++;
        }
        if (index == user.size() - 1)
            index = 0;
        else
            index++;
    }
    
    return temp;
}

vector<int> solution(vector<int> answers) {
    vector<int> answer;

    vector<int> temp; // 맞은 갯수 기록용
    // 각 유저 스타일, 반복 되는 만큼만 벡터에 넣음
    vector<int> user1 = { 1, 2, 3, 4, 5 };
    vector<int> user2 = { 2, 1, 2, 3, 2, 4, 2, 5 };
    vector<int> user3 = { 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 };

    temp.push_back(UserTest(answers, user1));
    temp.push_back(UserTest(answers, user2));
    temp.push_back(UserTest(answers, user3));
    
    // 가장 높은 수를 뽑아 max에 넣음
    int max = *max_element(temp.begin(), temp.end());
    // max와 하나하나 순서대로 비교해서 일치하거나 높으면 answer 배열에 추가
    for (int i = 0; i < temp.size(); i++)
    {
        if (max == temp[i])
            answer.push_back(i+1);
    }
    
    return answer;
}
  • 다른 사람 풀이
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> one = {1,2,3,4,5};
vector<int> two = {2,1,2,3,2,4,2,5};
vector<int> thr = {3,3,1,1,2,2,4,4,5,5};

vector<int> solution(vector<int> answers) {
    vector<int> answer;
    vector<int> they(3);
    for(int i=0; i<answers.size(); i++) {
        if(answers[i] == one[i%one.size()]) they[0]++;
        if(answers[i] == two[i%two.size()]) they[1]++;
        if(answers[i] == thr[i%thr.size()]) they[2]++;
    }
    int they_max = *max_element(they.begin(),they.end());
    for(int i = 0; i< 3; i++) {
        if(they[i] == they_max) answer.push_back(i+1);
    }
    return answer;
}

0개의 댓글