using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// Governs the FlyingBunny prefab used in the ZED plane detection samples.
/// Checks for collisions in front of it in midair, and spawns the flag when it hits the ground.
///
public class Bunny : MonoBehaviour
{
///
/// Stores initial position when we are enabled/spawned into the scene.
/// Used to calculate how far the bunny traveled after we hit it in the VR plane detection demo.
///
public Vector3 InitialPosition { get; private set; }
///
/// True whenever this object is moved by the baseball bat.
///
public bool IsMoving { get; private set; }
///
/// Reference to the BunnySpawner that spawned this GameObject.
///
private BunnySpawner bunnyspawner;
///
/// The transform used as center/pivot point for this GameObject when checking for collisions with the real world.
///
private Transform centerpoint;
///
/// Reference to the scene's ZED Plane Detection Manager.
///
private ZEDPlaneDetectionManager planeManager;
///
/// The bunny's Rigidbody component.
///
private Rigidbody rb;
///
/// The Bunny's Animator component.
///
[HideInInspector]
public Animator anim;
// Use this for initialization.
void Start()
{
IsMoving = false; //we're not moving at start.
//Caching
planeManager = FindObjectOfType();
rb = GetComponent(); //Get our Rigidbody component.
anim = GetComponent();
InitialPosition = transform.position; //Save for calculating distance traveled later.
//If there is a child in position 2, use it as new centerPoint.
if (transform.GetChild(2) != null)
{
centerpoint = transform.GetChild(2);
}
else //If not, use this transform.
{
centerpoint = transform;
}
}
///
/// Sets the BunnySpawner.
///
///
public void SetMySpawner(BunnySpawner spawner)
{
bunnyspawner = spawner;
}
///
/// Starts the HitDelay coroutine.
///
public void GetHit(bool hit)
{
GetComponent().drag = 0f;
GetComponent().angularDrag = 0.5f;
StartCoroutine(HitDelay(hit));
}
///
/// Coroutine used to delay the collision detection of the Bunny.
/// Setting the _moving variable after waiting X seconds.
///
IEnumerator HitDelay(bool hit)
{
//Wait for X amount of seconds...
yield return new WaitForSeconds(0.1f);
if (hit)
{
//... then set IsMoving to true, and allow collision detection in FixedUpdate().
IsMoving = true;
}
else
{
rb.isKinematic = true; //Freeze the object at the current position.
yield return new WaitForSeconds(1f);
bunnyspawner.SpawnUI(transform.position);
}
//Clearing the scene from any Planes created by the ZED Plane Detection Manager.
for (int i = 0; i < planeManager.hitPlaneList.Count; i++)
{
Destroy(planeManager.hitPlaneList[i].gameObject);
planeManager.hitPlaneList.RemoveAt(i);
}
}
///
/// This function is called every fixed framerate frame
/// Here we take care of enabling & disabling the laser pointer.
///
private void FixedUpdate()
{
//If we have been moved by the baseball bat
if (IsMoving)
{
//Look for our next position based on our current velocity.
Vector3 predictedPos = centerpoint.position + (rb.velocity * (Time.deltaTime * 2.5f));
transform.rotation = Quaternion.LookRotation(rb.velocity.normalized);
//Collision check with the real world at that next position.
foreach (ZEDManager manager in ZEDManager.GetInstances()) //Check all active cameras.
{
if (ZEDSupportFunctions.HitTestAtPoint(manager.zedCamera, manager.GetMainCamera(), predictedPos))
{
//We hit something, but is it a flat surface?
if (planeManager.DetectPlaneAtHit(manager, manager.GetMainCamera().WorldToScreenPoint(predictedPos)))
{
bunnyspawner.SpawnUI(predictedPos);
IsMoving = false;
}
else//If not, bounce off of it but still show the flag.
{
IsMoving = false; //Not moving anymore, so update our state.
bunnyspawner.SpawnUI(predictedPos); //Start spawning the UI on our current location.
rb.velocity = Vector3.Reflect(rb.velocity / 2, transform.forward); //Bounce off the surface we hit
}
break; //If it hit the real world in one camera's view, no need to check the other cameras.
}
}
}
}
}