创新项目实训实践笔记-15

    技术2022-07-11  82

    创新项目实训实践笔记-15

    平面检测部分2-脚本编写(物品放置)

    平面检测部分

    2-脚本编写(物品放置)

    首先我们先在场景中新建一个空物体,命名为Plane_controller。 然后将下面的脚本挂载到上面

    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; public bool hasFile; /// <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; hasFile = false; } /// <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; } if (!hasFile) { 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(180, k_PrefabRotation, 0, Space.Self); gameObject.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f); hasFile = true; // 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; } } } // Raycast against the location the player touched to search for planes. } /// <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"); })); } } } }

    并将相对应的变量进行赋值 这个脚本是ARCore中自带的一个DEMO名为HelloAR中的一个脚本,用于放置物体的,这里我们并不能直接拿过来使用,因为场景、物体等因素均有不同,因此放置的物体的大小与旋转角度均有不同,所以我们需要在后面进行一些改动,当我们实例化我们的物体后需要对其大小等进行调整

    // 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(180, k_PrefabRotation, 0, Space.Self); gameObject.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f); hasFile = true; // 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;

    修改一定的参数后,我们的物体可以比较完美的显示在我们点击的平面上了。

    Processed: 0.016, SQL: 9