Create a new project and import the SDK
- Open Unity Hub and create a new 3D project.
- For Unity 2019 only: Select Window > Package Manager and install the following packages:
- Multiplayer HLAPI (required by the CloudAnchors sample)
- XR Legacy Input Helpers (required by Instant Preview, which uses the
TrackedPoseDriver
)
- Import the ARCore SDK for Unity:
- Select Assets > Import Package > Custom Package.
- Select the
arcore-unity-sdk-1.14.0.unitypackage
that you downloaded. - In the Importing Package dialog, make sure that all package options are selected and click Import.
Open the sample scene
- In the Unity Project window, you can find the HelloAR sample in:
Assets/GoogleARCore/Examples/HelloAR/Scenes/
.
Configure project settings
- Go to File > Build Settings to open the Build Settings window.
- Select Android and click Switch Platform.
- In the Build Settings window, click Player Settings.
- In the Settings window, configure the following:
Setting Value Player Settings > Other Settings > Rendering Uncheck Auto Graphics API
If Vulkan is listed under Graphics APIs, remove it.Player Settings > Other Settings > Package Name Create a unique app ID using a Java package name format.
For example, usecom.
example. helloAR Player Settings > Other Settings > Minimum API Level Android 7.0 'Nougat' (API Level 24) or higher
(For AR Optional apps, the Minimum API level is 14.)Player Settings > XR Settings > ARCore Supported Enable
Build and run the sample app
- Enable developer options and USB debugging on your device.
- Connect your device to your development machine.
- In the Unity Build Settings window, click Build and Run.
Unity builds your project into an Android APK, installs it on your device, and launches it. - Move your device around until ARCore starts detecting and visualizing planes.
- Tap a plane to put an Andy Android object on it.
CODE :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GoogleARCore.Examples.HelloAR | |
{ | |
using System.Collections.Generic; | |
using GoogleARCore; | |
using GoogleARCore.Examples.Common; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
#if UNITY_EDITOR | |
// Set up touch input propagation while using Instant Preview in the editor. | |
using Input = InstantPreviewInput; | |
#endif | |
/// <summary> | |
/// Controls the HelloAR example. | |
/// </summary> | |
public class HelloARController : MonoBehaviour | |
{ | |
/// <summary> | |
/// The first-person camera being used to render the passthrough camera image (i.e. AR | |
/// background). | |
/// </summary> | |
public Camera FirstPersonCamera; | |
/// <summary> | |
/// A prefab to place when a raycast from a user touch hits a vertical plane. | |
/// </summary> | |
public GameObject GameObjectVerticalPlanePrefab; | |
/// <summary> | |
/// A prefab to place when a raycast from a user touch hits a horizontal plane. | |
/// </summary> | |
public GameObject GameObjectHorizontalPlanePrefab; | |
/// <summary> | |
/// A prefab to place when a raycast from a user touch hits a feature point. | |
/// </summary> | |
public GameObject GameObjectPointPrefab; | |
/// <summary> | |
/// The rotation in degrees need to apply to prefab when it is placed. | |
/// </summary> | |
private const float k_PrefabRotation = 180.0f; | |
/// <summary> | |
/// True if the app is in the process of quitting due to an ARCore connection error, | |
/// otherwise false. | |
/// </summary> | |
private bool m_IsQuitting = false; | |
/// <summary> | |
/// The Unity Awake() method. | |
/// </summary> | |
public void Awake() | |
{ | |
// Enable ARCore to target 60fps camera capture frame rate on supported devices. | |
// Note, Application.targetFrameRate is ignored when QualitySettings.vSyncCount != 0. | |
Application.targetFrameRate = 60; | |
} | |
/// <summary> | |
/// The Unity Update() method. | |
/// </summary> | |
public void Update() | |
{ | |
_UpdateApplicationLifecycle(); | |
// If the player has not touched the screen, we are done with this update. | |
Touch touch; | |
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began) | |
{ | |
return; | |
} | |
// Should not handle input if the player is pointing on UI. | |
if (EventSystem.current.IsPointerOverGameObject(touch.fingerId)) | |
{ | |
return; | |
} | |
// Raycast against the location the player touched to search for planes. | |
TrackableHit hit; | |
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon | | |
TrackableHitFlags.FeaturePointWithSurfaceNormal; | |
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit)) | |
{ | |
// Use hit pose and camera pose to check if hittest is from the | |
// back of the plane, if it is, no need to create the anchor. | |
if ((hit.Trackable is DetectedPlane) && | |
Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position, | |
hit.Pose.rotation * Vector3.up) < 0) | |
{ | |
Debug.Log("Hit at back of the current DetectedPlane"); | |
} | |
else | |
{ | |
// Choose the prefab based on the Trackable that got hit. | |
GameObject prefab; | |
if (hit.Trackable is FeaturePoint) | |
{ | |
prefab = GameObjectPointPrefab; | |
} | |
else if (hit.Trackable is DetectedPlane) | |
{ | |
DetectedPlane detectedPlane = hit.Trackable as DetectedPlane; | |
if (detectedPlane.PlaneType == DetectedPlaneType.Vertical) | |
{ | |
prefab = GameObjectVerticalPlanePrefab; | |
} | |
else | |
{ | |
prefab = GameObjectHorizontalPlanePrefab; | |
} | |
} | |
else | |
{ | |
prefab = GameObjectHorizontalPlanePrefab; | |
} | |
// Instantiate prefab at the hit pose. | |
var gameObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation); | |
// Compensate for the hitPose rotation facing away from the raycast (i.e. | |
// camera). | |
gameObject.transform.Rotate(0, k_PrefabRotation, 0, Space.Self); | |
// Create an anchor to allow ARCore to track the hitpoint as understanding of | |
// the physical world evolves. | |
var anchor = hit.Trackable.CreateAnchor(hit.Pose); | |
// Make game object a child of the anchor. | |
gameObject.transform.parent = anchor.transform; | |
} | |
} | |
} | |
/// <summary> | |
/// Check and update the application lifecycle. | |
/// </summary> | |
private void _UpdateApplicationLifecycle() | |
{ | |
// Exit the app when the 'back' button is pressed. | |
if (Input.GetKey(KeyCode.Escape)) | |
{ | |
Application.Quit(); | |
} | |
// Only allow the screen to sleep when not tracking. | |
if (Session.Status != SessionStatus.Tracking) | |
{ | |
Screen.sleepTimeout = SleepTimeout.SystemSetting; | |
} | |
else | |
{ | |
Screen.sleepTimeout = SleepTimeout.NeverSleep; | |
} | |
if (m_IsQuitting) | |
{ | |
return; | |
} | |
// Quit if ARCore was unable to connect and give Unity some time for the toast to | |
// appear. | |
if (Session.Status == SessionStatus.ErrorPermissionNotGranted) | |
{ | |
_ShowAndroidToastMessage("Camera permission is needed to run this application."); | |
m_IsQuitting = true; | |
Invoke("_DoQuit", 0.5f); | |
} | |
else if (Session.Status.IsError()) | |
{ | |
_ShowAndroidToastMessage( | |
"ARCore encountered a problem connecting. Please start the app again."); | |
m_IsQuitting = true; | |
Invoke("_DoQuit", 0.5f); | |
} | |
} | |
/// <summary> | |
/// Actually quit the application. | |
/// </summary> | |
private void _DoQuit() | |
{ | |
Application.Quit(); | |
} | |
/// <summary> | |
/// Show an Android toast message. | |
/// </summary> | |
/// <param name="message">Message string to show in the toast.</param> | |
private void _ShowAndroidToastMessage(string message) | |
{ | |
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); | |
AndroidJavaObject unityActivity = | |
unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); | |
if (unityActivity != null) | |
{ | |
AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast"); | |
unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => | |
{ | |
AndroidJavaObject toastObject = | |
toastClass.CallStatic<AndroidJavaObject>( | |
"makeText", unityActivity, message, 0); | |
toastObject.Call("show"); | |
})); | |
} | |
} | |
} | |
} |
loading...
Awesome Thanks for the information
ReplyDelete