나 개발자 진짜 되냐?

[ Unity 3D 서바이벌 게임 만들기 7 ] 아이템 장착 그리고 공격 본문

유니티를 공부해봐요!/중급이에요!

[ Unity 3D 서바이벌 게임 만들기 7 ] 아이템 장착 그리고 공격

Snow Rabbit 2024. 10. 29. 11:09

 

저번 6번 글에서는

사용하고 버리는 버튼을

만들었었다.

 

이번에는

무기 장착과 

무기 휘두르기까지 해 볼 예정이다!

 

휘리릭휘리릭


장착의 경우

장착하기를 했을때

우리는

카메라를 하나 더 만들어서

 

이렇게만 보이게 해 줄 것이다.

 

그다음에 우리가 평소 보던 카메라랑 합치면

무기를 들고 있는 듯한 느낌을 줄 것이다.

 

빠르게 카메라를 하나 더 만들어보자

 

카메라는

UI밑에 밑에 있다.

 

 

밑이 중요하다

원래는 skybox였는데

Depth Only고

 

바로밑에

Culling Mask를 통해

필요한 layer들만 보이게끔 해준다.

 

우리는 layer을 하나 만들어서

equip라고 적어주고 만들어두자.

 

그러면 이제 이 카메라 안에

equip라는 layer가 들어오면

이제야 보일 것이다.

 

이제 카메라 안에 들어갈

장착 프리팹을 만들어주어야 한다.

 

장착프리팹은

검과 도끼 두 종류만 만들어주면 될 것 같다.

 

먼저 빈오브젝트를 하나 만들고 그 안에 프리팹을 넣자

 

중요한 건

이제 카메라에 이 오브젝트를 넣어보고

위치를 초기화해준다.

 

다음에 우리는 위에 사진처럼

오른쪽에 들고 있는 듯한 느낌을 주기 위해

 

자식으로 되어있는

Ax_01 이 친구의 위치를 바꿔주어야 한다.

 

 

이렇게 수정해 주면

위치도, 각도도 괜찮은 거 같다.

 

이렇게 만들어준 다음에

오브젝트를 프리팹으로 만들어주자

프리팹으로 만들었으면 지워주자!

 

 

칼도 약간

대각선으로 잡고 있는 느낌을 주기 위해

위치를 특이하게 잡아주었다.


칼이나 도끼의 경우

저번 아이템들처럼

빈 오브젝트에 넣어주었다면

프리팹 언팩 해주고,

콜라이더를 지워주자.



자 이렇게 해주고

우리가 해야 할 것을 정리해 보면

 

1. SO값을 조금 수정해주어야 한다.

 

이 무기 프리팹들도 추가해 주고,

생성해주어야 하는데

그 생성하고 저장하는 값이

SO값에 필요할 듯하다.

 

ItemData.cs로 가서

한 줄 추가

 

이 한 줄로

SO에 무기들을 눌러보면

 

장착할 거냐는 친구가 활성화된다.

 

무기들 그에 맞는 프리팹을 넣어주자

 

Type가 Equipable이라면

말 그대로 장착이 가능할 거 같다.

 

스크립트를 만들어보자

Item폴더 밑에 

Equip과 EquipTool라는

스크립트를 만들자

 

Equip.cs , EquipTool 

 

< Equip.cs >

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

public class Equip : MonoBehaviour
{
    public virtual void OnAttackInput()// 상속을 시켜줄 것이기 때문에
    { // 공격함수를 만들어 둔다.

    }
}

Equip.cs에서는

 

상속을 위해 virtual을 써주었다.

 

EquipTool 은 프리팹에 장착시키고

코드를 적어봅시다.

 

 

장착 후 layer까지 equip로

만져주었다.

 

< EquipTool.cs >

using UnityEngine;

public class EquipTool : Equip //Equip를 상속받고
{   //공격때 사용할 속성들 
    public float attackRate; // 공격 주기
    private bool attacking; // 공격 했나 안했나
    public float attackDistance; // 최대 거리

    [Header("Resource Gathering")] // 리소스 채취가 되는지 안되는지 채크 해주는 bool값
    public bool doesGatherResources;

    [Header("Combat")] // 공격이 가능한가
    public bool doesDealDamage; // 데미지를 줄 수 있는가
    public int damage; // 얼만큼 줄 수 있는가

    private Animator animator; // 애니메이션 실행용 속성
    //private Camera camera;

    private void Awake()
    {
        //camera = Camera.main;
        animator = GetComponent<Animator>(); // 애니메이션 가져오기
    }

    public override void OnAttackInput() // 상속받으려했던 Equip를 가져와서 공격!
    {
        if (!attacking) // 공격해야하는데.. 공격을 하고있지않다면?
        {
            attacking = true; // 공격하시오!
            animator.SetTrigger("Attack"); // 공격!! 트리거 호출
            Invoke("OnCanAttack", attackRate); // 한대때리고 조금 쉴 수 있도록, 그 시간만큼
        }
    }

