본문 바로가기
Programming/Unity

[Unity] 15. 3D 기초 게임 개발

by 가가가가가가 2022. 7. 25.
반응형

1. 계획하기

  • 게임 개발은 계획부터 차근차근

 

2. 플레이어

  • 공(Sphere), 바닥(Plane) 생성
  • Material 적용
  • 기본 움직임, 점프(더블 이상 점프 불가능) 기능 적용
  • 공의 움직임이 너무 빠르면 Mass를 늘리거나 Power를 낮추거나
  • 테스트를 용이하게 위해서 변수를 public로 선언하여 Inspector창에서 값 설정
  • 공과 부딪히면 점수를 올리고, 해당 아이템이 없어지는 기능 적용
  • SetActive(bool) : 오브젝트 활성화 함수
  • 공과 부딪힐 때 사운드 삽입
  • AudioSource : 사운드 재생 컴포넌트, AudioClip 필요
  • AudioClip : 사운드 파일 컴포넌트
  • 비활성화 구간에서는 컴포넌트 함수가 실행되지 않을 수도 있음

 

3. 아이템

  • 아이템(Capsule) 생성
  • Material 적용
  • 세로축 기준으로 회전하는 기능 적용
  • transform.Rotate(Vector3) : 매개변수 기준으로 회전시키는 함수
  • 오버로드 : 이름은 같지만 매개변수가 다른 함수를 호출
  • 공중에 떠 있어야 하기 때문에 Rigidbody 추가 X
  • 물리 충돌이 필요 없기 때문에 Capsule Collider의 Is Trigger 체크
  • Tag : 오브젝트를 구분하는 단순한 문자열

 

4. 카메라

  • 공을 따라 다니도록 설정
  • FindGameObjectWithTag() : 주어진 태그로 오브젝트 검색

 

5. 결승점

  • 포인트(Cylinder) 생성
  • 물리 충돌이 필요없기 때문에 Capsule Collider의 Is Trigger 체크
  • 아이템을 다 먹지 못할 경우, 게임 리셋
  • 형태가 없고 전반적인 로직을 가진 오브젝트를 매니저로 지정
  • Find 계열 함수는 부하를 초래할 수 있으므로 피하는 것을 권장

 

6. 장면 이동

  • SceneManager : 장면을 관리하는 기본 클래스
  • LoadScene() : 주어진 장면을 불러오는 함수
  • Scene을 불러오려면 꼭 Build Setting에서 추가

 

7. 스테이지 추가

  • 바닥 밑으로 떨어질 때 게임 재실행
  • LoadScene의 매개변수는 장면 순서(int)도 가능

 

8. 유저 인터페이스

  • 이미지 및 텍스트로 현재 먹은 아이템 개수 화면에 표시
  • UI를 사용하려면 UnityEngine.UI 라이브러리 필수 적용

 

9. 빌드

  • Buildling Settings에서 Build 클릭

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerBall : MonoBehaviour
{
    public float jumpPower; // 점프 세기
    public int itemCount; // 점수(먹은 아이템)
    public GameManagerLogic manager; // GameManagerLogic
    bool isJump; // 점프 여부
    Rigidbody rigid; // Rigidbody 컴포넌트
    AudioSource audio; // AudioSorce 컴포넌트

    void Awake()
    {
        // 변수 초기화
        isJump = false;
        rigid = GetComponent<Rigidbody>();
        audio = GetComponent<AudioSource>();
    }

    void Update()
    {
        // 점프(더블 이상 점프 X)
        if (Input.GetButtonDown("Jump") && !isJump)
        {
            isJump = true;
            rigid.AddForce(new Vector3(0, jumpPower, 0), ForceMode.Impulse);
        }
    }

    void FixedUpdate()
    {
        // 기본 움직임
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        rigid.AddForce(new Vector3(h, 0, v), ForceMode.Impulse);
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Floor")
        {
            isJump = false;
        }
    }

   void OnTriggerEnter(Collider other)
   {
        if (other.tag == "Item") // 아이템과 부딪혔을 때
        {
            // 점수 증가
            itemCount++;

            // 오디오 플레이
            audio.Play();

            // 먹은 아이템 비활성화
            other.gameObject.SetActive(false);

            // 아이템 개수 UI 표시
            manager.GetItem(itemCount);
        } else if (other.tag == "Finish") // 결승점 도달했을 때
        {
           if(itemCount == manager.totalItemCount) // Game Clear
            {
                if(manager.stage == 2)
                {
                    SceneManager.LoadScene(0);
                }
                else
                {
                    SceneManager.LoadScene(manager.stage + 1);
                }
            } else // Restart
            {
                SceneManager.LoadScene(manager.stage);
            }
        }
    }
}

 

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

public class ItemCan : MonoBehaviour
{
    public float rotateSpeed; // 회전 속도
    
    void Update()
    {
        // 세로축 기준으로 회전
        transform.Rotate(Vector3.up * rotateSpeed * Time.deltaTime, Space.World);       
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMove : MonoBehaviour
{
    Transform playerTransform;
    Vector3 Offset;

    void Awake()
    {
        playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
        Offset = transform.position - playerTransform.position;
    }

    void LateUpdate()
    {
        transform.position = playerTransform.position + Offset;
    }
}

 

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

public class GameManagerLogic : MonoBehaviour
{
    public int totalItemCount; // 총 아이템 개수
    public int stage; // 단계
    public Text stageCountText; // 먹어야 할 아이템 개수 표시
    public Text playerCountText; // 먹은 아이템 개수 표시

    void Awake()
    {
        stageCountText.text = "/ " + totalItemCount;
    }

    public void GetItem()
    {
        playerCountText.text = playerCountText.ToString();
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.tag == "Player")
        {
            SceneManager.LoadScene(stage);
        }
    }
}

 


참고

반응형

댓글