일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Console.WriteLine
- unity공부
- c# 백준
- c#프로그래머스기초문법
- 스파르타코딩클럽
- 유니티게임만들기
- 오블완
- 유니티3dui
- unity3d게임만들기
- 시샵
- unity게임만들기
- c# c#프로그래머스
- 티스토리챌린지
- 스파르타
- c#코딩기초트레이닝
- C#문법
- c#
- 유니티
- 시샵문법
- c#기초문법
- 유니티상호작용
- unity3dservival
- unity게임
- Unity
- c#코테
- c#기본문법
- unity3d
- 유니티서바이벌게임만들기
- c#문제
- 유니티공부
- Today
- Total
나 개발자 진짜 되냐?
[ Unity 뱀서라이크 게임을 만들어보자 6 ] 게임에는 스텟이 필요하지! 본문
오늘내일 중으로
기본 부분을 다 공부해야 하는데..
참 어렵다.
나에게 시간이 그렇게 많지 않구나..!
졸린 눈을 비비며 시작한다.
게임에서 스텟은 굉장히 중요한 부분이다.
캐릭터 고유의 스텟을 만들고
데이터를 처리하는 코드를 짜보자!
그전에!
새로운 문법을 짚고 가자
먼저열거형 친구
Enum
상수형 값에 의미를 부여하기 위해 사용!
int가 기본타입이고
제일 앞이 0이 기본이다.
이렇게 써주며
자연스레 0 1 2 3으로 넘어가게 된다
만약에 웨폰이 100이면
그다음은 101,102,103
만약에 웨폰이 206이면
다음은 207,208,209이렇게 된다.
사용하는 이유는
이렇게 타입 형식처럼 저장해두면
이 친구를 활용할때
숫자를 통해 의미를 파악할 수 있다.
뭐 숫자에 코드를 붙이는 느낌이라고 생각해 주면 좋다.
하지만 인덱스와는 다르다.
왜냐면 아까 말했지만 인트랑 호환이 되어서
이론상 웨폰을 값으로도 활용이 가능하다.
100으로 설정해 둔다면?
퀘스트아이템이 103이 되어서
둘이 값을 더할 수 있다.
또!
꼭 알아야 하는 친구
그 친구의 이름은
스크립터블 오브젝트(Scriptable Object)
부르며
데이터를 저장하고 관리하는 유연한 데이터 컨테이너
게임에서 재사용 가능한 데이터 또는 설정을 저장하는 데 사용하며
하나의 스크립터블 오브젝트를
여러 게임 오브젝트에서 참조하거나 재사용할 수 있고
가장 중요한 건
유니티에디터와 통합되어
인스펙터 창에서 직접 수정하고 관리할 수 있다.
SO를 배웠으니 이제 코드를 작성해 보자
먼저 AttackSO이다.
새로운 친구들이 보인다.
CreateAssetMenu
실제로 만들어야 하는 메뉴이다.
아까 위에서 인스펙터창에서 뜬다고 했듯
이렇게 유니티 내에서 하나의 메뉴로 만들기 위해 적어두는 것이다.
또한 SO를 사용하기 위해서는
class에서 ScriptableObject라는 친구를 상속해주어야 한다.
밑에
헤더라는 친구가 보인다.
말 그대로
머리에 무슨 정보를 저장할지 적어두는 것이다.
여기서는 무기의 속도 크기만 조절하고
발사체 정보는 없다
그래서 발사체 정보
RangedAttackSO를 또 만들어주어야 한다.
아까랑 비슷한 원리!
자, SO친구들은
파일을 따로 만들어서 구분하는 게 좋다.
이렇게 해주면 된다.
에셋 밑에
SO파일 만들고 그 안에 스크립트를 넣어서 적어준 두 개를 넣어준다.
자 다음에
스크립트 안에
stats이라는 폴더를 하나 또 만들어보자
그래서
CharacterStat 클래스 생성
enum을 활용해서
이 친구들에게 번호를 매겨준다.
인덱스라고 생각할 수 있긴 한데
비슷하면서도 다르다.
enum에는 숫자값이 들어가 있다고 생각해 주면 좋다.
다음에는
CharacterStatHandler.cs파일을 만들어보자
모노비헤이비어를 상속받고,
이 친구를 만들어주는 이유는 기본스탯 + 버프스탯을 해주기 위해!
자,
지금까지 해준 친구들을
전에 해주었던 스크립트에 약간씩 추가하고
업데이트해 보자
1. TopDownMovement.cs
스탯을 추가해 주면
원래는 스피드로 5를 곱했는데
이제 스피드를 가져와서 넣어 줄 수 있게 된다.
저번에 우리가 숫자를 또 하나 하드코딩했었다.
거기는 어디냐..
2. TopDownController.cs
우리는 여기에 매직넘버라고
딜레이 시간을 0.2를 써주었었다.
수정해 보자!
먼저
아까 만든 스탯을 넣고
get해와야겠지!
여기서 중요한 건 protected virtual void Awake이다.
왜 여기서 프로택티드가 되었냐면
밑에서 설명하겠습니다.
다음에
0.2f를 써주었었는데
이제 딜레이라는 친구가 생겼으니
수정해 주면 된다.
3. PlayerInputController.cs
자!
여기서 보면
이 친구는 상속이
탑다운컨트롤러이다.
그리고 awake가 있기 때문에
protected override를 해줘서 상속받야 하고
상속해 주는 부모도 같아야 하기 때문에
아까 위에서
protected virtual을 해주어야 한다.
오늘 내용 간단하게 정리해 보자
먼저
CharacherStat에서
이 스텟이 어떻게 변하는지,
무기, 뭐 체력, 속도 등등을 정의한다.
다음
CharacterStatHandler 여기로 와서
아까 적어둔 능력치 + 버프를
리스트에 담는다.
즉 우리가 지난 시간 동안
스피드는 5로 하드코딩하고
딜레이는 0.2로 하드코딩하고 그랬는데
이제 이 친구들을
CurrentStat으로 넣어주게 되는 것이다.
스피드는 캐릭터 능력이기 때문에
CurrentStat.speed
딜레이는 무기 공격의 딜레이기 때문에
CurrentStat.AttackSo.delay
폴더를 세분화해 보자
Entites
: 몬스터, 캐릭터를 말함
Controller
그들을 컨트롤할 때 쓰는 파일
Behaviors
그들의 행동을 정의할 때 쓰는 파일
깔 - 끔
자 유니티로오면
난리가 나있다.
왜냐하면..
파일들이 도망갔기 때문
느낌표 뜬 친구들한테 가서 하나하나 채워주자!
다음에 늘 하던 대로 스크립트를 추가하는데
기본 스텟을 미리 저장해 두자!
이렇게
그리고 우리는 맨 마지막에 AttackSO가 들어가야 한다.
지금은 강화를 구현하지 않아서
기본스탯을 그대로 넣어줄 것이기 때문에
SO 파일에다가
AttackSO파일 추가한 다음에
우리가 아까
AttackSO 스크립트 파일에
CreateMenu 했던 게 있었다.
와우와우
여기서 레인지 클릭
이름은
PlayerDefaultAttackSO
이렇게 기입해 준다.
아 여기서 색상은
255 255 255 255이다
마지막에 0이 되면 투명이라는 점!
그다음에 만든 것을
아까 위에서 Attack SO에 넣어주면 끝!
끝!
< AttackSO.cs >
using UnityEngine;
//발사체 정보같은것을 담기 위한 친구
[CreateAssetMenu(fileName = "RangedAttackSO", menuName = "TopDownController/Attacks/Ranged", order = 1)]
public class RangedAttackSO : AttackSO
{
// 원거리 공격에만 있는 옵션 정의
[Header("Ranged Attack Data")]
public string bulletNameTag;
public float duration; // 얼마의 시간만큼 나갈지
public float spread; // 얼마나 퍼질지
public int numberofProjectilesPerShot; // 한번에 몇개나가나
public float multipleProjectilesAngel; // 몇도만큼 떨어져있나.
public Color projectileColor; // 색, 무기의 색 등등
}
< RangedAttackSO.cs >
using UnityEngine;
//메뉴는 포멧이 있어서 이렇게 정의
[CreateAssetMenu(fileName = "DefaultAttackSO", menuName = "TopDownController/Attacks/Default", order = 0)]
public class AttackSO : ScriptableObject
{
// 공격에 대한 기준 데이터를 유니티 에디터 상에서 편하게 관리할 수 있다.
// SO로 들고 있으면 모두가 이 SO를 바라보게 되어 중복된 데이터가 여기저기 흘러다니지 않는 장점!
[Header("Attack Info")] // 어택관련 정보 저장, 쓰지않으면 헷갈리기 때문에 카테고리화 해준다.
public float size;
public float delay;
public float power;
public float speed;
public LayerMask target;
[Header("Knock Back Info")] // 넉백정보 담아둔것
public bool isOnKnockback;
public float knockbackPower;
public float knockbackTime;
}
< CharacterStat.cs>
using System;
using UnityEngine;
// Add 먼저하고, Multiple하고, 마지막에 Override하는 개념임
// enum에는 각각 정수가 매핑되어있기 때문에 가능 (0, 1, 2,...)
// => 차후에 정렬 활용하면 오름차순으로 정렬활용해서 체계적으로 버프효과 적용순서 관리 가능
// Q: Override가 마지막에 있으면 무슨 효과가 있을까요?
// A: 공격력을 고정해야하는 특정 로직이나 기본 공격력 적용에 활용 가능
public enum StatsChangeType
{ // 순서가 굉장히 중요
Add, // 0
Multiple, // 1
Override, // 2
}
// 클래스가 Serializable한 멤버로만 구성되어 있으면 [Serializable]을 붙여 에디터에서 확인 가능해요!
// 데이터 폴더처럼 사용할 수 있게 만들어주는 속성, 인스펙터창에서 확인 가능
[System.Serializable]
public class CharacterStat
{
//스탯 버프가 있다고 하면, enum으로 순번을 정해준다면 얼마나 좋을까?
public StatsChangeType statsChangeType;
//이렇게 range를 해주면 슬라이더가 생겨서 편하다.
[Range(1, 100)] public int maxHealth;
[Range(1f, 20f)] public float speed;
public AttackSO attackSO;
}
< CharacterStatHandler.cs >
using UnityEngine;
using System.Collections.Generic;
//능력치가 변하게 해줄 수 있는 친구
public class CharacterStatHandler : MonoBehaviour
{
// 기본 스탯과 버프 스탯들의 능력치를 종합해서 스탯을 계산하는 컴포넌트
[SerializeField] private CharacterStat baseStats;
public CharacterStat CurrentStat { get; private set; }
//어떤 추가 스탯들이 있는지 리스트에 담아두기
public List<CharacterStat> statsModifiers = new List<CharacterStat>();
private void Awake() // 기본 능력치 적용
{
UpdateCharacterStat();
}
private void UpdateCharacterStat()
{
// statModifier를 반영하기 위해 baseStat을 먼저 받아옴
AttackSO attackSO = null;
if (baseStats.attackSO != null)
{
//값이 달라질 것이기 때문에 Instantiate를 해주어야한다.
//서로 다른 값으로 만들어주는 인스턴티에잇!
attackSO = Instantiate(baseStats.attackSO);
}
CurrentStat = new CharacterStat { attackSO = attackSO }; // 기본능력치 복사
// TODO : 지금은 기본 능력치만 적용되고 있지만, 향후 능력치 강화 기능등이 추가될 것임!
CurrentStat.statsChangeType = baseStats.statsChangeType;
CurrentStat.maxHealth = baseStats.maxHealth;
CurrentStat.speed = baseStats.speed;
}
}
'유니티를 공부해봐요! > 초급이에요!' 카테고리의 다른 글
[ Unity 뱀서라이크 게임을 만들어보자 8 ] 오브젝트 풀이란 무엇인가 (8) | 2024.10.11 |
---|---|
[ Unity 뱀서라이크 게임을 만들어보자 7 ] 투사체를 날려보자! (1) | 2024.10.10 |
[ Unity 뱀서라이크 게임을 만들어보자 5 ] 공격 구현하기 공격!!!! (1) | 2024.10.10 |
[ Unity 뱀서라이크 게임을 만들어보자 4 ] 삼각함수를 이용하여 조준 구현 (8) | 2024.10.09 |
[ Unity 뱀서라이크 게임을 만들어보자 3 ] 뛰어다니는 맵 구현 ( 타일맵 ) (0) | 2024.10.08 |