/// <summary> /// Stop listening for button presses if the plug stops touching the handle /// </summary> /// <param name="collision"></param> private void OnTriggerExit(Collider other) { Plug touchingPlug = other.transform.GetComponentInActor <Plug>(); if (touchingPlug != null) { VRTK_InteractableObject plugInteractable = touchingPlug.GetComponent <VRTK_InteractableObject>(); ObservePlugGrabbedState(plugInteractable, false); if (plugInteractable.IsGrabbed()) { GameObject grabbingController = touchingPlug.GetComponent <VRTK_InteractableObject>().GetGrabbingObject(); grabbingController.GetComponent <VRTK_ControllerEvents>().ButtonOnePressed -= OnMergeButtonPressed; } } }
protected virtual void UnlockPlug() { if (nearbyPlugs.Contains(LockedPlug)) { //Move Plug to the back of the nearby list nearbyPlugs.Remove(LockedPlug); nearbyPlugs.Add(LockedPlug); } LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectUngrabbed -= OnLockedPlugUngrabbed; LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectGrabbed -= OnLockedPlugGrabbed; LockedPlug.AttachUnlock(this); LockedPlug = null; lockedPlugGrabber = null; }
private IEnumerator ExtendPlug(Plug p, GameObject plugAttach, Vector3 target) { p.gameObject.SetActive(true); plugAttach.transform.position = PlugStart.position; plugAttach.transform.rotation = PlugStart.rotation; p.PlugTransform.position = PlugStart.position; p.PlugTransform.rotation = PlugStart.rotation; plugAttach.GetComponent <SnapToTargetPosition>().SnapToTarget(target, ExtendSpeed); p.GetComponent <VRTK_InteractableObject>().isGrabbable = true; while (plugAttach != null && !plugAttach.GetComponent <SnapToTargetPosition>().HasReachedTarget) { yield return(new WaitForEndOfFrame()); } }
public void DisconnectFromDataEndpoint() { DestinationEndpoint.Disconnect(connectedCord, CordAttachPoint); DestinationEndpoint = null; transform.GetComponent <VRTK_TransformFollow>().gameObjectToFollow = null; PlugTransform.GetComponent <CapsuleCollider>().center = plugColliderCenter; PlugTransform.GetComponent <CapsuleCollider>().height = plugColliderHeight; Transform oppositeNode = GetOppositeCordNode(); Plug p = oppositeNode.GetComponentInActor <Plug>(); if (p != null && !p.IsPluggedIn()) { connectedCord.Flow = 0; } }
private IEnumerator RetractPlug(Plug p, GameObject plugAttach) { plugAttach.GetComponent <SnapToTargetPosition>().SnapToTarget(PlugStart.position, ExtendSpeed); p.GetComponent <VRTK_InteractableObject>().isGrabbable = false; while (plugAttach != null && !plugAttach.GetComponent <SnapToTargetPosition>().HasReachedTarget) { yield return(new WaitForEndOfFrame()); } p.gameObject.SetActive(false); if (primaryPlug.Equals(p)) { cord.gameObject.SetActive(false); } state = State.Free; }
/// <summary> /// Collapse the cord if one of the following conditions are met: /// 1. Both ends of the cord are plugs and neither plug is plugged in /// 2. One end of the cord is an unplugged plug and the other is a BranchHandle. /// </summary> private IEnumerator TryCollapseRoutine() { yield return(null); if (!IsPluggedIn() && connectedCord != null) { Transform oppositeNode = GetOppositeCordNode(); Plug p = oppositeNode.GetComponentInActor <Plug>(); if (p != null && !p.IsPluggedIn()) { connectedCord.Collapse(); } else if (oppositeNode.GetComponent <BranchHandle>()) { connectedCord.Collapse(); } } }
/// <summary> /// Disregard whether the plug is grabbed or not- lock it and connect it to the socket /// </summary /// <param name="p"></param> public void ForcePlugLockAndConnect(Plug p) { if (p.AttachLock(this)) { if (p.GetComponent <VRTK_InteractableObject>().IsGrabbed()) { lockedPlugGrabber = p.GetComponent <VRTK_InteractableObject>().GetGrabbingObject().GetComponentInActor <VRTK_InteractGrab>(); } else { lockedPlugGrabber = null; } LockedPlug = p; LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectUngrabbed += OnLockedPlugUngrabbed; LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectGrabbed += OnLockedPlugGrabbed; LockedPlug.ConnectToDataEndpoint(plugReceptacle); } }
/// <summary> /// This method searches the network of cords connected to this cord in the direction determined by reverseFlow. /// /// For a given cord, flow is positive if the cord flows from A -> B (i.e. A is the output and B is the input) /// Flow is negative if the cords flows from B -> A /// /// When searching, we look for nodes that are 'downstream' from the start point. This means we only take paths with positive flow during our search. /// This is reversed when searching for output jacks /// /// </summary> /// <param name="reverseFlow"></param> /// <param name="cordPos"></param> /// <returns></returns> public HashSet <PhysicalDataEndpoint> GetConnectedEndpoints(bool reverseFlow, Transform searchStartNode) { HashSet <PhysicalDataEndpoint> results = new HashSet <PhysicalDataEndpoint>(); float workingFlow = Flow; if (reverseFlow) { workingFlow = -workingFlow; } if (workingFlow > 0 && !B.Equals(searchStartNode)) { BranchHandle handleB = B.GetComponent <BranchHandle>(); results.UnionWith(GetEndpointsConnectedToHandle(reverseFlow, handleB)); Plug plugB = B.GetComponentInActor <Plug>(); PhysicalDataEndpoint connectedReceptacle = GetConnectedEndpoint(plugB); if (connectedReceptacle != null) { results.Add(connectedReceptacle); } } else if (workingFlow < 0 && !A.Equals(searchStartNode)) { BranchHandle handleA = A.GetComponent <BranchHandle>(); results.UnionWith(GetEndpointsConnectedToHandle(reverseFlow, handleA)); Plug plugA = A.GetComponentInActor <Plug>(); PhysicalDataEndpoint connectedReceptacle = GetConnectedEndpoint(plugA); if (connectedReceptacle != null) { results.Add(connectedReceptacle); } } return(results); }
public void Connect(Transform start, Transform end) { A = start; B = end; Plug plugA = A.GetComponentInActor <Plug>(); ConnectPlug(plugA); Plug plugB = B.GetComponentInActor <Plug>(); ConnectPlug(plugB); if (Flow != 0) { Flowing = true; } else { Flowing = false; } }
protected virtual void TryLockPlug(Plug p) { if (p.GetComponent <VRTK_InteractableObject>().IsGrabbed()) { float flow = p.ConnectedCord.Flow; if (p.CordAttachPoint.Equals(p.ConnectedCord.StartNode)) { flow = -flow; } bool validReceptacleType = (flow > 0 && GetComponent <PhysicalDataInput>() != null) || (flow < 0 && GetComponent <PhysicalDataOutput>() != null) || flow == 0; if (validReceptacleType) { if (p.AttachLock(this)) { lockedPlugGrabber = p.GetComponent <VRTK_InteractableObject>().GetGrabbingObject().GetComponentInActor <VRTK_InteractGrab>(); LockedPlug = p; LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectUngrabbed += OnLockedPlugUngrabbed; LockedPlug.GetComponent <VRTK_InteractableObject>().InteractableObjectGrabbed += OnLockedPlugGrabbed; } } } }
// Update is called once per frame void Update() { if (A != null && B != null) { if (!collapsing) { //Start a path from the origin if (path.Count == 0) { path.Add(A.position); } if (!lastPos.Equals(B.position)) { updateLine = false; //Extend path if the end moves if (path.Count > 0) { if (Vector3.Distance(path.Last(), B.position) > SegmentLength) { path.Add(B.position); updateLine = true; timeRelaxed = 0; } } } //Add on to the beginning of the cord if the start point is not at the beginning of the cord path if (A.gameObject.activeSelf && path[0] != A.position) { if (Vector3.Distance(path[0], A.position) > SegmentLength) { path.Insert(0, A.position); updateLine = true; timeRelaxed = 0; } } if (timeRelaxed < RelaxTime) { timeRelaxed += Time.deltaTime; for (int i = 0; i < RelaxIterationsPerFrame; i++) { RelaxPath(); } updateLine = true; } if (updateLine) { UpdateLine(); UpdateBoundingBox(); } if (nearbyControllers.Count > 0) { UpdateBranchHandles(); } lastPos = B.position; TranslateFlowTexture(); } else if (collapsing) { int lineVertCount = collapseEnd - collapseStart; if (lineVertCount <= 1) { OnCollapseFinished(); } else { //Only render the portion of the path that has not yet been collapsed lineRenderer.positionCount = lineVertCount + 1; Vector3[] collapsingPath = new Vector3[lineRenderer.positionCount]; int j = 0; for (int i = collapseStart; i <= collapseEnd; i++) { collapsingPath[j] = path[i]; j += 1; } lineRenderer.SetPositions(collapsingPath); //Rotate plugs to point away from their movement direction Plug plugA = A.GetComponentInActor <Plug>(); if (plugA != null) { if (plugALookVector != Vector3.zero) { plugA.PlugTransform.transform.rotation = Quaternion.Slerp(plugA.PlugTransform.transform.rotation, Quaternion.LookRotation(plugALookVector), COLLAPSE_ROTATION_SPEED * Time.deltaTime); } plugA.GetComponent <CordFollower>().Speed += COLLAPSE_ACCELERATION; } Plug plugB = B.GetComponentInActor <Plug>(); if (plugB != null) { if (plugBLookVector != Vector3.zero) { plugB.PlugTransform.transform.rotation = Quaternion.Slerp(plugB.PlugTransform.transform.rotation, Quaternion.LookRotation(plugBLookVector), COLLAPSE_ROTATION_SPEED * Time.deltaTime); } plugB.GetComponent <CordFollower>().Speed += COLLAPSE_ACCELERATION; } //Play the collapse particle effect when the cord is almost completely collapsed if (lineRenderer.positionCount < COLLAPSE_PARTICLE_FIRE_COUNT && collapseParticles != null && !collapseParticles.gameObject.activeSelf) { collapseParticles.gameObject.SetActive(true); if (plugA != null && plugB != null) { collapseParticles.transform.position = GetPathPointAtIndex((collapseEnd - collapseStart) / 2 + collapseStart); } else if (plugA != null) { collapseParticles.transform.position = GetPathPointAtIndex(path.Count - 1); } else { collapseParticles.transform.position = GetPathPointAtIndex(0); } collapseParticles.Play(); } } } } }