Transform

트랜스폼 클래스에는 객체를 변형할 수 있는 프로퍼티들과 함수들이 들어있다.

회전하는 객체를 만들어 보자

Transform.Rotation();

Spinner.cs

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

public class Spinner : MonoBehaviour
{
    [SerializeField]
    private float xAngle;
    [SerializeField]
    private float yAngle;
    [SerializeField]
    private float zAngle;

    void Update()
    {
        // 프레임마다 x,y,z각도에 각 변수씩 더해진다.
        transform.Rotate(xAngle, yAngle, zAngle);
    }
}

transform.Rotation

추가로 오브젝트가 밀리는 경우가 좀 있는데 Collider를 사용할 때 위치 이동으로 충돌이 이루어져서 그렇다. 이러한 물리 작용을 할 때는 AddForce로 하는 방법이 있다.

 

 

Prefab

오브젝트를 프리펩화시키면 복제, 다른 씬에서의 사용 등 여러가지 좋은 점이 많다.

Prefabs

 

장애물 코스 만들기

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

Tag  (0) 2022.08.02
Score, Time.time, If, Rigidbody  (0) 2022.08.02
OnCollisionEnter(), GetComponent<>()  (0) 2022.08.02
메서드  (0) 2022.08.02
Collision  (0) 2022.07.28

Tag

게임 오브젝트에 태그를 넣어 관리할 수 있다.

- 태그로 검사 가능

Tag

 

목표

1. ObjectHit 스크립트에서 태그로 충돌을 검사하여 Player일 때 색을 변경하고 자신의 Tag를 Hit으로 변경하기

2. Scorer 스크립트에서 태그로 충돌을 검사하여 Hit인지 검사하고 Hit이 아니면 점수를 올리기

ObjectHit.cs

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

public class ObjectHit : MonoBehaviour
{
    private void OnCollisionEnter(Collision collision)
    {
        // 충돌한 객체의 게임 오브젝트의 태그가 Player이면
        if (collision.gameObject.tag == "Player")
        {
            GetComponent<MeshRenderer>().material.color = new Color(1, 0, 0, 1); // red
            // ObjectHit이 있는 해당 오브젝트의 tag를 Hit으로 변경함
            gameObject.tag = "Hit";
        }
    }
}

Scorer.cs

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

public class Scorer : MonoBehaviour
{
    // 점수를 담을 변수
    int hits = 0;

    private void OnCollisionEnter(Collision collision)
    {
        // 충돌한 객체의 태그가 Hit이면(이미 충돌한 객체이면) 스킵
        // if (collision.gameObject.tag != "Hit")과 반대
        if (collision.gameObject.tag == "Hit")
            return;
        
        hits++;

        // 문자열 + 변수이름 하면 붙어서 출력 (문자열변수 이런 식) 
        Debug.Log($"You've bumped into a thing this many times: " + hits); 
    }
}

Tag로 검사

Score

Scorer.cs

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

public class Scorer : MonoBehaviour
{
    // 점수를 담을 변수
    int hits = 0;

    private void OnCollisionEnter(Collision collision)
    {
        // hits가 hits에 1을 더한 값
        // hits = hits + 1;와 동치
        hits++;

        // 문자열 + 변수이름 하면 붙어서 출력 (문자열변수 이런 식) 
        Debug.Log($"You've bumped into a thing this many times: " + hits); 
    }
}

Score

 

 

문제과 해결방안

해결할 문제 : 개체가 3초 정도 이후에 떨어지게 만드는 것

해결책 :

1. 타이머 - Time.time

2. 3초가 지나면 무엇인가를 하는 메커니즘 - if문

3. 개체를 3초 이후에 떨어지게 하는 방법 - disable / enable gravity (3초 이후에 중력 활성화)

 

 

Time.time

게임이 시작하고 난 이후부터 소요된 초 단위의 시간

- Time클래스의 프로퍼티 중 하나

- 읽기전용(접근은 가능해도 변경할 수 없음)

 

Dropper.cs

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

public class Dropper : MonoBehaviour
{
    void Start()
    {
        
    }

    void Update()
    {
        Debug.Log(Time.time);   
    }
}

Debug Time.time

 

 

If

Dropper.cs

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

public class Dropper : MonoBehaviour
{
    [SerializeField]
    private float seconds;
    void Start()
    {
        // bool 값이 true(참)이면 if문 코드 실행 아니면 스킵
        /*if (bool 값)
        {
            무언가를 하시오
        }*/
    }

    void Update()
    {
        // 조건
        if (Time.time > seconds)
        {
            Debug.Log($"{seconds} seconds has left");
        }
    }

    
}

if문과 Serialized 변수

 

 

Rigidbody

