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

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

파티피플지선 2024. 12. 15. 15:00

지난주 리뷰

- 마카롱 키우기 완성

- 미로 탈출 기반 작업 : 미로 1개, 카메라 워킹

 

이번주 목표

-미로탈출 주요 기능 완성, 카메라 워킹, 이동, 낙하, 미로 탈출 콘텐츠 추가

-미로 제작

-바닥, 길, 벽과 천장, 오르막과 내리막을 통해 광원의 배치가 다르게 적용되는 맵 만들기

 

1인칭 기반 기술 :

카메라, 이동, Character Controller, 중력, Layer 이해 물리 충돌, 카메라 마스킹

 

 

에러나서 중간부터 엉망임...

그래두 맵 만들기 재밌당 ㅎ

 

맵 만들기

 

지붕 뚜껑 덮어줌

 

GameScene 코드

더보기

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

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

    [SerializeField] GameObject m_PlayerObj = null; //프리팹용.
    Player m_Player = null; //플레이어 인스턴스.

    Maze m_Maze = null; //현 미로의 인스턴스.

    [SerializeField] Slider m_sldMouseSensi = null;
    [SerializeField] Button m_btnContinue = null;

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

        RespawnPlayer();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            if(null != m_Player &&
                m_Player.IsGaming())
            {
                OnClickContinue();
            }
        }
    }

    void RespawnPlayer()
    {
        if (null == m_PlayerObj)
        {
            return;
        }

        GameObject instPlayer = Instantiate(m_PlayerObj);
        if(null != instPlayer)
        {
            instPlayer.transform.position = Vector3.zero;

            m_Player = instPlayer.GetComponent<Player>();
            if(null != m_Player &&
                null != m_Maze)
            {
                m_Player.SetWorldPosition(m_Maze.GetBeginPoint());

                Camera.main.transform.parent = m_Player.GetEyes().transform;
                Camera.main.transform.localPosition = Vector3.zero;
            }
        }
    }

    void CreateWorld()
    {
        if(null == m_WorldObj ||
            null == m_MazeObjs ||
            0 >= m_MazeObjs.Length)
        {
            return;
        }

        int mazeIndex = UnityEngine.Random.Range(0, m_MazeObjs.Length);
		//mazeIndex = 1;//[DEBUG]
        GameObject instMaze = Instantiate(m_MazeObjs[mazeIndex]);
        if(null != instMaze)
        {
            instMaze.transform.parent = m_WorldObj.transform;
            instMaze.transform.localPosition = Vector3.zero;

            m_Maze = instMaze.GetComponent<Maze>();
            if(null != m_Maze)
            {
                m_Maze.MakePoints();
            }
        }
    }

    public void OnValueChangedMouseSensi()
    {
        if (null != m_sldMouseSensi)
        {
            //Debug.Log($"Mouse sensi: {m_sldMouseSensi.value}");
            if(null!=m_Player)
            {
            	m_Player.SetMouseSensi(m_sldMouseSensi.value);
            }
        }
    }

    public void OnClickContinue()
    {
        if (null == m_Player) return;

        bool isGaming = m_Player.IsGaming();

        m_Player.SetGaming(!isGaming);
    }
}

Maze 코드

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

public class Maze : MonoBehaviour
{
    [SerializeField] GameObject[] m_PositionObj = null;

    Vector3 m_BeginPoint = Vector3.zero;
    Vector3 m_EndPoint = Vector3.zero;

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

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

    public void MakePoints()
    {
        if(null != m_PositionObj)
        {
            int beginIndex = -1;
            int endIndex = -1;

            int safeCnt = 0;
            while(1000 > safeCnt)
            {
                safeCnt++;

                beginIndex = UnityEngine.Random.Range(0, m_PositionObj.Length);
                endIndex = UnityEngine.Random.Range(0, m_PositionObj.Length);

                if(beginIndex != endIndex)
                {
                    break;
                }
            }

            m_BeginPoint = m_PositionObj[beginIndex].transform.position;
            m_EndPoint = m_PositionObj[endIndex].transform.position;
        }
    }

    public Vector3 GetBeginPoint()
    {
        return m_BeginPoint;
    }
    public Vector3 GetEndPoint()
    {
        return m_EndPoint;
    }
}

 

Player 코드

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

public class Player : MonoBehaviour
{
    CharacterController m_CharacterController = null;

    [SerializeField] GameObject m_Eyes = null;

    float mouseSensitivity = 100f; //마우스 민감도.
    float xRotation = 0f; //카메라 상하 회전 제한.

    bool m_isGaming = false; //메뉴냐, 게임 상태냐.

    float m_Speed = 5f;
    float m_Gravity = -9.81f;
    
    float m_mouseSensi

    // Start is called before the first frame update
    void Start()
    {
        m_CharacterController = GetComponent<CharacterController>();

        /*Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;*/
    }

    // Update is called once per frame
    void Update()
    {
        //UpdateCursor();

        UpdateCamera();

        UpdateMove();
    }

    void UpdateMove()
    {
        if (null == m_CharacterController) return;

        bool isGrounded = Physics.CheckSphere(transform.position, 2f,
            LayerMask.NameToLayer("Ground"));

        float x = Input.GetAxis("Horizontal"); //A, D 키.
        float z = Input.GetAxis("Vertical"); //W, S 키.

        Vector3 move = Camera.main.transform.right * x +
            Camera.main.transform.forward * z;

        if(isGrounded)
        {
            move.y = 0f;
        }
        m_CharacterController.Move(move * Time.deltaTime * m_Speed);

        Vector3 velUpDown = Vector3.down;

        //중력.
        velUpDown.y += Time.deltaTime * m_Gravity;
        m_CharacterController.Move(velUpDown);
    }

    void UpdateCursor()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            Cursor.lockState = CursorLockMode.None;
            Cursor.visible = true;

            m_isGaming = false;
        }
        if(Input.GetMouseButtonDown(0))
        {
            Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;

            m_isGaming = true;
        }
    }

    void UpdateCamera()
    {
        if (false == m_isGaming) return;
		
        //UI slider : 0~1
        //기획상 : 0.5~ 2
        //y=x*1.5+0.5: 0.5~2
        float optMouseSensi=m_Mousesensi *1.5f + 0.5
        
        float mouseX = Input.GetAxis("Mouse X") * Time.deltaTime * mouseSensitivity;
        float mouseY = Input.GetAxis("Mouse Y") * Time.deltaTime * mouseSensitivity;

        //카메라 위 아래 방향 회전.
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        m_Eyes.transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

        //몸통 좌우 방향 회전.
        transform.Rotate(Vector3.up * mouseX);
    }

    public void SetWorldPosition(Vector3 inPosition)
    {
        transform.position = inPosition;
    }

    public GameObject GetEyes()
    {
        return m_Eyes;
    }

    public void SetGaming(bool inGaming)
    {
        m_isGaming = inGaming;

        if(m_isGaming)
        {
            Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;
        }
        else
        {
            Cursor.lockState = CursorLockMode.None;
            Cursor.visible = true;
        }
    }
    public bool IsGaming()
    {
        return m_isGaming;
    }
    public void SetMouseSensi(float inSensi)
    {
    	m_MouseSensi = inSensi;
    }
    
    public float GetMouseSensi()
    {
    	return m_MouseSensi;
    }
}

중간부터 놓쳐서 신나게 놀았다..크킄... 에라 모르겠당! >_<