최종프로젝트 제작 과정 (아이템 만들기)

2024. 2. 27. 12:05카테고리 없음

미로게임에 필요한 아이템이 무엇이 있을 까 팀원들과의 회의를 거쳐 적과의 전투에서 필요한 체력 회복 물약, 빠른 탈출을 위한 이동속도 증가 물약, 탈출구(포탈)의 위치를 알려주는 나침반, 지나온 길을 표시할 수 있는 발광석을 만들기로 했다.

나침반, 체력물약, 이동속도물약, 발광석

1. 나침반 (Compass)

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

public class Compass : MonoBehaviour
{
    public Transform playerTransform; //플레이어의 Transform을 연결.
    public Transform exitTransform; //출구의 Transform을 연결.
    public GameObject compassArrowPrefab;   //나침반 화살표 프리팹
    public LineRenderer lineRenderer;
    public bool useCompass;
    private float time;
    public float activeTime;
    public bool activatingCompass;


    private GameObject compassArrowInstance; //나침반 화살표 인스턴스

    // Start is called before the first frame update
    void Start()
    {
        playerTransform = GameObject.Find("ItemHolder").transform;//ItemHolder라는 게임오브젝트를 찾아서 transform을 가져온다
        exitTransform = GameObject.Find("Portal red").transform;//Portal red라는 게임오브젝트를 찾아서 transform을 가져온다
        lineRenderer = GetComponent<LineRenderer>();
        lineRenderer.positionCount = 2;//LineRenderer를 잇는 점의 개수
        lineRenderer.enabled = false;

        //나침반 화살표 인스턴스 생성
        //compassArrowInstance = Instantiate(compassArrowPrefab, transform.position, Quaternion.identity);
    }

    private void Update()
    {   
        if (playerTransform != null && exitTransform != null)
        {
            if(useCompass)//CompassClass에서 useCompass가 true가 된다면
            {
                time += Time.deltaTime;//시간을 잰다
                if (time < activeTime)//시간이 ActiveTime을 넘지 못했다면
                {
                    lineRenderer.enabled = true;//LineRenderer를 켜고
                    activatingCompass = true;
                    lineRenderer.SetPosition(0, playerTransform.position);//LineRenderer의 첫번째 점의 위치는 playerTransform의 position이고
                    lineRenderer.SetPosition(1, exitTransform.position);//LineRenderer의 두번째 점의 위치는 exitTransform의 position이다
                }
                else
                {
                    activatingCompass=false;
                    Destroy(this.gameObject);//시간이 ActiveTime을 넘었다면 이 아이템을 파괴한다.
                }
            }

            else
            {
                lineRenderer.enabled=false;//평소에는 LineRenderer를 끈다.
            }
        }
    }
}

나침반은 플레이어의 Transform 과 탈출구(Portal red)의 Transform 위치를 이어주는 LineRender를 사용해 만들었다.

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


public class ItemClass : ScriptableObject
{
    public string itemName;
    public Sprite itemIcon;
    public bool isStackable;
    public GameObject ItemObject;
    [HideInInspector]public GameObject item;
    [HideInInspector] public bool itemUsed;
    [HideInInspector] public bool compassUsed;
    [Multiline]
    public string description;


    public virtual void Equip()
    {
        UnEquip();
        if(ItemObject != null)
        {
            Transform itemHolder = GameObject.Find("ItemHolder").transform; //Hierarchy에 있는 ItemHolder라는 transform을 찾아온다.
            item = GameObject.Instantiate(ItemObject, itemHolder.position, itemHolder.rotation); //ItemObject를 ItemHolder위치에 rotation값은 0으로 생성한다.
            item.GetComponent<BoxCollider>().enabled = false;//아이템의 BoxCollider를 끈다
            item.transform.GetChild(2).GetComponent<BoxCollider>().enabled = false;//아이템의 3번째 자식 오브젝트의 BoxCollider를 끈다
            item.GetComponent<Rigidbody>().useGravity = false;
            Rigidbody rb = item.GetComponent<Rigidbody>();
            rb.useGravity = false;//중력을 끈다
            rb.constraints = RigidbodyConstraints.FreezePosition;
            item.transform.parent = itemHolder.transform;//item을 ItemHolder의 자식으로 생성한다.
            item.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);//생성된 item의 크기를 0.4로 줄인다.

        }
    }

    public virtual void UnEquip()
    {
        Transform itemHolder = GameObject.Find("ItemHolder").transform;//ItemHolder라는 게임 오브젝트를 가지고 옴
        if (itemHolder.childCount > 0)//ItemHolder의 자식 오브젝트가 있을때
        {
            foreach (Transform child in itemHolder)
            {
                Destroy(child.gameObject); //모든 자식 오브젝트 제거
            }
        }
        Transform GunHolder = GameObject.Find("GunHolder").transform;//ItemHolder라는 게임 오브젝트를 가지고 옴
        if (GunHolder.childCount > 0)//ItemHolder의 자식 오브젝트가 있을때
        {
            foreach (Transform child in GunHolder)
            {
                Destroy(child.gameObject); //모든 자식 오브젝트 제거
            }
        }
    }

    public virtual void Use()//하위클래스에서 수정할 수 있도록
    {
        return;
    }

    public virtual void Shoot()
    {

    }

    public virtual void StopShoot()
    {

    }
}

스크립터블 오브젝트를 사용하여 아이템을 관리할 수 있도록 해주었고, 아이템 장착을 위한 기능도 함께 작성해주었다.

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

[CreateAssetMenu(menuName = "Item/Compass")]
public class CompassClass : ItemClass
{
    public override void Use()
    {
        SoundManager.Instance.PlayItemUseSound();
        Compass compassScript = item.GetComponent<Compass>();

        if (compassScript.useCompass == false)
        {
            compassScript.useCompass = true;
            itemUsed = true;
            compassUsed = true;
        }
        else
        {
            itemUsed = false;
            compassUsed = false;
        }
    }
}

다양한 아이템들의 생성을 위해 ItemClass를 상속해주었고, CompassClass를 통해 아이템의 사용을 관여했다.