상세 컨텐츠

본문 제목

유니티 뉴인풋시스템 - 구르기, 회피, 닷지, 롤

유니티/기능

by MJ_119 2024. 10. 24. 00:45

본문

유니티 뉴인풋시스템 - 구르기, 회피, 닷지, 롤

 

스페이스바 + WASD 눌렀을때 해당하는 애니메이션 재생하기

 

- 애니메이터에서 컨디션을 맞춰준다 ( RollCount 0~3 )

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem.XR;

public class PlayerAttack : MonoBehaviour
{
    PlayerController controller;
    Player player;
    Animator animator;

    void Start()
    {
        player = GetComponent<Player>();
        animator = GetComponentInChildren<Animator>();
        controller = player.playerController;
    }

    void Update()
    {
        controller.Character.Click1.performed += context =>
        {
            Attack();
        };

        controller.Character.Roll.performed += context =>
        {
            Roll();
        };
    }

    private void Roll()
    {
        if( player.playerMove.moveInput.y > 0 ) // W
        {
            animator.SetInteger("RollCount", 0);
        }
        else if ( player.playerMove.moveInput.y < 0 ) // S
        {
            animator.SetInteger("RollCount", 1);
        }
        else if ( player.playerMove.moveInput.x < 0 ) // A
        {
            animator.SetInteger("RollCount", 2);
        }
        else if ( player.playerMove.moveInput.x > 0 ) // D
        {
            animator.SetInteger("RollCount", 3);
        }
        animator.SetTrigger("Roll");
    }

    private void Attack()
    {
        print("Attack!");
        animator.SetTrigger("Attack");
    }
}

 

 

 

- 회피 방법 2 : WW, AA SS DD 등 더블 탭 했을 때 회피,구르기 시전

 

- 문제점 : WA, AD, DA, SD ,SA, WS 등 빠르게 다른 방향을 눌러도 구르기가 시전 됨.

 

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

public class PlayerMove : MonoBehaviour
{
    CharacterController characterController;
    Player player;
    PlayerController controller;
    Animator animator;

    public Vector2 moveInput { get; private set; }
    public float walkSpeed = 3f;

    Vector3 movementDirection;
    float verticalVelocity;
    float speed;


    // 입력 시간을 저장하는 변수
    private float lastTapTimeW = 0f;
    private float lastTapTimeA = 0f;
    private float lastTapTimeS = 0f;
    private float lastTapTimeD = 0f;

    // 더블탭을 감지할 시간 간격
    public float doubleTapTime = 0.3f;

    private void Awake()
    {

    }

    void Start()
    {
        characterController = GetComponent<CharacterController>();
        player = GetComponent<Player>();
        controller = player.playerController;
        animator = GetComponentInChildren<Animator>();

        speed = walkSpeed;
    }

    void Update()
    {
        controller.Character.Move.performed += context =>
        {
            moveInput = context.ReadValue<Vector2>();
            Roll();
        };
        controller.Character.Move.canceled += context => moveInput = Vector2.zero;

        ApplyMovement();

        float xVelocity = Vector3.Dot(movementDirection.normalized, transform.right);
        float yVelocity = Vector3.Dot(movementDirection.normalized, transform.forward);

        animator.SetFloat("X", xVelocity, 0.1f, Time.deltaTime);
        animator.SetFloat("Y", yVelocity, 0.1f, Time.deltaTime);
    }

    private void ApplyMovement()
    {
        movementDirection = new Vector3(moveInput.x, 0, moveInput.y);
        
        ApplyGravity();

        if (movementDirection.magnitude > 0)
        {
            characterController.Move(movementDirection * speed * Time.deltaTime);
        }
    }

    private void ApplyGravity()
    {
        if (characterController.isGrounded == false)
        {
            verticalVelocity -= 9.81f * Time.deltaTime;
            movementDirection.y = verticalVelocity;
        }
        else
        {
            verticalVelocity = -0.3f;
        }
    }

    private void Roll()
    {
        if (moveInput.y > 0) // W
        {
            DetectDoubleTap(ref lastTapTimeW, "RollForward");
        }
        else if (moveInput.y < 0) // S
        {
            DetectDoubleTap(ref lastTapTimeS, "RollBackward");
        }
        else if (moveInput.x > 0) // D
        {
            DetectDoubleTap(ref lastTapTimeD, "RollRight");
        }
        else if (moveInput.x < 0) // A
        {
            DetectDoubleTap(ref lastTapTimeA, "RollLeft");
        }

        //SpaceRoll();

    }

    private void DetectDoubleTap(ref float lastTapTime, string rollDirection)
    {
        if (Time.time - lastTapTime < doubleTapTime)
        {
            // 더블탭 감지됨 -> 롤 애니메이션 실행
            RollAnimation(rollDirection);
        }
        lastTapTime = Time.time; // 마지막 입력 시간 갱신
    }

    private void RollAnimation(string rollDirection)
    {
        animator.SetTrigger(rollDirection);
    }

    private void SpaceRoll()
    {
        if (player.playerMove.moveInput.y > 0) // W
        {
            animator.SetInteger("RollCount", 0);
        }
        else if (player.playerMove.moveInput.y < 0) // S
        {
            animator.SetInteger("RollCount", 1);
        }
        else if (player.playerMove.moveInput.x < 0) // A
        {
            animator.SetInteger("RollCount", 2);
        }
        else if (player.playerMove.moveInput.x > 0) // D
        {
            animator.SetInteger("RollCount", 3);
        }
        animator.SetTrigger("Roll");
    }
}

관련글 더보기