Monster Killer(8)
이전시간엔 무기 오브젝트를 폭탄으로 변경하고, 파티클이 재생되도록 디스트로이 시간을 딜레이를 통해 늦춰주었습니다. 또한 폭탄에 맞는 이펙트를 위해 파티클을 변경해주었습니다. 그런데 파티클을 테스트하던 중, 작지만 게임 플레이에 지장을 줄 수 있는 문제점을 발견하였습니다. 이번에 고쳐보는 시간을 가지도록 하겠습니다.
무기 연속 발사
저희가 이전에 무기가 바닥에 떨어졌을 때 없어지도록 하기 위해 Terrain을 태그로 설정하여 디스트로이 시켜주었습니다. 그런데 어차피 몬스터와 닿아도 디스트로이를 시켜주기 때문에 else에 디스트로이를 작성했었는데, 테스트를 하던 중 뭔가 이상한 점을 발견했습니다. 무기를 매우 빠르게 연사했을 때, 데미지가 제대로 박히지 않았습니다. 이유를 찾기 위해 여러번 시도해본 결과, 해당 문제점은 무기가 몬스터에 닿기 전에 무기끼리 부딪혀 디스트로이 되었던 것입니다. 그렇다면 어떻게 해결해 주어야 할까요?
저는 근본적인 문제점을 해결하기 보다는 부딪히는 상황을 만들지 않기로 하였습니다. 애초에 연사를 하지 못하도록 할 것입니다. 그 방법은 역시 딜레이를 주는 것입니다.
기존에 사용하던 방법은 클릭을 하면 무기를 생성함과 동시에 발사합니다. 하지만, 제가 원하는 것은 던지기 전에 미리 생성이 되어있고, 던지고 난 후 쿨타임을 가진 뒤에 생성되도록 하는 것입니다. 변경된 코드를 확인해 보시겠습니다.
WeaponGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponGenerator : MonoBehaviour
{
public GameObject WeaponPrefab;
private GameObject currentWeapon;
public float delay = 1f;
private bool canGenerate = true;
void Update()
{
if (currentWeapon == null && canGenerate)
{
GenerateWeapon();
}
if (Input.GetMouseButtonDown(0) && currentWeapon != null)
{
Vector3 spawnPosition = Camera.main.transform.position;
currentWeapon.transform.position = spawnPosition;
currentWeapon.GetComponent<Rigidbody>().isKinematic = false;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Vector3 worldDir = ray.direction;
currentWeapon.GetComponent<WeaponController>().Shoot(worldDir.normalized * 2000);
currentWeapon = null;
canGenerate = false;
Invoke("EnableGeneration", delay);
}
}
private void GenerateWeapon()
{
currentWeapon = Instantiate(WeaponPrefab);
currentWeapon.GetComponent<Rigidbody>().isKinematic = true;
}
private void EnableGeneration()
{
canGenerate = true;
}
}
폭탄을 미리 생성해두고 발사하는 스크립트를 짜는 과정에서 사소한 문제가 한가지 더 생겼습니다. 무기를 생성하는 것은 쉬웠지만, 생성된 위치에 고정되어있어야 하는데 Rigidbody를 사용하기 때문에 중력의 영향을 받습니다. 그리고 Shoot을 사용하려면 중력을 제거해서도 안됩니다. 그래서 제가 찾은 방법은 isKinematic을 생성되었을 때는 true로, 던질때는 false로 만들어주는 방법을 사용했습니다.
이외에도 폭탄을 1초 딜레이를 주고 생성되도록 하기 위해 꽤 많이 변경되었습니다. 현재 들고있는 폭탄을 currentWeapon에 저장하고, 던지면 null로 만들어 비워줍니다. 그리고 동시에 상태변수 canGenerate를 통해 1초의 딜레이 시간을 구현해줍니다. 1초가 지나면 canGenerate가 true가 되면서 다시 currentWeapon이 생성되는 구조입니다.
이제 충분히 설명하였으니, 게임을 실행하여 제대로 작동하는 지 확인해 보겠습니다.
폭탄이 고정된 위치에 잘 소환된 모습입니다. 아무 행동도 하지않고 있으면 그대로 고정되어 있습니다.
폭탄을 던자면, 폭탄이 적에게 날아가고 부딪혀 없어집니다. 그리고 1초가 지나면 다시 생성됩니다. 잘 작동하는 것을 확인했습니다. 딜레이가 있기 때문에 연사문제도 해결되었습니다.
그리고 추가로, 이전에 설명드릴 때, Destroy()를 따로 함수를 만들어 딜레이와 함께 Invoke()에 넣어 사용하는 방식으로 디스트로이에 딜레이를 주었는데, 그렇게 할 필요없이 그냥 Destroy(gameobject, 0.5f) 이런식으로 뒤에 타임을 직접 입력해주어도 사용가능합니다. 제가 사용한 방법은 Destory와 함께 다른동작도 같이 딜레이를 줄 때 사용하면 될것 같습니다.
<NEXT>
오늘은 사소한 줄 알았지만, 생각보다 어려웠던 문제점을 해결했습니다. 연사하면 데미지가 제대로 들어가지 않는 문제에서부터 발사체끼리 겹치는 문제로 이어져서, 근본적인 원인은 연사가 가능했기 때문이라 이를 막는 방식으로 해결했습니다. 다음에는 오늘 못한 몬스터 소환과 죽음에 대해서 다뤄보겠습니다. 감사합니다.
'게임 프로그래밍 > 게임개발 중급' 카테고리의 다른 글
게임개발 중급(48) - Monster Killer(10) (0) | 2023.06.09 |
---|---|
게임개발 중급(47) - Monster Killer(9) (0) | 2023.06.07 |
게임개발 중급(45) - Monster Killer(7) (0) | 2023.06.06 |
게임개발 중급(44) - Monster Killer(6) (2) | 2023.06.04 |
게임개발 중급(43) - Monster Killer(5) (0) | 2023.06.03 |