Input System 새로운 조작 시스템을 받아서 사용한다.

이런식으로 설정 대략적으로 WASD 이동과 시점은 마우스 조작과 스틱 조작 두개를 넣어준거 같다.

설정 시 카메라 액션값을 아래 처럼 바꾸지 않을 시 버튼이 초기값이므로 컨트롤 타입을 벡터2 값으로 안 바꿔주면

패드 조작과 마우스 조작 빌딩이 활성화가 안된다. 마우스 조작은 노멀라이즈 벡터2 정규화를 해준다.

Ps. +를 누르면 추가된다

/* 하지만 직접 기계를 연결하여 키를 입력 받는게 있다. 자세한건 밑에 링크

Ace Combat Zero: 유니티로 구현하기 #1 : Input (velog.io)

무튼 따라하기니까 이건 배워만 두자 */

 

이제 코드로 WASD를 구현해보자.

InputHandler.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace SG
{
    public class InputHandler : MonoBehaviour
    {
        public float horizontal;
        public float vertical;
        public float moveAmount;
        public float mouseX;
        public float mouseY;

        PlayerCtrl inputActions;

        Vector2 movementInput;
        Vector2 cameraInput;

        // 스크립트가 활성화 될때 실행
        public void OnEnable()
        {
            // 입력값이 null인지 확인
            if (inputActions == null)
            {
                inputActions = new PlayerCtrl();
                // 인풋 매니저에 입력해논 PlayerMovement를 실행 확정 시 호출 더 빠른건 Started가 있다.
                // 설정해논 키를 입력 할때마다 현재는 WASD
                // inputActions 입력 액션, 의 값을 Read Value 읽어서 movementInput 미리 만들어논 벡터2에 넣는다. 
                // movementInput 벡터값보다 플레이어가 입력된 inputActions 값이 크면 그 값을 더해준다. 어디에 더해주냐? 그것도 문제
                inputActions.PlayerMovement.Movement.performed += inputActions => movementInput = inputActions.ReadValue<Vector2>();
                inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
            }
            // 플레이어 컨트롤 스크립트 활성화
            inputActions.Enable();
        }
        // 컴포넌트가 비활성화 될때 작동
        private void OnDisable()
        {
            //컴포넌트를 비활성화
            inputActions.Disable();
        }

        // 유추해서 보면 껏다 켰다 관리해줘야함
        public void TickInput(float delta)
        {
            // TickInput이란 메서드가 대신 받아서 줌
            MoveInput(delta);
        }
        // 숨김 위에서 대신 받아서 넘겨줌
        private void MoveInput(float delta) 
        {
            // 이동값
            horizontal = movementInput.x;
            vertical = movementInput.y;

                        //Mathf.Clamp01 0에서 1에 값을 돌려줌 ,  Math.Abs 절대값 반환
            moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.Abs(vertical));

            // 마우스 이동 값
            mouseX = cameraInput.x;
            mouseY = cameraInput.y;
        }
    }
}

PlayerLocomotion.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SG
{
    public class PlayerLocomotion : MonoBehaviour
    {
        Transform camObj;
        InputHandler inputHandler;
        Vector3 moveDirection;

        [HideInInspector]
        public Transform myTransform;

        public new Rigidbody rigidbody;
        public GameObject normalCamera;

        [Header("스피드값")]
        [SerializeField]
        float movementSpeed = 5f;
        [SerializeField]
        float rotationSpeed = 10f;

        private void Start()
        {
            rigidbody = GetComponent<Rigidbody>();
            inputHandler = GetComponent<InputHandler>();
            // 메인 카메라 위치값
            camObj = Camera.main.transform;
            // 내 위치
            myTransform = transform;
        }

        public void Update()
        {
            // 평균 프레임 값
            float delta = Time.deltaTime;

            inputHandler.TickInput(delta);
                           // 카메라 위치 * 플레이어 입력 값
            moveDirection = camObj.forward * inputHandler.vertical;
            moveDirection += camObj.right * inputHandler.horizontal;
            // 정규화(이동속도 정규화 같은 느낌 대각선에 경우 이동속도가 빨리질 수 있으므로)
            moveDirection.Normalize();

            float speed = movementSpeed;
            // 스피드 값 계산
            moveDirection *= speed;
            // 평면에 벡터를 투영한다.        평면 위의 벡터 위치입니다(범선), 벡터에서 평면을 향한 방향입니다.
            Vector3 projectedVelocity = Vector3.ProjectOnPlane(moveDirection, normalVector);
            // 리지드 바디 속력 벡터 = 벡터
            rigidbody.velocity = projectedVelocity;
        }
        // #region 접는 기능
        #region Movement
        Vector3 normalVector;
        Vector3 targetPosition;

        // 회전 함수
        private void HandleRotation(float delta)
        {
            // 벡터값 초기화
            Vector3 targetDir = Vector3.zero;
            // inputHandler.moveAmount, 이동 값 받아옴
            float moveOverride = inputHandler.moveAmount;

            // 카메라 회전 카메라.forward * 캐릭터.vertical 타겟 디렉토리에 넣어둠
            targetDir = camObj.forward * inputHandler.vertical;
            // left로 갈 시 음수 값이라 뒤집힘
            targetDir += camObj.right * inputHandler.horizontal;
            targetDir.Normalize();
            // 목표 방향이 같은 경우 움직임을 원치 않기 때문에
            targetDir.y = 0;
            
            // 앞 보게
            if (targetDir == Vector3.zero)
                targetDir = myTransform.forward;

            // 회전 속도
            float rs = rotationSpeed;

            // 타겟에 쿼터니언 값 반환
            Quaternion tr = Quaternion.LookRotation(targetDir);
            //회전 시켜줄 값 반환                 회전할 캐릭터 디폴트 값, 타켓 쿼터니언값, 스피트*델타
            Quaternion targetRotation = Quaternion.Slerp(myTransform.rotation, tr, rs * delta);
            // 회전을 값에 적용
            myTransform.rotation = targetRotation;
        }
        #endregion
    }
}

 

 

 

'수업 일기장' 카테고리의 다른 글

네트워크 수업 (1)  (0) 2021.04.20
Untiy.7 Move, add, sound  (0) 2021.02.26
Unity.6 uv, 텍스쳐 Wrap mode  (0) 2021.02.26
Unity.5 uv, normals, triangles  (0) 2021.02.26
Unity.4 Collider, Rigidbody  (0) 2021.02.24

+ Recent posts