In Augmented Reality (AR), object placement/spawning refers to positioning virtual objects or content in the user’s real-world environment or virtual space. It involves placing digital 3D objects, images, or other virtual elements onto the physical world, making them appear as if they exist in the user’s surroundings.
Object placement is a crucial aspect of AR/VR applications as it directly affects the user’s experience and immersion. The goal is to integrate virtual content with the real-world environment to create a convincing and interactive user experience.
In AR applications, object placement relies on the detection and tracking of real-world surfaces (e.g., floors, tables, walls) to ensure that virtual objects align and interact realistically with the physical world. Create a Unity AR project.
In XR origin, add the AR plane management component and include the AR default plane.
The AR raycast manager is a key component that enables raycasting in AR scenes. Raycasting is the process of projecting a ray into the scene for collision detection. It provides a unified API for working with AR across different platforms. It allows you to perform AR-aware raycasts, which means the raycast considers the real-world geometry, to determine where the ray intersects the AR scene. Add the AR raycast manager component.
You now need the object that you will spawn on the plane. Create a prefab cube and name it "SpawnableObject." Update the scale to 0.1,0.1,0.1. Create a new tag called "Spawnable" and tag it to your spawnable object and drag it into the prefab folder.
To manage the spawned object, you need a manager. For that create a new C# script with the name "SpawnableManager." The script will include the code as mentioned below.
This script enables AR-based object placement using touch input.
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.XR.ARFoundation;public class SpawnableManager : MonoBehaviour{[SerializeField]ARRaycastManager m_RaycastManager;List<ARRaycastHit> m_Hits = new List<ARRaycastHit>();[SerializeField]GameObject prefabSpawn;Camera cam;GameObject spawnObject;// Start is called before the first frame updatevoid Start(){// Initialize variablesspawnObject = null;// Find the AR Camera in the scene and get its Camera componentcam = GameObject.Find("AR Camera").GetComponent<Camera>();}// Update is called once per framevoid Update(){// Check if there are no touches on the screenif (Input.touchCount == 0)return;// Create a ray from the touch position to detect potential AR hitsRay ray = cam.ScreenPointToRay(Input.GetTouch(0).position);// Raycast from the ARRaycastManager to check for AR hitsif (m_RaycastManager.Raycast(Input.GetTouch(0).position, m_Hits)){// Check if the touch phase has begun and there is no currently selected spawnObjectif (Input.GetTouch(0).phase == TouchPhase.Began && spawnObject == null){// Check if there is a regular RaycastHit, this is used for non-AR interactionsif (Physics.Raycast(ray, out RaycastHit hit)){// If the GameObject has the "Spawnable" tag, select it as the spawnObjectif (hit.collider.gameObject.tag == "Spawnable"){spawnObject = hit.collider.gameObject;}else{// Spawn a new prefab at the AR hit position if it's not a "Spawnable" GameObjectSpawnPrefab(m_Hits[0].pose.position);}}}// If the touch phase is Moved and there is a selected spawnObjectelse if (Input.GetTouch(0).phase == TouchPhase.Moved && spawnObject != null){// Move the selected spawnObject to the AR hit positionspawnObject.transform.position = m_Hits[0].pose.position;}// If the touch phase is Ended, reset the selected spawnObject to nullif (Input.GetTouch(0).phase == TouchPhase.Ended){spawnObject = null;}}}// Instantiate the prefab at the given position and set spawnObject to the newly instantiated objectprivate void SpawnPrefab(Vector3 spawnPosition){spawnObject = Instantiate(prefabSpawn, spawnPosition, Quaternion.identity);}}
Line 6: The SpawnableManager
class is defined and inherited from MonoBehaviour
, which is the base class for Unity scripts.
Line 8 – 13: Two serialized fields are declared: m_RaycastManager
, which is of type ARRaycastManager
, and prefabSpawn
, which is of type GameObject
. Serialized fields can be set in the Unity Inspector.
Line 10: List<ARRaycastHit> m_Hits
is declared to store the AR raycast hit information.
Line 15 – 16: Two more variables are declared: cam
of type Camera
, which will store the AR camera in the scene, and spawnObject
, which will represent the currently selected spawnable object.
Line 19 – 25: In the Start
method, the spawnObject
is initialized as null, and the AR camera component is obtained by searching for a GameObject named “AR Camera” in the scene.
Line 28 – 70: In the Update
method, the code checks if there are any touches on the screen. If there are none, the method returns.
Line 35: A ray is created from the touch position on the screen using the AR camera’s ScreenPointToRay
method.
Line 38: The m_RaycastManager
is used to perform an AR raycast to check for AR hits and to store results in the m_Hits
list.
Line 38 – 69: Inside the AR raycast block, it checks the touch phase:
Line 41: If the touch phase has just begun (TouchPhase.Began
) and no spawnObject
is currently selected, it checks for a regular raycast hit using Physics.Raycast
.
Line 47: If the raycast hits a GameObject with the tag “Spawnable,” it sets the spawnObject
variable to the hit GameObject.
Line 54: If the raycast does not hit a “Spawnable” GameObject, it calls the SpawnPrefab
method to instantiate a new prefab at the AR hit position.
Line 59: If the touch phase is “Moved” (TouchPhase.Moved
) and there is a selected spawnObject
, it updates the position of the spawnObject
to follow the AR hit position.
Line 65: If the touch phase is “Ended” (TouchPhase.Ended
), it resets the spawnObject
to null, indicating that no object is currently selected.
Line 73 – 76: The SpawnPrefab
method takes a spawnPosition
vector as a parameter and instantiates the prefabSpawn
GameObject at that position with a default rotation (Quaternion.identity
). The newly instantiated object is then assigned to the spawnObject
variable.
In the hierarchy tab, create an empty GameObject named "SpawnManager." Drag the SpawnableManager script onto the SpawnManager. Click on SpawnManager.
In the inspector tab, drag the XR origin to the raycast manager field and your spawnable object to the spawnable prefab field. Save the scene. Connect your Android or iOS device. Go to File > Build and Run.
In AR applications, object placement is generally within the virtual environment itself. Users can interact with and manipulate virtual objects in a simulated 3D space. In this Answer, you learned how to place an object on the plane.
Free Resources