Skip to content

Instantly share code, notes, and snippets.

@canxerian
Last active August 13, 2022 21:04
Show Gist options
  • Save canxerian/a9ecd20abba2257bb078331d23842128 to your computer and use it in GitHub Desktop.
Save canxerian/a9ecd20abba2257bb078331d23842128 to your computer and use it in GitHub Desktop.
Unity component for placing a target gameobject on a plane. Raycasts from the center of the screen
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
/// <summary>
/// Component for placing a target gameobject on a plane. Raycasts from the center of the screen.
/// </summary>
public class ARPlanePlacement : MonoBehaviour
{
[SerializeField]
[Tooltip("The target game object that we're trying to place")]
private Transform target;
[SerializeField]
[Tooltip("Y Offset from the AR Plane. Useful for avoiding occlusion artifacts")]
private float yOffset = 0.05f;
[SerializeField]
[Tooltip("ARRaycastManager. Usually attached to the AR Session Origin")]
private ARRaycastManager raycastManager;
[SerializeField]
[Tooltip("ARPlaneManager. Usually attached to the AR Session Origin")]
private ARPlaneManager planeManager;
private List<ARRaycastHit> hits = new List<ARRaycastHit>();
private Vector2 screenPos;
private bool isPlacing = true;
public void TogglePlacement()
{
isPlacing = !isPlacing;
planeManager.enabled = isPlacing;
foreach (var plane in planeManager.trackables)
{
plane.gameObject.SetActive(isPlacing);
}
}
private void Start()
{
screenPos = new Vector2(Screen.width / 2f, Screen.height / 2f);
}
private void LateUpdate()
{
if (isPlacing && Raycast(out Pose pose))
{
pose.position.y += yOffset;
target.SetPositionAndRotation(pose.position, pose.rotation);
}
}
/// <summary>
/// Perform a AR Raycast against an AR plane
/// </summary>
/// <param name="pose">Pose of the raycast hit, if successful</param>
/// <returns>True if raycast succeeded</returns>
private bool Raycast(out Pose pose)
{
if (raycastManager.Raycast(screenPos, hits))
{
foreach (ARRaycastHit hit in hits)
{
if ((hit.hitType & TrackableType.Planes) != 0)
{
ARPlane plane = planeManager.GetPlane(hit.trackableId);
pose = hit.pose;
return true;
}
}
}
pose = Pose.identity;
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment