본문 바로가기
게임 프로그래밍/게임개발 중급

게임개발 중급(45) - Monster Killer(7)

by jyppro 2023. 6. 6.

Monster Killer(7)

이전에는 코드리뷰 및 게임의 전반적인 문제점을 점검하는 시간을 가졌습니다. 오늘은 나왔던 문제점들을 하나씩 해결해 나가는 과정을 다뤄볼까 합니다. 순서대로 접근해보겠습니다. 첫번째와 두번째 문제점인 무기오브젝트, 파티클 부터 해결하겠습니다.

 

무기 오브젝트

저희가 기존에 사용하는 무기는 밤송이로, 몬스터를 사냥하기에는 어울리지 않을 뿐더러 강한 느낌을 줄 수 없다고 느꼈기 때문에 현재 무기로 사용되는 밤송이 대신 다른 오브젝트로 바꿔보겠습니다. 던져서 맞추는 컨셉을 지키기 위해서는 역시 비슷하게 생긴 던질 수 있는 물체여야 합니다. 저는 폭탄을 무기 오브젝트로 사용하겠습니다.

폭탄-오브젝트
폭탄 오브젝트

기존에 밤송이 프리팹이 가지고 있던 모든 특성을 bomb에 전부 넣어주고, bomb을 프리팹화 시켜 밤송이와 같은 상태로 만들어 줍니다. 그리고 밤송이 대신 폭탄을 아웃렛접속시켜 줍니다. 그러면 폭탄 오브젝트로 변경이 완료되었습니다.

 

스크립트 이름 변경

저희가 작성해왔던 스크립트의 이름에도 Bamsongi 가 들어가 있습니다. 이제는 전혀 다른 게임이 되어버렸으니 이름을 바꾸어 주겠습니다. 저는 Bamsongi 대신 Weapon을 넣어서 WeaponController, WeaponGenerator라고 바꿔주겠습니다.

 

스크립트의 이름을 변경할 때, 유니티 내에서 Rename을 통해 바꿔주기만 하면 되는것이 아닙니다. 스크립트에 들어가 클래스 이름도 똑같이 맞춰주어야 합니다. 오류가 발생한다면 이 부분을 한번 확인해보시길 바랍니다.

 

파티클 재생

이제 오브젝트 변경은 완료되었지만, 파티클은 여전히 나오지 않습니다. 저는 이전에 이야기 드린 것처럼 delay를 통해 간단히 이 문제를 해결하려 합니다.

 

WeaponController

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

public class WeaponController : MonoBehaviour
{
    public GameObject WeaponGenerator;
    public GameObject HeadPoint;
    public float delay = 0.5f;

    public void Shoot(Vector3 dir) //인자로 3차원 벡터가 입력되고
    {
        GetComponent<Rigidbody>().AddForce(dir); // 들어온 입력벡터 만큼 오브젝트에 힘이 가해진다.
    }

    
    // Start is called before the first frame update
    void Start()
    {
        this.WeaponGenerator = GameObject.Find("WeaponGenerator");
        this.HeadPoint = GameObject.Find("HeadPoint");
    }

    public void OnCollisionEnter(Collision collision) //다른 물체와 충돌하는 순간
    {
        GetComponent<Rigidbody>().isKinematic = true; //중력의 영향을 무시
        GetComponent<ParticleSystem>().Play(); // particle효과를 실행시킨다.

        Vector3 p1 = this.transform.position;
        Vector3 p2 = this.HeadPoint.transform.position;
        float dist = (p1 - p2).magnitude; // 벡터의 길이 리턴
        int damage = Mathf.CeilToInt(10 - dist * 5);

        if(damage <= 0) {damage = Random.Range(1,3);}

        if (collision.gameObject.tag == "Monster") //몬스터와 충돌하는 경우 점수 상승
        {
            collision.gameObject.GetComponent<MonsterController>().TakeDamage(damage);
            Invoke("DestroyWeapon",delay);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void DestroyWeapon()
    {
        Destroy(gameObject);
    }
}

변경된 WeaponController의 코드입니다. 바뀐내용은 간단합니다. Monster와 충돌하는 경우에 들어있던 디스트로이를 따로 DestroyWeapon()함수를 만들어주고, Invoke()함수를 통해 딜레이를 주며 실행시키는 방식입니다.

딜레이는 너무 많이 주면 폭탄이 계속 몬스터의 몸에 남아있어 맞추기 어려워지기 때문에 파티클만 출력하고 빠르게 없애도록 0.5초로 설정하였습니다.

 

이렇게만 해도 파티클은 정상출력됩니다. 하지만, 저는 파티클의 모습도 맘에 들지 않았습니다. 그래서 파티클을 약간 바꾸어 주겠습니다.

파티클-변경
파티클 시스템 컴포넌트

수많은 파티클 시스템의 체크박스 중 하나인 Shape에서 Radius를 0.01에서 0.05로 조금 높여주고, Mode를 Burst Spread로 바꾸어 주겠습니다.

렌더러
렌더러 머티리얼 변경

추가로, 기존에 사용하던 디폴트 머티리얼 대신 Standard Asset을 다운받으면 들어있는 파티클 시스템 머티리얼 중에서 ParticleFireCloud를 사용하겠습니다.

불꽃
불꽃파티클

이렇게 변경해준 후, 게임을 실행하여 변경사항을 한번 살펴보겠습니다.

 

게임-플레이
게임 플레이 화면

일순간에 이뤄지는 일이라 사진을 찍기 어려웠지만, 폭탄 오브젝트가 잘 나가고, 폭발하는 파티클이 제대로 나오는 것을 확인할 수 있었습니다.

 

<NEXT>

오늘은 무기 오브젝트를 폭탄으로 변경하고, 파티클이 재생되도록 디스트로이 시간을 딜레이를 통해 늦춰주었습니다. 또한 폭탄에 맞는 이펙트를 위해 파티클을 변경해주었습니다. 그런데 파티클을 테스트하던 중, 작지만 게임 플레이에 지장을 줄 수 있는 문제점을 발견하였습니다. 해당 문제점은 다음에 고쳐보는 시간을 가지도록 하겠습니다. 추가로 몬스터의 소환과 죽음에 대해서도 시간이 된다면 다뤄보도록 하겠습니다. 감사합니다.