void Start() { if (target == null) { Debug.LogError("No Target specified", gameObject); return; } item = GetComponent <VRInteractableItem>(); if (item == null) { Debug.LogError("This script requires an VRInteracableItem script on the same object", gameObject); return; } target.gameObject.SetActive(startEnabled); _enabled = startEnabled; }
/// <summary> /// Calls method on the focus item, either the hover item or held item. /// </summary> /// <param name="method">Method Name.</param> public void SendFocusItemMethod(string method) { VRInteractableItem item = null; if (heldItem != null) { item = heldItem; } else if (hoverItem != null) { item = hoverItem; } if (item != null && item.CanAcceptMethod(method)) { item.gameObject.SendMessage(method, this, SendMessageOptions.DontRequireReceiver); } }
virtual public void Drop() { if (_heldItem == null || beingDestroyed) { return; } VREvent.Send(GlobalKeys.KEY_DROP, new object[] { _heldItem }); if (hoverItem != null) { hoverItem.DisableHover(this); hoverItem = null; } _lastDropped = Time.time; _heldItem.Drop(true, this); _heldItem = null; if (hideControllersWhileHolding) { ToggleControllers(true); } }
virtual protected bool ItemWithinColliderBounds(VRInteractableItem item) { if (item.triggerColliders.Count == 0) { return(false); } foreach (Collider col in item.triggerColliders) { if (col == null) { Debug.LogError("Item has an empty collider in trigger colliders list: " + item.name, item.gameObject); continue; } //Is the controller anchor offset within the bounds of this collider if (col.bounds.Contains(getControllerAnchorOffset.position)) { return(true); } } return(false); }
void OnGUI() { var oldInteractableItem = interactableItem; interactableItem = (VRInteractableItem)EditorGUILayout.ObjectField("Interactive Item", interactableItem, typeof(VRInteractableItem), true); if (interactableItem == null) { return; } if (oldInteractableItem != interactableItem || serializedItem == null) { Init(); } serializedItem.Update(); SerializedProperty item = serializedItem.FindProperty("item"); if (item.objectReferenceValue == null) { item.objectReferenceValue = EditorGUILayout.ObjectField("Item", item.objectReferenceValue, typeof(Transform), true); if (item.objectReferenceValue == null) { return; } } SerializedProperty linkedLeftAndRightHeldPositions = serializedItem.FindProperty("linkedLeftAndRightHeldPositions"); linkedLeftAndRightHeldPositions.boolValue = EditorGUILayout.Toggle("Linked Left And Right Held Positions", linkedLeftAndRightHeldPositions.boolValue); SerializedProperty heldPosition = serializedItem.FindProperty("heldPosition"); heldPosition.vector3Value = EditorGUILayout.Vector3Field(linkedLeftAndRightHeldPositions.boolValue ? "Held Position" : "Left Held Position", heldPosition.vector3Value); SerializedProperty heldRotation = serializedItem.FindProperty("heldRotation"); Quaternion tempHeldRotation = heldRotation.quaternionValue; tempHeldRotation.eulerAngles = EditorGUILayout.Vector3Field(linkedLeftAndRightHeldPositions.boolValue ? "Held Rotation" : "Left Held Rotation", tempHeldRotation.eulerAngles); heldRotation.quaternionValue = tempHeldRotation; SerializedProperty heldPositionRight = serializedItem.FindProperty("heldPositionRightHand"); SerializedProperty heldRotationRightHand = serializedItem.FindProperty("heldRotationRightHand"); if (!linkedLeftAndRightHeldPositions.boolValue) { heldPositionRight.vector3Value = EditorGUILayout.Vector3Field("Right Held Position", heldPositionRight.vector3Value); Quaternion tempHeldRotationRightHand = heldRotationRightHand.quaternionValue; tempHeldRotationRightHand.eulerAngles = EditorGUILayout.Vector3Field("Right Held Rotation", tempHeldRotationRightHand.eulerAngles); heldRotationRightHand.quaternionValue = tempHeldRotationRightHand; } /*SerializedProperty heldPositionOculus = serializedItem.FindProperty("heldPositionOculus"); * heldPositionOculus.vector3Value = EditorGUILayout.Vector3Field(linkedLeftAndRightHeldPositions.boolValue ? "Held Position Oculus" : "Left Held Position Oculus", heldPositionOculus.vector3Value); * SerializedProperty heldRotationOculus = serializedItem.FindProperty("heldRotationOculus"); * Quaternion tempHeldRotationOculus = heldRotationOculus.quaternionValue; * tempHeldRotationOculus.eulerAngles = EditorGUILayout.Vector3Field(linkedLeftAndRightHeldPositions.boolValue ? "Held Rotation Oculus" : "Left Held Rotation Oculus", tempHeldRotationOculus.eulerAngles); * heldRotationOculus.quaternionValue = tempHeldRotationOculus; * * SerializedProperty heldPositionOculusRightHand = serializedItem.FindProperty("heldPositionOculusRightHand"); * SerializedProperty heldRotationOculusRightHand = serializedItem.FindProperty("heldRotationOculusRightHand"); * if (!linkedLeftAndRightHeldPositions.boolValue) * { * heldPositionOculusRightHand.vector3Value = EditorGUILayout.Vector3Field("Right Held Position Oculus", heldPositionOculusRightHand.vector3Value); * * Quaternion tempHeldRotationOculusRightHand = heldRotationOculusRightHand.quaternionValue; * tempHeldRotationOculusRightHand.eulerAngles = EditorGUILayout.Vector3Field("Right Held Rotation Oculus", tempHeldRotationOculusRightHand.eulerAngles); * heldRotationOculusRightHand.quaternionValue = tempHeldRotationOculusRightHand; * }*/ bool updatePrefab = false; if (controllerInstance == null) { bool makingReferenceController = false; GameObject referenceControllerPrefab = null; if (GUILayout.Button("Create SteamVR Reference Controller")) { makingReferenceController = true; referenceControllerPrefab = Resources.Load <GameObject>("ViveController"); if (referenceControllerPrefab == null) { Debug.LogError("Can't find ViveController in resources"); } } if (GUILayout.Button("Create Oculus Reference Controller")) { makingReferenceController = true; referenceControllerPrefab = Resources.Load <GameObject>("OculusController"); if (referenceControllerPrefab == null) { Debug.LogError("Can't find OculusController in resources"); } } if (makingReferenceController && referenceControllerPrefab != null) { leftHand = true; controllerInstance = (GameObject)Instantiate(referenceControllerPrefab, Vector3.zero, Quaternion.identity); Undo.RegisterCreatedObjectUndo(controllerInstance, "Create Reference Controller"); oldPosition = interactableItem.item.position; oldRotation = interactableItem.item.rotation; oldParent = interactableItem.item.parent; interactableItem.item.SetParent(controllerInstance.transform); interactableItem.item.localPosition = heldPosition.vector3Value; interactableItem.item.localRotation = heldRotation.quaternionValue; Vector3 diff = oldPosition - interactableItem.item.position; controllerInstance.transform.position = diff + heldPosition.vector3Value; controllerInstance.transform.rotation = oldRotation; Selection.activeGameObject = interactableItem.item.gameObject; } } else { EditorGUILayout.HelpBox("Make sure to move the target item and not just the object with this script on", MessageType.Info); bool saveChange = false; if (GUILayout.Button(linkedLeftAndRightHeldPositions.boolValue ? "Save" : "Save Left")) { saveChange = true; heldPosition.vector3Value = interactableItem.item.localPosition; heldRotation.quaternionValue = interactableItem.item.localRotation; } if (!linkedLeftAndRightHeldPositions.boolValue) { if (GUILayout.Button("Save Right")) { saveChange = true; heldPositionRight.vector3Value = interactableItem.item.localPosition; heldRotationRightHand.quaternionValue = interactableItem.item.localRotation; } } if (saveChange) { Undo.SetTransformParent(interactableItem.item, oldParent, "Save Changes"); Undo.RecordObject(interactableItem.item, "Save Changes"); interactableItem.item.position = oldPosition; interactableItem.item.rotation = oldRotation; Undo.DestroyObjectImmediate(controllerInstance); if (attachmentInstance != null && gunHandlerWindow) { updatePrefab = true; } } if (!linkedLeftAndRightHeldPositions.boolValue) { if (GUILayout.Button("Toggle " + (leftHand ? "Right" : "Left") + " Hand Position")) { leftHand = !leftHand; if (leftHand) { interactableItem.item.localPosition = heldPosition.vector3Value; interactableItem.item.localRotation = heldRotation.quaternionValue; } else { interactableItem.item.localPosition = heldPositionRight.vector3Value; interactableItem.item.localRotation = heldRotationRightHand.quaternionValue; } } } if (GUILayout.Button("Select Controller")) { Selection.activeGameObject = controllerInstance; } if (GUILayout.Button("Select Item")) { Selection.activeGameObject = interactableItem.item.gameObject; } if (GUILayout.Button("Cancel")) { Undo.SetTransformParent(interactableItem.item, oldParent, "Cancel"); Undo.RecordObject(interactableItem.item, "Save Changes"); interactableItem.item.position = oldPosition; interactableItem.item.rotation = oldRotation; Undo.DestroyObjectImmediate(controllerInstance); } } serializedItem.ApplyModifiedProperties(); EditorGUILayout.HelpBox("You can set up the held position using either the SteamVR Vive Controller or" + " the Native Oculus Controller. The two systems use a different base rotation so you can either base" + " the held position on steamVR or Oculus, so choose which one then set up all of your held positions with" + " that controller. For the other controller you can use the 'Controller Rotation Offset' value on the interactor" + " script attached to each controller to offset for either the alternative controller or to offset an alternative " + "anchor in the case of an IK hand for when you're not using the controller as the anchor.", MessageType.Info); if (updatePrefab && attachmentInstance != null && gunHandlerWindow && OnSaveEvent != null) { OnSaveEvent(this); } }
virtual protected void OnGUI() { GUILayout.Label("Welcome To The FinalIK hand poser for VRInteraction items", EditorStyles.boldLabel); EditorGUILayout.HelpBox("Reference the VRIK component of the target character you want to set hand poses for, then reference " + "the item you want the hand pose for.", MessageType.Info); var oldVRIK = _vrIK; _vrIK = (VRIK)EditorGUILayout.ObjectField("VRIK", _vrIK, typeof(VRIK), true); if (oldVRIK != null && _vrIK != oldVRIK) { ResetHands(oldVRIK); _handPoseController = null; } _item = (VRInteractableItem)EditorGUILayout.ObjectField("VR Interactable Item", _item, typeof(VRInteractableItem), true); if (_vrIK == null || _item == null || _item.item == null || IsPrefab(_item.item.gameObject)) { return; } if (_handPoseController == null) { _handPoseController = _vrIK.GetComponent <HandPoseController>(); if (_handPoseController == null) { _handPoseController = _vrIK.gameObject.AddComponent <HandPoseController>(); } //Set pose name to default if set foreach (Transform pose in _handPoseController.poses) { if (pose.name == _item.leftHandIKPoseName) { _leftPoseName = pose.name; } if (pose.name == _item.rightHandIkPoseName) { _rightPoseName = pose.name; } } } GUILayout.BeginHorizontal(); switch (_hand) { case Hand.LEFT: GUILayout.Box("Left Hand", GUILayout.ExpandWidth(true)); if (GUILayout.Button("Right Hand")) { _hand = Hand.RIGHT; } break; case Hand.RIGHT: if (GUILayout.Button("Left Hand")) { _hand = Hand.LEFT; } GUILayout.Box("Right Hand", GUILayout.ExpandWidth(true)); break; } GUILayout.EndHorizontal(); Transform handTrans = _hand == Hand.LEFT ? _vrIK.references.leftHand : _vrIK.references.rightHand; if (handTrans == null) { EditorGUILayout.HelpBox("VRIK left or right hand reference is null", MessageType.Error); return; } DefaultPoses(); bool changed = ShowExistingPoses(); if (changed) { if (_hand == Hand.LEFT && _leftPoseIndex < _handPoseController.poses.Count && _handPoseController.poses[_leftPoseIndex] != null) { _leftPoseName = _handPoseController.poses[_leftPoseIndex].name; } else if (_rightPoseIndex < _handPoseController.poses.Count && _handPoseController.poses[_rightPoseIndex] != null) { _rightPoseName = _handPoseController.poses[_rightPoseIndex].name; } } if (_hand == Hand.LEFT) { _leftPoseName = EditorGUILayout.TextField("Pose Name", _leftPoseName); } else { _rightPoseName = EditorGUILayout.TextField("Pose Name", _rightPoseName); } if (GUILayout.Button("Move Hand To Item")) { MoveToItem(); } if (GUILayout.Button("Reset Hand")) { ResetHands(_vrIK); } EditorGUI.BeginDisabledGroup((_hand == Hand.LEFT ? _vrIK.references.leftHand : _vrIK.references.rightHand) == null || string.IsNullOrEmpty(_hand == Hand.LEFT ? _leftPoseName : _rightPoseName)); if (GUILayout.Button("Select Hand Object")) { Selection.activeGameObject = _hand == Hand.LEFT ? _vrIK.references.leftHand.gameObject : _vrIK.references.rightHand.gameObject; } if (GUILayout.Button("Save Pose")) { SaveHand(); } EditorGUI.EndDisabledGroup(); }
virtual public void OnEnable() { interactableItem = (VRInteractableItem)target; }
public override void OnInspectorGUI() { serializedObject.Update(); SerializedProperty controllerAnchor = serializedObject.FindProperty("controllerAnchor"); SerializedProperty controllerAnchorOffset = serializedObject.FindProperty("controllerAnchorOffset"); GUIContent controllerAnchorContent = new GUIContent("Controller Anchor", "Reference the hand of a IK model if you are using one, otherwise leave blank to use the controller"); if (controllerAnchor.objectReferenceValue == null) { controllerAnchor.objectReferenceValue = interactor.transform; } var oldControllerAnchor = controllerAnchor.objectReferenceValue; EditorGUILayout.PropertyField(controllerAnchor, controllerAnchorContent); if (oldControllerAnchor != controllerAnchor.objectReferenceValue) { if (controllerAnchorOffset.objectReferenceValue != null) { DestroyImmediate(((Transform)controllerAnchorOffset.objectReferenceValue).gameObject); } controllerAnchorOffset.objectReferenceValue = null; } if (controllerAnchorOffset.objectReferenceValue == null) { Transform newAnchorOffset = null; foreach (Transform trans in (Transform)controllerAnchor.objectReferenceValue) { if (trans.name == VRInteractor.AnchorOffsetName) { newAnchorOffset = trans; break; } } if (newAnchorOffset == null) { interactor.controllerAnchor = (Transform)controllerAnchor.objectReferenceValue; } controllerAnchorOffset.objectReferenceValue = newAnchorOffset == null ? interactor.getControllerAnchorOffset : newAnchorOffset; } EditorGUILayout.PropertyField(controllerAnchorOffset); SerializedProperty ikTarget = serializedObject.FindProperty("ikTarget"); GUIContent ikTargetContent = new GUIContent("IK Target", "If using an IK rig this should be the hand target the rig is pointing to." + " Either this object or a child transform"); EditorGUILayout.PropertyField(ikTarget, ikTargetContent); SerializedProperty referenceObject = serializedObject.FindProperty("objectReference"); GUIContent referenceContent = new GUIContent("Object Reference", "The object reference will be set to held at the start. You can use this if you want to fix a gun to the player that can't be dropped"); referenceObject.objectReferenceValue = EditorGUILayout.ObjectField(referenceContent, referenceObject.objectReferenceValue, typeof(GameObject), true); if (badObjectReference) { EditorGUILayout.HelpBox("Object reference must be an instance in the scene and must have a VRInteractableItem (or something that inherits) script attached", MessageType.Warning); } if (referenceObject.objectReferenceValue != null) { SerializedProperty objectReferenceIsPrefab = serializedObject.FindProperty("objectReferenceIsPrefab"); badObjectReference = false; PrefabType objectPrefabType = PrefabUtility.GetPrefabType(referenceObject.objectReferenceValue); VRInteractableItem interactableItem = ((GameObject)referenceObject.objectReferenceValue).GetComponentInChildren <VRInteractableItem>(); if (interactableItem == null) { badObjectReference = true; referenceObject.objectReferenceValue = null; } objectReferenceIsPrefab.boolValue = objectPrefabType == PrefabType.ModelPrefab || objectPrefabType == PrefabType.Prefab; } SerializedProperty checkItemAngle = serializedObject.FindProperty("checkItemAngle"); EditorGUILayout.PropertyField(checkItemAngle); if (checkItemAngle.boolValue) { SerializedProperty itemCheckHalfAngle = serializedObject.FindProperty("itemCheckHalfAngle"); EditorGUILayout.PropertyField(itemCheckHalfAngle); } SerializedProperty useHoverLine = serializedObject.FindProperty("useHoverLine"); EditorGUILayout.PropertyField(useHoverLine); if (useHoverLine.boolValue) { SerializedProperty hoverLineMat = serializedObject.FindProperty("hoverLineMat"); EditorGUILayout.PropertyField(hoverLineMat); } SerializedProperty hideControllersWhileHolding = serializedObject.FindProperty("hideControllersWhileHolding"); GUIContent hideControllerContent = new GUIContent("Held Hide Controller", "Hide Controllers While Holding Item"); hideControllersWhileHolding.boolValue = EditorGUILayout.Toggle(hideControllerContent, hideControllersWhileHolding.boolValue); SerializedProperty triggerHapticPulse = serializedObject.FindProperty("triggerHapticPulse"); GUIContent triggerHapticPulseContent = new GUIContent("Trigger Haptic Pulse", "Determines whether or not haptic pulses can be triggered from this VRInteractor. " + "This is desirable for using VRInteractor with VRTK Simulators."); triggerHapticPulse.boolValue = EditorGUILayout.Toggle(triggerHapticPulseContent, triggerHapticPulse.boolValue); SerializedProperty forceGrabDirection = serializedObject.FindProperty("forceGrabDirection"); GUIContent forceGrabDirectionContent = new GUIContent("Force Grab Direction", "Local Controller Direction, use (1,0,0) for palm or (0,0,1) for forward"); EditorGUILayout.PropertyField(forceGrabDirection, forceGrabDirectionContent); SerializedProperty forceGrabDistance = serializedObject.FindProperty("forceGrabDistance"); EditorGUILayout.PropertyField(forceGrabDistance); SerializedProperty _vrRigRoot = serializedObject.FindProperty("_vrRigRoot"); GUIContent vrRigRootContent = new GUIContent("VR Rig Root", "Can usually leave null and it will be found automatically, if it is wrong you can set it here"); EditorGUILayout.PropertyField(_vrRigRoot, vrRigRootContent); serializedObject.ApplyModifiedProperties(); EditorGUILayout.HelpBox( "The VRInteractor script implements the 'Input Received' method called by VRInput, " + "it then calls the method matching the action name to any hovered or held VRInteractableItem.\n" + "By default an item can respond to:\n" + "PICKUP_DROP: Can Pickup a hovered item or drop the currently held item\n" + "PICKUP: Can Pickup a hovered item\n" + "DROP: Drops the currently held item\n" + "ACTION: Calls PICKUP if no item is held (The BasicToggle script uses this to toggle the light on and off)", MessageType.Info); }
virtual protected void CheckHover() { if (_heldItem != null) //If were holding something { if (_highlighting) //If were holding something and still highligting then stop { highlighting = false; } return; //End of update (We're holding something so no need to carry on) } VRInteractableItem closestItem = null; float closestDist = float.MaxValue; bool forceGrab = false; foreach (VRInteractableItem item in VRInteractableItem.items) { if (item == null || !item.CanInteract()) { continue; } Vector3 controllerPosition = getControllerAnchorOffset.position; Vector3 targetPosition = item.GetWorldHeldPosition(this); if (checkItemAngle) { float angle = Vector3.Angle(getControllerAnchorOffset.forward, (targetPosition - controllerPosition).normalized); if (angle > itemCheckHalfAngle) { continue; } } float dist = Vector3.Distance(controllerPosition, targetPosition); if (dist > closestDist) { continue; } bool canGrab = false; bool isForceGrab = false; if (dist < item.interactionDistance || ItemWithinColliderBounds(item)) { canGrab = true; } if ((item.interactionDistance < forceGrabDistance && VRUtils.PositionWithinCone(controllerPosition, getControllerAnchorOffset.TransformVector(new Vector3(vrInput.IsLeftHand ? forceGrabDirection.x : -forceGrabDirection.x, forceGrabDirection.y, forceGrabDirection.z)), targetPosition, 20f, forceGrabDistance))) { canGrab = true; isForceGrab = true; } if (canGrab) { forceGrab = isForceGrab; closestDist = dist; closestItem = item; } } if (hoverItem != null && hoverItem != closestItem) { highlighting = false; hoverItem.DisableHover(this); } if (closestItem != null && (hoverItem != closestItem)) { ForceGrabToggle forceToggle = GetComponent <ForceGrabToggle>(); bool forceToggleAllowed = true; if (forceToggle != null) { forceToggleAllowed = !forceGrab || !vrInput.ActionPressed(forceToggle.actionName); } if (_lastDropped + 0.5f < Time.time && forceToggleAllowed && (vrInput.ActionPressed(GlobalKeys.KEY_ACTION) || vrInput.ActionPressed(GlobalKeys.KEY_PICKUP_DROP) || vrInput.ActionPressed(GlobalKeys.KEY_PICKUP))) { hoverItem = closestItem; string actionDown = GlobalKeys.KEY_PICKUP; if (vrInput.ActionPressed(GlobalKeys.KEY_PICKUP_DROP)) { actionDown = GlobalKeys.KEY_PICKUP_DROP; } else if (vrInput.ActionPressed(GlobalKeys.KEY_ACTION)) { actionDown = GlobalKeys.KEY_ACTION; } SendMessage(GlobalKeys.KEY_INPUT_RECEIVED, actionDown, SendMessageOptions.DontRequireReceiver); return; } else if (hoverItem != closestItem) { highlighting = true; closestItem.EnableHover(this); } } hoverItem = closestItem; }