공부의 기록/유니티 게임프로그래밍 입문

유니티(Unity) 게임프로그래밍 입문 4일차 수업

파티피플지선 2024. 12. 1. 17:21

지난 주 리뷰

보물사냥꾼 빌드 게임 오브젝트 이동 카메라 조작 월드 구성

3D 객체 충돌 판정

UI기초

 

이번주 목표 

2D 기반 이해

안드로이드 빌드

마카롱 키우기 기반 작업

 

 

 

 

■ 2D 카메라의 개념을 이해하기 위한 활동

100*100 사이즈 캔버스에 필기도구 1px로 해서 점 찍어주기

 

기준 해상도만큼의 이미지를 유저들에게 보여주기 위해서 더미를 만든 것 

이 단계 없이 막 진행하면 "무슨 폰으로 했는데 그림이 짤려요", "그림이 찌부됐어요" 등등  QA 팀의 피드백이 들어온다고 함.

 

layout이 2 by 3인 화면

 

게임 화면 해상도 800*1422로 바꾼 화면

 

 


1422*0.5/100을 한 값 7.11을 카메라 값에 넣어준다

 

 

 

 ■ 안드로이드 빌드해보기(feat. 블루스택)

 

● Build로 안드로이드로 플랫폼 바꾸기

Player Setting에서 해상도로 portrait만 진행하기

패키지 이름 밑에 코드는 마켓에 올릴 때 부여해야하는데, 새로 마켓에 올릴 때는 새로운 코드로 올려야함.

 

 

안드로이드 빌드한 것에 UI 추가해서 빌드+마카롱 키우기 시작

안드로이드에 클릭했을 때의 좌표 확인하는 코드 추가해보기

 

