유니티 오디오

효과음을 내기위한 세 가지

Audio Listener

- 오디오를 듣기

Audio Source

- 오디오를 플레이 하기

Audio File

- 재생되는 소리

 

Audio Listener

메인 카메라에는 기본적으로 Audio Listener가 들어있는데 기본 설정상 우리가 보는 화면이기 때문이다.

메인 카메라 오디오 리스너

오디오 소스나 오디오 리스너는 다른 컴포넌트처럼 오브젝트에 추가해서 사용한다.

오디오 소스

Audio Source

오디오 소스 컴포넌트는 오디오 클립을 추가해서 플레이 하는 식으로 동작한다.

- Play On Awake : 시작할 때 켜짐

- Loop : 반복

오디오 소스 2

 

Audio File

- 오디오 파일 다운로드 사이트 (저작권 주의)
https://freesound.org/

 

Freesound - Freesound

Freesound Blog Recent Additions Woodpecker pecking on a tree, slight wind shaking foliage, birds singing, far plane passing and road hum at the end ... 13 more sounds from felix.blume in the last 48 hours 4 more sounds from josefpres in the last 48 hours 2

freesound.org

- 직접 효과음 녹음하는 사이트

https://www.audacityteam.org/

 

Home

Welcome to Audacity Audacity® is free, open source, cross-platform audio software for multi-track recording and editing. Audacity is available for Windows®, Mac®, GNU/Linux® and other operating systems. Check our feature list, Wiki and Forum. Download

www.audacityteam.org

 

오디오 파일은 이런식으로 에셋 폴더에 넣고 누르면 확인이 된다.

오디오 파일을 Audio Source 컴포넌트의 Audio Clip에 드래그 앤 드롭다운 해서 넣으면 플레이할 준비가 된 것이다

오디오 클립


Movement.cs

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

public class Movement : MonoBehaviour
{
    private Rigidbody rigid;
    private AudioSource audioSource;
    [SerializeField]
    private float mod = 100f;
    [SerializeField]
    private float rotationSpeed = 1f;
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
        audioSource = GetComponent<AudioSource>();
    }

    void Update()
    {
        ProcessThrust();
        ProcessRotation();
    }

    void ProcessThrust()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            rigid.AddRelativeForce(Vector3.up * mod * Time.deltaTime); // Time.deltaTime은 1프레임당 시간
            // 재생하고 있지 않을 때만 재생 (재생이 겹치는 걸 막음)
            if (!audioSource.isPlaying)
                audioSource.Play();
        }
        else
            audioSource.Stop();
    }

    void ProcessRotation()
    {
        if (Input.GetKey(KeyCode.A))
        {
            // Ctrl + .으로 반복되는 문장을 함수로 빠르게 만들 수 있다.
            // 반복되는 문장은 다른 것만 매개변수로 받으면 좋다.
            // Ctrl + R 두 번으로 이름을 한 번에 수정할 수 있다.
            ApplyRotation(rotationSpeed);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            ApplyRotation(-rotationSpeed);
        }
    }

    private void ApplyRotation(float rotationThisFrame)
    {
        // 비트연산이라 더하면 xy 값 물리적 고정과 같음
        // rigid.constraints = (RigidbodyConstraints)((int)RigidbodyConstraints.FreezeRotationX + (int)RigidbodyConstraints.FreezeRotationY);
        // 물리적으로 회전 고정
        // rigid.constraints = RigidbodyConstraints.FreezeRotation;
        
        rigid.freezeRotation = true; // 회전 값을 고정해서 수동으로 회전을 조작할 수 있게 함
        // 이게 되는 이유는 rigid(물리)충돌의 회전만 제어했을 뿐이지 transform 기반으로 한 회전은 수동으로 제어 가능 
        transform.Rotate(Vector3.forward * rotationThisFrame * Time.deltaTime);
        rigid.freezeRotation = false; // 회전 값 고정을 풀어서 물리 시스템이 적용 됨
    }
}

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 부스트 프로젝트' 카테고리의 다른 글

SceneManager  (0) 2022.08.12
Switch  (0) 2022.08.12
소스 컨트롤  (0) 2022.08.12
오브젝트 회전과 매개변수와 Rigidbody  (0) 2022.08.04
부스터  (0) 2022.08.03

소스 컨트롤

코드 및 프로젝트의 변경 사항을 추적 및 관리하는 시스템 

- 무엇이 변경됐는지 알 수 있는 좋은 방법

- 변경하려던 것이 잘 풀리지 않거나 변경하기 싫었던 것을 변경했을 때 이전 버전으로 돌아갈 수 있음

ex) Git, Gitlab, Github

Gitlab : 호스팅 서비스를 할 수 있는 저장소(온라인 공간)

