Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.04k stars 1.14k forks source link

I'm not sure what I am doing wrong... #1147

Closed kenhuang1964 closed 8 months ago

kenhuang1964 commented 9 months ago

Hey everyone, I hope you are all doing well. I have been trying to use AR Foundation to help me with navigation. My code currently detects and classifies planes, treating certain planes as obstacles. I am coming across an issue where the raycasting would give me a different label for the plane classification compared to what I see on my screen on my iphone. The warning sound for obstacles is somehow delayed I think and I can't figure out why. For example, if I am looking at a chair, it would say "Warning, table ahead." which is strange because in the world, it is clearly a chair and "Warning, table ahead." was played before, which leads me to suspect that the sound coming out is delayed somehow. Can someone please help me with this? I have been trying to figure out what is wrong all day and couldn't figure it out. Also, please feel free to give criticism on my code because this is my first time writing code in unity and C# :)

Here is my current code that is related to obstacle avoidance:

[RequireComponent(typeof(ARRaycastManager), typeof(ARPlaneManager))]
public class DistanceToPlane : MonoBehaviour
{ 
    private ARRaycastManager raycastManager;
    private ARPlaneManager planeManager;
    private float warningDistance = 0.3f;  // Distance at which the warning should trigger
    private TrackableId lastDetectedPlaneId; // ID of the last plane that was detected (used to prevent multiple warnings for the same plane)
    public AudioSource wallAudioSource;
    public AudioClip wallAudioClip;
    public AudioSource tableAudioSource;
    public AudioClip tableAudioClip;
    public AudioSource seatAudioSource;
    public AudioClip seatAudioClip;
    public AudioSource doorAudioSource;
    public AudioClip doorAudioClip;
    public AudioSource obstacleAudioSource;
    public AudioClip obstacleAudioClip;
    public AudioSource windowAudioSource;
    public AudioClip windowAudioClip;
    private AudioRecorder audioRecorder;
    public GameObject waypointPrefab;
    private List<GameObject> instantiatedSpheres = new List<GameObject>();
    private float turnThreshold = 30f; // Threshold for turning in degrees
    private float timer = 0.0f; // Timer to keep track of time --> used to execute raycasting every 1 second instead of every frame
    private float interval = 1.0f; // Execute every 1 second

    private void Awake()
    {
        raycastManager = GetComponent<ARRaycastManager>();
        planeManager = GetComponent<ARPlaneManager>();
        audioRecorder = FindFirstObjectByType<AudioRecorder>();
        wallAudioSource.clip = wallAudioClip;
        tableAudioSource.clip = tableAudioClip;
        seatAudioSource.clip = seatAudioClip;
        doorAudioSource.clip = doorAudioClip;
        obstacleAudioSource.clip = obstacleAudioClip;
        windowAudioSource.clip = windowAudioClip;
        Input.gyro.enabled = true;
    }

    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= interval)
        {
            // Determine if the user is turning
            float currentYaw = Input.gyro.attitude.eulerAngles.y;
                    if (Mathf.Abs(currentYaw) > turnThreshold)
            { // Only run raycasting when the user is not turning
                Vector2 screenCenter = new Vector2(Screen.width / 2, Screen.height / 2);
                List<ARRaycastHit> hits = new List<ARRaycastHit>();

                if (raycastManager.Raycast(screenCenter, hits, TrackableType.Planes))
                {
                    ARRaycastHit hit = hits[0];
                    if (hit.trackable.GetComponent<ARPlane>().trackingState == TrackingState.Tracking)
                    {
                        float dist = CalculateDistance(hit);
                        string label = PlaneLabel(hit);

                        if (dist <= warningDistance &&
                            hit.trackableId != lastDetectedPlaneId && label != "Floor" &&
                            label != "Ceiling")
                        {
                            lastDetectedPlaneId = hit.trackableId;
                            Debug.Log("Getting too close to a plane. Label: " + label + ", Distance: " + dist);
                            PlaySoundBasedOnLabel(label);

                           // ... rest of the code
                        }
                    }
                }
            }
            timer = 0.0f;
        }
    }

    private void InstantiateSphereAtPosition(Vector3 position)
    {
        GameObject sphere = Instantiate(waypointPrefab, position, Quaternion.identity);
        sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); // Scaling the sphere to be 0.1x its original size
        instantiatedSpheres.Add(sphere);
    }
    public void DeleteAllSpheres()
    {
        foreach (GameObject sphere in instantiatedSpheres)
        {
            Destroy(sphere);
        }
        instantiatedSpheres.Clear(); // Clear the list after deleting all spheres
    }

    private void PlaySoundBasedOnLabel(string label)
    {
        switch (label)
        {
            case "Wall":
                wallAudioSource.Play();
                break;
            case "Table":
                tableAudioSource.Play();
                break;
            case "Seat":
                seatAudioSource.Play();
                break;
            case "None":
                obstacleAudioSource.Play();
                break;
            case "Door":
                doorAudioSource.Play();
                break;
            case "Window":
                windowAudioSource.Play();
                break;
            default:
                break;
        }
    }

    private float CalculateDistance(ARRaycastHit hit)
    {
        Vector3 hitPosition = hit.pose.position;

        // Calculate horizontal distance
        Vector3 devicePosition = Camera.main.transform.position;
        Vector3 devicePositionHorizontal = new Vector3(devicePosition.x, 0, devicePosition.z);
        Vector3 hitPositionHorizontal = new Vector3(hitPosition.x, 0, hitPosition.z);
        float distance = Vector3.Distance(devicePositionHorizontal, hitPositionHorizontal);

        Debug.Log("Horizontal Distance to Plane: " + distance);
        return distance;
    }

    private string PlaneLabel(ARRaycastHit hit)
    {
        // Get the ARPlane associated with the hit
        ARPlane plane = hit.trackable as ARPlane;
        if (plane != null)
        {
            var classification = plane.classification;

            string label = GetPlaneLabel(classification);
            Debug.Log("Detected Plane Label: " + label);
            return label;
        }
        else
        {
            Debug.Log("DisplayPlaneLabel isn't working!!!!");
        }
        return "";
    }

    private string GetPlaneLabel(PlaneClassification classification)
    {
        switch (classification)
        {
            case PlaneClassification.None:
                return "None";
            case PlaneClassification.Wall:
                return "Wall";
            case PlaneClassification.Floor:
                return "Floor";
            case PlaneClassification.Ceiling:
                return "Ceiling";
            case PlaneClassification.Table:
                return "Table";
            case PlaneClassification.Seat:
                return "Seat";
            case PlaneClassification.Door:
                return "Door";
            case PlaneClassification.Window:
                return "Window";
            default:
                return "Unknown";
        }
    }
//...
andyb-unity commented 8 months ago

This question is better suited for the forums: https://forum.unity.com/forums/ar.161/. Please do not use our GitHub issues to ask for help building your project. As stated in our repo README, this GitHub issues section is for bug reports only, and we will close any issue that does not contain an official bug ID number:

AR Foundation bug reports To report a bug in AR Foundation, please file a bug. You may also submit a GitHub issue, but we will close your GitHub issue if it does not contain an official bug ID number. The best way to ensure that your issue is addressed is to file a bug using Unity's official bug reporting process.

Accordingly, I'm going to close this issue. When you post on the forums, please include your AR Foundation version number.