RBG-Unity 정리

임효진·2024년 7월 25일

프로젝트- 게임을 구성하는 파일(그래픽,사운드)
계층구조- 게임 오브젝트 확인 및 직접 제작
장면-실제로 우리 눈으로 확인
인스펙터- 게임 오브젝트 선택한 것을 속성 확인

  1. 계층구조에서 오른쪽 마우스 클릭으로 오브젝트 생성

Q : 뷰 이동
W : 이동 (화살표 선 누른 방향대로 이동)
E : 회전
R : 크기
T : 사각툴 크기 변환

마우스 오른쪽 : 카메라 회전
Alt + 마우스 왼쪽 : 사물 기준 카메라 축 이동
키보드 방향키 : 카메라 자유 이동ㅜ
마우스 휠: 카메라 줌,아웃

  1. C# 스크립트 준비
    프로젝트 창에 마우스 오른쪽 클릭
    Create -> C# scirpt 클릭
    파일 생성 후 더블클릭 하면 비주얼스튜디오 실행

C#프로그래밍 기초

  • 변수
    int : 정수형 데이터
    float : 숫자형 데이터 (숫자 뒤에 f붙여줘야함)
    string : 문자열 데이터 (양 끝 따옴표)
    bool : 논리형 데이터 (참/거짓)

// : 주석

  • 그룹형 변수
string[] monstars={"슬라임","사막뱀","악마"};  

시작 순번은 항상 0 부터 시작!
Debug.Log(monsters[0]);

new : 새롭게 변수를 만들겠다는 뜻 [_] 안에 숫자는 크기

string[] monsters = { '슬라임', '사막뱀', '악마' };

int[] monsterLevel = new int[3];
	monsterLevel[0] =1;
    monsterLevel[1]=6;
    monsterLevel[2]=20;
  • list
    : 기능이 축된 가변형 그룹형 변수
// List<string> items = new List<string>();

item.Add("생명물약30");
item.Add("마나물약30");

items.RemoveAt(0);

<> 안에다 자료형
변수.RemoveAt(); : 제거

  • 연산자
		int fullLevel = 99;
        isFullLevel = level == fullLevel;
        Debug.Log("용사는 만랩입니까?" + isFullLevel);

        bool isEndTutorial = level > 10;
        Debug.Log("튜토리얼이 끝난 용사입니까?" + isEndTutorial);

        int health = 30;
        int mana = 25;
        bool isBadConditon = health <= 50 || mana <= 20;
        bool isBadConditon = health <= 50 && mana <= 20;

        string condition = isBadConditon ? "나쁨" : "좋음";
        Debug.Log("용사의 상태가 나쁩니까?" + condition);

&& : and 연산자- 두 값이 모두 true일 때만 true 출력
|| : or 연산자- 두 값 중에서 하나만 true이면 true 출력
? A:B : true 일 때 A, false 일 때 B 출력

  • if문
		if (isBadConditon && items[0] == "생명물약30") 
        {
            items.RemoveAt(0);
            health += 30;
            Debug.Log("마나포션30을 사용했습니다");

        }

switch,case : 변수의 값에 따라 로직 실행

