Unity TIL) 2-2

2022. 4. 1. 15:43코딩/TIL

1. 게임오브젝트 생성 방법 

메뉴에서 GameObject > Create Empty를 선택하면 Scene 뷰에 GameObject가 생성된다. 생성된 GameObject는 Transfrom 컴포넌트만 가진 빈 게임오브젝트다. 이름을 Player로 지정 

특별한 경우가 아니고서는 Transform의 속성을 (0,0,0)으로 설정하자 

 

 Hierachy 뷰에 나열된 것은 모두 게임오브젝트다. Directional Light,Main Camera도 빈 게임오브젝트에 Light와 Camera 컴포넌트를 추가한 것일 뿐 

 

2. 그룹핑 

05.Models 폴더에서 주인공으로 사용할 Player 3D 모델을 앞서 만든 Player 게임오브젝트로 드래그앤 드롭 하면 3D 모델인 Player 모델이 차일드화된다. 이렇게 차일드화된 객체는 부모 객체가 이동하면 함께 이동할 수 있게 그룹핑된다.

같은 이름으로 발생하는 혼란을 방지하기 위해 부모는 Player 차일드화된 Player 모델의 이름을 PlayerModel로 변경 

> Player와 PlayerModel을 번갈아 선택해도 Position 값이 같아야 한다.

 

* Scene 뷰에 배치한 모델이나 게임오브젝트는 항상 Transform의 Position 속성을 (0,0,0)으로 설정한 다음에 작업한다

또한 빈 게임오브젝트 하위로 다른 게임오브젝트나 3D 모델을 차일드화한 이후에도 반드시 Transform의 Position 속성을 원점으로 설정한다.

 

3. 컴포넌트 

유니티는 컴포넌트 기반 개발 방법론을 제공한다. 오브젝트에 필요한 기능을 하나씩 추가하는 방식으로 개발 속도가 빠르고 재사용성이 높은 효율적인 개발 방법론 

 

Inspector 뷰에서는 선택된 게임오브젝트에 포함된 컴포넌트를 나열하고 각 컴포넌트의 속성을 조회하거나 수정가능

ex) [Inspector] 

Main Camera 게임오브젝트명

Transform (컴포넌트명) 

Position (컴포넌트 속성)

Rotation (컴포넌트 속성)

Scale (컴포넌트 속성)

컴포넌트는 추가하거나 삭제할 수 있지만 유일하게 Transform 컴포넌트는 삭제할 수 없다. 

3차원 공간에서 해당 게임오브젝트의 위치,각도 및 스케일 속성은 반드시 있어야 하기 때문이다. 

 

4. 스크립트 생성 

Player 게임오브젝트를 이동시킬 로직을 작성할 스크립트 생성 

02.Scripts 폴더 선택 > 마우스 오른쪽 버튼 > 컨텍스트 메뉴에서 Create > C# Scripts > 이름 PlayerCtrl이라고 입력

 

스크립트는 클래스 구조와 Start,Update 함수가 포함된 기본 스크립트가 자동으로 작성된 상태다. 

Start : Update 함수가 호출되기 전에 한 번만 호출된다. 

스크립트가 활성화돼 있어야 실행된다

다른 스크립트의 모든 Awake가 모두 다 실행된 이후에 실행된다.

Update : 모든 Update 함수가 호출되고 나서 한 번씩 호출된다.

순차적으로 실행해야 하는 로직에 사용한다. 

카메라 로직 이동에 주로 사용하는 함수다.

스크립트가 활성화돼 있어야 실행된다. 

 

5. Input Class 키보드 값 받아들이기 

외부에서 들어오는 입력 소스는 키보드,마우스,모바일 터치,조이스틱 등 다양 

외부에서 들어오는 입력 값을 관리하는 클래스가 Input 클래스 

 

키 조합에 관한 정의 > InputManager에서 관리 

메뉴는 Editor > Project Settings > Input

Vertical,Horizontal,Mouse X등의 이름으로 키조합이 정의돼 있고 세부 내용을 직접 수정 가능 

미리 설정한 키 조합의 반환값은 Input.GetAxis("키 조합 이름") 함수를 이용해 가져올 수 있다. 

 

* 키보드 입력 값을 받아오는 스크립트

using UnityEngine;
using System.Collections; 

public class PlayerCtrl : MonoBehaviour {
	private float h=0.0f;
    private float v=0.0f;
    
    void start() { 
   	}
    
    void Update() { 
    	h=Input.GetAxis("Horizontal");
       	v=Input.GetAxis("Vertical");
        
		Debug.Log("H="+h.ToString());
        Debug.Log("V="+v.ToString());
       }
  }

Input.GetAxis("Horizontal")은 InputManager의 "Horizontal"에 미리 설정한 값으로 키보드의 A,D 또는 화살표키 Left,Right를 눌렀을 때 -1부터 +1까지의 값을 반환한다. 

 

Input.GetAxis("Vertical") 함수 역시 키보드의 W,S Up,Down을 눌렀을 때 -1부터 +1까지 반환한다. 

 

스크립트 작성 후에는 해당 소스를 Hierarchy 뷰의 Player 게임오브젝트로 드래그앤드롭 추가. 스크립트 역시 컴포넌트의 일종으로 해당 게임오브젝트에 추가해야만 동작한다. 

 

