/// <summary> /// Handles movements and collisions on a constant basis. /// </summary> void FixedUpdate() { //Calculate where the object should move this frame Vector3 newpos = transform.position + transform.rotation * Vector3.forward * (speed * Time.deltaTime); //Collisions with the real World. As the object moves, collisions checks are made each frame at the next position. Vector3 collisionpoint; Vector3 collisionnormal; //First, test the primary ZED. Collisions will look the most accurate if calculated from this one. bool primaryhit = ZEDSupportFunctions.HitTestOnRay(zedManager.zedCamera, cam, newpos, transform.rotation, Vector3.Distance(transform.position, newpos), distanceBetweenRayChecks, out collisionpoint, false, realWorldThickness); if (primaryhit) { //Call the function to resolve the impact. This allows us to easily override what happens on collisions with classes that inherit this one. ZEDSupportFunctions.GetNormalAtWorldLocation(zedManager.zedCamera, collisionpoint, sl.REFERENCE_FRAME.WORLD, cam, out collisionnormal); OnHitRealWorld(collisionpoint, collisionnormal); } if (!primaryhit && testCollisionsUsingAllZEDs) //If set to true, test the rest of the ZEDs as well. { foreach (ZEDManager manager in ZEDManager.GetInstances()) { if (manager == zedManager) { continue; //If it's the primary ZED, skip as we've already tested that one. } if (ZEDSupportFunctions.HitTestOnRay(manager.zedCamera, manager.GetMainCamera(), newpos, transform.rotation, Vector3.Distance(transform.position, newpos), distanceBetweenRayChecks, out collisionpoint, false, realWorldThickness)) { //Call the function to resolve the impact. This allows us to easily override what happens on collisions with classes that inherit this one. ZEDSupportFunctions.GetNormalAtWorldLocation(manager.zedCamera, collisionpoint, sl.REFERENCE_FRAME.WORLD, manager.GetMainCamera(), out collisionnormal); OnHitRealWorld(collisionpoint, collisionnormal); break; //No need to test the rest of the ZEDs. } } } //Collisions with virtual objects //Cast a ray to check collisions between here and the intended move point for virtual objects. RaycastHit hitinfo; if (Physics.Raycast(transform.position, newpos - transform.position, out hitinfo, Vector3.Distance(transform.position, newpos))) { //Call the function to resolve the impact. This allows us to easily override what happens on collisions with classes that inherit this one. OnHitVirtualWorld(hitinfo); } //Move it to this new place transform.position = newpos; //Tick down its lifespan and check if we should destroy it. lifespan -= Time.deltaTime; if (lifespan <= 0f) { Destroy(gameObject); } }
private IEnumerator Start() { isMoving = false; if (!zedManager) { zedManager = FindObjectOfType <ZEDManager>(); if (ZEDManager.GetInstances().Count > 1) //They let the plugin auto-assign a ZED but there are multiple ZED's. Warn the user. { UnityEngine.Debug.Log("Warning: ZEDTransformController's zedManager field was not specified, but there are multiple ZEDManagers in the scene " + "so first available ZED was assigned. This can cause the object to move relative to the wrong camera. " + "It's recommended to assign the desired ZEDManager in the Inspector."); } } //Find the available VR controllers and assigning them to our List. yield return(new WaitForSeconds(1f)); var trackers = FindObjectsOfType <ZEDControllerTracker>(); foreach (ZEDControllerTracker_DemoInputs tracker in trackers) { objectTrackers.Add(tracker); } if (repositionAtStart) //If the user wants, move the object in front of the ZED once it's initialized. { zedManager.OnZEDReady += RepositionInFrontOfZED; } }
void Start() { if (zedManager == null) { zedManager = FindObjectOfType <ZEDManager>(); if (ZEDManager.GetInstances().Count > 1) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user. { Debug.Log("Warning: " + gameObject.name + "'s zedManager was not specified, so the first available ZEDManager instance was " + "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " + "use to display a point cloud."); } } if (zedManager != null) { zed = zedManager.zedCamera; } if (_pointMaterial == null) { _pointMaterial = new Material(Resources.Load("Materials/PointCloud/Mat_ZED_FusedPC_Point") as Material); } if (_diskMaterial == null) { _diskMaterial = new Material(Resources.Load("Materials/PointCloud/Mat_ZED_FusedPC_Disk") as Material); } _diskMaterial.hideFlags = HideFlags.DontSave; _pointMaterial.hideFlags = HideFlags.DontSave; zedManager.OnGrab += startMap; }
/// <summary> /// This function is called every fixed framerate frame /// Here we take care of enabling & disabling the laser pointer. /// </summary> 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.GetLeftCamera(), predictedPos)) { //We hit something, but is it a flat surface? if (planeManager.DetectPlaneAtHit(manager, manager.GetLeftCamera().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. } } } }
// Update is called once per frame void Update() { foreach (ZEDManager manager in ZEDManager.GetInstances()) { DrawAsteroids(manager); } }
/// <summary> /// Checks if another ArUcoDrone is in front of the drone and within range. /// Will also check if there's a real object in the way, if checkRealWorldObstaclesBeforeShooting is true. /// </summary> /// <returns>True if there's a valid target in front of the drone.</returns> private bool IsAimingAtTarget() { //First make sure there's a valid virtual target in front of the drone. Ray ray = new Ray(shootAnchorObject.position, shootAnchorObject.rotation * Vector3.forward); RaycastHit[] hits = Physics.RaycastAll(ray, shootRangeMeters); bool foundvirtualtarget = false; float nearestdist = Mathf.Infinity; foreach (RaycastHit hit in hits) { ArUcoDrone otherdrone = hit.transform.GetComponent <ArUcoDrone>(); if (otherdrone != null && otherdrone != this) { foundvirtualtarget = true; if (hit.distance < nearestdist) { nearestdist = hit.distance; } } } if (!foundvirtualtarget) { return(false); } if (checkRealWorldObstaclesBeforeShooting) //Make sure there's not a real-world obstacle in the way of the target. { //If there is one, check to make sure there's not a real-world object in the way. Vector3 collisionpoint; //Not used but required for HitTestOnRay function. foreach (ZEDManager manager in ZEDManager.GetInstances()) { bool hitreal = ZEDSupportFunctions.HitTestOnRay(manager.zedCamera, manager.GetLeftCamera(), shootAnchorObject.transform.position, shootAnchorObject.transform.rotation, nearestdist, 0.01f, out collisionpoint, false, 0.1f); if (hitreal) { return(false); } } return(true); } else { return(true); //We're not checking against the real world, and we already found a virtual object, so fire. } }
/// <summary> /// Detects the floor plane. Replaces the current floor plane, if there is one, unlike DetectPlaneAtHit(). /// If a floor is detected, also assigns the user's height from the floor to estimatedPlayerHeight. /// <para>Uses the first available ZEDManager in the scene.</para> /// </summary> /// <returns><c>true</c>, if floor plane was detected, <c>false</c> otherwise.</returns> public bool DetectFloorPlane(bool auto) { //Find the first available ZEDManager. List <ZEDManager> managers = ZEDManager.GetInstances(); if (managers.Count == 0) { return(false); //No ZEDManager to use. } else { return(DetectFloorPlane(managers[0], auto)); } }
/// <summary> /// Detects the plane around screen-space coordinates specified. /// <para>Uses the first available ZEDManager in the scene.</para> /// </summary> /// <returns><c>true</c>, if plane at hit was detected, <c>false</c> otherwise.</returns> /// <param name="screenPos">Position of the pixel in screen space (2D).</param> public bool DetectPlaneAtHit(Vector2 screenPos) { //Find the first available ZEDManager. List <ZEDManager> managers = ZEDManager.GetInstances(); if (managers.Count == 0) { return(false); //No ZEDManager to use. } else if (managers.Count > 1) //They're using multiple cameras but using the first available manager. Not ideal. { Debug.LogWarning("Using DetectPlaneAtHit without specifying a manager while multiple ZEDManagers are present. " + "This can cause planes to be calculated by the wrong camera. It's recommended to use the (ZEDManager, Vector2) overload."); } return(DetectPlaneAtHit(managers[0], screenPos)); }
void Start() { if (zedManager == null) { zedManager = FindObjectOfType <ZEDManager>(); if (ZEDManager.GetInstances().Count > 1) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user. { Debug.Log("Warning: " + gameObject.name + "'s zedManager was not specified, so the first available ZEDManager instance was " + "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " + "use to display a point cloud."); } } if (zedManager != null) { zed = zedManager.zedCamera; } }
/// <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, leftcamera, 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); }
private void Awake() { if (zedManager == null) { zedManager = FindObjectOfType <ZEDManager>(); //If this happenend when only using a primary ZED for collisions but there are multiple ZEDs, collisions will be //calculated using an arbitrary camera. Warn the user. if (testCollisionsUsingAllZEDs == false && ZEDManager.GetInstances().Count > 1) { Debug.LogWarning("Warning: ZEDProjectile's zedManager value was not specified, resulting in assigning to first available " + " camera, but there are multiple cameras in the scene. This can cause strange collision test behavior."); } } if (!cam) { cam = zedManager.GetMainCamera(); } }
/// <summary> /// Sets up the timed pose dictionary and identifies the VR SDK being used. /// </summary> void Awake() { poseData.Clear(); //Reset the dictionary. poseData.Add(1, new List <TimedPoseData>()); //Create the list within the dictionary with its key and value. //Looking for the loaded device loadeddevice = UnityEngine.XR.XRSettings.loadedDeviceName; if (!zedManager) { zedManager = FindObjectOfType <ZEDManager>(); //If there are multiple cameras in a scene, this arbitrary assignment could be bad. Warn the user. if (ZEDManager.GetInstances().Count > 1) { //Using Log instead of LogWarning because most users don't enable warnings but this is actually important. Debug.Log("Warning: ZEDController automatically set itself to first available ZED (" + zedManager.cameraID + ") because zedManager " + "value wasn't set, but there are multiple ZEDManagers in the scene. Assign a reference directly to ensure no unexpected behavior."); } } zedRigRoot = zedManager.GetZedRootTansform(); }
protected override void OnEnable() { hmdToCamera = new Vector3(-0.0315f, 0, 0.115f); if (zedManager == null) { zedManager = FindObjectOfType <ZEDManager>(); if (ZEDManager.GetInstances().Count > 1) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user. { Debug.Log("Warning: " + gameObject.name + "'s zedManager was not specified, so the first available ZEDManager instance was " + "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " + "use to display a point cloud."); } } if (zedManager != null) { zedManager.OnGrab += UpdateMeshPosition; } base.OnEnable(); }
/// <summary> /// Check if the screen was clicked. If so, check for a plane where the click happened using DetectPlaneAtHit(). /// </summary> void Update() { //Detect hits when you click on the screen. if (Input.GetMouseButtonDown(0)) { Vector2 ScreenPosition = Input.mousePosition; List <ZEDManager> managers = ZEDManager.GetInstances(); if (managers.Count == 1) //There's only one ZEDManager, so use that one. { DetectPlaneAtHit(managers[0], ScreenPosition); } else if (managers.Count > 1) { //There are at least two ZEDManagers rendering. Find the one that's likely the last to render, so it's the one the user clicked on. float highestdepth = Mathf.NegativeInfinity; ZEDManager highestmanager = managers[0]; foreach (ZEDManager manager in managers) { float depth = manager.GetMainCamera().depth; if (depth >= highestdepth) { highestdepth = depth; highestmanager = manager; } } DetectPlaneAtHit(highestmanager, ScreenPosition); } } //Update plane physics if needed. if (willUpdatePhysics) { if (floorPlane != null && floorPlane.IsCreated) { floorPlane.SetPhysics(addPhysicsOption); } if (hitPlaneList != null) { foreach (ZEDPlaneGameObject c in hitPlaneList) { if (c.IsCreated) { c.SetPhysics(addPhysicsOption); } } } willUpdatePhysics = false; } //Update visibility if needed. if (willUpdateSceneVisibility) { /*if (floorPlane != null && floorPlane.IsCreated) * { * floorPlane.SetVisible(isVisibleInSceneOption); * } * if (hitPlaneList != null) * { * foreach (ZEDPlaneGameObject c in hitPlaneList) * { * c.SetVisible(isVisibleInSceneOption); * } * }*/ SwitchSceneDisplay(); willUpdateSceneVisibility = false; } //Update in-game visibility if needed. if (willUpdateGameVisibility) { SwitchGameDisplay(); willUpdateGameVisibility = false; } }
IEnumerator Start() { audiosource = GetComponent <AudioSource>(); if (zedManager == null) { zedManager = FindObjectOfType <ZEDManager>(); if (ZEDManager.GetInstances().Count > 1) { Debug.Log("Warning: " + gameObject + " ZEDManager reference not set, but there are multiple ZEDManagers in the scene. " + "Setting to first available ZEDManager, which may cause undesirable crosshair positions."); } } if (laserPointerBeadHolder != null) { //Get the laser bead from the parent/achor object. pointerbead = laserPointerBeadHolder.transform.GetChild(0).gameObject; //Disable the laser bead to wait for the ZED to initialize. pointerbead.SetActive(false); } //Wait for VR Controllers to initilize yield return(new WaitForSeconds(1f)); objecttracker = GetComponent <ZEDControllerTracker_DemoInputs>(); if (objecttracker != null) { #if ZED_STEAM_VR if (objecttracker.index >= 0) { yield break; } #endif #if ZED_OCULUS if (OVRInput.GetConnectedControllers().ToString().ToLower().Contains("touch")) { yield break; } #endif // If it got here then there's no VR Controller connected int children = transform.childCount; for (int i = 0; i < children; ++i) { transform.GetChild(i).gameObject.SetActive(false); } //this.enabled = false; } else { //If its not attached to an object tracker var otherObjectTracker = FindObjectsOfType <ZEDControllerTracker>(); if (otherObjectTracker != null) { int children = transform.childCount; #if ZED_STEAM_VR foreach (ZEDControllerTracker trackers in otherObjectTracker) { if (trackers.index >= 0) { for (int i = 0; i < children; ++i) { transform.GetChild(i).gameObject.SetActive(false); } this.enabled = false; yield break; } } #endif #if ZED_OCULUS if (OVRManager.isHmdPresent) { if (OVRInput.GetConnectedControllers().ToString().ToLower().Contains("touch")) { for (int i = 0; i < children; ++i) { transform.GetChild(i).gameObject.SetActive(false); } //this.enabled = false; yield break; } } #endif } } }
/// <summary> /// Update is called every frame. /// Here we receive the input from the Controller. /// Then we decide what to do in each case. /// </summary> private void Update() { if (tracker == null) { if (Input.GetKeyDown(KeyCode.Space)) { button = state.Down; } else if (Input.GetKey(KeyCode.Space)) { button = state.Press; } else if (Input.GetKeyUp(KeyCode.Space)) { button = state.Up; } else { button = state.Idle; } } else { if (tracker.CheckClickButton(ControllerButtonState.Down)) { button = state.Down; } else if (tracker.CheckClickButton(ControllerButtonState.Held)) { button = state.Press; } else if (tracker.CheckClickButton(ControllerButtonState.Up)) { button = state.Up; } else { button = state.Idle; } } //If the Trigger Button is being used. if (button != state.Idle) { //It just got pressed. if (button == state.Down) { //Enable the bunnySpawner to display the placeholder. bunnySpawner.canDisplayPlaceholder = true; //If we were holding the baseball bat but the user wants to re-place the bunny, hide the baseball bat. if (bunnySpawner.baseballBat != null) { bunnySpawner.baseballBat.SetActive(false); } //Clean up the list of detected planes. if (zedPlane.hitPlaneList.Count > 0) { for (int i = 0; i < zedPlane.hitPlaneList.Count; i++) { Destroy(zedPlane.hitPlaneList[i].gameObject); zedPlane.hitPlaneList.RemoveAt(i); } } //Destroy the current Bunny, if any, on the scene. if (!bunnySpawner.canSpawnMultipleBunnies && bunnySpawner.currentBunny != null) { Destroy(bunnySpawner.currentBunny); bunnySpawner.currentBunny = null; } } //From the first input to the next ones as it keeps being hold down. if (button == state.Press || button == state.Down) { if (zedPlane.hitPlaneList.Count == 0) { //Start detecting planes through the ZED Plane Detection Manager. foreach (ZEDManager manager in ZEDManager.GetInstances()) //Check all active ZED cameras for planes. { if (zedPlane.DetectPlaneAtHit(manager, manager.GetMainCamera().WorldToScreenPoint(placeholder.position))) { //Get the normal of the plane. ZEDPlaneGameObject currentPlane = zedPlane.hitPlaneList[zedPlane.hitPlaneList.Count - 1]; Vector3 planeNormal = currentPlane.worldNormal; //Check if the plane has a normal close enough to Y (horizontal surface) to be stable for the Bunny to spawn into. if (Vector3.Dot(planeNormal, Vector3.up) > 0.85f) { //Allow spawning the Bunny, and set the placeholder to a positive color. if (canspawnbunny == false) { canspawnbunny = true; bunnySpawner.placeHolderMat[0].mainTexture = goodPlacementTex[0]; bunnySpawner.placeHolderMat[1].mainTexture = goodPlacementTex[1]; pointlight.color = Color.blue; } else //Clear the list of planes. { for (int i = 0; i < zedPlane.hitPlaneList.Count; i++) { if (i == 0) { Destroy(zedPlane.hitPlaneList[i].gameObject); zedPlane.hitPlaneList.RemoveAt(i); } } } } else //Surface wasn't horizontal enough { //Don't allow the Bunny to spawn, and set the placeholder to a negative color. canspawnbunny = false; bunnySpawner.placeHolderMat[0].mainTexture = badPlacementTex[0]; bunnySpawner.placeHolderMat[1].mainTexture = badPlacementTex[1]; pointlight.color = Color.red; //Clear the list of planes. for (int i = 0; i < zedPlane.hitPlaneList.Count; i++) { Destroy(zedPlane.hitPlaneList[i].gameObject); zedPlane.hitPlaneList.RemoveAt(i); } } break; //If we detected a plane in one view, no need to go through the rest of the cameras. } } } else if (zedPlane.hitPlaneList.Count > 0) { if (!Physics.Raycast(transform.position, placeholder.position - transform.position)) { //Don't allow for the Bunny to spawn, and set the placeholder to a negative color. canspawnbunny = false; bunnySpawner.placeHolderMat[0].mainTexture = badPlacementTex[0]; bunnySpawner.placeHolderMat[1].mainTexture = badPlacementTex[1]; pointlight.color = Color.red; //Clear the list of planes. for (int i = 0; i < zedPlane.hitPlaneList.Count; i++) { Destroy(zedPlane.hitPlaneList[i].gameObject); zedPlane.hitPlaneList.RemoveAt(i); } } } } //Button is released. if (button == state.Up) { //If at that moment the bunny was allowed to spawn, proceed ot make the call. if (canspawnbunny) { bunnySpawner.SpawnBunny(placeholder.position); } else //Clear the list of planes. { for (int i = 0; i < zedPlane.hitPlaneList.Count; i++) { Destroy(zedPlane.hitPlaneList[i].gameObject); zedPlane.hitPlaneList.RemoveAt(i); } } //Reset the booleans. canspawnbunny = false; bunnySpawner.canDisplayPlaceholder = false; } } }
// Raycast from given screen position, using the first manager public RaycastHit raycastFromScreenSpace(Vector2 screenPosition) { List <ZEDManager> managers = ZEDManager.GetInstances(); return(raycastFromScreenSpace(screenPosition, managers[0])); }
// Attach an object to a plane in screen space using the first manager. public bool attachToPlaneFromScreenSpace(GameObject attachmentObject, Vector2 screenPosition) { List <ZEDManager> managers = ZEDManager.GetInstances(); return(attachToPlaneFromScreenSpace(attachmentObject, screenPosition, managers[0])); }