Repository - 프로젝트를 공개적으로 호스팅하면 무료로 여러 버전을 사용할 수 있고 온라인에서 클라우드로 프로젝트를 호스팅 할 수 있다. (우리가 프로젝트를 저장하는 공간) 

SourceTree : 리포를 볼 수 있도록 돕는 데스크톱 클라이언트

 

소스 컨트롤을 사용하는 이유

- 프로젝트를 저장하기 좋은 방법이다 => 하드드라이브에 문제가 생겨도 안전하게 보호되도록 클라우드에 저장하는 것

- 돌아갈 수 있는 프로젝트의 이전 버전이 있다는 것을 알면 프로젝트를 안전히 변경할 수 있음

- 동시에 여러 아이디어를 한 번에 적용할 수도 있음(여러 아이디어 실험)

- 다른 작업자들과 쉽게 공유할 수 있음

* 아래처럼 뭐가 추가가 됐고 뭐가 빠졌는지 알 수 있다. (좌측 빨간색 빠진 것, 우측 초록색 추가된 것)  

깃 데스크탑

 히스토리를 클릭하면 이 특정 파일의 히스토리를 보여준다.

히스토리

깃허브의 코드를 누르면 클론을 만들어서 로컬 저장소에 저장할 수 있다.

클론

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 부스트 프로젝트' 카테고리의 다른 글

Switch  (0) 2022.08.12
유니티 오디오  (0) 2022.08.12
오브젝트 회전과 매개변수와 Rigidbody  (0) 2022.08.04
부스터  (0) 2022.08.03
클래스, Input 클래스  (0) 2022.08.03

Transform.Rotation(Vector3 vec)

transform을 기준으로 vec만큼 회전한다.

매개변수

반복되는 문장은 다른 부분만 매개변수로 대입하는 함수를 만들어주면 실수도 방지할 수 있고 가독성이 올라간다.

- 호출할 때 함수의 인자는 선언한 함수의 매개변수 타입과 같아야한다.

* Ctrl + .으로 반복되는 문장을 함수로 빠르게 만들 수 있다.
** Ctrl + R 두 번으로 이름을 한 번에 수정할 수 있다.

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

public class Movement : MonoBehaviour
{
    private Rigidbody rigid;
    [SerializeField]
    private float mod = 100f;
    [SerializeField]
    private float rotationSpeed = 1f;
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
    }

    void Update()
    {
        ProcessThrust();
        ProcessRotation();
    }

    void ProcessThrust()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            rigid.AddRelativeForce(Vector3.up * mod * Time.deltaTime); // Time.deltaTime은 1프레임당 시간
        }
    }

    void ProcessRotation()
    {
        if (Input.GetKey(KeyCode.A))
        {
            // Ctrl + .으로 반복되는 문장을 함수로 빠르게 만들 수 있다.
            // 반복되는 문장은 다른 것만 매개변수로 받으면 좋다.
            // Ctrl + R 두 번으로 이름을 한 번에 수정할 수 있다.
            ApplyRotation(rotationSpeed);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            ApplyRotation(-rotationSpeed);
        }
    }

    private void ApplyRotation(float rotationThisFrame)
    {
        transform.Rotate(Vector3.forward * rotationThisFrame * Time.deltaTime);
    }
}

 

 

Rigidbody Constraints

Rigidbody의 Constraints에서 위치와 회전 값을 고정할 수 있다.

Rigidbody의 Constaraints

물체에 부딪혔을 때 회전이 마음대로 안 되는 버그가 있다. (충돌 후 물리 계산 방향과 다른 방향으로 움직일려고 해서 버그가 발생함)

* 해결 방안 : 물리적 충돌에 의한 회전과 transform을 기반으로 한 회전은 다르기 때문에 물리적 충돌의 제약을 걸어 묶어준 후 수동으로 transform 회전을 하고 수동 회전 입력이 없으면 물리적 충돌의 제약을 푼다.  

물리적 충돌과 transform 회전

 

Rigidbody Drag

Drag 값은 공기 저항 값으로 움직일 때 저항이 발생한다.

물리적 힘을 줬을 때 어느정도 까지만 가고 더 추진 되지 않는다.

 

Physics Gravity

Project Setting - Physics - Gravity에서 월드 중력 값을 조정할 수 있다.

ex) 플레이어가 뚫고 가야할 맞바람 구현 - x축으로 -값을 줌

* 플레이 화면에서 고쳐도 저장 안 됨 => 플레이 중 테스트 가능

Gravity

 

Movement.cs

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

public class Movement : MonoBehaviour
{
    private Rigidbody rigid;
    [SerializeField]
    private float mod = 100f;
    [SerializeField]
    private float rotationSpeed = 1f;
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
    }

    void Update()
    {
        ProcessThrust();
        ProcessRotation();
    }

    void ProcessThrust()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            rigid.AddRelativeForce(Vector3.up * mod * Time.deltaTime); // Time.deltaTime은 1프레임당 시간
        }
    }

    void ProcessRotation()
    {
        if (Input.GetKey(KeyCode.A))
        {
            // Ctrl + .으로 반복되는 문장을 함수로 빠르게 만들 수 있다.
            // 반복되는 문장은 다른 것만 매개변수로 받으면 좋다.
            // Ctrl + R 두 번으로 이름을 한 번에 수정할 수 있다.
            ApplyRotation(rotationSpeed);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            ApplyRotation(-rotationSpeed);
        }
    }

    private void ApplyRotation(float rotationThisFrame)
    {
        // 비트연산이라 더하면 xy 값 물리적 고정과 같음
        // rigid.constraints = (RigidbodyConstraints)((int)RigidbodyConstraints.FreezeRotationX + (int)RigidbodyConstraints.FreezeRotationY);
        // 물리적으로 회전 고정
        // rigid.constraints = RigidbodyConstraints.FreezeRotation;
        
        rigid.freezeRotation = true; // 회전 값을 고정해서 수동으로 회전을 조작할 수 있게 함
        // 이게 되는 이유는 rigid(물리)충돌의 회전만 제어했을 뿐이지 transform 기반으로 한 회전은 수동으로 제어 가능 
        transform.Rotate(Vector3.forward * rotationThisFrame * Time.deltaTime);
        rigid.freezeRotation = false; // 회전 값 고정을 풀어서 물리 시스템이 적용 됨
    }
}

Rotate

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 부스트 프로젝트' 카테고리의 다른 글

유니티 오디오  (0) 2022.08.12
소스 컨트롤  (0) 2022.08.12
부스터  (0) 2022.08.03
클래스, Input 클래스  (0) 2022.08.03
유니티 유닛  (0) 2022.08.03

부스터

RigidBody.AddRelativeForce(Vector3 vec)

상대적인 힘 (특정 개체의 좌표 혹은 변형 정보를 기반으로 힘을 가함)

RigidBody.AddForce(Vector3 vec)은 절대적인 힘 (월드좌표 기준)

 

Movement.cs

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

public class Movement : MonoBehaviour
{
    private Rigidbody rigid;
    [SerializeField]
    private float mod = 100f;
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
    }

    void Update()
    {
        ProcessThrust();
        ProcessRotation();
    }

    void ProcessThrust()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            rigid.AddRelativeForce(Vector3.up * mod * Time.deltaTime); // Time.deltaTime은 1프레임당 시간
        }
    }

    void ProcessRotation()
    {
        if (Input.GetKey(KeyCode.A))
        {
            Debug.Log("rotate left");
        }
        else if (Input.GetKey(KeyCode.D))
        {
            Debug.Log("rotate right");
        }
    }

}

클래스

- 코드를 정리할 때 사용되고 비슷한 것들을 그룹화할 수 있게 해줌

- 변수와 메서드를 보관하는 매우 유용한 용기임

- 보통 여러 개의 일이 아닌 하나의 주된 일을 하도록 구성됨 => 코드를 읽기도 쉽고 문제 해결도 편하고 여러 사람이랑 프로젝트를 작업하기 편하다.

ex) 움직임, 충돌 처리기, 슈팅, 점수, 적 인공지능 등

 

유니티 내장 클래스

- 유니티가 사용하기 좋게 이미 만들어 놓은 클래스

- 클래스에 접근하면 안에 있는 컨텐츠에 접근하는 것임

- .연산자를 통해 접근한다.

ex) 

클래스이름.메서드이름();

ClassName.MethodName();

Input클래스는 플레이어가 키를 눌렀을 때 어떤 키를 눌렀는지에 대한 정보가 'Input'에 저장되어 있음

Input.anyKey // 키 입력이 들어왔는지 체크하는 프로퍼티(bool형 값)

Input.GetKeyDown(KeyCode.Space) // 플레이어가 Space를 눌렀을 때 체크하는 메서드(bool형 반환)

  

 

Input 클래스

Input.GetKey vs GetKeyDown vs GetKeyUp

// 키가 눌려졌을 때 1번
Input.GetKeyDown()

// 키를 누르고 있을 때 계속
Input.GetKey()

// 눌렀던 키를 뗐을 때 1번
Input.GetKeyUp()

 

매개변수가 다른 경우

메서드가 매개변수 형태를 둘 다 허용하는 경우다.

- 위아래 화살표로 페이지를 넘길 수 있다.

* 문자열 참조는 안 하는 게 좋다 - 오류가 생길 확률이 증가(실수)

* 만약 해당 시그니처 옵션(매개변수 형태가 보이는 창)이 사라졌을 때 Ctrl + Shift + Space를 누르면 다시 창이 뜬다.

