나 개발자 진짜 되냐?

[ Unity 3D 서바이벌 게임 만들기 2 ] UI 만들기 본문

유니티를 공부해봐요!/중급이에요!

[ Unity 3D 서바이벌 게임 만들기 2 ] UI 만들기

Snow Rabbit 2024. 10. 27. 02:45

두 번째는 UI를 만들어 볼 것이다.

 

어떤 UI냐!

체력, 배고픔, 스태미나 이렇게

3가지를 만들어 볼 것이다.

 


먼저

UI 해주려면!

Canvas부터 만들어 주자

 

캠버스 사이즈를 정해주자

 

 

이렇게 해주면

해상도가 줄어들어도

화면만 줄지않고

다른 것들도 크기가 자연스레 조절된다.

 

자 다음에

캠버스 안에 이미지를 하나 만들자

 

이렇게 설정!

Color은

82, 82, 82, 255로 설정했다.

 

자 그 밑에다가 이미지 하나 더 생성

 

아이콘 모양이다.

아이콘은

 

Textures에 있다.

 

그다음에 게이지를 만들어보자

 

이미지 하나 더 생성!

 

게이지를 만들어 주기 전에!

이 친구를 다운로드하여주자

다운로드하는 방법은 다들 알겠지만

윈도우 > 패키지 매니저에 가서 검색해 주면 된다!

 

 

다음에

Textures파일로 가서

 

 

생성

 

이 생성해 준 네모를

위에 이미지에 이미지소스에 넣어주면

추가적인 설정창이 뜬다.

 

 

여기서 이미지 타입을 우리는

Filed로 바꿔주게 되면

 

또 밑에 주르륵 나오는데

Method를

Horizontal로 바꿔주면 된다.

 

 

Amount를 0에 가까이 움직이면

게이지가 줄어드는 느낌이 들게 된다.

 

이렇게 되었다면!

우리는 두 가지 게이지를

더 추가해주어야 한다.

 

추가 전에!

위치를 조금 정해보자

 

빈 오브젝트를 만들어주고

그 안에다가 우리는 게이지 3개를 예쁘게 넣어 줄 예정이다.

 

이 오브젝트의 크기를 정하고

중요한 것은!

위치를 

shift와 alt를 이용해서

오른쪽 하단으로 위치를 바꿔준 다음에

 

 

Vertical Layout Group을 해준다.

세로정렬!이라는 친구로

이것은 이제 그룹을 묶어준다는 뜻이다.

다음에 이 오브젝트 안에

아까 게이지를 넣어주면!

 

 

 

자라라 잘 들어가져 있다!!

 

이제 게이지 두 개를 더 추가해 보자

하게 되면 

이 그룹 덕분에 

깔끔하게 위치를 따로 조정하지 않아도

예쁘게 들어가지게 된다.

 

Spacing은 이미지 사이의 간격이다

 

그래서 이걸 10 정도 주면

 

예쁘게 배치가 된다.

 

이 외에도

Horizontal Layout Group : 가로로 배치해 주는 그룹

Grid Layout Group : 상하좌우로 배치 해주는 그룹

 

 

이렇게 해주고

이름과 아이콘들을 바꿔주면 끝!

 

 

자, 이제 스크립트.. 흑흑

짜러 가요

 

 

스크립트 안에 UI파일 만들어서

두 개 스크립트를 만든다

 

Condition의 경우는

위에 3개의 게이지에다가 넣어주는 친구이다.

 

이 3개의 컨디션을 관리해 주는

UI Codition이다.

이 UI는

 

위에 만들어 둔

Conditions 오브젝트에 넣어줘서

아래 있는 컨디션들을 관리해줄 것이다.

 

미리 드래그 앤 드롭해놓자!

 

Coditions 오브젝트에 UI Condition.cs

그리고 Health, Hunger, Stamina 에는 Condition.cs

를 넣어주면 된다.

 

 

먼저!

 Condition.cs부터 보자

using UnityEngine;
using UnityEngine.UI;

public class Condition : MonoBehaviour
{
    public float curValue; // 현재값
    public float maxValue; // 최대값
    public float startValue; // 시작값
    public float passiveValue; //배고픔이나 스태미나 등 주기적으로 변하는 값
    public Image uiBar; // 아까 이미지 타입을 filled로 해놨던것을 만지기 위해

    private void Start()
    {
        curValue = startValue; // 현재값은 시작값
    }

    private void Update()
    {//우리는 지속적으로 fill값을 만져줘야한다. 
        uiBar.fillAmount = GetPercentage();
    }

    public void Add(float amount) // 추가 할때
    {   //Min함수는 두개 매개변수를 보고 작은 값을 넣어준다.
        curValue = Mathf.Min(curValue + amount, maxValue);
    }

    public void Subtract(float amount) // 감소할때
    {   //Max함수는 두개 매개변수를 보고 큰 값을 넣어준다.
        curValue = Mathf.Max(curValue - amount, 0.0f);
    }

    public float GetPercentage()
    {
        return curValue / maxValue; // 백분율로 나누는 느낌
    }
}

 

변수를 적어 주고

 

시작할 때

값을 정해준다.

 

그다음 우리는 "지속적"으로

fill값을 줄어들게 해주어야 한다.

 

생각해 보자

fill은 아까 

0에서 1이었고

백분위로 나타낼 수 있다.

100%라고 하면

1이 max일거고

현재값은 curValue 이니까

 

그렇다면?!

 

update문에서 해줘야 할 것이고

cur / max 해주면

될 것 같다.

 

update에 바로 쓰는 것보다

이런 연산은

따로 함수를 만들어서

update에서 선언만 할 수 있게 끔

하는 것이 좋다.

연산은 최대한 내부적으로!!

 

 

다음에 이렇게 해주면 된다.

 

자 이렇게 해주면,

현재 값만 바꿔주면

지속적으로 게이지가 늘고 줄어들 것이다.

 

이제 현재값을 늘고 줄어들게 계산해 주는

함수를 만들어보자

 

 

Mathf 함수를 이용해서

Min의 경우

curValue = 90

amount = 20

= 110

인데 최대를 넘으면 안 되기 때문에

max = 100을 비교해서

더 작은 값인 100 이 들어가게 해서

max보다 커지지 않게 써 줄 수 있게 된다.

Max의 경우도 마찬가지이다.

curValue = 10

amount = 20

= -10

최소를 넘어가면 안 되기 때문에

0이랑 비교해서

더 큰 0 이 들어가게 한다.

 

자 다 써주었으면

유니티로 돌아가서

값을 넣어주자

 

Health

 

Hunger

 

Stamina

 

 

자 이제 

게이지 3개를 줄이고 늘려보자

 

UICondition.cs

using UnityEngine;

public class UICondition : MonoBehaviour
{
    public Condition health;
    public Condition hunger;
    public Condition stamina;

    private void Start()
    {
        CharacterManager.Instance.Player.condition.uiCondition = this;
    }
}

 

먼저 변수 3개 입력!

 

UI스크립트를 통해 우리가 눈으로 보이게끔

해주는 것이고

실제로 코드는

playerCondition에서 만지고

ui로 데려가서

눈에 보이게끔 할 것이다.

 

스크립트를 또..........

만들어 보자!

 

PlayerConditions.cs

using System;
using UnityEngine;


public class PlayerCondition : MonoBehaviour
{
    public UICondition uiCondition;

    //소문자 친구들을 통해서 ui에서 데이터를 가져와 업데이트 해준다.
    Condition health { get { return uiCondition.health; } }  
    Condition hunger { get { return uiCondition.hunger; } }
    Condition stamina { get { return uiCondition.stamina; } }

    public float noHungerHealthDecay;
    public event Action onTakeDamage;

    private void Update()
    {
        //시간에 따라 배고픔이 줄어들게 하기위해, 성능에 따라 줄어들지 않게 하기위해 deltaTime
        hunger.Subtract(hunger.passiveValue * Time.deltaTime);
        stamina.Add(stamina.passiveValue * Time.deltaTime);

        if (hunger.curValue <= 0.0f) //배고픔이 0이면 체력을 깎게 만든다.
        {
            health.Subtract(noHungerHealthDecay * Time.deltaTime);
        }

        if (health.curValue <= 0.0f)
        {
            Die();
        }
    }

    public void Heal(float amount)
    {
        health.Add(amount);
    }

    public void Eat(float amount)
    {
        hunger.Add(amount);
    }

    public void Die()
    {
        Debug.Log("플레이어가 죽었다.");
    }

}

 

get을 통해서 uiCondition에 있는 값들을 가져온다.

 

그리고 우리는 여기 update문을 이용해서

늘리고 줄어들게 만들 것이다.

 

deltaTime은 모든 컴퓨터가 동일하게 흐르는 시간을 이용하는 것이다!

참고!!

 

if문을 통해

배고픔을 넘어서 체력을 줄어들게 해주어야 한다.

줄어들게 해주는 변수

하나 만들어줘서 if문에 넣어주었다!

 

그리고 여기서 중요한 건 0이면 깎어야 하기 때문에

0까지 쭉쭉 깎아줘야 한다.

 

왜냐면 0이어야, 체력을 깎기 시작할 것이다.

조금이라도 남아있다면 체력이 안 깎일 테니

< 이 부등호가 아니라 <= 가 되어야 한다!

 

자,

이렇게 해주었으니

마무리로

 

1. PlayerCondition.cs를 만들어주었으니

player.cs에 넣어주어야 한다.

using System;
using UnityEngine;

public class Player : MonoBehaviour
{
    public PlayerController controller;
    public PlayerCondition condition; 

    private void Awake()
    {
        CharacterManager.Instance.Player = this;
        // 플레이어 옵젝에 컨트롤러를 넣어놨으니.. get으로 찾아서 잘 넣을것이다.
        controller = GetComponent<PlayerController>();
        condition = GetComponent<PlayerCondition>();

    }
}

 

별표 줄 추가!

condition추가하고 get으로 가져온다.

 

그다음에 

마지막으로

 

UICondition에

start를 통해

this를 넣어준다.

 

 

이제 unity로 와서

 

값을 넣어주고

 

player에도

PlayerConditions.cs를 넣어주고

 

값 넣어준다.

여기서 이미 우리는 get으로 넣어주기로 했으니

굳이 넣어주지 않아도 자동으로 들어갈 것이다.

 

 

이렇게 해주면!

 

배고픔의 게이지가 끝나니

체력이 깎이게 된다.

 

이러면 게이지 UI 완성!!

 

다음에는

플레이어가 아야 할 때 대미지가 다는 느낌을 만들어 보자!!