public override void Initialize() { base.Initialize(); // check if any action mapping is defined for OnTravel foreach (VRIL_ActionMapping mapping in Mappings) { if (mapping.ActionType == VRIL_ActionTypes.OnTravel) { TravelOnRelease = false; break; } } // check if any interaction techniques are registered foreach (VRIL_RegisteredController regController in Manager.RegisteredControllers) { if (regController.InteractionTechniques.Count > 0) { MoveSelectedObjects = true; break; } } //check distance to ground and save it if (Viewpoint) { Ray ray = new Ray(Viewpoint.transform.position, Viewpoint.transform.up * -1); if (Physics.Raycast(ray, out RaycastHit raycastHit)) { VRIL_Navigable navigableObject = raycastHit.transform.gameObject.GetComponent <VRIL_Navigable>(); if (navigableObject != null) { DistanceViewpointToGround = Mathf.Abs(Viewpoint.transform.position.y - navigableObject.transform.position.y); return; } } } DistanceViewpointToGround = 0; }
/// <summary> /// Coroutine for vizualization of the target selection /// It is "virtual" to allow custom ray implementation in future (such as curved trajectories or just a straight line) /// </summary> /// <returns>WaitForSeconds()</returns> protected virtual IEnumerator SelectPosition(VRIL_ControllerActionEventArgs e) { TeleportLineRenderer.enabled = true; while (IsActivated) { // disable hit entity to avoid ray cast blocking if (HitEntity != null) { HitEntity.SetActive(false); } TeleportLineRenderer.startColor = InvalidPositionColor; TeleportLineRenderer.endColor = InvalidPositionColor; // first point of curve is at controller Vector3 p0 = RegisteredControllers[0].transform.position; List <Vector3> positions = new List <Vector3>() { p0 }; // save last point Vector3 lastPoint = p0; bool hit = false; Vector3 InitialVelocity = RegisteredControllers[0].transform.forward * CurveVelocity; Vector3 velocity = transform.TransformDirection(InitialVelocity); float t = 0; // calculate all points for (int i = 1; i <= NumberOfRayFragments && !hit; i++) { t += 0.3f / ParabolicCurveDeriv(velocity, Physics.gravity, t).magnitude; Vector3 curPoint = GetTrajectoryVector(p0, velocity, Physics.gravity, t); Vector3 diff = curPoint - lastPoint; Ray ray = new Ray(lastPoint, diff.normalized); // check next trajectory part for object collision if (Physics.Raycast(ray, out RaycastHit raycastHit, diff.magnitude)) { VRIL_Navigable navigableObject = raycastHit.transform.gameObject.GetComponent <VRIL_Navigable>(); // valid position in case it is navigable and angle is allowed if (navigableObject && Vector3.Angle(raycastHit.normal, Vector3.up) <= MaximumSurfaceAngle) { TargetPosition = raycastHit.point; PositionSelected = true; if (HitEntity != null) { HitEntity.transform.position = TargetPosition + new Vector3(0f, DistanceHitEntityToGround, 0f); HitEntity.SetActive(true); HitEntity.transform.up = raycastHit.normal; } TargetPosition += new Vector3(0, DistanceViewpointToGround, 0); TeleportLineRenderer.startColor = ValidPositionColor; TeleportLineRenderer.endColor = ValidPositionColor; } else { PositionSelected = false; } positions.Add(raycastHit.point); hit = true; }