유니티 입력(Input), 트랜스폼(Transform)

simple_coding·2024년 2월 1일

입력(Input)

유니티에서 사용자의 명령을 감지할 수 있는 수단으로 사용자는 외부 장치를 이용하여 게임을 제어할 수 있다.
유니티는 다양한 타입의 입력기기(키보드 및 마우스, 조이스틱, 터치스크린 등)를 지원한다.

      // <Device>
    // 특정한 장치를 기준으로 입력 감지
    // 특정한 장치의 입력을 감지하기 때문에 여러 플랫폼에 대응이 어려움
    private void InputByDevice()
    {
        // 키보드의 입력감지
        if (Input.GetKey(KeyCode.Space))//누르는 동안
            Debug.Log("Space key is pressing");
        if (Input.GetKeyDown(KeyCode.Space))//눌렀을 때
            Debug.Log("Space key is down");
        if (Input.GetKeyUp(KeyCode.Space))//눌렀다 땔 때
            Debug.Log("Space key is up");

        // 마우스의 입력감지
        if (Input.GetMouseButton(0))//누르는 동안
            Debug.Log("Mouse left button is pressing");
        if (Input.GetMouseButtonDown(0))//눌렀을 때
            Debug.Log("Mouse left button is down");
        if (Input.GetMouseButtonUp(0))//눌렀다 땔 때
            Debug.Log("Mouse left button is up");
    }


    // <InputManager>
    // 여러 장치의 입력을 입력매니저에 이름과 입력을 정의
    // 입력매니저의 이름으로 정의한 입력의 변경사항을 확인
    // 유니티 에디터의 Edit -> Project Settings -> Input Manager 에서 관리

    // 단, 유니티 초창기의 방식이기 때문에 키보드, 마우스, 조이스틱에 대한 장치만을 고려함
    // 추가) VR Oculus Integraion Kit 같은 경우 입력매니저와 유사한 방식을 사용
    private void InputByInputManager()
    {
        // 축 입력
        // Horizontal(수평) : 키보드(a,d / ←, →), 조이스틱(왼쪽 아날로그스틱 좌우)
        float x = Input.GetAxis("Horizontal");
        // Vertical(수직) : 키보드(w,s / ↑, ↓), 조이스틱(왼쪽 아날로그스틱 상하)
        float y = Input.GetAxis("Vertical");

        transform.position += new Vector3(x *3* Time.deltaTime, y * Time.deltaTime, 0);
       
        // 버튼 입력
        // Fire1 : 키보드(Left Ctrl), 마우스(Left Button), 조이스틱(button0)으로 정의됨
        if (Input.GetButton("Fire1"))
            Debug.Log("Fire1 is pressing");
        if (Input.GetButtonDown("Fire1"))
            Debug.Log("Fire1 is down");
        if (Input.GetButtonUp("Fire1"))
            Debug.Log("Fire1 is up");
    }


    // <InputSystem>
    // Unity 2019.1 부터 지원하게 된 입력방식
    // 컴포넌트를 통해 입력의 변경사항을 확인
    // GamePad, JoyStick, Mouse, Keyboard, Pointer, Pen, TouchScreen, XR 기기 등을 지원
    
    private void InputByInputSystem()
    {
        // InputSystem은 이벤트 방식으로 구현됨
        // Update마다 입력변경사항을 확인하는 방식 대신 변경이 있을 경우 이벤트로 확인
        // 메시지를 통해 받는 방식과 이벤트 함수를 직접 연결하는 방식 등으로 구성
    }

    // Move 입력에 반응하는 OnMove 메시지 함수

    private void Onmove(InputValue value)
    {
        Vector2 inputDir = value.Get<Vector2>();
        Debug.Log(inputDir);
    }

    private void OnJointBreak(InputValue value)
    {
        bool inputButton = value.isPressed;
        Debug.Log(inputButton);
    }


    //활용 예시

    Vector3 moveDir;
    private void OnMove(InputValue value)
    {
        Vector2 inputDir = value.Get<Vector2>();
        moveDir.x = inputDir.x;
        moveDir.z = inputDir.y;
    }

    private void Move()
    {
        transform.position += moveDir * 3f * Time.deltaTime;
    }

    public Rigidbody rigid;
    private void OnJump(InputValue value)
    {
        Jump();
    }

    private void Jump()
    {
        rigid.AddForce(Vector3.up * 5f, ForceMode.Impulse);
    }

    private void Update()
    {
        Move();
    }
}

트랜스폼(Transform)