Rigidbody컴포넌트의 Use Gravity는 키면 중력을 허용하고 끄면 중력을 허용하지 않는다.

- MeshRenderer컴포넌트처럼 껐다가 킬 수 있음 => 둘 다 꺼서 떨어지기 전엔 안 보이도록 함

Rigidbody

 

캐싱

자주 사용되는 데이터나 정보를 필요할 때 쉽게 접근할 수 있도록 메모리에 저장하는 기술

캐싱

 

Dropper.cs

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

public class Dropper : MonoBehaviour
{
    // Meshrenderer형을 담는 renderer
    MeshRenderer renderer;
    Rigidbody rigid;

    [SerializeField]
    private float seconds;
    void Start()
    {
        // GetComponent<MeshRenderer>().enabled = false;
        // 캐싱
        renderer = GetComponent<MeshRenderer>();
        renderer.enabled = false;

        rigid = GetComponent<Rigidbody>();
        rigid.useGravity = false;
    }

    void Update()
    {
        // 조건
        if (Time.time > seconds)
        {
            Debug.Log($"{seconds} seconds has left");
            renderer.enabled = true;
            rigid.useGravity = true;
        }
    }

    
}

캐싱

 

Directional light

- 위치는 상관 없고 회전이 그림자에 관련 있음

Directional Light

 

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

회전하는 객체, Prefab, 장애물 코스 만들기  (0) 2022.08.02
Tag  (0) 2022.08.02
OnCollisionEnter(), GetComponent<>()  (0) 2022.08.02
메서드  (0) 2022.08.02
Collision  (0) 2022.07.28

ObjectHit.cs

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

public class ObjectHit : MonoBehaviour
{
    // private은 이 함수가 이 클래스 내에서만 접근할 수 있다는 말임
    // Collision은 부딪힌 대상에 대한 정보가 들어있음
    // 들어왔을 때 충돌을 감지함 (들어올 시점에 1번) - 떨어졌다 다시 부딪치면 다시 감지
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("Bumped into a wall");
        // GetComponent메서드
        GetComponent<MeshRenderer>().material.color = new Color(1, 0, 0, 1); // red
    }
}

Collision, GetComponent

 

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

Tag  (0) 2022.08.02
Score, Time.time, If, Rigidbody  (0) 2022.08.02
메서드  (0) 2022.08.02
Collision  (0) 2022.07.28
Cinemachine  (0) 2022.07.28

메서드 이론

함수로 불리기도 하며 게임에서 작은 특정한 것을 하도록 만드는 코드의 블록을 실행하는 것이다.

 

수행해야하는 것

1. 메서드를 선언하고 정의한다. (이것을 하는 거야) ex) CleanYourRoom // 옷 정리하기, 쓰레기 버리기

2. 메서드를 실행하고 싶을 때 불러와야 한다. (이제 가서 실행해)

1. 메서드 선언

 

1. 반환을 요청 가능(반환 값이 있을 시 중괄호 내에 return 반환형 값; 필수)

2. 메서드를 불러올 때 필요한 매개변수를 설정할 수 있음(매개변수 있을 시 앞에 타입을 적어줌)

선언 - 메서드 선언 코드 내부에 ';' 있음

/*반환형 함수이름(파라미터)
    {
        ~해라;
    }*/
void Clean Your Room(int deadline) 
{
	// ~해라; 
}

// 반환 유형은 불려진 곳으로 돌아가고 매개변수는 불린 곳에서 인자를 받아옴
bool CleanYourRoom(int time)
{
	return false; // 반환 키워드(반환 타입이 bool타입 일 때)
}

2. 메서드 호출

호출 - 메서드 이름 뒤에 ';' 있음

// 함수명(매개변수 있을 시 값만 써줌);

CleanYourRoom();

 

그럼 Start()와 Update()는?!

유니티 내부 로직이 적절한 시기에 대신 호출해줌

Start() - Play버튼 누를 때

Update() - Start() 후 매 프레임마다 실행 됨

 

 

메서드 실습

Mover.cs

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

public class Mover : MonoBehaviour
{
    [SerializeField]
    float moveSpeed;
    void Start()
    {
        // 함수로 실행하면 가독성이 좋음
        // 문제가 생기면 작성했던 곳에서 수정하면 됨
        // 여러 곳에서 반복해서 사용할 수 있음
        PrintInstruction();
    }

    void Update()
    {
        MovePlayer();
    }

    // 반환 값 없고 매개변수 값 없음
    void PrintInstruction()
    {
        Debug.Log("welcome to the game");
        Debug.Log("Press arrow keys to move");
        Debug.Log("avoid walls");
    }

    void MovePlayer()
    {
        float xValue = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float zValue = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
        transform.Translate(xValue, 0f, zValue);
    }
}

