Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.03k stars 1.13k forks source link

AR Foundation place object at a different position on Image Detection #651

Closed TheIntellify-Pankaj closed 3 years ago

TheIntellify-Pankaj commented 3 years ago

I am working on an app that spawns a model when an image is detected, I need an object to spawn at a different position and also face the camera but i am unable to do that and i am searching on all the site for this but i can't find anything so is there any way to place the 3d model on a different position on image tracking?

tdmowrer commented 3 years ago

Sure, you can do this. Spawning an object a particular position and orientation is straightforward using Instantiate. If you want it to face the camera, you can use the Quaternion.LookAt helper method.

To do this in response to a detected image, you can subscribe to the ARTrackedImageManager's trackedImagesChanged event. This event provides a list of newly detected images, among other things.

TheIntellify-Pankaj commented 3 years ago

i have tried that way but unable to achieve that so i am providing you my code so you can easily understand.

with this code, i am able to instantiate gameobject at the different positions but the gameobject is not steady as you move the device it will also move with the device.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.UI;

[Serializable]
public class ImageTargetData {
    public string imageTargetName;
    public Vector3 position;
    public Quaternion rotation;
}

public class ImageTrackingController : MonoBehaviour
{

    public ARTrackedImageManager m_ImageManager;

    [SerializeField]
    private GameObject m_ArObjectsToPlace;

    [SerializeField]
    private Vector3 m_ScaleFactor = Vector3.one;

    [SerializeField]
    private Transform rootObject;

    bool isFirstTime = false;

    GameObject m_SpawnedPrefab;
    public GameObject spawnedPrefab
    {
        get => m_SpawnedPrefab;
        set => m_SpawnedPrefab = value;
    }

    public List<ImageTargetData> Pose = new List<ImageTargetData>();

    void Start()
    {
        Init();

    }

    void Init()
    {

        m_ImageManager = GetComponent<ARTrackedImageManager>();
        m_ImageManager.requestedMaxNumberOfMovingImages = 1;
        m_ImageManager.enabled = true;

    }

    void OnEnable()
    {
        m_ImageManager.trackedImagesChanged += ImageManagerOnTrackedImagesChanged;
    }

    void OnDisable()
    {

        m_ImageManager.trackedImagesChanged -= ImageManagerOnTrackedImagesChanged;
    }

    void ImageManagerOnTrackedImagesChanged(ARTrackedImagesChangedEventArgs obj)
    {
        // added, spawn prefab
        foreach (ARTrackedImage image in obj.added)
        {
            Debug.Log("Image ready to tracked : "+image.referenceImage.guid);
        }

        // updated, set prefab position and rotation
        foreach (ARTrackedImage image in obj.updated)
        {
            // image is tracking or tracking with limited state, show visuals and update it's position and rotation
            if (image.trackingState == TrackingState.Tracking)
            {

                if (isFirstTime == false)
                {

                    Debug.Log("IMAGE TARGET NAME : " + image.referenceImage.name);

                    UI_.text = image.referenceImage.name;

                    spawnedPrefab = Instantiate(m_ArObjectsToPlace);
                    spawnedPrefab.transform.SetParent(rootObject);
                    spawnedPrefab.transform.localPosition = Vector3.zero;
                    spawnedPrefab.transform.localScale = Vector3.one;
                    spawnedPrefab.transform.localRotation = Quaternion.Euler(0, 0, 0);

                    rootObject.transform.SetPositionAndRotation(image.transform.position, image.transform.rotation);

                    rootObject.transform.position = new Vector3(0, 0, 10);

                    // spawnedPrefab.transform.localScale = new Vector3(25, 25, 25);

                    //  UI_Rot.text = "After_Position:" + rootObject.transform.position.ToString();

                    //  UI_Rot.text = ("Rotation:"  + rootObject.transform.rotation.x.ToString() +","+ rootObject.transform.rotation.y.ToString() + "," + rootObject.transform.rotation.z.ToString());

                    m_ImageManager.GetComponent<ARTrackedImageManager>().enabled = false;

                    isFirstTime = true;
                }

            }

        }

        // removed, destroy spawned instance
        foreach (ARTrackedImage image in obj.removed)
        {
           // Destroy(rootObject.gameObject);
        }
    }

    public Text UI_;

    public Text UI_Rot;

    public void ReloadScene()
    {
        isFirstTime = false;

        Destroy(spawnedPrefab);

        UI_.text = "Rescan";

        m_ImageManager.GetComponent<ARTrackedImageManager>().enabled = true;
    }
}
tdmowrer commented 3 years ago

What is rootObject?

TheIntellify-Pankaj commented 3 years ago

rootObject Parent object of spawnedPrefab.

i instantiate the spawnedPrefab and make it a child of rootObject.

tdmowrer commented 3 years ago

I understand how it is used in your code, but I was asking what it is set to in the inspector.

However, this issues page is more suitable for issues with the ARFoundation-related packages -- e.g., how to use them, or bug reporting. Your question seems less like an AR specific issue and more of a general Unity usage issue. You might want to peruse some of Unity's learning resources or try a more general Unity forum.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.