[20260120] AssetStore / Raycast / UI

SmartBear·2026년 1월 20일

Asset Store

  • 아주 활발한하고 큰 마켓
  • 라이선스에 주의하자
    • 개인 라이선스 vs 기업 라이선스
      • 당연하지만 기업라이선스는 비싸다.
      • 개인 라이선스라도 상용 불가인 것도 있으니 주의해야 한다.
  • 유니티 버전이나 빌드 종류도 주의 필요
    • 버전 6 부터는 기본으로 Built-in이 아닌 Universal 이기 때문에 주의 필요.
  • 에셋은 기본적인 데이터 뿐만 아니라 프로젝트 내 여러 설정을 같이 건드는 것들도 있으니 주의 필요.
  • 즉, 에셋을 사용하는 것도 좋지만 사용하기 전 여러가지 잘 확인하자.

에셋에 기능 구현도 있는 것들도 있지만 지금은 그런 것들은 사용 하지 말자

Raycast

  • 가상의 레이저를 쏴서 뭔가 닿는지 확인하는 메커니즘
  • 기준은 충돌체
  • FPS 뿐만 아니라 마우스로 컨트롤(RTS 같은)에도 많이 사용
  • 레이저가 닿는 거리에 대한 계산을 잘 해야 한다. 그렇지 않으면 무한한 거리만큼을 계산하게 되어 연산이 조금 많이 무거워 질 수 있다.

Raycast 사용시 많이 사용하는 함수, 프로퍼티 등

// Ray 정의
ray = new Ray(시작, 방향);

// 카메라기준 스크린에 보이는 특정 포인트에 Ray 를 발사!
// Input.mousePosition ; 현재 마우스 포인터의 위치를 받아온다
ray = cam.ScreenPointToRay(Input.mousePosition); 

// 단일 ray 에 대한 충돌 감지. 
bool res = Physics.Raycast(ray, out hit, range, ...); 
// ray 가 감지한 다수의 충돌체에 대한 감지. RaycastHit 배열을 받음. 매번 배열 생성.
RaycastHit[] resArry = Physics.RaycastAll(ray, range, ... ); 
// 참조값을 리턴. 생성한 배열을 재사용. 메모리 사용이 조금 더 절약됨.
int res = Physics.RaycastNonAlloc(); 

Raycast 응용

카메라 무빙

케릭터와 조금 떨어진 엥글을 갖는 뷰에서 User 뒤에 벽이 있는 경우 카메라가 조금 더 앞으로 나오는 경우가 있다.
이에 대해여 Raycast 를 통해 간단히 구현이 가능하다

참고로, 일반적으로는 카메라 관련은 LateUpdate에서 호출 하는 것이 좋다.

메커니즘은, 플레이어 오브젝트에서 카메라방향으로 Ray 를 쏘는데 뭔가가 중간에 닿으면
Ray 의 방향을 기준으로 현재 충돌이 되고 있는 Position 만큼 카메라를 (자연스럽게) 땡겨오면 된다.

// 아래 코드는 대략 이런 느낌이라는 것이다. 참고만 하자.
Vector3 direction = (_cameraPoint.position - transform.position).normalized;
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance, _speed);
_camera.transform.position = transform.position + direction * _currentDistance;
_camera.transform.LookAt(transform.position);

_ray = new Ray(transform.position, direction);
RaycastHit hit;
if (Physics.Raycast(_ray, out hit, _maxDistance, _targetLayerMask))
{
    _targetDistance = hit.distance;
}
else
{
    _targetDistance = _maxDistance;
}
  • Mathf❓; 수학적인 함수 컬렉션이다. 쉽게 수학적인 내용에 대한 결과값을 받아낼 수 있다. 링크
    • Lerp(float a, float b, float t): a를 시작으로 b까지의 t 비율 만큼의 중간값을 전달한다.
      • ex) t=0 -> return a / t=1 -> return b / t=0.5 -> return (b-a) * 0.5
    • Clamp(float a, float min, float max): a값이 min/max 사이에 있으면 a 값을, min/max 를 벗어나면 각각에 해당하는 값을 전달 한다.
      • ex) a=3, min=1, max=4 -> 3 / a=-1, min=1, max=4 -> 1 / a=5, min=1, max=4 -> 4

특이점 확인

Box 를 이용한 forward 방향의 Ray 를 갖고 있는 오브젝트를 뒤로 움직여 구 형이나 실린더, 캡슐등 완만한 곡선인 물체에 충돌 하게 되면 Box 의 표면이 아닌 조금 더 앞쪽에서 충돌이 감지됨.

관련하여 링크에 나와 있는데, 해당 페이지내 Raycasts will not detect Colliders for which the Raycast origin is inside the Collider 이 내용이 주 원인이다.

결론은 Raycast 는 내부에 origin 을 둘 경우 동작하지 않는다는 것인데,
내부에 있어도 조금 움직이다보면 동작을 한다.

이것은 경계선(Surface)와 충돌체(Collision) 간의 사람의 인식의 어긋남에서 온거라고 하는데,
아직 잘 모르겠다. 나중에 다시 알아보도록 하자 🫣

(느낌상은, 실제 눈에 보이는 것과 물리 엔진이 계산하는 값과의 간극이 있는 것으로 보인다.
아주 미시적인 것이기 때문에 큰 문제는 발생할 것으로 보이지는 않지만.... 궁금한데 어쩌겠어!)

Tip

기즈모 활용

기즈모를 통해 Raycast 의 효과를 확인하면 조금 더 편하게 개발할 수 있다

Gizmo.DrawRay(ray.origin, ray.direction * distance);

Vector3 의 두 포지션 간 거리

  • magnitude vs sqrMagnitude
    • magnitude 는 두 벡터간의 거리다.
    • sqrMagnitude 는 거리를 제곱으로 반환한다.
    • ex) (transform.position - target.position).magnitude
  • Vector3.Distance
    • 두 벡터간 거리를 반환한다.
    • ex) Vector3.Distance(transform.position, target.position)

UI Basic

  • Canvas: UI 를 그리기 위해서는 캔버스가 필히 있어야 한다. UI 는 캔버스 하위로 속해야 화면에 잘 나타난다.
    • 캔버스 생성 후 "2D" 버튼을 누르면 화면에서 비교적 쉽게 UI 설정이 가능해진다.
  • TextMeshPro: Text 를 UI 에 그리는 기능.
  • Rect Transform: 해상도 대비 UI 의 위치를 상대적으로 위치시켜주기 위한 기능.
  • Image: UI 에 그림을 그린다
    • Sprite: UI 에 그림은 그냥 PNG 를 올릴 수 없다. Sprite 화 시켜야 실제로 적용이 가능하다.
profile
Python Dev with Infra -> Game Programmer

0개의 댓글