[Unity] Teleport Anchor Object Hover & Teleport 기능 추가
[Unity] Teleport 시 특정 좌표로 순간이동하기 (Teleport Anchor)
컨트롤러의 GripButton을 눌렀을때 컨트롤러의 Raycast가 가르키는 방향으로 Teleport(텔레포트)를 합니다. 여기서 특정 위치의 텔레포트 좌표로 이동시키고 싶어서 .. 보니까 Teleport Anchor 컴포넌트가
shapes.tistory.com
이 글에서 존재했던 문제인
1. 해당 Anchor에 Hover가 됐는지 육안으로 구분하기 어렵다.
2. Anchor로 텔레포트 시 구체가 사라지지 않는다.
이러쿵저러쿵... 맨땅에 헤딩하다 보니... 결국 해결했다!!
저는 Unity를 배우지 못하고 프로젝트를 시작하여
코드가 비효율적이거나, 잘못된 사용이 있을 수 있습니다.
지적해 주시면 감사하겠습니다.
1. 해당 Anchor에 Hover가 됐는지 육안으로 구분하기 어렵다!
진짜 많이 헤맸다..
처음에는 컨트롤러의 XR Interactor Line을 이용하여 해당 선과 Teleport Anchor 오브젝트가
Raycast를 통해 충돌 시 불투명하게 하고 충돌 해제 시 반투명하게 하려는 속셈이었는데...
반응이 느리거나 잘 동작하지 않아 골머리를 쌓던 도중...
Teleport Anchor 컴포넌트에 기본 기능이 있더라...
멘탈 와르르...( 허튼짓 한 느낌 )

Hover, Exit, Select , Teleport 등 등...
여기서 사용할 것은 Hover와 Exit만 사용하면 된다.
저는 5개의 Anchor용 구체 오브젝트를 생성하였고, 각 위치에 배치했습니다.
그리고 해당 Anchor에Teleport, Hover, Exit가 발생했을 시에 동작할 C# 스크립트도 만들었습니다.
- Anchor들을 담고 있는 Parent Object에 추가해줘야 하는 스크립트
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
namespace Anchor
{
public class AnchorController : MonoBehaviour
{
[SerializeField] private TeleportationProvider teleportationProvider;
[HideInInspector]
public GameObject prevAnchor;
void Start()
{
if (teleportationProvider != null)
{
teleportationProvider.endLocomotion += OnDeActiveAnchor;
teleportationProvider.beginLocomotion += OnActiveAnchor;
}
}
void OnDeActiveAnchor(LocomotionSystem locomotionSystem)
{
if(prevAnchor != null)
{
prevAnchor.SetActive(false);
}
}
void OnActiveAnchor(LocomotionSystem locomotionSystem)
{
if (prevAnchor != null)
{
prevAnchor.SetActive(true);
}
}
public Renderer getRenderer()
{
return prevAnchor.GetComponent<Renderer>();
}
}
}
변수명 or 함수명 | 의미 or 기능 |
teleportationProvider | 텔레포트 동작의 시작과 끝을 알기 위한 변수 |
prevAnchor | 이전에 선택한 Anchor가 있다면 다시 활성화 시키기 위한 변수 |
OnDeActiveAnchor() | 선택한 Anchor를 비활성화 시키는 함수 |
OnActiveAnchor() | 이전 Anchor를 활성화 시키는 함수 |
getRenderer() | prevAnchor의 Renderer를 반환하는 함수 |
TeleportationProvider는 LocomotionSystem을 상속받고 있고
해당 클래스에 beginLocomotion과 endLocomotion이 있습니다.
이는 해당 텔레포트 동작 시작 시 실행시키고 싶은 함수를 beginLocomotion에 += 연산자로 대입해 주고,
동작이 끝날 시에 실행시키고 싶은 함수를 endLocomotion에 += 연산자로 대입해 주시면 됩니다.
각각의 함수들이 어느 순서로 실행되는지는 마지막에 말씀드리겠습니다.
저도 LocomotionSystem에 대해 아직 자세히 공부하진 못했습니다. ㅠㅠ
더 자세한 Locomotion은 아래 주소를 참고해 주세요.
https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@2.4/manual/locomotion.html
Locomotion | XR Interaction Toolkit | 2.4.3
Locomotion The XR Interaction Toolkit package provides a set of locomotion primitives that offer the means to move around in a scene during an XR experience. These components include: An XR Origin that represents the center of the tracking space for the us
docs.unity3d.com
- 각각의 Anchor마다 추가해줘야 하는 스크립트
using UnityEngine;
using Anchor;
public class AnchorManager : MonoBehaviour
{
[SerializeField] private GameObject _anchor;
private Renderer _anchorRenderer;
private AnchorController _controller;
void Start()
{
_anchorRenderer = _anchor.GetComponent<Renderer>();
_controller = transform.parent.GetComponent<AnchorController>();
}
public void onHover()
{
Color oldColor = _anchorRenderer.material.color;
_anchorRenderer.material.color = new Color(oldColor.r, oldColor.g, oldColor.b, 1.0f);
}
public void onExit()
{
Color oldColor = _anchorRenderer.material.color;
_anchorRenderer.material.color = new Color(oldColor.r, oldColor.g, oldColor.b, 0.5f);
}
public void teleporting()
{
_controller.prevAnchor = _anchor;
}
}
변수명 or 함수명 | 기능 or 의미 |
_anchor | Anchor 오브젝트를 직렬화하여 inpector에서 받아온 Object 변수 |
_anchorRenderer | _anchor에서 renderer를 가지고 있는 변수 |
_controller | parent가 가지고 있는 AnchorController를 가지고 있는 변수 Anchor들이 공통적으로 사용하는 변수나 함수들이 담겨져 있음 |
onHover() | Anchor에 컨트롤러 호버 시 해당 Object를 불투명하게 만드는 함수 |
onExit() | Anchor에서 컨트롤러가 벗어났을 시 다시 Object를 투명하게 만드는 함수 |
teleporting() | Anchor에 텔레포트가 됐을 시 실행하는 함수 _controller에 prevAnchor 변수에 현재 Anchor 오브젝트를 대입한다. |
Anchor들을 감싸고 있는 부모가 AnchorController를 가지고 있고 해당 AnchorController에 prevAnchor는
텔레포트 시 텔레포트한 Anchor의 오브젝트를 집어넣는다.
그러면 예상에는
위 그림의 순서로 실행되서 onActiveAnchor() 에서 이전 Anchor를 다시 활성화 시키고 teleporting()에서 prevAnchor를 현재 Anchor 오브젝트로 변경한다음 onDeActiveAnchor() 에서 비활성화 하고자 하였는데
실제 실행된 순서는
이렇게 실행되서 비활성화만 되는 상황이 되어버렸다....
해결책으로 onActiveAnchor()에 있는 코드를 teleporting()에서 가장 먼저 발생시키고 onActiveAnchor()를 제거하면 될 것 같습니다.
* 결과
보시면 호버 시에는 불투명, 호버에서 벗어나면 반투명, 텔레포트 시에는 비활성화되는 것을 볼 수 있습니다.

끝!