728x90
1. 개발 현황
생각보다 빠르게 게임 개발이 끝나가고 있다.
1. 프리팹 일원화
- 추후 다양한 무기 추가를 위해 프리팹 구조를 개선하였다.
이전: 무기별 개별 프리팹 활용
현재: 무기별 공통 프리팹 활용 (스프라이트 및 콜라이더 제어)
2. 오디오 시스템 추가
- BGM과 SFX 시스템으로 나눠 오디오가 출력되는 시스템을 구현했다.
3. 아이템 드롭 & 픽업 시스템 구현
- 몬스터 사냥 시 게임 내 경험치 오브젝트를 드롭하는 시스템을 구현했다.
- 픽업 범위 내 드롭 오브젝트가 포함된 경우 아이템을 획득하는 시스템을 구현했다.
4. Setting HUD 구현
- 게임 옵션 세팅을 위한 HUD를 제작했다.
5. Window Screen 제어 로직 구현
- Setting HUD 내 옵션 중 Window Screen과 관련된 옵션을 제어하는 로직을 구현하였다.
2. 상세 개발 내용
1. 프리팹 일원화
public enum PrefabType
{
Enemy,
MeleeBox,
MeleeCircle,
RangeBox,
RangeCircle,
DropItem
}
public class WeaponCtrl : MonoBehaviour
{
int mId;
bool mEnable;
PoolManager mWeaponPool;
public void Init(int id)
{
mEnable = true;
if (id >= GameManager.instance.mPlayerData.WeaponSize)
Debug.Assert(false, "Error");
mId = id;
// initialize Pool Manager (general setting)
mWeaponPool = new GameObject("WeaponPool").AddComponent<PoolManager>();
mWeaponPool.transform.parent = transform;
mWeaponPool.transform.localPosition = Vector3.zero;
mWeaponPool.transform.localRotation = Quaternion.identity;
mWeaponPool.Init((int) GameManager.instance.mWeaponJsonData[GameManager.instance.mWeaponCtrlData[mId].Id].PrefabType);
mWeaponPool.mPool[0].GetComponent<SpriteRenderer>().sprite = GameManager.instance.mWeaponSprite[GameManager.instance.mWeaponJsonData[GameManager.instance.mWeaponCtrlData[mId].Id].SpriteId];
mWeaponPool.mPool[0].tag = GameManager.instance.mWeaponJsonData[GameManager.instance.mWeaponCtrlData[mId].Id].WeaponTag.ToString();
// initialize Root Prefab (particular setting)
switch (GameManager.instance.mWeaponJsonData[GameManager.instance.mWeaponCtrlData[mId].Id].WeaponType)
{
case Enum.WeaponType.Melee:
case Enum.WeaponType.RangeDagger:
mWeaponPool.mPool[0].GetComponent<BoxCollider2D>().size = new Vector2(0.4f, 1);
break;
case Enum.WeaponType.RangeBullet:
mWeaponPool.mPool[0].GetComponent<BoxCollider2D>().size = new Vector2(0.4f, 0.4f);
break;
case Enum.WeaponType.RangeAxe:
mWeaponPool.mPool[0].GetComponent<BoxCollider2D>().size = new Vector2(0.5f, 0.7f);
mWeaponPool.mPool[0].GetComponent<Rigidbody2D>().gravityScale = 1;
break;
case Enum.WeaponType.Garlic:
mWeaponPool.mPool[0].GetComponent<CircleCollider2D>().radius = 0.5f;
break;
case Enum.WeaponType.Web:
mWeaponPool.mPool[0].GetComponent<BoxCollider2D>().size = new Vector2(3, 3);
break;
case Enum.WeaponType.Boom:
mWeaponPool.mPool[0].GetComponent<CircleCollider2D>().radius = 1;
break;
case Enum.WeaponType.ThrowBoom:
mWeaponPool.mPool[0].GetComponent<CircleCollider2D>().radius = 1;
break;
default:
Debug.Assert(false, "Error");
break;
}
}
}
2. 오디오 시스템 추가
public class GameManager : MonoBehaviour
{
public static GameManager instance;
// 생략
[Header("# BGM")]
public AudioClip mBGMClip;
public float mBGMVolume;
public AudioSource mBGMPlayer;
public AudioHighPassFilter mBGMFffect;
[Header("# SFX")]
public AudioClip[] mSFXClip;
public float mSFXVolume;
public int mMaxSFXChannel;
public AudioSource[] mSFXPlayer;
public void PlayBGM(bool en)
{
if (en)
{
mBGMPlayer.Play();
}
else
{
mBGMPlayer.Stop();
}
}
public void PlayEffect(bool en)
{
mBGMFffect.enabled = en;
}
public void PlaySFX(Enum.SFX sfx)
{
for(int i=0; i < mSFXPlayer.Length; ++i)
{
if (mSFXPlayer[i].isPlaying)
continue;
mSFXPlayer[i].clip = mSFXClip[(int)sfx];
mSFXPlayer[i].Play();
break;
}
}
}
3. 아이템 드롭 & 픽업 시스템 구현
- 드롭 시스템
if (mHealth > 0)
{
StartCoroutine(KnockBack());
mAnim.SetTrigger("Hit");
}
else
{
mIsLive = false;
mIsGarlic = false;
mMovementSpeedCoef = 1.0f;
mColl.enabled = false;
mRigid.simulated = false;
mSpriter.sortingOrder = 1;
mAnim.SetBool("Dead", true);
GameManager.instance.mPlayerData.Kill++;
// 경험치 드롭
GameObject item = GameManager.instance.mDropPool.Get();
item.transform.position = transform.position;
item.transform.rotation = Quaternion.identity;
item.GetComponent<DropItem>().mData = mDropExp;
switch (mDropExp)
{
case > 50:
item.GetComponent<DropItem>().mType = Enum.DropItemSprite.Exp2;
item.GetComponent<SpriteRenderer>().sprite = GameManager.instance.mDropItemSprite[(int)Enum.DropItemSprite.Exp2];
break;
case > 10:
item.GetComponent<DropItem>().mType = Enum.DropItemSprite.Exp1;
item.GetComponent<SpriteRenderer>().sprite = GameManager.instance.mDropItemSprite[(int)Enum.DropItemSprite.Exp1];
break;
default:
item.GetComponent<DropItem>().mType = Enum.DropItemSprite.Exp0;
item.GetComponent<SpriteRenderer>().sprite = GameManager.instance.mDropItemSprite[(int)Enum.DropItemSprite.Exp0];
break;
}
GameManager.instance.PlaySFX(Enum.SFX.Dead);
}
- 픽업 시스템
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DropItem : MonoBehaviour
{
public Enum.DropItemSprite mType;
public int mData;
public bool mEnable;
Rigidbody2D mRigid;
Rigidbody2D mTarget;
private void Awake()
{
mRigid = GetComponent<Rigidbody2D>();
mTarget = GameManager.instance.mPlayer.GetComponent<Rigidbody2D>();
}
private void OnEnable()
{
mEnable = false;
}
private void FixedUpdate()
{
if (!GameManager.instance.mIsLive)
return;
if (!mEnable)
return;
Vector2 dirVec = mTarget.position - mRigid.position;
Vector2 nextVec = dirVec.normalized * 2 * Time.fixedDeltaTime;
mRigid.MovePosition(mRigid.position + nextVec);
mRigid.velocity = Vector2.zero;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
mEnable = false;
switch (mType)
{
case Enum.DropItemSprite.Exp0:
case Enum.DropItemSprite.Exp1:
case Enum.DropItemSprite.Exp2:
GameManager.instance.GetExp(mData);
break;
case Enum.DropItemSprite.Health:
GameManager.instance.GetHealth(mData);
break;
case Enum.DropItemSprite.Mag:
foreach (GameObject item in GameManager.instance.mDropPool.mPool)
{
if (item.GetComponent<DropItem>().mType == Enum.DropItemSprite.Exp0 || item.GetComponent<DropItem>().mType == Enum.DropItemSprite.Exp1 || item.GetComponent<DropItem>().mType == Enum.DropItemSprite.Exp2)
item.GetComponent<DropItem>().mEnable = true;
}
break;
default:
Debug.Assert(false, "Error");
break;
}
gameObject.SetActive(false);
return;
}
if (collision.CompareTag("PickupCollider"))
mEnable = true;
}
}
4. 옵션창 추가
public class GameManager : MonoBehaviour
{
public static GameManager instance;
// 생략
public HUDSetting mHUDSetting;
public void SetWindowScreen()
{
Debug.Log("hi");
Screen.SetResolution(Screen.resolutions[mHUDSetting.mDropdownResoultion.value].width, Screen.resolutions[mHUDSetting.mDropdownResoultion.value].height, mHUDSetting.mToggleResoultion.isOn, Screen.resolutions[mHUDSetting.mDropdownResoultion.value].refreshRate);
}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class HUDSetting : MonoBehaviour
{
public TMP_Dropdown mDropdownResoultion;
public Toggle mToggleResoultion;
public TMP_Dropdown mDropdownLanguage;
private void Awake()
{
for(int i=0; i< Screen.resolutions.Length; ++i)
{
TMP_Dropdown.OptionData option = new TMP_Dropdown.OptionData();
option.text = Screen.resolutions[i].width + "x " + Screen.resolutions[i].height + " " + Screen.resolutions[i].refreshRate + "hz";
mDropdownResoultion.options.Add(option);
if (Screen.resolutions[i].width == Screen.width && Screen.resolutions[i].height == Screen.height)
mDropdownResoultion.value = i;
}
mDropdownResoultion.RefreshShownValue();
mToggleResoultion.isOn = Screen.fullScreenMode.Equals(FullScreenMode.FullScreenWindow) ? true : false;
}
}
3. TODO
1. 필드 파괴형 오브젝트 추가 (e.g. 박스, 촛대, etc.)
2. 언어 제어 로직 추가
3. 볼륨 제어 로직 추가
'--------게임만들기-------- > |unity| by C#' 카테고리의 다른 글
[Unity] Day10 - 골드 및 드롭 로직 추가 (Random.insideUnitCircle, 스프라이트 추가, 스프라이트 아틀라스, Pixel Perfect) (0) | 2024.06.10 |
---|---|
[Unity] Day9 - 다국어 지원, 볼륨 제어 (Dropdown, Slider, Toggle) (0) | 2024.06.09 |
[Unity] Day7 - 원거리 폭발형 무기 구현, HUD 프리펩 구현, 업적 시스템 구현 (0) | 2024.06.07 |
[Unity] Day6 - 도끼, 마늘 무기 구현 (0) | 2024.06.07 |
[Unity] Day5 - 단검 무기 구현, 버그 개선 (position, localPosition) (0) | 2024.06.06 |