6. 캐릭터 이동 Translate 

실제로 Player을 움직이게 하는 로직 추가 

using UnityEngine;
using System.Collections; 

public class PlayerCtrl : MonoBehaviour {
	private float h=0.0f;
    private float v=0.0f;
    
    // 자주 사용하는 컴포넌트는 반드시 변수에 할당한 후 사용 
    private Transform tr; 
    // 이동 속도 변수 
    public float moveSpeed = 10.0f;
    
    	void Start() { 
        	//스크립트 처음에 Transform 컴포넌트 할당 
            tr = GetComponent<Transform>();
   	}
    
    void Update() { 
    	h=Input.GetAxis("Horizontal");
       	v=Input.GetAxis("Vertical");
        
		Debug.Log("H="+h.ToString());
        Debug.Log("V="+v.ToString());
        
        
       // Translate(이동 방향*속도*변위값*Time.deltaTime,기준좌표)
       tr.Translate(Vector3.forward*moveSpeed*v*Time.delateTime,Space.Self); 
       }
  }

접근지시자 public으로 선언한 변수는 다른 스크립트에서 접근할 수 있으며 Inspector 뷰에 노출되어 변수 값을 직ㅈ버 수정할 수 있다.

반대로 스크립트가 아닌 Inspector 뷰에서 설정한 값이 moveSpeed 변수의 초기값으로 설정된다 

- Inspector 뷰에서 20으로 고쳐도 스크립트에서 moveSpeed 초기값은 10.0으로 고정되어있다는 뜻

 

* Time.deltaTime은 이전 프레임부터 현재 프레임까지 걸린 시간을 의미하며 Update 함수 안에서 Transform 컴포넌트를 이용해 이동하는 로직에서는 반드시 deltaTime을 곱해야하지만 FrameRate에 상관없이 지정한 속도로 이동한다. 

* 기준좌표계

Space.Self(로컬) , Space.World(월드) 기준좌표계 인자를 생략하면 로컬 좌표를 기준으로 이동한다.

월드좌표는 3차원 공간에서 바뀌지 않는 기준이 되는 좌표 

로컬좌표는 해당 게임오브젝트의 고유 좌표 

 

7. Update 함수 

매 프레임마다 한 번씩 호출되는 함수. 항상 최적화에 주의를 기울여야 한다

ex)  게임이 실행되는 디바이스가 30프레임일 경우 update 함수는 1초에 30번씩 호출된다. 

 

update함수에서 접근해야 할 컴포넌트는 awake나 start함수에서 미리 변수에 할당한 후 update 함수에서 사용하길 권장한다

void Start() {
	tr = this.gameObject.GetComponent<Transform>();
}

Transform 컴포넌트를 tr 변수에 할당하는데 사용한 GetComponent 함수는 게임오브젝트가 가진 특정 컴포넌트를 참조할 때 사용한다. 

tr=GetComponent<Transform>();

 

8. Translate 함수 

유니티에서는 Transform.position의 해당 축의 값을 변경해 게임오브젝트를 이동시킨다. 

 

다음 예제는 Z축이 값을 매 프레임마다 1씩 증가시켜 전진시키는 스크립트다. 

void Update() { 
	transform.position+=new Vector3(0,0,1);
 }

 

 

9. 정규화벡터

벡터는 크기와 방향을 가지 데이터 타입

각 축의 크기가 1인 벡터를 단위 벡터(정규화된 벡터)라 한다. 방향만 표시되는 벡터이다 

 

Vector3.forward  Vector3(0,0,1) 

Vector3.back      Vector3(0,0,-1) 

Vector3.left        Vector3(-1,0,0)

Vector3.right      Vector3(1,0,0)

Vector3.up         Vector3(0,1,0)

Vector3.down     Vector3(0,-1,0)

~one                Vector3(1,1,1)

~zero               Vector3(0,0,0)

 

using UnityEngine;
using System.Collections; 

public class PlayerCtrl : MonoBehaviour {
	private float h=0.0f;
    private float v=0.0f;
    
    // 자주 사용하는 컴포넌트는 반드시 변수에 할당한 후 사용 
    private Transform tr; 
    // 이동 속도 변수 
    public float moveSpeed = 10.0f;
    
    	void Start() { 
        	//스크립트 처음에 Transform 컴포넌트 할당 
            tr = GetComponent<Transform>();
   	}
    
    void Update() { 
    	h=Input.GetAxis("Horizontal");
       	v=Input.GetAxis("Vertical");
        
		Debug.Log("H="+h.ToString());
        Debug.Log("V="+v.ToString());
        
        // 전후좌우 이동 방향 벡터 계산
        Vector3 moveDir = (Vector3.forward * v) + (Vector3.right *h);
        
       // Transform 클래스에 정의된 이동 관련 Translate 메서드 
       // Translate(이동 방향*속도*변위값*Time.deltaTime,기준좌표)
       tr.Translate(Vector3.forward*moveSpeed*v*Time.delateTime,Space.Self); 
       }
  }

정규화 벡터가 되려면 tr.Translate(moveDir.normalized*Time.deltaTime*moveSpped,Space.Self 가 되어야 한다