1. 게임 디자인
- 정해진 목표를 달성하면 게임을 클리어할 수 있도록 하는 서바이벌 생존형식의 디자인을 채택했다.
- 플레이어가 느낄 수 있는 경험(긴장감, 공포)과 게임의 목표(지정된 위치까지 이동하기), 핵심리텐션 요소(게임 디자인)들을 정했다.
2. 사용한 기술
> 전략 패턴 (디자인 패턴)
주요 시스템인 무기관련 시스템을 스크립트 하나로 작성할 경우, 시스템이 커져서 확장이 될수록 같은 메서드를 반복해서 작성해야하는 문제가 발생한다. 따라서 전략 패턴을 사용하기 적합하다고 생각했다.
전략 클래스들을 캡슐화 하기 위한 GunWeapon 클래스
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 무기과 관련된 정보들
public struct Data{
public float range;
public float damage;
public float timeBetweenShots;
public bool zoom;
public AmmoType ammoType;
}
public abstract class GunWeapon : MonoBehaviour
{
public Data data;
bool canShoot = true;
// 무기마다 초기 설정이 다르기 때문에 각 무기마다 초기 설정을 다르게 하기 위한 추상 클래스.
public abstract void InitSetting();
void OnEnable() {
canShoot = true;
}
// 여러 정보들을 전달
public virtual void Using(Ammo ammoSlot, AmmoType ammoType, ParticleSystem muzzleFlash, Camera FPCamera, GameObject hitEffect){
if(Input.GetMouseButtonDown(0) && canShoot){
StartCoroutine(Shoot(ammoSlot, ammoType, muzzleFlash, FPCamera, hitEffect));
}
}
IEnumerator Shoot(Ammo ammoSlot, AmmoType ammoType, ParticleSystem muzzleFlash, Camera FPCamera, GameObject hitEffect)
{
canShoot = false;
if(ammoSlot.GetCurrentAmmo(ammoType) > 0)
{
PlayMuzzleFlash(muzzleFlash);
ProcessRaycast(FPCamera, hitEffect);
ammoSlot.ReduceCurrentAmmo(ammoType);
}
yield return new WaitForSeconds(data.timeBetweenShots);
canShoot = true;
}
private void PlayMuzzleFlash(ParticleSystem muzzleFlash)
{
muzzleFlash.Play();
}
// 총알의 히트를 체크
private void ProcessRaycast(Camera FPCamera, GameObject hitEffect)
{
RaycastHit hit;
if (Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, data.range))
{
CreateHitImpact(hit, hitEffect);
Enemy_Health target = hit.transform.GetComponent<Enemy_Health>();
if (target == null) return;
target.TakeDamage(data.damage);
}
else
{
return;
}
}
// 총알 명중 이펙트
private void CreateHitImpact(RaycastHit hit, GameObject hitEffect)
{
GameObject impact = Instantiate(hitEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(impact, 0.1f);
}
}
GunWeapon 을 상속받는 WeaponCarbine 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponCarbine : GunWeapon
{
public override void InitSetting()
{
data.range = 100f;
data.damage = 30f;
data.timeBetweenShots = 0.5f;
data.zoom = true;
data.ammoType = AmmoType.Bullets;
}
public override void Using(Ammo ammoSlot, AmmoType ammoType, ParticleSystem muzzleFlash, Camera FPCamera, GameObject hitEffect)
{
base.Using(ammoSlot, ammoType, muzzleFlash, FPCamera, hitEffect);
}
}
#참조
https://victorydntmd.tistory.com/292
[디자인패턴] 전략 패턴 ( Strategy Pattern )
전략 패턴 ( Strategy Pattern )객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화 하는 인터페이스를 정의하여,객체의 행위를 동적으로 바꾸고 싶은 경우 직접
victorydntmd.tistory.com
https://refactoring.guru/ko/design-patterns/strategy
전략 패턴
/ 디자인 패턴들 / 행동 패턴 전략 패턴 다음 이름으로도 불립니다: Strategy 의도 전략 패턴은 알고리즘들의 패밀리를 정의하고, 각 패밀리를 별도의 클래스에 넣은 후 그들의 객체들을 상호교환
refactoring.guru
> ProBuilder
- 프로 빌더를 사용해서 프로토타입에 적합한 오브젝트들을 커스텀으로 제작했다.
건물 지붕이나 배터리팩 등등 에셋을 가져와서 사용해도 되지만 개발자가 원하는 타입의 모양을 빠르게 찾기는 힘들기때문에 직접 빠르게 제작할 수 있는 프로빌더를 사용했다.
#참조
https://blog.naver.com/unity_kr/221770179865
[유니티 기능소개] 유니티 ProBuilder(프로빌더)
유니티 프로빌더(ProBuilder) Unity 에디터에서 월드 구축하기 이제 Unity의 일부가 된 ProBuilder는...
blog.naver.com
3. 내가 가진 의문점들에 대한 해결
- 의문점이라기 보다는 다른 방식을 사용해보는 것은 어떨까라는 의문이 많이 들었다.
무기를 스위칭하는 부분에서 무기가 붙어있는 인덱스를 기준으로 특정 동작에서 무기가 변경되는 쪽으로 시스템을 구현했었다.
만약 무기가 더 많아지고 무기뿐만 아니고 폭탄이나 열쇠같은 특정 아이템들이 추가된다면 인덱스를 가지고 스위칭하기기 쉽지는 않을것 같았다. 여기서 최선은 전략패턴이 아닐까라는 생각이 들어서 전략 패턴을 무기 시스템에 적용했다.
4. 전체적으로 느낀점
- 3D 기반 게임들은 확실히 디테일한 설정들이 많이 필요하다는 것을 느꼈다. 조금만 각도가 안맞거나 오브젝트의 배치가 틀어질 경우에 플레이어가 벽너머의 시야를 가지게 된다던가, 게임의 몰입을 방해하는 요소들을 많이 발생시켰다. 하나하나 다듬다보면 시간이 훌쩍 지나가는 느낌이었다.
> 실제 구현한 게임
https://sharemygame.com/@UnknownBird/zombierunnerprototype
Play ZombieRunnerPrototype in your Browser | ShareMyGame
sharemygame.com
'Unity' 카테고리의 다른 글
Unity) Cinemachine Part 1 (3) | 2023.11.23 |
---|---|
Unity) Progrids, Polybrush (0) | 2023.10.31 |
Unity) ProBuilder (0) | 2023.10.30 |
Unity) ML Agent (0) | 2023.10.27 |
Unity) Design Pattern (3) | 2023.10.25 |