본문 바로가기

유니티/유니티 연습프로젝트

[유니티/연습 프로젝트] 걷기 모션, 공격 모션, 근접 공격 범위 설정

728x90
반응형

 애니메이션

 

기본 상태인 Idle 애니메이션, 걷는 상태인 Walk 애니메이션, 공격 모션인 Attack 애니메이션을 추가했다.

 

 

 

 

Bool 형 Walk, Attack 파라미터를 설정해서 Idle 상태에서

Attack 이 True 이면 Attack 애니메이션으로 Walk 가 True 이면 Walk 애니메이션으로 진행되고

반대의 경우 다시 Idle 로 돌아오게 설정하였다.

 

 

 

 

 

 

 

 

 

 

 걷기 모션

 

스크립트에서 Animator 컴포넌트를 불러온 후 SetBool 함수를 통해서 파라미터를 컨트롤 해준다.

 

프레임이 Update 될 때 마다 Walk 함수는 항상 false 상태를 유지해서 화살표 키보드 입력을 받기 전에는

항상 Idle 상태를 유지한다.

 

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

public class PlayerMove : MonoBehaviour
{
    Animator MyAnimator;

    // Start is called before the first frame update
    void Start()
    {
        MyAnimator = GetComponent<Animator>();
        
    }

    // Update is called once per frame
    void Update()
    {
        MyAnimator.SetBool("Walk", false);

        if (Input.GetKey(KeyCode.RightArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(0.001f * speed, 0, 0);
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(-0.001f * speed, 0, 0);
        }
        
        if (Input.GetKeyDown(KeyCode.LeftAlt) && GroundTag)
        {
            GroundTag = false;
            MyRigidbody2D.AddForce(new Vector2(0, 100*jumpforce));
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 공격 모션

 

걷기 모션과 같은 방법으로 코드를 추가해준다.

 

공격 모션 중 점프하거나 방향 전환 하는 것을 막기위해서 CurAttackTime 을 설정하고

공격을 시작하면 시간을 부여한 후 Time.deltaTime 으로 CurAttackTime 의 값을 줄인다.

 

공격이 끝나 CurAttackTime 이 0 이하가 되면 점프나 방향 전환이 가능하다.

 

공격 중 움직이는 것은 가능하게 하기 위해 transform.localScale 을 변경하는 코드만 적용하였다.

 

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

public class PlayerMove : MonoBehaviour
{
    Animator MyAnimator;
    
    private float AttackTime = 0.56f;
    public float CurAttackTime = 0;

    // Start is called before the first frame update
    void Start()
    {
        MyAnimator = GetComponent<Animator>();
        
    }

    // Update is called once per frame
    void Update()
    {
        MyAnimator.SetBool("Walk", false);
        MyAnimator.SetBool("Attack", false);


        if (Input.GetKey(KeyCode.RightArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
                transform.localScale = Vector2.one;
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(-0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
                transform.localScale = new Vector2(-1, 1);
        }
        
        
        if (Input.GetKeyDown(KeyCode.LeftAlt) && (GroundTag && CurAttackTime <= 0))
        {
            GroundTag = false;
            MyRigidbody2D.AddForce(new Vector2(0, 100*jumpforce));
        }
        
        
        if (CurAttackTime <= 0)  // 공격시작
		{
        	MyAnimator.SetBool("Attack", true);
	        CurAttackTime = AttackTime;
        	if (Input.GetKeyDown(KeyCode.LeftControl))
            	CurAttackTime = AttackTime;
        }
        if (CurAttackTime >= 0)
            CurAttackTime -= Time.deltaTime;
	}
}

 

 

 

 

 

 

 

 

 공격 범위 설정

 

오버랩 박스를 사용하여 공격 범위를 설정하였고 방향 전환 시 공격 범위도 변경하기 위해서 현재 보고있는 방향을 나타내는 Bool 형 RightState 변수를 선언했다.

 

오버랩 박스의 위치는 플레이어 위치에 (1.255f, -0.3f) 를 더한 값이다.

 

공격 범위에 Enemy 가 충돌하면 "Hi" 라는 메시지를 출력한다.

 

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

public class PlayerMove : MonoBehaviour
{
    Rigidbody2D MyRigidbody2D;
    Animator MyAnimator;

    
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.name == "Ground")
            GroundTag = true;
    }

    private float AttackTime = 0.56f;
    public float CurAttackTime = 0;
    public Transform AttackPos;
    private Vector2 AttackBoxSize = new Vector2(0.94f, 1.19f);
    bool RightState;
    bool GroundTag = false;


    // Start is called before the first frame update
    void Start()
    {
        MyRigidbody2D = GetComponent<Rigidbody2D>();
        MyAnimator = GetComponent<Animator>();
        RightState = true;
        
    }

    // Update is called once per frame
    void Update()
    {
        MyAnimator.SetBool("Walk", false);
        MyAnimator.SetBool("Attack", false);


        if (Input.GetKey(KeyCode.RightArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
            {
                transform.localScale = Vector2.one;
                RightState = true;
            }
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(-0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
            {
                transform.localScale = new Vector2(-1, 1);
                RightState = false;
            }
        }


        if (RightState == true)
            AttackPos.position = new Vector2(transform.position.x + 1.255f, transform.position.y - 0.3f);
        else
            AttackPos.position = new Vector2(transform.position.x - 1.255f, transform.position.y - 0.3f);


        if (Input.GetKeyDown(KeyCode.LeftAlt) && (GroundTag && CurAttackTime <= 0))
        {
            GroundTag = false;
            MyRigidbody2D.AddForce(new Vector2(0, 100*jumpforce));
        }


        if (CurAttackTime <= 0)  // 공격시작
        {
            if (Input.GetKeyDown(KeyCode.LeftControl))
            {
            	MyAnimator.SetBool("Attack", true);
                CurAttackTime = AttackTime;
                Collider2D[] collider2Ds = Physics2D.OverlapBoxAll(AttackPos.position, AttackBoxSize, 0);
                foreach (Collider2D collider in collider2Ds)
                {
                    if (collider.name == "Enemy")
                    {
                        Debug.Log("hi");
                    }
                }
            }
        }
        if (CurAttackTime >= 0)
            CurAttackTime -= Time.deltaTime;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 최종 코드

 

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

public class PlayerMove : MonoBehaviour
{
    Rigidbody2D MyRigidbody2D;
    Animator MyAnimator;

    
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.name == "Ground")
            GroundTag = true;
    }

    public int speed = 6;
    public int jumpforce = 8;
    private float AttackTime = 0.56f;
    public float CurAttackTime = 0;
    public Transform AttackPos;
    private Vector2 AttackBoxSize = new Vector2(0.94f, 1.19f);
    bool RightState;
    bool GroundTag = false;
    

    // Start is called before the first frame update
    void Start()
    {
        MyRigidbody2D = GetComponent<Rigidbody2D>();
        MyAnimator = GetComponent<Animator>();
        RightState = true;
        
    }

    // Update is called once per frame
    void Update()
    {
        MyAnimator.SetBool("Walk", false);
        MyAnimator.SetBool("Attack", false);


        if (Input.GetKey(KeyCode.RightArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
            {
                transform.localScale = Vector2.one;
                RightState = true;
            }
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            MyAnimator.SetBool("Walk", true);
            transform.Translate(-0.001f * speed, 0, 0);
            if (CurAttackTime <= 0)
            {
                transform.localScale = new Vector2(-1, 1);
                RightState = false;
            }
        }


        if (RightState == true)
            AttackPos.position = new Vector2(transform.position.x + 1.255f, transform.position.y - 0.3f);
        else
            AttackPos.position = new Vector2(transform.position.x - 1.255f, transform.position.y - 0.3f);


        if (Input.GetKeyDown(KeyCode.LeftAlt) && (GroundTag && CurAttackTime <= 0))
        {
            GroundTag = false;
            MyRigidbody2D.AddForce(new Vector2(0, 100*jumpforce));
        }


        if (CurAttackTime <= 0)  // 공격시작
        {
            if (Input.GetKeyDown(KeyCode.LeftControl))
            {
                CurAttackTime = AttackTime;
                Collider2D[] collider2Ds = Physics2D.OverlapBoxAll(AttackPos.position, AttackBoxSize, 0);
                foreach (Collider2D collider in collider2Ds)
                {
                    if (collider.name == "Enemy")
                    {
                        Debug.Log("hi");
                    }
                }
            }
        }
        if (CurAttackTime >= 0)
            CurAttackTime -= Time.deltaTime;

    }
}

 

 

 

 

 

 결과물

 

 

 

 

 

 

 

 

 

 

 

 앞으로 해야할 것

 

플레이어와 몬스터 체력 구현

 

피격 시 넉백, 이펙트 구현

 

플레이어와 몬스터 사망 구현

 

몬스터 스폰 구현

 

 

 

 

728x90
반응형