Last active
August 13, 2022 21:04
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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