defualt : 모든 case를 통화한 후 실행

			swich(monster[1]){
           case "슬라임";
               Debug.Log("소형 몬스터 출현");
               break;

           case "악마";
               Debug.Log("소형몬스터 출현");
               break;
               
           defualt;
           	Debug.Log("???몬스터가 출현");
               break;
               
  • 반복문

    while 문

       while (health > 0)
           {
               health--;
               if (health < 0) 
                   Debug.Log("독 데미지를 입었습니다");
               else
                   Debug.Log("사망");
    
               if (health == 10)
               {
                   Debug.Log("해독제를 사용합니다");
                   break;
               }
           }
           

    for문
    : 변수를 연산하면서 로직 반복 실행

    for(연산될 변수; 조건; 연산){
    로직
    }

        for (int count=0; count < 10; count++)
        {
            health++;
            Debug.Log("붕대 치료중.." + health);
        }

for문의 최대 강점: 그룹형 변수

        for (int index=0; index < monsters.Length; index++)
        {
            Debug.Log("이 지역에 있는 몬스터: "+ monsterLevel[index]);
        }

그룹형 변수의 길이 : .Length(배열) .Count(리스트)

foreach문
: for의 그룹형 탐색 '특화' -> 확실히 더 간단함
(직접 그룹형 변수 안에 있는 아이템을 하나씩 꺼내서 사용)

        foreach(string monster in monsters)
        {
            Debug.Log("이 지역에 있는 몬스터:" + monster);
        }
  • 함수(메소드)
    : 여러가지 기능을 편리하게 사용하도록 구성된 도구

반환 자료형 함수이름 (자료형 함수가 받을 변수){
로짓
retrun 받을 변수;
}

retrun: 바깥으로 함수 값을 반환할 때 사용


//star함수 바깥에 작성
    int Heal(int currenthealth)
    {
        currenthealth += 10;
        Debug.Log("힐을 받았습니다" + currenthealth);
        return currenthealth;
    }

값을 받고 반환 필요없이 함수 사용만 해도 힐 받는 구조 만들기
* void
:반환 데이터가 없는 함수타입

사용할 때 Heal(); 만 작성하면 적용

    void Heal()
    {
        //health가 start 함수 안에 있는 변수라서 사용 불가
        health += 10;
        Debug.Log("힐을 받았습니다" + health);

    }

health 같은 변수를 '지역변수( 함수 안에 선언된 변수 )'라고 함
->변수를 가장 위쪽에 선언해 '전역변수(함수 바깥에 선언)'로 만들기

  • 클래스
    :하나의 사물(오브젝트)와 대응하는 로직

public class 파일명 : ____

하나의 클래스 대응 하나의 파일

-게임에서의 배우(Actor) 파일을 만들어봄

-클래스 제외 다 제외

-중요한 데이터 변수들과 행동할 수 있을만한 함수 작성

 //배우에 들어가는 데이터들 변수 만들기, 행동할 수 있는 함수 만들기

    int id;
    string name;
    string title;
    string weapon;
    float strength;
    int level;

    string Talk()
    {
        return "대화를 걸었습니다";

    }
    string HasWeapon()
    {
        return weapon;
    }

    void LevelUp()
    {
        level = level + 1;
    }

-원래 스크립트로 돌아가 클래스를 직접 사용 가능

        Actor player = new Actor();
        player.id = 0;
        player.name = "나법사";
        player.title = "현명한";
        player.strength = 2.4f;
        player.weapon = "나무 지팡이";
        Debug.Log(player.Talk());
        Debug.Log(player.HasWeapon());

        player.LevelUp();
        Debug.Log(player.name + "의 레벨은" + player.level + "입니다");

        Debug.Log(player.move());

-클래스 이름 작성 변수명 new클래스명();
인스터스화 : 정의된 클래스를 변수 초기화롤 실체화함(클래스를 하나의 변수로 만든단 뜻)

!! 멤버변수. (player.)
하면 결과가 나오지 않음
-> 접근자 문제

왜?
배우클레스 앞에 접근자가 사실 맨 앞에 private 접근자가 생략되어 있기 때문
private: 외부 클래스에 비공개로 설치하는 접근자

따라서 public를 맴버 함수 맴버 변수에 작성
public: 외부 클래스에 공개로 설정하는 접근자

public class Actor
{
    //배우에 들어가는 데이터들 변수 만들기, 행동할 수 있는 함수 만들기

    public int id;
    public string name;
    public string title;
    public string weapon;
    public float strength;
    public int level;

    public string Talk()
    {
        return "대화를 걸었습니다";

    }
    public string HasWeapon()
    {
        return weapon;
    }

    public void LevelUp()
    {
        level = level + 1;
    }
}

만든 배우가 용사일수도 슬라임일수도 악마일수도 있음
배우라는 클래스를 가지고 또 다른 클래스를 만들 수 있음

-Player 파일을 또 만들어 봄

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

public class Player : Actor
{
    //움직이는 함수만 넣어놓기
    public string move()
    {
        return "플레이어는 움직입니다";
    }


}

-원래 작성하던 파일에서 Actor 클래스를 Player클래스로 바꿈
Actor player = new Actor(); 에서
Player player = new Player();

그 안에 멤버 변수 멤버 함수 변하지 않음!
=> 배우 클래스 안에 있는 멤버 변수 멤버 함수는 Player클래스가 물려받아 사용가능
: 상속 관계

MonoBehaviour: 유니티 게임 오브젝트 클래스

유니티 오브젝트 라이프사이클

1. 초기화 영역

* Awake 함수
:게임 오브젝트가 장면 안에 생성할 때 최초 실행

    void Awake()
    {
        //게임 안에 넣을 데이터 가져오기
        Debug.Log("플레이어 데이터가 준비되었습니다.");
    }

* start 함수
: 업데이트 시작 직전에 최초 실행

    void Start()
    {
        Debug.Log("사냥 장비를 챙겼습니다");
    }

2. 물리영역

* FixedUpdate함수
: 물리 연산 하기 전에 업데이트 하는 함수 (여러 번 작동)

특징-고정된 실행 주기로 cpu 많이 사용
(고정적으로 프레임을 계속 유지하기 때문 /약 1초에 50번)

 void FixedUpdate()
   {
       Debug.Log("이동~");

   }

3. 게임 로직 영역

* Update함수
: 게임 로직 업데이트
(물리 연산 제외 나머지 주기적으로 변하는 로직에 사용)

특징- 환경에 따라 실행 주기가 떨어질 수 있음
(1초에 약 60번인데 환경에 따라 더 느릴수도 더 빠를수도있다는 뜻)

 void Update()
   {
       Debug.Log("몬스터 사냥!!");
   }
  • LateUpdate
    : 모든 업데이트 끝난 후 마지막에 호출되는 것
    (카메라,로직의 후처리를 받는 곳)
    void LateUpdate()
       {
           Debug.Log("경험치 획득");
       }

4. 해체 영역

* OnDestroy함수
: 게임 오브젝트가 삭제되기 직전 무언가 남기고 삭제됨
(awake의 반대)

플레이어 오브젝트를 삭제했을 때 실행됨

   void OnDestroy()
   {
       Debug.Log("플레이어 데이터를 해제했습니다");
   }

1.5. 활성화

(초기화-물리 사이에 위치)

* OnEable함수
: 게임 오브젝트가 활성화 되었을 때
(최초 1회 실행이 아닌 끄고 킬 때마다 활성화 됨)

 void OnEnable()
   {
       Debug.Log("플레이어가 로그인 되었습니다");
   }

3.5. 비활성화

(게임로직-해체 사이에 위치)

* OnDisable함수
: 게임 오브젝트가 비활성화 되었을 때

void OnDisable()
   {
       Debug.Log("플레이어가 로그아웃 되었습니다");
   }

키보드 마우스로 이동

1. 키보드,마우스 입력

  • input: 게임 내 입력을 관리하는 클래스

anyKeyDown: 아무 입력 최초로 받을 때 true
(아무 키를 눌러도 호출이 된다, return값은 불 사용)

 void Update()
    {
        if (Input.anyKeyDown)
            Debug.Log("플레이어가 아무 키를 눌렀습니다");
    }
    

-> 게임 화면창에 아무 클릭 하면 출력

  • anyKey: 아무입력 받으면 true

-> 게임 화면창 계속 누르고 있으면 증가

GetKey: 키보드 입력 받으면 true

1.눌렀을 때 -> GetKeyDown
2. 누르고 가만히 있을 때 -> GetKey
3. 누르고 뗐을 때-> GetKeyUp


//Return은 키보드 상 엔터를 말함 !!
        if (Input.GetKeyDown(KeyCode.Return))
            Debug.Log("아이템을 구입하였습니다");
            
//ESC는 escape

//키보드 방향키엔 ___Arrow

        if (Input.GetKey(KeyCode.LeftArrow))
            Debug.Log("왼쪽으로 이동중");

        if (Input.GetKeyUp(KeyCode.RightArrow))
            Debug.Log("왼쪽으로 이동중");

GetMouse: 마우스 버튼 입력 받으면 true

  1. 눌렀을 때 -> GetMouseButtonDown()
  2. 누르고 가만히 있을 때 -> GetMouseButton()
  3. 누르고 뗐을 때-> GetMouseButtonUp()


//매개변수 0,1로 받음
//0: 왼쪽 클릭    1: 오른쪽 클릭

        if (Input.GetMouseButtonDown(0))
            Debug.Log("미사일 발사!");

        if (Input.GetMouseButtonDown(0))
            Debug.Log("미사일 모으는중..");

        if (Input.GetMouseButtonUp(0))
            Debug.Log("수슈슈퍼 미사일 발사!");

2. 버튼설정

(잘 모르겟음)
1. 왼쪽 Edit 클릭
2. Project Settings 클릭
나와있는 설정된 변수 이용하기

3. 버튼 입력

GetButten: Input버튼 입력 받으면 true


// "Jump"문자열값은 위에 셋팅 변수 이용한 것임
// "Horizontal"=횡 이동 

        if (Input.GetMouseButtonDown("Jump"))
            Debug.Log("점프!");

        if (Input.GetMouseButtonDown("Jump"))
            Debug.Log("점프 모으는중..");

        if (Input.GetMouseButtonUp("Jump"))
            Debug.Log("수슈슈퍼 점프!");

4. 축 입력

GetAxis : 수평, 수직 버튼 입력받으면 float


        if (Input.GetButton("Horizontal"))
        {
            Debug.Log("횡 이동중.." + Input.GetAxis("Horizontal"));
        }

->누른 버튼 초 마다 가중치 부여

가중치 필요없고 왼쪽 오른쪽만 묻고싶다면?
: GetAxisRaw으로 변환하면 가능 !

       if (Input.GetButton("Horizontal"))
        {
            Debug.Log("횡 이동중.." + Input.GetAxisRaw("Horizontal"));
        }

: GetAxisRaw으로 변환하면 가능 !

a누르면 1 출력
d누르면 -1 출력
동시에 누르면 0 출력

5. 오브젝트 이동

오브젝트를 생성하면 무조건 transform을 생성함

transform: 오브젝트 형태에 대한 기본 컴포넌트
-위치
-회전
-크기

* Translate: 벡터값을 현재 위치에 더하는 함수

        Vector3 vec = new Vector3(0, 0.1f, 0);  
        //벡터: 방향과 그에 대한 크기 값
        transform.Translate(vec);
        //vec크기 만큼 이동시키기

void Update 함수 안에 넣으면 계속 증가하는 거임

실수값 말고 input함수 이용하여 키보드 사용

        Vector3 vec = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);  
        transform.Translate(vec);