게임오브젝트의 위치, 회전, 크기를 저장하는 컴포넌트이며, 게임오브젝트의 부모-자식 상태를 저장하는 컴포넌트이다.
게임오브젝트는 반드시 하나의 트랜스폼 컴포넌트를 가지고 있으며 추가 & 제거할 수 없다.

 //<트랜스폼 접근>
 private void TransformReference()
 {
     thisTransform = transform; //자신의 트랜스폼 직접 가리키기
 }


 // <트랜스폼 이동>
 // Translate : 트랜스폼의 이동 함수
 private void TranslateMove()
 {
     // 월드를 기준으로 이동
     transform.Translate(1, 0, 0, Space.World);
     // 자신을 기준으로 이동, Space 생략 시 자신 기준
     transform.Translate(1, 0, 0, Space.Self);
     // position을 이용한 이동, 월드기준
     transform.position += new Vector3(1, 0, 0);

 }


 // <트랜스폼 회전>
 // Rotate : 트랜스폼의 회전 함수
 private void Rotate()
 {
     // 월드를 기준으로 회전
     transform.Rotate(1, 0, 0, Space.World);
     transform.Rotate(Vector3.up, 30 * Time.deltaTime, Space.World);
    
     // 자신을 기준으로 회전
     transform.Rotate(1, 0, 0, Space.Self);
     transform.Rotate(Vector3.up, 30 * Time.deltaTime, Space.Self);
   
     // 특정 위치를 기준으로 회전
     transform.RotateAround(new Vector3(0, 0, 0), Vector3.up, 30*Time.deltaTime);
     transform.RotateAround(Camera.main.transform.position, Vector3.up, 1);

     // 위치를 바라보는 회전
     transform.LookAt(new Vector3(0, 0, 0));
 }


 //<트랜스폼 축>
 private void Axis()
 {
     // 트랜스폼의 x축
     Vector3 right = transform.right;

     // 트랜스폼의 y축
     Vector3 up = transform.up;

     // 트랜스폼의 z축
     Vector3 forward = transform.forward;
 }

 //비교 예시
 public Transform sphere;
 public Transform cube;
 public void Update()
 {
     sphere.position = transform.position + 3 * Vector3.forward;
     cube.position = transform.position + 3 * transform.forward;
 }
 
     // <트랜스폼 부모-자식 상태>
    // 트랜스폼은 부모 트랜스폼을 가질 수 있음
    // 부모 트랜스폼이 있는 경우 부모 트랜스폼의 위치, 회전, 크기 변경이 같이 적용됨
    // 이를 이용하여 계층적 구조를 정의하는데 유용함 (ex. 팔이 움직이면, 손가락도 같이 움직임)
    // 하이어라키 창 상에서 드래그 & 드롭을 통해 부모-자식 상태를 변경할 수 있음
    private void TransformParent()
    {
        GameObject newGameObject = new GameObject() { name = "NewGameObject" };

        // 부모 지정
        transform.parent = newGameObject.transform;

        // 부모를 기준으로한 트랜스폼
        // transform.localPosition	: 부모트랜스폼이 있는 경우 부모를 기준으로 한 위치
        // transform.localRotation	: 부모트랜스폼이 있는 경우 부모를 기준으로 한 회전
        // transform.localScale		: 부모트랜스폼이 있는 경우 부모를 기준으로 한 크기

        // 부모 해제
        transform.parent = null;

        // 월드를 기준으로한 트랜스폼
        // transform.localPosition == transform.position	: 부모트랜스폼이 없는 경우 월드를 기준으로 한 위치
        // transform.localRotation == transform.rotation	: 부모트랜스폼이 없는 경우 월드를 기준으로 한 회전
        // transform.localScale								: 부모트랜스폼이 없는 경우 월드를 기준으로 한 크기
    }


    // <Quarternion & Euler>
    // Quarternion	: 유니티의 게임오브젝트의 3차원 방향을 저장하고 이를 방향에서 다른 방향으로의 상대 회전으로 정의
    //				  기하학적 회전으로 짐벌락 현상이 발생하지 않음
    // EulerAngle	: 3축을 기준으로 각도법으로 회전시키는 방법
    //				  직관적이지만 짐벌락 현상이 발생하여 회전이 겹치는 축이 생길 수 있음
    // 짐벌락		: 같은 방향으로 오브젝트의 두 회전 축이 겹치는 현상

    // Quarternion을 통해 회전각도를 계산하는 것은 직관적이지 않고 이해하기 어려움
    // 보통의 경우 쿼터니언 -> 오일러각도 -> 연산진행 -> 결과오일러각도 -> 결과쿼터니언 과 같이 연산의 결과 쿼터니언을 사용함
    private void Rotation()
    {
        Quaternion rotation = transform.rotation;

        Vector3 position = transform.position;
        Vector3 scale = transform.localScale;

        // 트랜스폼의 회전값은 Euler각도 표현이 아닌 Quaternion을 사용함
        transform.rotation = Quaternion.identity;

        // Euler각도를 Quaternion으로 변환
        transform.rotation = Quaternion.Euler(0, 90, 0);
        //  Vector3 rotation = transform.rotation.eulerAngles;
    }
}
profile
기록하는 것이 기억된다.

0개의 댓글