더보기
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class samplescene : MonoBehaviour
{
    [SerializeField] Camera m_MainCamera = null;
    [SerializeField] TextMeshProUGUI m_txtScreen = null;
    [SerializeField] TextMeshProUGUI  m_txtMouse= null; 


    // Start is called before the first frame update
    void Start()
    {
        RefreshOrthographicSize();

        if (null != m_txtScreen) 
        {
            m_txtScreen.text =$"({Screen.width}, {Screen.height})";
        }
    }

    void RefreshOrthographicSize()
    {
        if (null != m_MainCamera)
        {
            float cameraSize = Screen.height * 0.5f * 0.01f;

            m_MainCamera.orthographicSize = cameraSize;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (null != m_txtMouse) 
        {   //마우스 왼쪽 클릭은 0
            if (Input.GetMouseButtonDown(0)) 
            {
                Vector2 pos = Input.mousePosition;
                m_txtMouse.text = $"M({pos})";
            }
        }
    }
}

 

 

■ 마카롱 키우기, 수박 게임 등 비슷한 게임들 분석

상단에 여러 레벨의 물체를 떨어트릴 수 있음

• 같은 레벨끼리 둘이 만나면 더 높은 레벨 물체 하나로 합체함

• 공간이 꽉 차서 특정 높이까지 오면 3초 정도 후 게임 오버

• 특수한 폭탄(인게임 아이템)이 있을 가능성 有

• 부담 없이 머리 식히는 게임(스낵 게임류)

 

 

■ 마카롱 키우기 만들기 시작(이후는 스샷은 거의 못 뜰듯 이미지 저작권 보호 요청이 있었음!)

 

 

 

 

 

 

 

 

 

 

 

LobbyScene 백업

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;


public class lobyscene : MonoBehaviour
{



    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void OnclickButtonStart() 
    
    {
        SceneManager.LoadScene("GameScene");
        
    }

}

 

GameScene 백업

더보기
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class GameScene : MonoBehaviour
{
    [SerializeField] GameObject m_RespawnObj = null;

    GameObject m_RespawnMacaron = null;
    bool m_MouseClick = false;
    bool m_MouseRelease = false;

    const float RESPAWN_TIME = 3f;
    float m_RespawnTime = RESPAWN_TIME;

    [Header("DEBUG")]
    [SerializeField] TextMeshProUGUI m_txtMousePos = null;
    List<Macaron>m_ListMacaron=new List<Macaron>();

    // Start is called before the first frame update
    void Start()
    {
        RespawnMacaron(1);
    }

    // Update is called once per frame
    void Update()
    {
        UpdateRespawnMacaron(); //move
        UpdateRespawnCheck(); //respawn
        UpdateMerging();
    }

    void UpdateMerging() 
    {
        for (int i = 0; i < m_ListMacaron.Count; ++i)
        {
            if (null == m_ListMacaron[i])
            {
                if (m_ListMacaron[i].GetDestroy())
                    { 
                    Destroy(m_ListMacaron[i].gameObject);
                    m_ListMacaron.RemoveAt(i);
                    break;
                    }
            }
        }

        for (int i = 0; i < m_ListMacaron.Count; i++)
        {
            if (null != m_ListMacaron[i])
            {
                if (m_ListMacaron[i].GetMerging()) 
                {
                    Vector3 pos = m_ListMacaron [i].transform.position;
                    Macaron macaron = RespawnMacaron(m_ListMacaron[i].GetLevel() + 1);
                    if (null != macaron) 
                    {
                        macaron.transform.position = pos;
                        Rigidbody2D rigid = macaron.GetComponent<Rigidbody2D>();
                        if (null != rigid) 
                        {
                            rigid.gravityScale = 1f;
                        }
                    }

                    Destroy(m_ListMacaron[i].gameObject);
                    m_ListMacaron.RemoveAt(i);
                    break;
                }
            }
        }
    }


    void UpdateRespawnCheck() 
    {
        if (null == m_RespawnMacaron) 
        {
            m_RespawnTime -= Time.deltaTime;
            if (0f > m_RespawnTime)
            {
                RespawnMacaron(1);
                m_RespawnTime = RESPAWN_TIME;
            }
        }
    }
    void UpdateRespawnMacaron()
    {
        if (null != m_RespawnMacaron)
        {
            m_MouseClick = false;
            m_MouseRelease = false;
            if (Input.GetMouseButtonDown(0))
            {
                m_MouseClick = true;
            }
            else if (Input.GetMouseButton(0))
            {
                m_MouseClick = true;
            }
            if (Input.GetMouseButtonUp(0))
            {
                m_MouseRelease = true;
            }

            Vector3 wpos = Vector3.zero;
            if (m_MouseClick)
            {
                if (null != m_txtMousePos)
                {
                    m_txtMousePos.text = $"{Input.mousePosition}";
                }

                wpos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                if (null != m_RespawnMacaron)
                {
                    wpos.y = m_RespawnMacaron.transform.position.y;
                    wpos.z = 0f;
                    m_RespawnMacaron.transform.position = wpos;
                }
            }
            if (m_MouseRelease)
            {
                if (null != m_RespawnMacaron)
                {
                    Rigidbody2D rigid = m_RespawnMacaron.GetComponent<Rigidbody2D>();
                    if (null != rigid)
                    {
                        rigid.gravityScale = 1f;
                    }

                    m_RespawnMacaron = null;
                }
            }
        }
    }

    Macaron RespawnMacaron(int inLevel)
    {
        inLevel = Mathf.Clamp(inLevel, 1, 13);
        string macaronName = "Macaron ";
        if (10 > inLevel)
        {
            macaronName += "0" + inLevel.ToString();
        }
        else
        {
            macaronName += inLevel.ToString();
        }

        string prefabPath = "Prefabs/" + macaronName;
        GameObject prefabObj = Resources.Load(prefabPath) as GameObject;
        if (null != prefabObj)
        {
            GameObject inst = Instantiate(prefabObj);
            if (null != inst)
            {
                inst.transform.parent = m_RespawnObj.transform;
                inst.transform.localPosition = Vector3.zero;
                Rigidbody2D rigid = inst.GetComponent<Rigidbody2D>();
                if (null != rigid)
                {
                    rigid.gravityScale = 0f;
                }

                Macaron macaron = inst.GetComponent<Macaron>();
                if (null!=macaron) 
                {
                    macaron.SetLevel(inLevel);
                }

                m_ListMacaron.Add(macaron);

                m_RespawnMacaron = inst;

                return macaron;
            }
        }
        return null;
    
    }
}

 

Macaron의 충돌과 합침 코드 백업

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Macaron : MonoBehaviour
{
    int m_Level = 1;
    bool m_Merging = false; //이 기준이면 머징할 것 -> 파괴도 이루어짐
    bool m_Destroy = false; //이 플래그면 파괴할 것

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (null == collision ||
            null == collision.collider) { return; }

        if(GetDestroy()|| GetMerging()) 
            { 
            return;  
        }       
        Macaron macaron = collision.collider.gameObject.GetComponent<Macaron>();
        if (null != macaron) 
        {   
            if (macaron.GetMerging() || macaron.GetDestroy()) { }

            
            
            else if (macaron.GetLevel() == this.GetLevel())
            {
                //merging처리해주기
                SetMerging(true);
                macaron.SetDestroy(true);
            }
        }


    
    }

    public void SetLevel(int inLevel) 
    { 
        m_Level = inLevel; 

    }
    public int GetLevel() { return m_Level; }


    public void SetMerging(bool inMerging) {
        m_Merging = inMerging; 
    }
    public bool GetMerging()
    {
        return m_Merging;
    }

    public void SetDestroy(bool inDestroy)
    { m_Destroy = inDestroy; 
    }

    public bool GetDestroy() { return m_Destroy; }
}