티스토리 뷰

💻 Unity

GetKey와 GetKeyDown

Input.GetKey(KeyCode.키값) 키가 누르고 있는 동안 계속 true를 반환
Input.GetKeyDown(KeyCode.키값) 키를 처음 누르는 순간 단 한 번만 true를 반환

TextMeshPro

유니티가 제공하는 고품질 텍스트 렌더링 시스템

속성  설명  사용 예시
color TMP 텍스트 전체의 기본 색상을 설정합니다. (머티리얼 색상 포함) tmpText.color = Color.red;
faceColor TMP의 머티리얼 속성 중 글자(전면부)의 색상을 설정합니다. (머티리얼을 직접 변경) tmpText.fontMaterial.SetColor("_FaceColor", Color.blue);
  • color는 TextMeshProUGUI/TextMeshPro의 기본 색상을 변경한다
  • faceColor는 머티리얼의 글자 색상(Face Color) 을 변경하므로, 머티리얼을 변경하면 적용된 모든 텍스트에 영향을 미칠 수 있다
using TMPro;
using UnityEngine;

public class TMPColorTest : MonoBehaviour
{
    public TMP_Text tmpText;

    void Start()
    {
        // 기본 텍스트 색상 변경
        tmpText.color = Color.red;

        // 머티리얼의 글자 색상 변경
        tmpText.fontMaterial.SetColor("_FaceColor", Color.blue);
    }
}

Obejct Pool

Object Pool(오브젝트 풀)은 게임에서 객체를 반복적으로 생성하고 삭제하는 비용을 줄이기 위해 미리 일정 개수의 객체를 생성해두고, 필요할 때 재사용하는 디자인 패턴이다

using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour
{
    public GameObject prefab; // 풀링할 오브젝트 프리팹
    public int poolSize = 10; // 초기 생성할 오브젝트 개수

    private Queue<GameObject> pool = new Queue<GameObject>();

    void Start()
    {
        // 미리 오브젝트 생성
        for (int i = 0; i < poolSize; i++)
        {
            GameObject obj = Instantiate(prefab);
            obj.SetActive(false);
            pool.Enqueue(obj);
        }
    }

    // 오브젝트 요청
    public GameObject GetObject()
    {
        if (pool.Count > 0)
        {
            GameObject obj = pool.Dequeue();
            obj.SetActive(true);
            return obj;
        }
        else
        {
            // 풀에 남은 오브젝트가 없으면 새로 생성
            GameObject obj = Instantiate(prefab);
            return obj;
        }
    }

    // 오브젝트 반환
    public void ReturnObject(GameObject obj)
    {
        obj.SetActive(false);
        pool.Enqueue(obj);
    }
}


🕹️ 실습(1945)

Laser

public GameObject MyEffect;
Transform pos;
int Attack = 10;

void Start()
{
    pos = GameObject.FindWithTag("Player").GetComponent<Player>().pos;
}

void Update()
{
    transform.position = pos.position;
}

private void OnTriggerEnter2D(Collider2D collision)
{
    HandleTrigger(collision);
}

private void OnTriggerStay2D(Collider2D collision) // 충돌 지속
{
    HandleTrigger(collision);
}

private void HandleTrigger(Collider2D collision)
{
    if (collision.CompareTag("Monster"))
    {
        collision.gameObject.GetComponent<Monster>().Damage(Attack++);
        ShowEffect(collision.transform.position);
    }

    if (collision.CompareTag("Boss"))
    {
        ShowEffect(collision.transform.position);
    }
}

private void ShowEffect(Vector3 position)
{
    GameObject effect = Instantiate(MyEffect, position, Quaternion.identity);
    Destroy(effect, 1);
}

Player

public GameObject MyLaser;
public float gValue = 0;

private void FireBullet()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        var i = Mathf.Min(Power, 3);
        Instantiate(MyBullets[i], LauncherPos.position, Quaternion.identity);
    }
    else if (Input.GetKey(KeyCode.Space))
    {
        ShowLaser();
    }
    else
    {
        gValue -= Time.deltaTime;
        gValue = (gValue <= 0) ? 0 : gValue;
    }
}

private void ShowLaser()
{
    gValue += Time.deltaTime;
    if (gValue >= 1)
    {
        GameObject lazer = Instantiate(MyLaser, LauncherPos.position, Quaternion.identity);
        Destroy(lazer, 1);
        gValue = 0;
    }
}

Monster

public int hp = 100;

public void Damage(int attack)
{
    hp -= attack;
    ShowEffect();
    if (hp <= 0)
    {
        DropItem();
        Destroy(gameObject);
    }
}

Boss

public void Damage(int attack)
{
    hp -= attack;
    ShowEffect();
    if (hp <= 0)
    {
        Destroy(gameObject);
    }
}

Text 색상 전환

UI > Text/TextMeshPro 생성

[SerializeField]
float lerpTime = 0.1f;

TextMeshProUGUI textBossWarning;

void Start()
{
    textBossWarning = GetComponent<TextMeshProUGUI>();
}

private void OnEnable()
{
    StartCoroutine(ColorLerpLoop());
}

IEnumerator ColorLerpLoop()
{
    while (true)
    {
        yield return StartCoroutine(ColorLerp(Color.white, Color.red));
        yield return StartCoroutine(ColorLerp(Color.red, Color.white));
    }
}

IEnumerator ColorLerp(Color startColor, Color endColor)
{
    float currentTime = 0.0f;
    float percent = 0.0f;

    while (percent < 1)
    {
        currentTime += Time.deltaTime;
        percent = currentTime / lerpTime;
        textBossWarning.faceColor = Color.Lerp(startColor, endColor, percent);
        yield return null;
    }
}

SpawnManager

[SerializeField]
GameObject BossWarningText;

private void Awake()
{
    BossWarningText.SetActive(false);
}

private void Stop2()
{
    isMonster2 = false;
    StopCoroutine("RandomSpawn2");

    ShowBoss();
}

private void ShowBoss()
{
    BossWarningText.SetActive(true);
    Vector3 pos = new Vector3(0, 2.97f, 0);
    GameObject boss = Instantiate(Boss, pos, Quaternion.identity);
}

Object Pool

using System.Collections.Generic;
using UnityEngine;

public class ObjectPool
{

    private GameObject prefab; // 풀링할 프리팹
    private Queue<GameObject> pool; // 오브젝트들을 보관하는 큐
    private Transform parent; // 풀링된 오브젝트들의 부모 트랜스폼

    public ObjectPool(GameObject prefab, int initialSize, Transform parent = null)
    {
        this.prefab = prefab;
        this.parent = parent;
        pool = new Queue<GameObject>();

        for (int i = 0; i < initialSize; i++)
        {
            CreateNewObject();
        }
    }

    private void CreateNewObject()
    {
        GameObject obj = GameObject.Instantiate(prefab, parent);
        obj.SetActive(false);
        pool.Enqueue(obj);
    }

    // 풀에서 사용 가능한 오브젝트를 가져오는 메서드, 풀이 비어있으면 새로 생성
    public GameObject GetObject()
    {
        if (pool.Count == 0)
        {
            CreateNewObject();
        }

        GameObject obj = pool.Dequeue();
        obj.SetActive(true);
        return obj;
    }

    // 사용이 끝난 오브젝트를 풀로 반환하는 메서드
    public void ReturnObject(GameObject obj)
    {
        obj.SetActive(false);
        pool.Enqueue(obj);
    }
}
public class PoolManager : MonoBehaviour
{

    private static PoolManager _instance;
    public static PoolManager Instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = new GameObject("PoolManager");
                _instance = go.AddComponent<PoolManager>();
                DontDestroyOnLoad(go);
            }
            return _instance;
        }
    }

    // 프리팹 이름을 키로 사용하는 풀 딕셔너리
    private Dictionary<string, ObjectPool> pools = new Dictionary<string, ObjectPool>();

    void Start()
    {

    }

    void Update()
    {

    }

    public void CreatePool(GameObject prefab, int initialSize)
    {
        string key = prefab.name;
        if (!pools.ContainsKey(key))
        {
            pools.Add(key, new ObjectPool(prefab, initialSize, transform));
        }
    }

    public GameObject Get(GameObject prefab)
    {
        string key = prefab.name;
        if (!pools.ContainsKey(key))
        {
            CreatePool(prefab, 10);
        }
        return pools[key].GetObject();
    }

    public void Return(GameObject obj)
    {
        string key = obj.name.Replace("(Clone)", "");
        if (pools.ContainsKey(key))
        {
            pools[key].ReturnObject(obj);
        }
    }
}

💫 Tip!

폰트 한국어 사용 가능하게

  • Windo > TextMeshPro > Font Asset Creator
  • 32-126,44032-55203,12593-12643,8200-9900
  • 생성된 TMP 파일 인스펙터에서 Dynamic, 20, 5로 변경
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함