Image & RawImage
Image Type (4가지)
Image
단점: Sprite 변환 과정이 필요(자원 소모가 상대적으로 있음)
Raw Image
단점: 각 텍스처당 Draw Call 발생
Slider
[환경 설정]

[체력바 - 플레이어, 적, 보스 등등]

[과열기능 - 게임적 허용]
Scroll View
TextMeshPro (TMP)
MVC / MVP
using TMPro;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int hp = 100;
public TextMeshProUGUI hp Text; // UI와 강한 결합
public void OnDamage(int damage)
{
hp -= damage;
// 로직 스크립트 안에서 UI를 건든다 -> UI와 강한 결합
hpText.text = "HP:" + hp.ToString();
if(hp <= 0)
{
Debug.Log("Enemy 죽음...");
}
}
}

[Model - 데이터 관리]
public class PlayerModel_MVC
{
public int hp = 100;
}
[View - 화면에 출력 - Model 직접 참조중]
using UnityEngine;
using UnityEngine.UI;
public class PlayerView_MVC : MonoBehaviour
{
public PlayerModel_MVC playerModel;
public Slider hpSlider;
public void UpdateView()
{
hpSlider.value = playerModel.hp / 100f;
}
}
[Controller - 입력 처리 및 Model(데이터) 수정]
using UnityEngine;
public class PlayerController_MVC : MonoBehaviour
{
PlayerModel_MVC playerModel = new PlayerModel_MVC();
public PlayerView_MVC playerView;
public void OnDamage(int damage)
{
playerModel.hp -= damage; // Model(데이터) 수정
playerView.UpdateView(); // View(UI - Slider) 갱신
}
}
[Model 파트 MVC와 동일]
[View - 오로지 그려주기만 한다]
using UnityEngine;
using UnityEngine.UI;
public class PlayerView_MVP : MonoBehaviour
{
[serializeField] Slider slider;
public void SetFillAmount(float ratio)
{
slider.value = ratio;
}
}
// Model을 직접 참조하고 있지 않다.
// 데이터 가공도 하지 않는다.
// 오로지 그려주기만 한다.
[Presenter - Model(데이터)와 View(화면) 중재]
using UnityEngine;
public class PlayerPresenter_MVP : MonoBehaviour
{
PlayerModel_MVC model = new PlayerModel_MVC();
[SerializeField] PlayerView_MVP playerview; // 조립할 대상
public void TakeDamage(int damage)
{
model.hp -= damage;
float ratio = model.hp / 100f;
playerView.SetFillAmount(ratio)
}
}
1) Basic - 단일 연동 (1:1)
[model]
public class StatModel
{
public float hp = 100f;
public float maxHP = 100f;
public float GetHpRatio() => hp / maxHP;
}
[View]
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SliderBarView : MonoBehaviour
{
public Slider slider;
public void SetValue(float ratio) => slider.value = ratio;
}
public class TextPercentView : MonoBehaviour
{
public TMP_Text hpText;
public void SetProgress(float ratio)
{
hpText.text = $"HP; {ratio * 100}%";
}
}
[presenter]
using UnityEngine;
public class StastPresenter : MonoBehaviour
{
StatModel model = new StatModel();
[SerializeField] SliderBarView viewA;
[SerializeField] TextPercentView viewB;
public void OnDamage(float damage)
{
model.hp -= damage;
viewA.SetValue(model.GetHpRatio());
viewB.SetProgress(model.GetHpRatio());
}
}
2) Advanced - 다중 연동 (1:N)
[Model]
public class ScoreModel
{
int score;
public event System.Action<int> OnScoreChanged; // 전광판
public void AddScore(int amount)
{
score += amount;
OnScoreChanged?.Invoke(score);
}
}
[Presenter]
using UnityEngine;
public class ScorePresenter : MonoBehaviour
{
[SerializeField] ScoreView scoreView;
[SerializeField] TargetView targetView;
[SerializeField] RankingView rankingView;
[SerializeField] AchievementPopupView popupView;
ScoreModel model = new ScoreModel();
void OnEnable()
{
model.OnScoreChanged += scoreView.UpdateScoreText;
model.OnScoreChanged += targetView.UpdateTargetText;
model.OnScoreChanged += CheckAchievement; // Q. 왜 View쪽이 아닌 여기에 구현할까?
}
void OnDisable()
{
// 구독 해지 안해준다면??
}
void CheckAchievement(int score)
{
if(score >= 100) popupView.Show("팝업 떳습니다");
}
}
📢중요 ) 밥먹듯이 습관적으로 해주기