123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- /// <summary>
- /// Moves around the placeholder object in the ZED place detection demo.
- /// Also spawns the real object if BunnyPlacement.cs reports the placeholder is in a valid position.
- /// </summary>
- public class BunnySpawner : MonoBehaviour
- {
- /// <summary>
- /// Prefab of the Bunny object that we're going to spawn.
- /// </summary>
- [Tooltip("Prefab of the Bunny object that we're going to spawn.")]
- public GameObject bunnyPrefab;
- /// <summary>
- /// Prefab of the pointer/placeholder that indicates if we can place the object there or not.
- /// </summary>
- [Tooltip("Prefab of the pointer/placeholder that indicates if we can place the object there or not.")]
- public GameObject pointerPrefab;
- /// <summary>
- /// Prefab of the flag UI that spawns when the Bunny collides with anything.
- /// </summary>
- [Tooltip("Prefab of the flag UI that spawns when the Bunny collides with anything.")]
- public GameObject uiPrefab;
- /// <summary>
- /// The Material used on the placeHolder of the pointer prefab. Reference used to change colors based on placement validity.
- /// </summary>
- [Tooltip("The Material used on the placeholder of the pointer prefab. Reference used to change colors based on placement validity.")]
- public Material[] placeHolderMat;
- /// <summary>
- /// The origin position for the pointer, from which you aim the ray to check for a valid placement location.
- /// If null (such as in the non-VR sample) it takes this script's GameObject position.
- /// </summary>
- [Tooltip("The origin position for the pointer, from which you aim the ray to check for a valid placement location. " +
- "If null (such as in the non-VR sample) it takes this script's GameObject position.")]
- public Transform rayOrigin;
- /// <summary>
- /// Whether or not we can spawn multiple bunnies at once.
- /// </summary>
- [Tooltip("Whether or not we can spawn multiple bunnies at once.")]
- public bool canSpawnMultipleBunnies = false;
- /// <summary>
- /// Whether or not we can display the placeHolder bunny.
- /// </summary>
- [HideInInspector]
- public bool canDisplayPlaceholder;
- /// <summary>
- /// The last UI spawned for a Bunny collision.
- /// </summary>
- private GameObject currentui;
- /// <summary>
- /// The last Bunny gameObject spawned in the scene.
- /// </summary>
- [HideInInspector]
- public GameObject currentBunny;
- /// <summary>
- /// Reference to the object that holds the laser as an anchor.
- /// </summary>
- private GameObject pointer;
- /// <summary>
- /// Reference to the object that will be placed at the end of the laser.
- /// </summary>
- private GameObject placeholder;
- /// <summary>
- /// The "primary" ZEDManager used for spawning bunnies. Used to aim the UI and decide where bunnies are looking on spawn.
- /// <para>If not set, the first available one in the scene will be used.</para>
- /// </summary>
- [Tooltip("The 'primary' ZEDManager used for spawning bunnies. Used to aim the UI and decide where bunnies are looking on spawn. " +
- "If not set, the first available one in the scene will be used.")]
- public ZEDManager zedManager;
- /// <summary>
- /// Reference to the ZED's left camera gameobject.
- /// </summary>
- private Camera cam;
- /// <summary>
- /// The text componenet of the current UI gameObject for displaying the score (Distance) of how far the Bunny was sent.
- /// </summary>
- private Text distancetext;
- /// <summary>
- /// The gameObject that holds the 3D Model of the Baseball Bat, so we can Show/Hide it.
- /// </summary>
- [HideInInspector]
- public GameObject baseballBat;
- void Awake()
- {
- if (!zedManager)
- {
- zedManager = FindObjectOfType<ZEDManager>();
- }
- //Find the left camera object if we didn't assign it at start.
- if (!cam)
- {
- cam = zedManager.GetMainCamera();
- }
- //Check if there is a Object Tracker on this object for VR controls.
- var tracker = GetComponent<ZEDControllerTracker>();
- if (tracker != null)
- {
- //Get the parent object of the baseball bat.
- if (transform.childCount > 1)
- {
- baseballBat = transform.GetChild(1).gameObject;
- baseballBat.SetActive(false); //Hide it by default. It'll get revealed once we place a bunny.
- }
- }
- //Instantiate the pointer prefab and assign it to our variables.
- if (pointerPrefab != null)
- {
- pointer = Instantiate(pointerPrefab) as GameObject; //Get the Anchor/root of the pointerBead.
- placeholder = pointer.transform.GetChild(0).gameObject; //Get the laser's pointerBead.
- }
- //If we didn't set a transform for the pointer's origin position...
- if (rayOrigin == null)
- {
- rayOrigin = transform; //...then take our local position.
- }
- //Set the PlaneManager's reference to our placeholder.
- GetComponent<BunnyPlacement>().SetPlaceholder(placeholder.transform);
- }
- /// <summary>
- /// This function is called every fixed framerate frame
- /// Here we take care of enabling & disabling the laser pointer by looking for collisions with the real world.
- /// </summary>
- void FixedUpdate()
- {
- //Do we have a Pointer Bead to position in the world?
- if (pointer != null && GetComponent<BunnyPlacement>().button != BunnyPlacement.state.Idle)
- {
- Vector3 pointerposition;
- //Point the bead at the closest thing in front of the camera.
- if (zedManager.IsZEDReady && FindPointerPosition(out pointerposition) && canDisplayPlaceholder)
- {
- //We hit something. Make sure the bead is active.
- pointer.SetActive(true);
- //Position the bead a the collision point, and make it face you.
- pointer.transform.position = pointerposition;
- Quaternion rot = Quaternion.LookRotation(cam.transform.position - pointer.transform.position);
- pointer.transform.eulerAngles = new Vector3(0f, rot.eulerAngles.y, 0f);
- }
- else
- {
- //We didn't hit anything. Disable the bead object.
- pointer.SetActive(false);
- }
- }
- else
- pointer.SetActive(false);
- }
- /// <summary>
- /// Spawning the Bunny prefab.
- /// </summary>
- /// <param name="spawnPos">Where we'll spawn the bunny.</param>
- public void SpawnBunny(Vector3 spawnPos)
- {
- //Instantiating the prefab.
- GameObject newBunny = Instantiate(bunnyPrefab, spawnPos, Quaternion.identity, null) as GameObject;
- //Make the UI to face the camera only on the Y axis.
- Quaternion rot = Quaternion.LookRotation(cam.transform.position - spawnPos);
- newBunny.transform.eulerAngles = new Vector3(0f, rot.eulerAngles.y, 0f);
- //Set this script as the BunnySpawner of the instantiated Bunny.
- newBunny.GetComponent<Bunny>().SetMySpawner(this);
- //Assigning it to the currentBunny variable.
- currentBunny = newBunny;
- //Start the coroutine that will enable/show the baseball bat.
- StartCoroutine(EnableBat());
- }
- /// <summary>
- /// Waits for X seconds (to let the bunny fall into place) before activating the bat object.
- /// </summary>
- /// <returns></returns>
- IEnumerator EnableBat()
- {
- //Wait for X seconds...
- yield return new WaitForSeconds(1f);
- //...then enable/show the baseball bat.
- if (!canDisplayPlaceholder && baseballBat != null)
- {
- baseballBat.SetActive(true); //It's wabbit season.
- }
- }
- /// <summary>
- /// Instantiating the flag UI prefab.
- /// </summary>
- /// <param name="spawnPos"></param>
- public void SpawnUI(Vector3 spawnPos)
- {
- //Hide the baseball bat.
- if (baseballBat != null)
- baseballBat.SetActive(false);
- //Destroy the last UI that was spawned, if any.
- if (currentui != null)
- {
- Destroy(currentui);
- currentui = null;
- }
- //Instantiate a new UI GameObject and position it.
- GameObject newUI = Instantiate(uiPrefab, null);
- newUI.transform.position = spawnPos;
- //Make the UI to face the camera only on the Y axis.
- Quaternion rot = Quaternion.LookRotation(cam.transform.position - spawnPos);
- newUI.transform.eulerAngles = new Vector3(0f, rot.eulerAngles.y, 0f);
- //Configure the flag UI to be spawned.
- currentui = newUI;
- distancetext = currentui.GetComponentInChildren<Text>();
- //Update the distanceText value to the current Distance between the first/spawned position of the Bunny, and his current one.
- distancetext.text = Vector3.Distance(currentBunny.GetComponent<Bunny>().InitialPosition, spawnPos).ToString("F2") + " Meters";
- //If the UI position is higher than ours, and for a minimum of 1.5 meters, then rotate it 180 on the X axis so it's turned upside down.
- if (currentui.transform.position.y > cam.transform.position.y && currentui.transform.position.y > 1.5f)
- {
- currentui.transform.eulerAngles = new Vector3(180f, currentui.transform.rotation.eulerAngles.y, 0f);
- distancetext.transform.localEulerAngles = new Vector3(180f, 0f, 0f);
- }
- }
- /// <summary>
- /// Tests the depth of the real world based on the pointer origin position and rotation.
- /// Returns the world position if it collided with anything.
- /// </summary>
- /// <param name="pointerbeadpoint">The world space position where the pointer is pointing.</param>
- /// <returns>True if a valid real world point was found.</returns>
- bool FindPointerPosition(out Vector3 pointerbeadpoint)
- {
- //Find the distance to the real world. The bool will be false if there is an error reading the depth at the center of the screen.
- Vector3 realpoint;
- foreach (ZEDManager manager in ZEDManager.GetInstances()) //Check all cameras, in case it's hitting something the main ZEDManager can't see.
- {
- if (ZEDSupportFunctions.HitTestOnRay(zedManager.zedCamera, cam, rayOrigin.position, rayOrigin.rotation, 5.0f, 0.05f, out realpoint))
- {
- pointerbeadpoint = realpoint;
- return true; //No need to check the other cameras.
- }
- }
- //No camera was able to see a collision.
- pointerbeadpoint = Vector3.zero;
- return false;
- }
- }
|