    void OnCanAttack() // 약간의 시간차를 주는 공격을 위해 
    {
        attacking = false; // 잠시 끄기
    }
}

 

이 장비로 공격이 되는가,

자원채취가 되는가

등을 여기서 만져주게 된다.

 

그리고 우리는 사람이 이 무기들을 가지고 있어야 하니

Player스크립트 폴더에 가서 

스크립트를..

또!..

만들어주어야 한다.

 

 

저번시간에

우리는 상호작용이라는 스크립트를 따로 만들었던 거처럼

장착도 그렇게 따로 만들어주어야 한다.

 

 < Equipment.cs > 

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


public class Equipment : MonoBehaviour
{
    public Equip curEquip; // 아까 상속받았던 친구, 현재 장착하는 정보를 가지고 있을것
    public Transform equipParent; // 장비를 달아줄 카메라 위치

    private PlayerController controller; // palyer에 넣어주어야하니..
    private PlayerCondition condition; // 이 두가지는 꼭 넣어주자.

    void Start()
    {   // 초기화
        controller = CharacterManager.Instance.Player.controller;
        condition = CharacterManager.Instance.Player.condition;
    }

    public void OnAttackInput(InputAction.CallbackContext context) // 마우스 좌클릭으로
    { // 버튼이 눌려진 상태라면 그리고 널이 아니면 그리고 컨트롤러가 볼 수 있다면, 즉 인벤토리가 꺼져있다면
        if (context.phase == InputActionPhase.Performed && curEquip != null && controller.canLook)
        {
            curEquip.OnAttackInput(); //상속된 친구의 함수를 실행해줘서 애니메이션 동작하게끔
        }
    }

    public void EquipNew(ItemData data) // 새로운 아이템 장착, 아이템 데이터를 매개변수로 가져온다.
    {
        UnEquip(); // 혹시 장착하고있으면 그것 해제
        curEquip = Instantiate(data.equipPrefab, equipParent).GetComponent<Equip>();
        // 현재 장착을 할 프리팹 생성해서 넣어줄 것이다., 위치는 parent / 생성된 프리팹 가져오기
    }

    public void UnEquip() // 장착 해제
    {
        if (curEquip != null) // 장착을 하고있다면
        {
            Destroy(curEquip.gameObject); // 없애주자
            curEquip = null; //비워주기
        }
    }
}

 

변수를 만들어주고

start는 꼭 해주자

 

 

다음에

 

이제 장착해 주자,

 

UnEquip에서 에러가 날 텐데

이유는 안 만들어줘서 이다..ㅎㅋ

 

 

장착할 때 그것을 빼주는 함수를 만들어주었다.

장착해제이다.

 

이렇게 해주었으면

유니티로 돌아가서

플레이어에 방금 만든 스크립트

Equipment를

넣어주자

 

 

 

2. 이제 인벤토리에

장착하기 버튼을 눌러주면 프리팹이 생성되어

카메라에 딱 나오게 해주어야 한다.

 

이거 하기 전에!

이 장착은 사람이 해주는 것이기 때문에

Player.cs로가서

장착을 추가해 주자.

장착했다면

 

2번을 수행하기 위해

UIInventory.cs로 가봐야겠다.

 

변수 하나 추가해 준다.

 

장착과 장착해제 함수를 만들어보자

 

장착 해제부터 만들어보자

( 이유는 사실 큰 차이 없긴 한데

장착하기에 예외로 장착해제해 주는 함수가 있다. )

 

장착하기

 

이렇게 장착과 장착해제 함수를 만들어주었으니

버튼에 이벤트를 넣어주러 가야겠다.

 

 

넣어주기

 

자,

이제

3. 공격 모션이 있는 애니메이션을 구현해 보자

 

애니메이션 패키지를 다운로드하여서 넣고,

 

EquipTool.cs로 가서

코드를 더 작성해 보자

 

 

애니메이터 넣고 Awake에서 호출

 

 

공격 트리거가 뭐지?

Attack라는

트리거를 만들어 두었다.

 

넣어주면 된다.

마지막으로 동작하게끔 하기 위해

 

Equipment.cs로 가서

 

 

좌클릭으로 애니메이션이 시작하게끔 만들어준다.

여기서 인벤토리를 끈 이유는

인벤토리에서 아이템 클릭 장착도

좌클릭이어서 공격으로 인식할 수 도 있기 때문이다.

 

player 가서

player 넣어주고 클릭 이벤트 넣어주면 끝!

 

그리고 애니메이터도 넣어주어야 한다.

 

무기 두 개 프리팹으로 가서

Animator 컴포넌트 추가하고

넣어준다.

 

 

그리고 값도 넣어준다.

도끼는 자원을 캐는 친구기 때문에

Resources에 체크 해주어야 한다.

 

반대로 칼은

 

대미지에 체크 해주고

값을 10 정도로 준다.

 

 

그럼 장착까지 완성!!!

좌클릭을 하면

휭휭 움직인다.

 

다음은 도끼로

자원을 채취해 보자!

 

다음에! 무기로 공격을 구현해 본다!