Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Ensure a prefab can be added/removed from a marker image

Discussion in 'AR' started by Temp23457, Dec 4, 2023.

  1. Temp23457

    Temp23457

    Joined:
    Jan 28, 2022
    Posts:
    6
    Hello, I have a specific functionality I wish to input in my AR scene that I am currently struggling to find a solution for. What I want to do is, when a marker is scanned, have both a prefab (that was assigned to said marker via the prefabimagepairmanager script) and a textbox be displayed on the phone and when a button is pressed, have this prefab and textbox removed from the scene. The current script I have to do this is as follows:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.XR.ARSubsystems;
    6. using UnityEngine.XR.ARFoundation;
    7. public class TreasureFound : MonoBehaviour
    8. {
    9.     private GameObject treasureImage;
    10.     private GameObject treasureText;
    11.     public static bool cathedralFound = false;
    12.     public static bool footballFound = false;
    13.     public static bool universityFound = false;
    14.     private DisplayTrophy d;
    15.     public AudioSource clip;
    16.     public GameObject foundText;
    17.     private Button closeButton;
    18.     private void Start()
    19.     {
    20.         d = GameObject.Find("ButtonController").GetComponent<DisplayTrophy>();
    21.         if(this.gameObject.tag == "Angel")
    22.         {
    23.             treasureText = GameObject.Find("CathedralContainer");
    24.             treasureText.transform.GetChild(1).gameObject.SetActive(true);
    25.             closeButton = treasureText.transform.GetChild(1).gameObject.GetComponent<Button>();
    26.             closeButton.onClick.AddListener(() => RemoveFromScene());
    27.             if (!cathedralFound)
    28.             {
    29.                 treasureImage = GameObject.Find("CathedralTreasure");
    30.                 treasureImage.SetActive(false);
    31.                 cathedralFound = true;
    32.                 clip.Play();
    33.                 Handheld.Vibrate();
    34.                 d.markersFound++;
    35.             }
    36.             else
    37.             {
    38.                 Instantiate(foundText, foundText.transform.position, foundText.transform.rotation);
    39.                 Invoke("DestroyText", 2.0f);
    40.             }
    41.             treasureText.transform.GetChild(0).gameObject.SetActive(true);
    42.         }
    43.         else if(this.gameObject.tag == "Football")
    44.         {
    45.             treasureText = GameObject.Find("FootballContainer");
    46.             treasureText.transform.GetChild(1).gameObject.SetActive(true);
    47.             closeButton = treasureText.transform.GetChild(1).gameObject.GetComponent<Button>();
    48.             closeButton.onClick.AddListener(() => RemoveFromScene());
    49.             if (!footballFound)
    50.             {
    51.                 treasureImage = GameObject.Find("FootballTreasure");
    52.                 treasureImage.SetActive(false);
    53.  
    54.                 footballFound = true;
    55.                 clip.Play();
    56.                 Handheld.Vibrate();
    57.                 d.markersFound++;
    58.             }
    59.             else
    60.             {
    61.                 Instantiate(foundText, foundText.transform.position, foundText.transform.rotation);
    62.                 Invoke("DestroyText", 2.0f);
    63.             }
    64.             treasureText.transform.GetChild(0).gameObject.SetActive(true);
    65.         }
    66.         else if(this.gameObject.tag == "Laptop")
    67.         {
    68.             treasureText = GameObject.Find("UniversityContainer");
    69.             treasureText.transform.GetChild(1).gameObject.SetActive(true);
    70.             closeButton = treasureText.transform.GetChild(1).gameObject.GetComponent<Button>();
    71.             closeButton.onClick.AddListener(() => RemoveFromScene());
    72.             if (!universityFound)
    73.             {
    74.                 treasureImage = GameObject.Find("UniversityTreasure");
    75.                 treasureImage.SetActive(false);
    76.                 universityFound = true;
    77.                 clip.Play();
    78.                 Handheld.Vibrate();
    79.                 d.markersFound++;
    80.             }
    81.             else
    82.             {
    83.                 Instantiate(foundText, foundText.transform.position, foundText.transform.rotation);
    84.                 Invoke("DestroyText", 2.0f);
    85.             }
    86.             treasureText.transform.GetChild(0).gameObject.SetActive(true);
    87.         }
    88.     }
    89.     private void RemoveFromScene() //should be called when game object is destroyed
    90.     {
    91.         treasureText.transform.GetChild(0).gameObject.SetActive(false);
    92.         treasureText.transform.GetChild(1).gameObject.SetActive(false);
    93.         Destroy(this.gameObject);
    94.     }
    95.     void DestroyText()
    96.     {
    97.         Destroy(foundText);
    98.     }
    99. }
    It must likely could be more efficient, but this script is attached to each individual prefab that is associated with each marker. In theory it should check which prefab is instantiated, find and display the relevant textbox and button and when this button is pressed, no longer display the text and destroy the current prefab. Ideally the next time the marker is scanned, it should display the same prefab and text again but also show a message to the user saying it is already scanned.

    I initially believed that the marker image might have been instantiating a copy but on testing, this clearly isn't the case. I'm trying to think how best to ensure that the prefab instantiated can both be removed from the scene and then re-instantiated later using the same marker. Is there any way to do this?
     
  2. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    956
  3. Temp23457

    Temp23457

    Joined:
    Jan 28, 2022
    Posts:
    6
    Thank you, I'll have a look later