Method

 

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

Score, Time.time, If, Rigidbody  (0) 2022.08.02
OnCollisionEnter(), GetComponent<>()  (0) 2022.08.02
Collision  (0) 2022.07.28
Cinemachine  (0) 2022.07.28
Time.deltaTime  (0) 2022.07.27

Collider

플레이어가 부딪히거나 통과하지 못하는 투명한 결계 ex) 맵 끝 밖으로 가지 못하게 막는 투명한 벽

Cube 오브젝트로 플레이어나 Wall을 생성했기 때문에 컴포넌트로 박스 콜라이더가 들어있다.

- Box Collider의 Size로 콜라이더의 크기를 조절할 수 있다.

- Box Collider의 Center로 콜라이더의 중심 위치를 조절할 수 있다.

Box Collider

* 초록색 부분이 Collider이다.

Collider

Collider가 컴포넌트에 없다면 Inspector창의 AddComponent - Box Collider로 추가하면 된다.

* 상황에 맞는 콜라이더를 넣으면 됨 - 대부분의 경우는 개체의 크기와 맞게

Colliders

 

 Rigidbody

개체에 질량을 부여하여 물리 시스템에게 물리를 사용해서 개체의 반응을 일으키게 함

- 플레이어를 움직여도 벽과의 충돌이 안 이루어지는데 이 때 최소 둘 중 한 오브젝트에 Rigidbody 컴포넌트가 존재해야 충돌이 이루어진다.

- Use Gravity : 중력 사용 

벽과의 여러 번 충돌 이후 움직임에 버그가 생겼다.

fly

이 문제를 해결하려면 Inspector창 - Rigidbody - Constraints - Freeze Rotation과 Freeze Position을 조정해서 해결할 수 있다.

* 여기선 각 축의 회전과 y축 이동은 사용하지 않으므로 y축 position을 고정했다.

Constraints

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

OnCollisionEnter(), GetComponent<>()  (0) 2022.08.02
메서드  (0) 2022.08.02
Cinemachine  (0) 2022.07.28
Time.deltaTime  (0) 2022.07.27
C# 포맷팅, Input.GetAxis()메서드  (0) 2022.07.27

Cinemachine

- 씬에 있는 여러 카메라를 관리하고 쉽게 카메라에 법칙을 추가할 수 있는 패키지

ex) 전투를 할 때, 숲 속을 달릴 때 컷 씬이나 극적인 순간을 보여줄 때 다른 카메라를 원할 수 있음

- 메인 카메라에 Cinemachine Brain을 추가해 어떤 가상 카메라를 통해서 봐야할 지 알도록 만든다.

ex) 전투를 위한 카메라는 오버 숄더 샷의 카메라로 잡음, 정글을 위한 카메라는 나무에 부딪히지 않도록 좀 더 멀리나 아래에서 씬을 잡을 수 있다.

 

Cinemachine 설치

Window - Pakage Manager - Pakage: Unity Registry - 우측 돋보기에서 Cinemachine 입력 후 선택하여 Install

설치된 모습

Inspector에서 AddComponent로 Cinemachine Brain을 선택하여 추가한다.

* 만약 카메라가 한 대라면 Cinemachine Brain 컴포넌트 추가 없이 바로 아래의 Hierachy창에 우클릭 - Cinemachine - Virtual Camera를 하면 main Camera에 Cinemachine Brain 컴포넌트가 자동으로 생성된다.

 

CinemachineBrain

Hierachy창에 우클릭 - Cinemachine - Virtual Camera를 한다.

Create Virtual Camera

이후 Virtual Camera의 이름을 Follow Cam으로 바꾼 후 드롭다운인 Body를 클릭하여 Framing Transposer로 변경한다.

- Follow : 정해진 위치에서 선택한 개체를 따라다님

- Look At : 감시카메라처럼 선택한 개체를 바라보며 회전함

Follow에서 플레이어를 선택하여 추가함

Follow

Body - Camera Distance : 개체와 카메라 거리

Save During Play : 체크하면 Play 중 수정이 플레이 끝나고도 적용된다.

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

메서드  (0) 2022.08.02
Collision  (0) 2022.07.28
Time.deltaTime  (0) 2022.07.27
C# 포맷팅, Input.GetAxis()메서드  (0) 2022.07.27
SerializedField  (0) 2022.07.27

* 실행 환경 변경 (강의 내용 아님)

임시적으로 내가 편한 환경으로 바꿨다.

Window 탭 - Layout - Tall 후 각 탭을 드래그하여 변경하였음

- 변경된 사항을 저장하고 싶으면 Layout - Save Layout을 클릭하여 저장하면 된다. 

레이아웃

 

 