Input.GetLKey(KeyCode)
Input.GetKey(string)

 

Movement.cs

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

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

    void Update()
    {
        // 키가 눌려졌을 때 1번
        // Input.GetKeyDown()

        // 키를 누르고 있을 때 계속
        // Input.GetKey()

        // 눌렀던 키를 뗐을 때
        // Input.GetKeyUp()

        ProcessThrust();
        ProcessRotation();
    }

    void ProcessThrust()
    {
        // Input.GetKey("Space");
        if (Input.GetKey(KeyCode.Space))
        {
            Debug.Log("Pressed SPACE - Thrusting");
        }
    }

    void ProcessRotation()
    {
        // 왼쪽으로 회전하면서 오른쪽으로 회전할 수는 없으므로
        if (Input.GetKey(KeyCode.A))
        {
            Debug.Log("rotate left");
        }


        // 여기서 else는 위의 if문에만 해당됨
        else if (Input.GetKey(KeyCode.D))
        {
            Debug.Log("rotate right");
        }
    }

}

실행

 

코드를 어디에 캡슐화 하는가?

캡슐 : 코드의 부분마다 알아야하는 기초 수준의 접근

- 모든 것이 서로에게 접근할 수 없도록 하면 좋음

ex) Movement 클래스에 있는 메서드만 움직임을 수정 할 수 있음 - 두 세개의 클래스가 움직임을 같이 처리하면 실제로 속도가 무엇이어야 하는지와 어떤 것이 진짜인지 헷갈릴 수 있음

구조

러시아 인형인 마트료시카처럼 구성됨

ex) 작은 인형이 큰 인형에 들어있고 또 그 인형이 더 큰 인형에 들어있음 == 실행문이 메서드에 들어있고 메서드는 클래스에 보관되며 클래스는 전체 시스템의 네임 스페이스에 들어간다.

 

 

유니티 유닛

만들 것

간단하게 땅을 만들고, 발사대를 만들고, 로켓과 발사대에 올라갈 착륙대를 만든다.

- 기능의 세부적인 것에 너무 많은 시간을 투자하기 전에 우선 작동하도록 만든다.

 

유니티 월드 좌표축

유니티 씬 화면의 우측 상단에 월드 좌표축이 있다.

좌표축

유니티는 1유닛을 기본 단위로 사용하는데 1유닛당 편의상 미터로 생각해도 된다. ex) 단위를 맞춰줘서 현실과 크기 비교 가능

아래는 스케일이 x,y,z로 각 1유닛씩인 트랜스폼이다. ex) 플레이어 크기가 2유닛이면 2m쯤 된다고 생각

유닛

스케일을 증가시킬 때 축의 양의 방향과 음의 방향으로 나누어 같이 증가하기 때문에 이에 대응해 이동한다면 증가한 스케일 축으로 증가한 반절 값만큼 이동하면 된다.

스케일 변화 후 이동

오브젝트 프리펩화

오브젝트 프리펩화

게임 디자인

플레이어 경험

정밀함, 기술적

핵심 매커닉

- 우주선을 능숙하게 조종해 주변의 자연 위험요소를 피하는 것

게임 루프

- 특정 레벨을 완료하려면 A에서 B로 가야하고 다음 레벨로 넘어감

- 마지막 레벨을 클리어하면 다시 처음 레벨로 돌아감

게임 테마

: 비주얼, 게임의 느낌을 이야기함

- 플레이어는 실험적인, 이전 시대의 초기 우주선임

- 모르는 행성에서 탈출하는 것

필수 요소

- 좌우 움직임

- 부스트 (중력 반대 방향)

- 움직이는 물체(장애물)

- 출발지, 도착지

 

 

양파 디자인

게임에서 가장 중요한 요소를 정하는 것 = 반드시 있어야 하는, 없이는 게임을 만들 수 없는 것이 무엇인지 보기

- 1순위 2순위 3순위 ... 가 양파처럼 층층이 쌓임

- 시간이 없으면 제일 중요한 필수적인 요소들을 만들고 멈춤

- 다음 요소를 추가해야 할지 고민할 때 그것이 핵심요소를 더 좋게 만드는지 생각해보고 결정

ex)

1순위 : 우주선 이동

2순위 : 장애물(충돌)

3순위 : 출발지, 도착지 (레벨 진행)

 

추가 요소 예시

- 연료 추가

- 총 발사

- 파워 업

 

 

'유데미 강의 > C#과 Unity로 3D 게임 개발하기 : 부스트 프로젝트' 카테고리의 다른 글

소스 컨트롤  (0) 2022.08.12
오브젝트 회전과 매개변수와 Rigidbody  (0) 2022.08.04
부스터  (0) 2022.08.03
클래스, Input 클래스  (0) 2022.08.03
유니티 유닛  (0) 2022.08.03

+ Recent posts