Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug AR Raycast VERY delayed start after scene loads

Discussion in 'AR' started by rsjowell, Mar 28, 2021.

  1. rsjowell

    rsjowell

    Joined:
    Jun 15, 2019
    Posts:
    4
    Hello, I'm working on a game where if an ARRaycast, cast every frame, hits a plane within a certain distance from the device, a button will turn green, and if not, it will stay red. My code is posted here. I also have a loading screen that covers the scene until after the Raycasts have started. However, I've found that it usually takes a number of seconds, if not minutes, for the Raycasts to start. I've Debugged the Raycast status in the scene and it doesn't turn from False to True until hundreds of frames in. The script is a component of the button, which is a UI.Button, and I import the Raycast Manager. Any thoughts?

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using Unity.Collections;
    5. using Unity.Collections.LowLevel.Unsafe;
    6. using UnityEngine;
    7. using UnityEngine.UI;
    8. using UnityEngine.XR.ARFoundation;
    9. using UnityEngine.XR.ARSubsystems;
    10.  
    11. public class MainButtonScript : MonoBehaviour
    12. {
    13.     // Start is called before the first frame update
    14.  
    15.     public Sprite redButton;
    16.     public Sprite greenButton;
    17.  
    18.     public Button colorButton;
    19.  
    20.  
    21.     public ARSessionOrigin aRSessionOrigin;
    22.     public Camera ARCamera;
    23.     ARRaycastManager raycastManager;
    24.     XRCameraSubsystem aRCameraSubsystem;
    25.     List<ARRaycastHit> hits;
    26.     XRCpuImage.ConversionParams convParams;
    27.     XRCameraSubsystem camsys;
    28.  
    29.     public GameObject confirmWindow;
    30.     public GameObject loadingWindow;
    31.  
    32.     NativeArray<byte> buffer;
    33.     XRCpuImage theImage;
    34.  
    35.     Texture2D previewTexture;
    36.  
    37.     Color currentColor;
    38.  
    39.    
    40.  
    41.     unsafe void CheckColor()
    42.     {
    43.  
    44.  
    45.         Debug.Log("capture 1");
    46.        
    47.         //imgSize = theImage.GetConvertedDataSize(convParams);
    48.         Debug.Log("capture 2");
    49.         //Debug.Log(theImage);
    50.         buffer = new NativeArray<byte>(theImage.GetConvertedDataSize(convParams), Allocator.Temp);
    51.         Debug.Log("capture 3");
    52.         //previewImgBuffer = new NativeArray<byte>(imgSize, Allocator.Temp);
    53.         theImage.Convert(convParams, new IntPtr(buffer.GetUnsafePtr()), buffer.Length);
    54.         Debug.Log("capture 4");
    55.         //imgPlane = theImage.GetPlane(0);
    56.         theImage.Dispose();
    57.         Debug.Log("capture 5");
    58.         //previewImgBuffer = buffer;
    59.         previewTexture.LoadRawTextureData(buffer);
    60.         Debug.Log("capture 5");
    61.         previewTexture.Apply();
    62.         buffer.Dispose();
    63.  
    64.  
    65.  
    66.  
    67.         float newR = 0f;
    68.         float newG = 0f;
    69.         float newB = 0f;
    70.         int count = 0;
    71.         Debug.Log("blooo" + previewTexture.width + " " + previewTexture.height);
    72.  
    73.  
    74.         Color[] frameColors = previewTexture.GetPixels((int)(previewTexture.width * 0.4), (int)(previewTexture.height * 0.4), (int)(previewTexture.width * 0.2), (int)(previewTexture.height * 0.2));
    75.         Debug.Log("Frame " + frameColors.Length);
    76.  
    77.  
    78.  
    79.         foreach (Color currentColor in frameColors)
    80.         {
    81.             newR += currentColor.r;
    82.             newG += currentColor.g;
    83.             newB += currentColor.b;
    84.             count++;
    85.         }
    86.  
    87.  
    88.  
    89.         currentColor = new Color(newR / (count * 0.65f), newG / (count * 0.65f), newB / (count * 0.65f));
    90.         colorButton.GetComponent<Image>().color = currentColor;
    91.     }
    92.  
    93.  
    94.     void Start()
    95.     {
    96.         raycastManager = aRSessionOrigin.GetComponent<ARRaycastManager>();
    97.         //aRCameraSubsystem = aRSessionOrigin.gameObject.transform.GetChild(0).gameObject.GetComponent<ARCameraManager>().subsystem;
    98.         camsys = ARCamera.GetComponent<ARCameraManager>().subsystem;
    99.         hits = new List<ARRaycastHit>();
    100.         GetComponent<Button>().onClick.AddListener(delegate
    101.         {
    102.             confirmWindow.SetActive(true);
    103.             confirmWindow.GetComponent<ConfirmTargetScript>().ConfigureWindow(-1, currentColor, previewTexture.GetRawTextureData());
    104.  
    105.         });
    106.  
    107.         //currentTargets = new List<SpyTarget>();
    108.        
    109.  
    110.         convParams = new XRCpuImage.ConversionParams
    111.         {
    112.             // Get the entire image.
    113.             inputRect = new RectInt(Screen.width / 4, Screen.height / 4, Screen.height, Screen.width),
    114.  
    115.             // Downsample by 2.
    116.             outputDimensions = new Vector2Int(Screen.height, Screen.width),
    117.  
    118.             // Choose RGBA format.
    119.             outputFormat = TextureFormat.RGBA32,
    120.  
    121.             // Flip across the vertical axis (mirror image).
    122.             //transformation = CameraImageTransformation.MirrorY
    123.         };
    124.  
    125.         previewTexture = new Texture2D(convParams.outputDimensions.x, convParams.outputDimensions.y, convParams.outputFormat, false);
    126.     }
    127.  
    128.     // Update is called once per frame
    129.     void Update()
    130.     {
    131.  
    132.      
    133.         Debug.Log("Dimens "+theImage.width);
    134.      
    135.  
    136.         Debug.Log("Raycast status "+ raycastManager.Raycast(new Vector2(Screen.width / 2, Screen.height / 2 + 220),hits));
    137.         //Debug.Log("Update Loop "+hits);
    138.         if (raycastManager.Raycast(new Vector2(Screen.width / 2, Screen.height / 2 + 220), hits,TrackableType.PlaneWithinInfinity))
    139.         {
    140.  
    141.             loadingWindow.SetActive(false);
    142.             Debug.Log("it started");
    143.             Debug.Log("Hits "+hits[0].distance + " " + hits[0].trackable.GetType());
    144.             if(hits.Count == 2)
    145.             {
    146.                 Debug.Log("Hits2 " + hits[1].distance);
    147.             }
    148.             if (hits[0].distance < 1.0f)
    149.             {
    150.                 Debug.Log("Yup" + hits);
    151.                 GetComponent<Image>().sprite = greenButton;
    152.                 GetComponent<Button>().interactable = true;
    153.             }
    154.  
    155.             else
    156.             {
    157.                 Debug.Log("Nope " + hits.Count);
    158.                 GetComponent<Image>().sprite = redButton;
    159.                 GetComponent<Button>().interactable = false;
    160.             }
    161.  
    162.  
    163.  
    164.         }
    165.  
    166.         camsys.TryAcquireLatestCpuImage(out theImage);
    167.         CheckColor();
    168.  
    169.  
    170.  
    171.  
    172.     }
    173. }
     
  2. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,128
    Underlying AR providers should collect the environment data first to be able to raycast. This is probably the reason why you see the delay.
    The best practice is to guide the user to scan the environment for a flat surface, like here:
     
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,816
    rsjowell likes this.