Preview
- Vector
- 스크립트 간 연결
- 메서드 사용
- MonoBehaviour
- Unity Thread
- Reflection
Vector
- 개념: 크기(길이)와 방향을 나타내는 요소
- 위치는 상관 x, 모든 시작점이 원점(0,0,0) 이라고 가정하고 계산하여 좌표로 표현
[ Vector의 활용 ]
1) 위치 표현: 특정 시작점으로부터 크기와 방향에 따라 어디에 위치하는지 표현
2) 물리 표현: 특정 시작점으로부터 크기와 방향에 따라 얼마나 이동해야 하는지 표현
Vector 연산
덧셈: x좌표끼리 더하고, y좌표끼리 더함 ex) A(1, 3), B(3, 1) => C(4, 4)
뺄셈: x좌표끼리 빼고, y좌표끼리 뺌 ex) A(-2, 3), B(-3, -3) => C(1, 6)

A -> B 는 B - A, B -> A 는 A - B
곱셈: 각 좌표에 스칼라 값을 곱함 ex) A(2, 0) * 2 => B(4, 0)
참고 자료: https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab
Vector 정규화
- Vector3.normalized
- 방향만 필요하고 크기는 필요 없는 경우, 크기가 1인 단위 벡터로 만듦
- 필요에 따라 정규화된 방향 벡터에 * speed (* Time.deltaTime)으로 인스턴스 고유의 빠르기와 프레임 속도를 조절
- Vector3.magnitude
- 크기만 필요하고 방향은 필요 없는 경우, 정확한 거리 연산
오브젝트 이동 스크립트 예시
private Vector3 dir;
public float speed;
public Rigidbody rb;
private void Start()
{
dir = new Vector3(0, 0, 1);
speed = 10.0f;
}
private void FixedUpdate()
{
// 방법 1) 속도, 프레임 조절, 벡터 값 직접 조정
rb.velocity = speed * Time.fixedDeltaTime * dir;
// 방법 2) 벡터 값 바로 대입
rb.velocity = new Vector3(1, 0, 0);
}
스크립트 간 연결
Finder 오브젝트가 Target 오브젝트 찾는 방법
필드를 열어서 연결
public GameObject target0;
[SerializeField] private GameObject target1;
[SerializeField] private Target target2;
private void Awake()
{
target1.GetComponent<Target>().TargetMethod(); // 게임오브젝트형은 컴포넌트 가져오는 과정 필요
target2.TargetMethod(); // Target 타입은 바로 메서드 사용 가능
}
Find 계열 함수 사용
- 성능 부하있으므로 사용 지양
public GameObject target;
private void Start()
{
target = GameObject.Find("Target");
target = GameObject.FindWithTag("Target");
}
Find: 활성화 된 Scene의 모든 GameObject 중 인자로 받은 문자열과 일치하는 이름의 GameObject 반환
FindWithTag: Tag가 있는 GameObject 중 인자로 받은 문자열과 일치하는 이름의 GameObject 반환
* Find보다는 FindWithTag가 빠르므로 Find 계열 불가피하게 사용 시에 권장
메서드 사용
다른 클래스의 private 메서드 사용 (SendMessage)
using UnityEngine;
public class Finder : MonoBehaviour
{
public Target target;
private void Start()
{
// ERROR! 다른 클래스에서 private으로 보호된 메서드 접근 불가
// target.catch();
// SendMessage 방식으로는 가능
target.SendMessage("Catch");
}
}
using UnityEngine;
public class Target : MonoBehaviour
{
private void Catch()
{
Debug.Log("GOTCHA!");
}
}
MonoBehavior를 상속하는 모든 GameObject에 사용 가능
해당 GameObject의 메서드를 전부 탐색하고 인자로 받은 문자열과 이름이 일치하는 메서드 있으면 호출
성능 부하 크고, 디버깅 시 중단점 안잡히고, 객체지향을 무시하는 방식이므로 사용 지양
(애니메이션 클립 생성해서 메서드 추가할 때는 어쩔 수 없이 사용, 현재 다른 방법 없음)
MonoBehaviour
- 기본적으로 모든 Unity 스크립트가 파생되는 기본 클래스
- 에디터에서 게임 오브젝트에 스크립트를 연결할 수 있는 프레임워크를 제공
- Start, Update 등과 같은 유용한 이벤트에 대한 연결을 제공
참고 자료: https://docs.unity3d.com/kr/2022.3/Manual/class-MonoBehaviour.html
Unity Thread
Q. Unity는 단일스레드인가 멀티스레드인가?
A. 관점의 차이. but 현재까지는 단일스레드라고 봄.
이유
1) 유니티 엔진 자체는 멀티스레드로 동작하나 개발자에게 제공되는 환경은 단일스레드로 동작
2) Job System이나 Awaitable 을 사용해 비동기로 만들 수 있지만 추가적으로 조치를 취해야한다는 점에서 기본적으로는 동기라고 볼 수 있음
3) Coroutine은 비동기처럼 보이지만 사실은 동기로 동작하므로 비동기가 아님
Reflection
- 내부 코드를 검사하여 활용할 수 있게 만드는 기능
- 성능 부하 매우 심하므로 사용 지양, Runtime에서는 절대 사용 X
- Unity 생명 주기 함수 최초 등록 시에 사용될 것으로 추측,
처음 등록은 클래스 내의 Event 함수를 Reflection으로 찾아 등록하고 이를 배열로 저장해 순환시키며 동작
Reflection을 활용해 다른 클래스에서 private로 보호된 변수 사용하는 예
(사용 예시일 뿐 사용 최대한 지양하기)
using System.Reflection;
using UnityEngine;
public class Finder : MonoBehaviour
{
public Target target;
private void Start()
{
var t = target.GetType();
var fields = t.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (var field in fields)
{
var secertNum = field.GetValue(target);
Debug.Log($"{field.Name} value is : {secertNum}");
}
}
}
using UnityEngine;
public class Target : MonoBehaviour
{
private float secretNum = 11.23f;
}
'내일배움캠프 > TIL' 카테고리의 다른 글
| [내배캠][Unity6기][TIL] ObjectPool (0) | 2024.11.27 |
|---|---|
| [내배캠][Unity6기][TIL] 최종 프로젝트 기획 (0) | 2024.11.26 |
| [내배캠][Unity6기][TIL] 최종 프로젝트 시작 (0) | 2024.11.25 |
| [내배캠][Unity6기][TIL] 11.22 최종 프로젝트에 임하는 자세 (0) | 2024.11.24 |
| [내배캠][Unity6기][TIL] Unity 심화 주차 개인 과제 리뷰 (0) | 2024.11.14 |