목표지점으로 이동시키기

1. 일정한 이동

MoveTowards

(현재위치,목표위치,속도)로 구성
-> 마지막 매개변수에 미례하여 속도 증가

{
    Vector3 target = new Vector3(8, 1.5f, 0);

    void Update()
    {
        transform.position =
            Vector3.MoveTowards(transform.position, target, 2f);

    }
}

2. 부드러운 이동

SmoothDamp:

(현재위치,목표위치,참조속도,속도)로 구성
->마지막 매개변수에 반비례하여 속도 증가

        Vector3 velo = Vector3.zero;
        transform.position =
            Vector3.SmoothDamp(transform.position, target, ref velo, 0.1f);

3. 선형보간이동

(:직선 거리에 따라 선형적으로 이동)

Lerp: 선형보간, SmoothDamp보다 감속시간이 김
MoveToward와 매우 유사

마지막 매개변수에 비례하여 속도 증가 (최대값 1)

        transform.position =
            Vector3.Lerp(transform.position, target, 1f);

4. 구면보간이동

SLerp: 구면선형 보간, 호를 그리며 이동

        transform.position =
            Vector3.Slerp(transform.position, target, 0.1f);

델타타임

Time.deltaTime: 이전 프레임의 완료까지 걸린 시간

deltaTime값은 프레임이 적으면 크고, 프레임이 많으면 작음

따라서 Time.deltaTime곱하여 프레임 값이 크든 작든 나오는 값은 동일

사용법

Translate: 벡터에 곱하기

transform.Translate(Vec*Time.deltaTime);

Vector함수: 시간 매개변수에 곱하기

Vector3.Lerp(Vec1,Vec2,T*Time.deltaTime);

공부하면서 헷갈린 것

  • Too many characters in character literal 에러
    : "" 써야하는데 ''를 쓸 경우
  • 사용 안 하는 변수는 만들어 두면 경고창 뜸

  • 오브젝트는 변수 transfrom을 항상 갖고 있음 (변환 가능)

  • 스칼라: 순수한 값

  • ref: 참조 접근-> 실시간으로 바뀌는 값 적용 가능

profile
뫗팅

0개의 댓글