0721 유니티(NewInputSystem)

기존 Input받던거
문제점 :
1. Update에서 계속 입력을 받고있어야함 -> 메모리 낭비가 심하다
2. 플랫폼이 달라지면 입력방법도 달라져야함
New Input System
장점 :
외부 입력장치와 동작하는 코드를 완벽하게 분리 가능 -> 매 프레임마다 입력받지 않아도 된다
코드에서 어떤 입력장치로부터 입력됐는지 확인할 필요가 없음
다른 플랫폼으로 변경되면 바인딩 정보만 변경하면 됨

설치(설치 시 재시작 됨)

그럼 이런게 생김



active Input Handling

어떤걸로 입력받을지 정하는것





지상 조작과 물 조작 등을 다 따로 만들 수 있다




여러개 넣기도 가능
여기서 지정한 애들만 컨트롤이 가능해진다



입력을 값으로 (wasd)

Vector2 로 (상하좌우)


2D Vector
DigitalNormalized : 키보드값

-
Digital:키보드, 조이스틱 등 디지털 입력 장치에서 값을 받아온다는 의미입니다.
-
Normalized:입력 값을 0과 1 사이의 값으로 변환하여 사용한다는 의미입니다.





바인딩을 여러개 추가 가능 -> 플랫폼이 바뀌는거에 대응 가능

Button : 마우스 클릭
보다는
Value는 지속적으로 변하는 값 말하는거같고
Button은 한번 눌러서 true뜨는거 말하는거 같음



플레이어 쪽에 Player Input추가


Defalut Map : Action쪽에서 만든 Map들중에서 어떤걸 기본설정으로 할건지

Send Messages : PlayerInput 컴포넌트가 붙은 게임 오브젝트에 Send Message를 이용해서 함수 호출
Broadcast Messages : Send Messages와 동일하지만 Broadcast SendMessages 함수를 이용해서 하위에 있는 게임 오브젝트의 메서드도 호출
Invoke Unity Events : 액션별로 이벤트 연결 인터페이스가 생성되고 각각 호출하려는 함수를 연결

이렇게
Invoke CSharp Events : 스크립트에서 직접 연결해서 사용

Action을 만든것들에 대해서 SendMessage 이름이 On~~~하고 더 정해짐
OnDeviceLost 등등은 기본으로 있음
연결이 끊기거나 등등 해서 저기 적힌 일들이 일어나면, player Input이 붙은 애가 저 이름의 SendMessage를 날림
코드에서 저 이름으로 함수를 만들어두면 알아서 실행됨
public class PlayerCtrl : MonoBehaviour
{
void OnMove(InputValue value)
{
}
void OnAttack(InputValue value)
{
}
}
매개변수 넣어서 함수 만들어야함
public class PlayerInput : MonoBehaviour
{
PlayerCtrl ctrl;
PlayerAnim animCtrl;
private void Start()
{
ctrl = GetComponent<PlayerCtrl>();
animCtrl = GetComponent<PlayerAnim>();
}
void OnMove(InputValue value)
{
Vector2 dir = value.Get<Vector2>();
ctrl.moveDir = new Vector3(dir.x, 0, dir.y);
animCtrl.anim.SetFloat("Movement", dir.magnitude);
}
void OnAttack(InputValue value)
{
animCtrl.anim.SetTrigger("Attack");
}
}
//////////////////////////////////////////////
public class PlayerAnim : MonoBehaviour
{
public Animator anim;
void Start()
{
this.anim = GetComponent<Animator>();
}
}
//////////////////////////////
public class PlayerCtrl : MonoBehaviour
{
public Vector3 moveDir;
public float moveSpeed = 2;
private void Start()
{
}
private void Update()
{
if(this.moveDir != Vector3.zero)
{
this.transform.rotation = Quaternion.LookRotation(this.moveDir);
this.transform.Translate(Vector3.forward * Time.deltaTime * this.moveSpeed);
}
}
}
Invoke 방식

InputAction에 CallbackContext를 이용해서 함
started : 시작
performed : 실행
canceled : 취소
public void OnMove(InputAction.CallbackContext ctx)
{
Vector2 dir = ctx.ReadValue<Vector2>();
ctrl.moveDir = new Vector3(dir.x, 0, dir.y);
animCtrl.anim.SetFloat(hashMove, dir.magnitude);
}
public void OnAttack(InputAction.CallbackContext ctx)
{
if (ctx.performed)
{
Debug.Log("Attack");
animCtrl.anim.SetTrigger(hashAttack);
}
}
이렇게 만든 함수를

PlayerAction쪽에 할당해서 사용
저게 바로 안보인다면 다른 오브젝트 눌렀다가 다시 누르면 보임
CSharpInvoke
PlayerInput playerInput;
InputActionMap mainActionMap;
private InputAction moveAction;
private InputAction attackAction;
void Start_For_CSharp_Invoke()
{
//컴포넌트 초기화
this.playerInput = GetComponent<PlayerInput>();
//Action Map 추출
this.mainActionMap = this.playerInput.actions.FindActionMap("PlayerAction");
this.moveAction = mainActionMap.FindAction("Move");
this.attackAction = mainActionMap.FindAction("Attack");
this.moveAction.performed += (ctx) =>
{
Vector2 dir = ctx.ReadValue<Vector2>();
ctrl.moveDir = new Vector3(dir.x, 0, dir.y);
animCtrl.anim.SetFloat(hashMove, dir.magnitude);
};
this.attackAction.performed += (ctx) =>
{
animCtrl.anim.SetTrigger(hashAttack);
};
}
private void Start()
{
ctrl = GetComponent<PlayerCtrl>();
animCtrl = GetComponent<PlayerAnim>();
//CSharp Invoke방식을 위한 내용
this.Start_For_CSharp_Invoke();
}
Invoke방식에서 자동으로 만들어지던 이벤트를 직접 코드로 만들어서 사용
Start쪽에서 AddListener비슷하게 한번 할당하고나면 계속 작동함
_______________________________________________
만약 AD가 설정되어있다면

여기 있는 ad파일을 할당하면 됨