/// <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); } }
/// <summary> /// Tests the depth of both the real and virtual in the center of the screen, and returns the world position of the closest one. /// </summary> /// <param name="crosshairpoint">Where the crosshair should be rendered.</param> /// <param name="collisionnormal">The normal vector of the surface aimed at, for rotating the crosshair accordingly if desired.</param> /// <returns>False if there is no valid object, real or virtual, on which to place the crosshair. </returns> private bool FindCrosshairPosition(out Vector3 crosshairpoint, out Vector3 collisionnormal) { //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; bool foundrealdistance = ZEDSupportFunctions.HitTestOnRay(leftcamera, laserPointerBeadHolder.transform.position, laserPointerBeadHolder.transform.rotation, 5f, 0.01f, out realpoint); float realdistance = Vector3.Distance(laserPointerBeadHolder.transform.position, realpoint); //Find the distance to the virtual. The bool will be false if there are no colliders ahead of you. RaycastHit hitinfo; bool foundvirtualdistance = Physics.Raycast(laserPointerBeadHolder.transform.position, laserPointerBeadHolder.transform.rotation * Vector3.forward, out hitinfo); //If we didn't find either, return false so the laser and bead can be disabled. if (!foundrealdistance && !foundvirtualdistance) { crosshairpoint = Vector3.zero; collisionnormal = Vector3.zero; return(false); } //Decide if we use the real or virtual distance if (!foundvirtualdistance || realdistance < hitinfo.distance) { //The real world is closer. Give the position of the real world pixel and return true. crosshairpoint = realpoint; ZEDSupportFunctions.GetNormalAtWorldLocation(realpoint, sl.REFERENCE_FRAME.WORLD, leftcamera, out collisionnormal); return(true); } else { //The virtual world is closer, or they're tied. Return the world posiiton where the raycast hit the virtual collider. crosshairpoint = hitinfo.point; collisionnormal = hitinfo.normal; return(true); } }
/// <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; if (ZEDSupportFunctions.HitTestOnRay(_leftCamera, 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. Vector3 collisionnormal; ZEDSupportFunctions.GetNormalAtWorldLocation(collisionpoint, sl.REFERENCE_FRAME.WORLD, _leftCamera, out collisionnormal); OnHitRealWorld(collisionpoint, collisionnormal); } //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); } }