유니티:컴포넌트 조작하기
- 유니티:개요
- 유니티:기본 조작
- 유니티:카메라
- 유니티:오브젝트
- 유니티:코딩기초
- 유니티:UI
- 유니티:게임 내 화면
- 유니티:플레이어
- 유니티:맵
- 유니티:씬
- 유니티:몬스터
- 유니티:아이템
- 유니티:음향
- 유니티:빌드
- 유니티:VR
- 유니티:팁
개요
코드로 오브젝트의 컴포넌트를 조작해야 할 때가 있다.
방법
드래그&드롭으로 컴포넌트 지정하기
단순하게 생각하면 스크립트의 클래스 변수에 컴포넌트를 드래그&드롭으로 컴포넌트를 넣을 수 있다.
컴포넌트 준비.
조작할 컴포넌트를 게임 오브젝트 내에 추가한다.
코드 내에서의 준비. 프로퍼티 만들기.
코드 안에서 공용 변수를 지정해주어 인스펙터 창에서 볼 수 있게 한다.
public class 클래스명 : MonoBehaviour {
public 받을타입명 받을변수명;
}
예컨대 RigidBody를 조작하고자 한다면 public RigidBody mine
형태로 익스펙터 창에서 리지드바디 컴포넌트를 끌어다 놓을 공간을 보이게 할 수 있다.
리지드바디 컴포넌트 안엔 AddForce 등 힘을 가하는 물리기능을 포함하고 있다.
위처럼 필드를 public으로 할당하면 인스펙터 창에서 편집이 가능하게 보인다.(mine이라는 필드 안에 Rigidbody라는 형태로 보임) 이를 프로퍼티라 부른다.
코드에 적용하기
- 이처럼 지정된 공용변수를 필드라 부르는데, 필드에 해당 컴포넌트를 드래그&드롭한다.(해당 컴포넌트를 접어두고 옮기면 편하다.)
- 이후, '받을변수명'을 조작함으로써 컴포넌트를 다룰 수 있다.
- 게임 오브젝트 뿐 아니라 UI요소인 Text 등도 조작이 가능하다.
코드 내에서 오브젝트 내부 컴포넌트 가져오기
드래그&드롭은 직관적이고 편하지만, 조작에 실수가 있을 수도 있고, 코드로 해결하고 싶은 경우도 있다. 그런 경우, 다음과 같이 해당 컴포넌트를 가져올 수 있다.
public class 클래스명 : MonoBehaviour {
private 받을타입명 받을변수명;
void 메서드명() {
받을변수명 = GetComponent<컴포넌트명>();
}
}
가져오고 싶은 것이 RigidBody라면 다음과 같이 작성한다.
public class Move : MonoBehaviour {
private Rigidbody playerRigidbody;
void Start() {
playerRigidbody = GetComponent<Rigidbody>();
}
}
컴포넌트를 가져올 때, 해당 컴포넌트가 없다면 null을 반환한다.
외부 오브젝트의 컴포넌트 가져오기
외부 오브젝트의 속성을 가져와 대응하는 게 필요할 때가 있다.
다음과 같이 작성하면 해당 컴포넌트를 가진 오브젝트가 target에 매칭된다.
void Start() {
target = FindObjectOfType<찾을 오브젝트 내 컴포넌트>();
position = FindObjectOfType<찾을 오브젝트 내 컴포넌트>().transform; // .문법으로 하위속성에 접근 가능하다.
example = FindObjectOfType<찾을 오브젝트 내 컴포넌트>().GetComponent<Rigidbody>(); // 이게 정석.
[컴포넌트가 아니라, 게임오브젝트 이름으로 찾아올 수는 없는 걸까;;?]
- 컴포넌트가 아닌, 오브젝트를 매칭한다는 것에 유의해야 한다.
- 이 메서드는 처리비용이 크기 때문에 start() 메서드처럼 초기에 1,2회 실행되는 메서드 안에서 사용해야 한다. Update()같은 곳에서 사용하면 처리가 크게 늦어질 수 있다.
- FindObjectOfType은 찾으면 검색을 멈추고, FindObjectsOfType은 해당 타입의 오브젝트를 모두 찾아낸다.
외부 메서드에 접근하기
void Start() {
타입 변수명 = FindObjectOfType<클래스이름>();
변수명.목표메서드();
기타
transform
트렌스폼 컴포넌트는 편의상 GetComponent를 사용할 필요 없이, transform
변수로 바로 불러올 수 있게 되어있다.
transform은 재미난 속성들을 갖고 있다.
함수 | 기능 |
---|---|
transform.position(벡터3); | 오브젝트의 위치를 지정할 수 있다.(절대좌표의 위치를 조정한다.) |
transform.Translate(벡터3); | 특정 벡터값만큼 위치값을 이동시키는 메서드가 준비되어 있다. 보통 transform.Translate(벡터3 * Time.deltaTime); 형식으로 사용한다.
이 메서드에 의한 이동은 전역공간이 아니라 지역공간을 기준으로 움직인다는 데에 유의해야 한다. 전역공간에서의 이동으로 고치고 싶다면 transform.Translate(벡터3, Space.World); 처럼 두번째 인자를 준다. |
transform.Rotation(Quaternion.Euler(벡터3)); | 오브젝트의 회전값을 지정한다.(절대좌표에 대하여) |
transform.rotation(쿼터니온); | 회전값을 넣을 땐 벡터3이 아닌, 쿼터니온(사원수)을 사용한다. 오일러 각을 사용할 때 발생하는 짐벌락 때문이다. 쿼터니온은 유니티에서 직접 생성할 수 없게 막아두었고, 이를 위한 메서드가 준비되어 있다.Quaternion rotation = Quaternion.Euler((0, 1, 2)); // 오일러각을 쿼터니온으로 만들고, 한 번에 회전시킨다.
Vector 3 eulerAngle = rotation.eulerAngles; // 사원수를 오일러각으로 반환한다.
|
transform.Rotate(3벡터); | 보통 rotationSpeed 값을 지정하여 Update함수에 transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f); 처럼 두면 프레임당 이동속도를 볼 수 있다.(혹은 벡터 자체에 Time.daltaTime을 걸든가.)
|
transform.LookAt(트렌스폼); | 다른 객체의 트렌스폼을 받아 해당 객체를 바라보게 한다. |
transform.localPosition = 값
transform.localRotation = Quaternion.Euler(벡터3) |
어떤 오브젝트가 자식 오브젝트일때, 지역좌표계를 조작해야 하는 상황이 있다. 그 좌표계는 local 속성을 만져 조작할 수 있다. |
게임 오브젝트에 접근하기
코드 내에서 gameObject라는 변수로 게임오브젝트에 접근이 가능하다.
게임 오브젝트 활성화, 비활성화
다음과 같이 게임 오브젝트가 기본적으로 갖고 있는 메서드를 이용해 오브젝트 활성/비활성이 가능하다.
public void End() { // public으로 해주면 외부에서 이 함수에 접근할 수 있다.
gameObject.SetActive(false); // gameObject는 이 코드를 담고 있는 오브젝트를 의미한다.
}