Time.deltaTime

컴퓨터 사양에 따라 프레임이 달라지는데 Update() 메서드는 프레임에 종속적이다. 그래서 정규화 해줄 필요가 있다. 이 때 이용하는 방법 중 하나가 Time.DetaTime이다.

프레임

- Time.deltaTime은 유니티가 각 프레임을 실행하는데 얼마나 걸렸는지를 알려준다. => 이를 이용해서 게임을 프레임 레이트에서 독립시킬 수 있다.

- 값에 Time.deltaTime을 곱해주는 방식으로 많이 사용한다.

ex) 초당 10프레임 컴퓨터 => 1프레임 당 0.1초 vs 초당 100프레임 컴퓨터 => 1프레임 당 0.01초

10(프레임) * 0.1(초) => 1

100(프레임) * 0.01(초) => 1

 

실행

실행

 

Mover.cs

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

public class Mover : MonoBehaviour
{
    [SerializeField]
    float moveSpeed;
    void Start()
    {

    }

    void Update()
    {
        float xValue = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
        float zValue = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
        transform.Translate(xValue, 0f, zValue);
    }
}

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

Collision  (0) 2022.07.28
Cinemachine  (0) 2022.07.28
C# 포맷팅, Input.GetAxis()메서드  (0) 2022.07.27
SerializedField  (0) 2022.07.27
변수  (0) 2022.07.27

C# 포맷팅

주석

// 내용

이런 식으로 사용하고 // 뒤의 내용은 코드에 영향을 주지 않는다. - 메모 같은 느낌 

주석

 

중괄호 위치와 코드 위치

가독성을 위해 중괄호와 코드 위치를 맞추는 것이 좋다. (반드시 따라야 하는 건 아님 - 작동이 됨)

ex) 한 메서드 내의 중괄호 위치와 코드의 옆 간격을 맞춤(들여쓰기)

중괄호 위치

 

메서드 실행

메서드가 실행되면 안의 코드도 같이 실행됨

메서드 실행

 

 

Input.GetAxis() 메서드

InputManager

Edit 탭 - Project Setting - InputManager

InputManager

Axes내에는 여러 값들이 있는데 Horizontal과 Vertical을 이용하면 키보드로부터 좌우, 위아래 값을 받아올 수 있다.

- Positive Button / Alt Positive Button - 이 키를 누르면 양수 값이 반환된다.

- Negative Button / Alt Negative Button - 이 키를 누르면 음수 값이 반환된다.

Axes

Input.GetAxis("")

"" 부분에 위 사진의 Name부분을 입력하면 GetAXis함수가 실행되어 float 값을 반환한다.

Input.GetAxis

이렇게 반환된 값은 변수에 저장하여 사용할 수 있음

변수 저장

 

실행

* 3D 환경에서 좌우는 x축과 관련있고 위아래는 y축 앞뒤는 z축과 관련있으므로 x축과 z축으로 조작을 건드렸다.

빨강 화살표 - x축

파랑 화살표 - z축

초록 화살표 - y축

xyz축
실행

 

Mover.cs

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

public class Mover : MonoBehaviour
{
    void Start()
    {

    }

    void Update()
    {
        float xValue = Input.GetAxis("Horizontal");
        float zValue = Input.GetAxis("Vertical");
        transform.Translate(xValue, 0f, zValue);
    }
}

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 장애물 코스' 카테고리의 다른 글

Cinemachine  (0) 2022.07.28
Time.deltaTime  (0) 2022.07.27
SerializedField  (0) 2022.07.27
변수  (0) 2022.07.27
Start() 함수와 Update() 함수  (0) 2022.07.27

SerializedField

변수 값을 변경할 때 매번 스크립트로 돌아와서 수정해야하는 번거로움이 있다. 이 때 SerializedField로 변수를 선언하면 에디터에서 수정이 가능하다.

SerializedField
SerializedField2

* 여기서 인스펙터에서 값을 변경해도 스크립트에 적혀있는 기존 값은 변경되지 않는다.

* Play 모드에서 인스펙터 값을 수정하면 게임에 즉각 반영된다.

 

Material

생성

Material

오브젝트 색 변경, 재질 변경

*스크립트처럼 오브젝트의 컴포넌트에 추가해야함

Material2

 

Mover.cs

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

public class Mover : MonoBehaviour
{
    // 선언
    [SerializeField] float xValue = 0f;
    [SerializeField] float yValue = 0f;
    [SerializeField] float zValue = 0f;

    void Start()
    {

    }

    void Update()
    {
        // 프레임 당 값만큼 움직임
        // 변수 자동완성 됨 - 편리
       transform.Translate(xValue, yValue, zValue);
    }
}

+ Recent posts