Search Unity

ARCore HelloWorld : Simple One Touch Gameobject Active

Discussion in 'AR' started by SyedImranUnity, Apr 4, 2018.

  1. SyedImranUnity

    SyedImranUnity

    Joined:
    Apr 4, 2018
    Posts:
    16
    Hello,
    I runs demo app of AR Core Hello World with tracking area. Its worked good but user's when multiple clicks, its shows multiple Andy (Android) simultaneously. Now, I want to know "how can i stop multiple touches in my app ?" that's my queries. I want to show one click for one Andy (Android) game object. I hope for best solution for my query.

    Please find out on below screenshot.


    Thanks for Advance...........!!!!!
    Screenshot (23).png
     
    hako-975 and V-J like this.
  2. Deleted User

    Deleted User

    Guest

  3. K0n0

    K0n0

    Joined:
    Oct 29, 2014
    Posts:
    27
    I wanted to do the same thing recently so I changed the HelloARController script with the help of this video:


    Basically, you will have to place the 'Spawn' code in a separate method which will be called from the LeanFinger script.
    You will have to install the LeanTouch plugin (free on the asset store) for it to work.

    Keep in mind that the HelloARController script used in this video has been updated, my script is a bit different in order to comply with the latest update. I'm pasting it below for your reference.

    Ps, I'm quite a noob, the code may not be perfect and there's some unnecessary stuff in there (mostly for testing purposes). Let me know if you need more help though.

    Code (CSharp):
    1. //-----------------------------------------------------------------------
    2. // <copyright file="HelloARController.cs" company="Google">
    3. //
    4. // Copyright 2017 Google Inc. All Rights Reserved.
    5. //
    6. // Licensed under the Apache License, Version 2.0 (the "License");
    7. // you may not use this file except in compliance with the License.
    8. // You may obtain a copy of the License at
    9. //
    10. // http://www.apache.org/licenses/LICENSE-2.0
    11. //
    12. // Unless required by applicable law or agreed to in writing, software
    13. // distributed under the License is distributed on an "AS IS" BASIS,
    14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15. // See the License for the specific language governing permissions and
    16. // limitations under the License.
    17. //
    18. // </copyright>
    19. //-----------------------------------------------------------------------
    20.  
    21. namespace GoogleARCore.HelloAR
    22. {
    23.     using System.Collections.Generic;
    24.     using GoogleARCore;
    25.     using UnityEngine;
    26.     using UnityEngine.UI;
    27.     using UnityEngine.Rendering;
    28.     using Lean.Touch;
    29.  
    30.  
    31. #if UNITY_EDITOR
    32.     using Input = InstantPreviewInput;
    33. #endif
    34.  
    35.     /// <summary>
    36.     /// Controls the HelloAR example.
    37.     /// </summary>
    38.     public class HelloARController : MonoBehaviour
    39.     {
    40.         /// <summary>
    41.         /// The first-person camera being used to render the passthrough camera image (i.e. AR background).
    42.         /// </summary>
    43.         public Camera FirstPersonCamera;
    44.  
    45.         /// <summary>
    46.         /// A prefab for tracking and visualizing detected planes.
    47.         /// </summary>
    48.         public GameObject TrackedPlanePrefab;
    49.  
    50.         /// <summary>
    51.         /// A model to place when a raycast from a user touch hits a plane.
    52.         /// </summary>
    53.         public GameObject AndyAndroidPrefab;
    54.  
    55.         /// <summary>
    56.         /// A gameobject parenting UI for displaying the "searching for planes" snackbar.
    57.         /// </summary>
    58.         public GameObject SearchingForPlaneUI;
    59.  
    60.         /// <summary>
    61.         /// A list to hold new planes ARCore began tracking in the current frame. This object is used across
    62.         /// the application to avoid per-frame allocations.
    63.         /// </summary>
    64.         private List<TrackedPlane> m_NewPlanes = new List<TrackedPlane>();
    65.  
    66.         /// <summary>
    67.         /// A list to hold all planes ARCore is tracking in the current frame. This object is used across
    68.         /// the application to avoid per-frame allocations.
    69.         /// </summary>
    70.         private List<TrackedPlane> m_AllPlanes = new List<TrackedPlane>();
    71.  
    72.         /// <summary>
    73.         /// True if the app is in the process of quitting due to an ARCore connection error, otherwise false.
    74.         /// </summary>
    75.         private bool m_IsQuitting = false;
    76.  
    77.         /// insert new class here
    78.  
    79.             public void Spawn(LeanFinger finger)
    80.         {
    81.             // Raycast against the location the player touched to search for planes.
    82.             TrackableHit hit;
    83.             TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
    84.                 TrackableHitFlags.FeaturePointWithSurfaceNormal;
    85.  
    86.             if (Frame.Raycast(finger.ScreenPosition.x, finger.ScreenPosition.y, raycastFilter, out hit))
    87.             {
    88.  
    89.                 Debug.Log("########Touch########");
    90.                 // andyText.text = "Touch";
    91.                 if (currentNumberOfObjects < numberOfObjectsAllowed)
    92.                 {
    93.                    // andyText.text = "Touch =" + currentNumberOfObjects + " + " + numberOfObjectsAllowed;
    94.  
    95.                     currentNumberOfObjects = currentNumberOfObjects + 1;
    96.                     andyObject = Instantiate(AndyAndroidPrefab, hit.Pose.position, hit.Pose.rotation);
    97.  
    98.                     // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    99.                     // world evolves.
    100.                     var anchor = hit.Trackable.CreateAnchor(hit.Pose);
    101.  
    102.  
    103.                     //   Andy should look at the camera but still be flush with the plane.
    104.                     if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None)
    105.                     {
    106.                         // Get the camera position and match the y-component with the hit position.
    107.                         Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
    108.                         cameraPositionSameY.y = hit.Pose.position.y;
    109.  
    110.                         // Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
    111.                         andyObject.transform.LookAt(cameraPositionSameY, andyObject.transform.up);
    112.                     }
    113.  
    114.                     // Make Andy model a child of the anchor.
    115.                     andyObject.transform.parent = anchor.transform;
    116.                 }
    117.                
    118.                 else
    119.                 {
    120.                     andyObject.GetComponent<moveObject>().StartMove(hit.Pose.position);
    121.                 }
    122.                
    123.             }
    124.  
    125.         }
    126.  
    127.  
    128.  
    129.  
    130.  
    131.  
    132.         /// <summary>
    133.         /// The Unity Update() method.
    134.         /// </summary>
    135.         ///
    136.  
    137.         /// from tut, set max number of objects.
    138.         public int numberOfObjectsAllowed = 5;
    139.         public int currentNumberOfObjects = 0;
    140.  
    141.         public Text andyText;
    142.  
    143.         public GameObject andyObject;
    144.  
    145.        
    146.         public void Update()
    147.         {
    148.             if (Input.GetKey(KeyCode.Escape))
    149.             {
    150.                 Application.Quit();
    151.             }
    152.  
    153.             _QuitOnConnectionErrors();
    154.  
    155.             // Check that motion tracking is tracking.
    156.             if (Session.Status != SessionStatus.Tracking)
    157.             {
    158.                 const int lostTrackingSleepTimeout = 15;
    159.                 Screen.sleepTimeout = lostTrackingSleepTimeout;
    160.                 if (!m_IsQuitting && Session.Status.IsValid())
    161.                 {
    162.                     SearchingForPlaneUI.SetActive(true);
    163.                 }
    164.  
    165.                 return;
    166.             }
    167.  
    168.             Screen.sleepTimeout = SleepTimeout.NeverSleep;
    169.  
    170.             // Iterate over planes found in this frame and instantiate corresponding GameObjects to visualize them.
    171.             Session.GetTrackables<TrackedPlane>(m_NewPlanes, TrackableQueryFilter.New);
    172.             for (int i = 0; i < m_NewPlanes.Count; i++)
    173.             {
    174.                 // Instantiate a plane visualization prefab and set it to track the new plane. The transform is set to
    175.                 // the origin with an identity rotation since the mesh for our prefab is updated in Unity World
    176.                 // coordinates.
    177.                 GameObject planeObject = Instantiate(TrackedPlanePrefab, Vector3.zero, Quaternion.identity,
    178.                     transform);
    179.                 planeObject.GetComponent<TrackedPlaneVisualizer>().Initialize(m_NewPlanes[i]);
    180.             }
    181.  
    182.             // Disable the snackbar UI when no planes are valid.
    183.             Session.GetTrackables<TrackedPlane>(m_AllPlanes);
    184.             bool showSearchingUI = true;
    185.             for (int i = 0; i < m_AllPlanes.Count; i++)
    186.             {
    187.                 if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
    188.                 {
    189.                     showSearchingUI = false;
    190.                     break;
    191.                 }
    192.             }
    193.  
    194.             SearchingForPlaneUI.SetActive(showSearchingUI);
    195.  
    196.             // If the player has not touched the screen, we are done with this update.
    197.             Touch touch;
    198.             if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
    199.             {
    200.              
    201.                 return;
    202.             }
    203.  
    204.             /*
    205.             // Raycast against the location the player touched to search for planes.
    206.             TrackableHit hit;
    207.             TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
    208.                 TrackableHitFlags.FeaturePointWithSurfaceNormal;
    209.  
    210.             if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
    211.             {
    212.                
    213.                 Debug.Log("########Touch########");
    214.                // andyText.text = "Touch";
    215.                 if (currentNumberOfObjects < numberOfObjectsAllowed)
    216.                 {
    217.                     andyText.text = "Touch ="+ currentNumberOfObjects + " + " + numberOfObjectsAllowed;
    218.  
    219.                     currentNumberOfObjects = currentNumberOfObjects + 1;
    220.                     andyObject = Instantiate(AndyAndroidPrefab, hit.Pose.position, hit.Pose.rotation);
    221.  
    222.                     // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    223.                     // world evolves.
    224.                     var anchor = hit.Trackable.CreateAnchor(hit.Pose);
    225.  
    226.  
    227.                  //   Andy should look at the camera but still be flush with the plane.
    228.                       if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None)
    229.                       {
    230.                          // Get the camera position and match the y-component with the hit position.
    231.                          Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
    232.                          cameraPositionSameY.y = hit.Pose.position.y;
    233.                  
    234.                           // Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
    235.                           andyObject.transform.LookAt(cameraPositionSameY, andyObject.transform.up);
    236.                       }
    237.                  
    238.                     // Make Andy model a child of the anchor.
    239.                     andyObject.transform.parent = anchor.transform;
    240.                 }
    241.  
    242.                else
    243.                {
    244.                    andyObject.GetComponent<moveObject>().StartMove(hit.Pose.position);
    245.                }
    246.             }
    247.  
    248.             */
    249.         }
    250.  
    251.         /// <summary>
    252.         /// Quit the application if there was a connection error for the ARCore session.
    253.         /// </summary>
    254.         private void _QuitOnConnectionErrors()
    255.         {
    256.             if (m_IsQuitting)
    257.             {
    258.                 return;
    259.             }
    260.  
    261.             // Quit if ARCore was unable to connect and give Unity some time for the toast to appear.
    262.             if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
    263.             {
    264.                 _ShowAndroidToastMessage("Camera permission is needed to run this application.");
    265.                 m_IsQuitting = true;
    266.                 Invoke("_DoQuit", 0.5f);
    267.             }
    268.             else if (Session.Status.IsError())
    269.             {
    270.                 _ShowAndroidToastMessage("ARCore encountered a problem connecting.  Please start the app again.");
    271.                 m_IsQuitting = true;
    272.                 Invoke("_DoQuit", 0.5f);
    273.             }
    274.         }
    275.  
    276.         /// <summary>
    277.         /// Actually quit the application.
    278.         /// </summary>
    279.         private void _DoQuit()
    280.         {
    281.             Application.Quit();
    282.         }
    283.  
    284.         /// <summary>
    285.         /// Show an Android toast message.
    286.         /// </summary>
    287.         /// <param name="message">Message string to show in the toast.</param>
    288.         private void _ShowAndroidToastMessage(string message)
    289.         {
    290.             AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    291.             AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    292.  
    293.             if (unityActivity != null)
    294.             {
    295.                 AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
    296.                 unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    297.                 {
    298.                     AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity,
    299.                         message, 0);
    300.                     toastObject.Call("show");
    301.                 }));
    302.             }
    303.         }
    304.     }
    305. }
    306.  
     
  4. SyedImranUnity

    SyedImranUnity

    Joined:
    Apr 4, 2018
    Posts:
    16

    I Solved this problem in within a one simple script. I think i made easy to solve that. Thanks for all your response.

    Code (CSharp):
    1. namespace GoogleARCore.HelloAR
    2. {
    3.     using System.Collections.Generic;
    4.     using GoogleARCore;
    5.     using UnityEngine;
    6.     using UnityEngine.Rendering;
    7.  
    8. #if UNITY_EDITOR
    9.     // Set up touch input propagation while using Instant Preview in the editor.
    10.     using Input = InstantPreviewInput;
    11. #endif
    12.  
    13.     /// <summary>
    14.     /// Controls the HelloAR example.
    15.     /// </summary>
    16.     public class Controller : MonoBehaviour
    17.     {
    18.         /// <summary>
    19.         /// The first-person camera being used to render the passthrough camera image (i.e. AR background).
    20.         /// </summary>
    21.         public Camera FirstPersonCamera;
    22.  
    23.         /// <summary>
    24.         /// A prefab for tracking and visualizing detected planes.
    25.         /// </summary>
    26.         public GameObject TrackedPlanePrefab;
    27.  
    28.         /// <summary>
    29.         /// A model to place when a raycast from a user touch hits a plane.
    30.         /// </summary>
    31.         //public GameObject AndyAndroidPrefab;
    32.         //public GameObject catObject;
    33.         public GameObject m_ObjectPrefeb;
    34.         public int numberOfObjectsAllowed = 1;
    35.         private int currentNumberOfObjects = 0;
    36.         /// <summary>
    37.         /// A gameobject parenting UI for displaying the "searching for planes" snackbar.
    38.         /// </summary>
    39.         public GameObject SearchingForPlaneUI;
    40.  
    41.         /// <summary>
    42.         /// A list to hold new planes ARCore began tracking in the current frame. This object is used across
    43.         /// the application to avoid per-frame allocations.
    44.         /// </summary>
    45.         private List<TrackedPlane> m_NewPlanes = new List<TrackedPlane>();
    46.  
    47.         /// <summary>
    48.         /// A list to hold all planes ARCore is tracking in the current frame. This object is used across
    49.         /// the application to avoid per-frame allocations.
    50.         /// </summary>
    51.         private List<TrackedPlane> m_AllPlanes = new List<TrackedPlane>();
    52.  
    53.         /// <summary>
    54.         /// True if the app is in the process of quitting due to an ARCore connection error, otherwise false.
    55.         /// </summary>
    56.         private bool m_IsQuitting = false;
    57.  
    58.         /// <summary>
    59.         /// The Unity Update() method.
    60.         /// </summary>
    61.         public void Update()
    62.         {
    63.             // Exit the app when the 'back' button is pressed.
    64.             if (Input.GetKey(KeyCode.Escape))
    65.             {
    66.                 Application.Quit();
    67.             }
    68.  
    69.             _QuitOnConnectionErrors();
    70.  
    71.             // Check that motion tracking is tracking.
    72.             if (Session.Status != SessionStatus.Tracking)
    73.             {
    74.                 const int lostTrackingSleepTimeout = 15;
    75.                 Screen.sleepTimeout = lostTrackingSleepTimeout;
    76.                 if (!m_IsQuitting && Session.Status.IsValid())
    77.                 {
    78.                     SearchingForPlaneUI.SetActive(true);
    79.                 }
    80.  
    81.                 return;
    82.             }
    83.  
    84.             Screen.sleepTimeout = SleepTimeout.NeverSleep;
    85.  
    86.             // Iterate over planes found in this frame and instantiate corresponding GameObjects to visualize them.
    87.             Session.GetTrackables<TrackedPlane>(m_NewPlanes, TrackableQueryFilter.New);
    88.             for (int i = 0; i < m_NewPlanes.Count; i++)
    89.             {
    90.                 // Instantiate a plane visualization prefab and set it to track the new plane. The transform is set to
    91.                 // the origin with an identity rotation since the mesh for our prefab is updated in Unity World
    92.                 // coordinates.
    93.                 GameObject planeObject = Instantiate(TrackedPlanePrefab, Vector3.zero, Quaternion.identity,
    94.                     transform);
    95.                 planeObject.GetComponent<TrackedPlaneVisualizer>().Initialize(m_NewPlanes[i]);
    96.             }
    97.  
    98.             // Hide snackbar when currently tracking at least one plane.
    99.             Session.GetTrackables<TrackedPlane>(m_AllPlanes);
    100.             bool showSearchingUI = true;
    101.             for (int i = 0; i < m_AllPlanes.Count; i++)
    102.             {
    103.                 if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
    104.                 {
    105.                     showSearchingUI = false;
    106.                     break;
    107.                 }
    108.             }
    109.  
    110.             SearchingForPlaneUI.SetActive(showSearchingUI);
    111.  
    112.             // If the player has not touched the screen, we are done with this update.
    113.             Touch touch;
    114.             if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
    115.             {
    116.                 return;
    117.             }
    118.  
    119.             // Raycast against the location the player touched to search for planes.
    120.             TrackableHit hit;
    121.             TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
    122.                 TrackableHitFlags.FeaturePointWithSurfaceNormal;
    123.         /*//Object
    124.             if (Session.Raycast(FirstPersonCamera.ScreenPointToRay(touch.position), raycastFilter, out hit))
    125.             {
    126.                 if (currentNumberOfCats < numberOfCatsAllowed) {
    127.                     currentNumberOfCats = currentNumberOfCats + 1;
    128.                
    129.  
    130.                     // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    131.                     // world evolves.
    132.                     var anchor = Session.CreateAnchor(hit.Point, Quaternion.identity);
    133.  
    134.                     var catObject = Instantiate (m_catPrefeb, hit.Point, Quaternion.identity, anchor.transform);
    135.  
    136.                     catObject.transform.LookAt (FirstPersonCamera.transform);
    137.                     catObject.transform.rotation = Quaternion.Euler(0.0f, catObject.transform.rotation.eulerAngles.y, catObject.transform.rotation.z);
    138.                     // Make Andy model a child of the anchor.
    139.                     catObject.transform.parent = anchor.transform;
    140.                 }
    141.             }
    142.             //Object */
    143.  
    144.             if (Frame.Raycast (touch.position.x, touch.position.y, raycastFilter, out hit)) {
    145.                 if (currentNumberOfObjects < numberOfObjectsAllowed) {
    146.                     currentNumberOfObjects = currentNumberOfObjects + 1;
    147.  
    148.                     var catObject = Instantiate (m_ObjectPrefeb, hit.Pose.position, hit.Pose.rotation);
    149.  
    150.                     // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    151.                     // world evolves.
    152.                     var anchor = hit.Trackable.CreateAnchor (hit.Pose);
    153.  
    154.                     // Andy should look at the camera but still be flush with the plane.
    155.                     if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None) {
    156.                         // Get the camera position and match the y-component with the hit position.
    157.                         Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
    158.                         cameraPositionSameY.y = hit.Pose.position.y;
    159.  
    160.                         // Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
    161.                         catObject.transform.LookAt (cameraPositionSameY, catObject.transform.up);
    162.                     }
    163.  
    164.                     // Make Andy model a child of the anchor.
    165.                     catObject.transform.parent = anchor.transform;
    166.                 }
    167.             }
    168.  
    169.         }
    170.  
    171.         /// <summary>
    172.         /// Quit the application if there was a connection error for the ARCore session.
    173.         /// </summary>
    174.         private void _QuitOnConnectionErrors()
    175.         {
    176.             if (m_IsQuitting)
    177.             {
    178.                 return;
    179.             }
    180.  
    181.             // Quit if ARCore was unable to connect and give Unity some time for the toast to appear.
    182.             if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
    183.             {
    184.                 _ShowAndroidToastMessage("Camera permission is needed to run this application.");
    185.                 m_IsQuitting = true;
    186.                 Invoke("_DoQuit", 0.5f);
    187.             }
    188.             else if (Session.Status.IsError())
    189.             {
    190.                 _ShowAndroidToastMessage("ARCore encountered a problem connecting.  Please start the app again.");
    191.                 m_IsQuitting = true;
    192.                 Invoke("_DoQuit", 0.5f);
    193.             }
    194.         }
    195.  
    196.         /// <summary>
    197.         /// Actually quit the application.
    198.         /// </summary>
    199.         private void _DoQuit()
    200.         {
    201.             Application.Quit();
    202.         }
    203.  
    204.         /// <summary>
    205.         /// Show an Android toast message.
    206.         /// </summary>
    207.         /// <param name="message">Message string to show in the toast.</param>
    208.         private void _ShowAndroidToastMessage(string message)
    209.         {
    210.             AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    211.             AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    212.  
    213.             if (unityActivity != null)
    214.             {
    215.                 AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
    216.                 unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    217.                 {
    218.                     AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity,
    219.                         message, 0);
    220.                     toastObject.Call("show");
    221.                 }));
    222.             }
    223.         }
    224.     }
    225. }
    226.  

    You can use this better than of Lean touch ;).............

    Regards,
    Syed Imran
     
    mad7droid, BJosephine and K0n0 like this.
  5. K0n0

    K0n0

    Joined:
    Oct 29, 2014
    Posts:
    27
    Good to hear you found a solution!
     
    SyedImranUnity likes this.
  6. maart

    maart

    Joined:
    Aug 3, 2010
    Posts:
    82
    i get the ollowing error

    Assets\GoogleARCore\Examples\HelloAR\Scripts\HelloARController.cs(95,42): error CS0246: The type or namespace name 'TrackedPlaneVisualizer' could not be found (are you missing a using directive or an assembly reference?)

    can anyone please help?
     
  7. Riasdi

    Riasdi

    Joined:
    Jul 23, 2015
    Posts:
    1
    Este funciona muy bien
    Code (CSharp):
    1. namespace GoogleARCore.Examples.HelloAR
    2. {
    3.     using System.Collections.Generic;
    4.     using GoogleARCore;
    5.     using GoogleARCore.Examples.Common;
    6.     using UnityEngine;
    7.  
    8. #if UNITY_EDITOR
    9.     // Set up touch input propagation while using Instant Preview in the editor.
    10.     using Input = InstantPreviewInput;
    11. #endif
    12.  
    13.     /// <summary>
    14.     /// Controls the HelloAR example.
    15.     /// </summary>
    16.     public class HelloARController : MonoBehaviour
    17.     {
    18.         /// <summary>
    19.         /// The first-person camera being used to render the passthrough camera image (i.e. AR background).
    20.         /// </summary>
    21.         public Camera FirstPersonCamera;
    22.  
    23.         /// <summary>
    24.         /// A prefab for tracking and visualizing detected planes.
    25.         /// </summary>
    26.         public GameObject DetectedPlanePrefab;
    27.  
    28.         /// <summary>
    29.         /// A model to place when a raycast from a user touch hits a plane.
    30.         /// </summary>
    31.         // public GameObject AndyPlanePrefab;
    32.  
    33.         // /// <summary>
    34.         // /// A model to place when a raycast from a user touch hits a feature point.
    35.         // /// </summary>
    36.         // public GameObject AndyPointPrefab;
    37.                 public GameObject m_ObjectPrefeb;
    38.         public int numberOfObjectsAllowed = 1;
    39.         private int currentNumberOfObjects = 0;
    40.  
    41.         /// <summary>
    42.         /// A game object parenting UI for displaying the "searching for planes" snackbar.
    43.         /// </summary>
    44.         public GameObject SearchingForPlaneUI;
    45.  
    46.         /// <summary>
    47.         /// The rotation in degrees need to apply to model when the Andy model is placed.
    48.         /// </summary>
    49.         private const float k_ModelRotation = 180.0f;
    50.  
    51.         /// <summary>
    52.         /// A list to hold all planes ARCore is tracking in the current frame. This object is used across
    53.         /// the application to avoid per-frame allocations.
    54.         /// </summary>
    55.         private List<DetectedPlane> m_AllPlanes = new List<DetectedPlane>();
    56.  
    57.         /// <summary>
    58.         /// True if the app is in the process of quitting due to an ARCore connection error, otherwise false.
    59.         /// </summary>
    60.         private bool m_IsQuitting = false;
    61.  
    62.         /// <summary>
    63.         /// The Unity Update() method.
    64.         /// </summary>
    65.         public void Update()
    66.         {
    67.             _UpdateApplicationLifecycle();
    68.  
    69.             // Hide snackbar when currently tracking at least one plane.
    70.             Session.GetTrackables<DetectedPlane>(m_AllPlanes);
    71.             bool showSearchingUI = true;
    72.             for (int i = 0; i < m_AllPlanes.Count; i++)
    73.             {
    74.                 if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
    75.                 {
    76.                     showSearchingUI = false;
    77.                     break;
    78.                 }
    79.             }
    80.  
    81.             SearchingForPlaneUI.SetActive(showSearchingUI);
    82.  
    83.             // If the player has not touched the screen, we are done with this update.
    84.             Touch touch;
    85.             if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
    86.             {
    87.                 return;
    88.             }
    89.  
    90.             // Raycast against the location the player touched to search for planes.
    91.             TrackableHit hit;
    92.             TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
    93.                 TrackableHitFlags.FeaturePointWithSurfaceNormal;
    94.  
    95.             // if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
    96.             // {
    97.             //     // Use hit pose and camera pose to check if hittest is from the
    98.             //     // back of the plane, if it is, no need to create the anchor.
    99.             //     if ((hit.Trackable is DetectedPlane) &&
    100.             //         Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
    101.             //             hit.Pose.rotation * Vector3.up) < 0)
    102.             //     {
    103.             //         Debug.Log("Hit at back of the current DetectedPlane");
    104.             //     }
    105.             //     else
    106.             //     {
    107.             //         // Choose the Andy model for the Trackable that got hit.
    108.             //         GameObject prefab;
    109.             //         if (hit.Trackable is FeaturePoint)
    110.             //         {
    111.             //             prefab = AndyPointPrefab;
    112.             //         }
    113.             //         else
    114.             //         {
    115.             //             prefab = AndyPlanePrefab;
    116.             //         }
    117.  
    118.             //         // Instantiate Andy model at the hit pose.
    119.             //         var andyObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);
    120.  
    121.             //         // Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
    122.             //         andyObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);
    123.  
    124.             //         // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    125.             //         // world evolves.
    126.             //         var anchor = hit.Trackable.CreateAnchor(hit.Pose);
    127.  
    128.             //         // Make Andy model a child of the anchor.
    129.             //         andyObject.transform.parent = anchor.transform;
    130.             //     }
    131.             // }
    132.                 if (Frame.Raycast (touch.position.x, touch.position.y, raycastFilter, out hit)) {
    133.                 if (currentNumberOfObjects < numberOfObjectsAllowed) {
    134.                     currentNumberOfObjects = currentNumberOfObjects + 1;
    135.                     var catObject = Instantiate (m_ObjectPrefeb, hit.Pose.position, hit.Pose.rotation);
    136.                     // Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
    137.                     // world evolves.
    138.                     var anchor = hit.Trackable.CreateAnchor (hit.Pose);
    139.                     // Andy should look at the camera but still be flush with the plane.
    140.                     if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None) {
    141.                         // Get the camera position and match the y-component with the hit position.
    142.                         Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
    143.                         cameraPositionSameY.y = hit.Pose.position.y;
    144.                         // Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
    145.                         catObject.transform.LookAt (cameraPositionSameY, catObject.transform.up);
    146.                     }
    147.                     // Make Andy model a child of the anchor.
    148.                     catObject.transform.parent = anchor.transform;
    149.                 }
    150.             }
    151.         }
    152.  
    153.         /// <summary>
    154.         /// Check and update the application lifecycle.
    155.         /// </summary>
    156.         private void _UpdateApplicationLifecycle()
    157.         {
    158.             // Exit the app when the 'back' button is pressed.
    159.             if (Input.GetKey(KeyCode.Escape))
    160.             {
    161.                 Application.Quit();
    162.             }
    163.  
    164.             // Only allow the screen to sleep when not tracking.
    165.             if (Session.Status != SessionStatus.Tracking)
    166.             {
    167.                 const int lostTrackingSleepTimeout = 15;
    168.                 Screen.sleepTimeout = lostTrackingSleepTimeout;
    169.             }
    170.             else
    171.             {
    172.                 Screen.sleepTimeout = SleepTimeout.NeverSleep;
    173.             }
    174.  
    175.             if (m_IsQuitting)
    176.             {
    177.                 return;
    178.             }
    179.  
    180.             // Quit if ARCore was unable to connect and give Unity some time for the toast to appear.
    181.             if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
    182.             {
    183.                 _ShowAndroidToastMessage("Camera permission is needed to run this application.");
    184.                 m_IsQuitting = true;
    185.                 Invoke("_DoQuit", 0.5f);
    186.             }
    187.             else if (Session.Status.IsError())
    188.             {
    189.                 _ShowAndroidToastMessage("ARCore encountered a problem connecting.  Please start the app again.");
    190.                 m_IsQuitting = true;
    191.                 Invoke("_DoQuit", 0.5f);
    192.             }
    193.         }
    194.  
    195.         /// <summary>
    196.         /// Actually quit the application.
    197.         /// </summary>
    198.         private void _DoQuit()
    199.         {
    200.             Application.Quit();
    201.         }
    202.  
    203.         /// <summary>
    204.         /// Show an Android toast message.
    205.         /// </summary>
    206.         /// <param name="message">Message string to show in the toast.</param>
    207.         private void _ShowAndroidToastMessage(string message)
    208.         {
    209.             AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    210.             AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    211.  
    212.             if (unityActivity != null)
    213.             {
    214.                 AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
    215.                 unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    216.                 {
    217.                     AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity,
    218.                         message, 0);
    219.                     toastObject.Call("show");
    220.                 }));
    221.             }
    222.         }
    223.     }
    224. }
    225.  
     
  8. RvDKEKhWmMWRhZDxS

    RvDKEKhWmMWRhZDxS

    Joined:
    Sep 27, 2019
    Posts:
    1