How to modify Grabable scripts?
I renamed HandGrabInteractable to HandleLeft and confirmed that the grab functionality is working well. Additionally, I want to save the position when HandleLeft is grabbed and moved, and create a new object at that position. So, I wanted to add a public bool DropDown variable inside the Grabbable script and set DropDown = true during EndTransform(), but it keeps getting deleted automatically. I'm not sure how to solve this issue. Please help. + Additionally, the PointableElement, IGrabbable properties are not enabled. (The font color does not change.) Note : Visual Studio 2022 , Unity 2022.03.20f1,meta XR interaction SDK 63.00 /* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System.Collections.Generic; using UnityEngine; namespace Oculus.Interaction { /// <summary> /// Moves the object it's attached to when an Interactor selects that object. /// </summary> public class Grabbable : PointableElement, IGrabbable { /// <summary> /// A One Grab...Transformer component, which should be attached to the grabbable object. Defaults to One Grab Free Transformer. /// If you set the Two Grab Transformer property and still want to use one hand for grabs, you must set this property as well. /// </summary> [Tooltip("A One Grab...Transformer component, which should be attached to the grabbable object. Defaults to One Grab Free Transformer. If you set the Two Grab Transformer property and still want to use one hand for grabs, you must set this property as well.")] [SerializeField, Interface(typeof(ITransformer))] [Optional(OptionalAttribute.Flag.AutoGenerated)] private UnityEngine.Object _oneGrabTransformer = null; /// <summary> /// A Two Grab...Transformer component, which should be attached to the grabbable object. /// If you set this property but also want to use one hand for grabs, you must set the One Grab Transformer property. /// </summary> [Tooltip("A Two Grab...Transformer component, which should be attached to the grabbable object. If you set this property but also want to use one hand for grabs, you must set the One Grab Transformer property.")] [SerializeField, Interface(typeof(ITransformer)), Optional] private UnityEngine.Object _twoGrabTransformer = null; [Tooltip("The target transform of the Grabbable. If unassigned, " + "the transform of this GameObject will be used.")] [SerializeField] [Optional(OptionalAttribute.Flag.AutoGenerated)] private Transform _targetTransform; /// <summary> /// The maximum number of grab points. Can be either -1 (unlimited), 1, or 2. /// </summary> [Tooltip("The maximum number of grab points. Can be either -1 (unlimited), 1, or 2.")] [SerializeField] private int _maxGrabPoints = -1; public int MaxGrabPoints { get { return _maxGrabPoints; } set { _maxGrabPoints = value; } } public Transform Transform => _targetTransform; public List<Pose> GrabPoints => _selectingPoints; private ITransformer _activeTransformer = null; private ITransformer OneGrabTransformer; private ITransformer TwoGrabTransformer; protected override void Awake() { base.Awake(); OneGrabTransformer = _oneGrabTransformer as ITransformer; TwoGrabTransformer = _twoGrabTransformer as ITransformer; } protected override void Start() { this.BeginStart(ref _started, () => base.Start()); if (_targetTransform == null) { _targetTransform = transform; } if (_oneGrabTransformer != null) { this.AssertField(OneGrabTransformer, nameof(OneGrabTransformer)); OneGrabTransformer.Initialize(this); } if (_twoGrabTransformer != null) { this.AssertField(TwoGrabTransformer, nameof(TwoGrabTransformer)); TwoGrabTransformer.Initialize(this); } // Create a default if no transformers assigned if (OneGrabTransformer == null && TwoGrabTransformer == null) { OneGrabFreeTransformer defaultTransformer = gameObject.AddComponent<OneGrabFreeTransformer>(); _oneGrabTransformer = defaultTransformer; OneGrabTransformer = defaultTransformer; OneGrabTransformer.Initialize(this); } this.EndStart(ref _started); } public override void ProcessPointerEvent(PointerEvent evt) { switch (evt.Type) { case PointerEventType.Select: EndTransform(); break; case PointerEventType.Unselect: ForceMove(evt); EndTransform(); break; case PointerEventType.Cancel: EndTransform(); break; } base.ProcessPointerEvent(evt); switch (evt.Type) { case PointerEventType.Select: BeginTransform(); break; case PointerEventType.Unselect: BeginTransform(); break; case PointerEventType.Move: UpdateTransform(); break; } } private void ForceMove(PointerEvent releaseEvent) { PointerEvent moveEvent = new PointerEvent(releaseEvent.Identifier, PointerEventType.Move, releaseEvent.Pose, releaseEvent.Data); ProcessPointerEvent(moveEvent); } // Whenever we change the number of grab points, we save the // current transform data private void BeginTransform() { // End the transform on any existing transformer before we // begin the new one EndTransform(); int useGrabPoints = _selectingPoints.Count; if (_maxGrabPoints != -1) { useGrabPoints = Mathf.Min(useGrabPoints, _maxGrabPoints); } switch (useGrabPoints) { case 1: _activeTransformer = OneGrabTransformer; break; case 2: _activeTransformer = TwoGrabTransformer; break; default: _activeTransformer = null; break; } if (_activeTransformer == null) { return; } _activeTransformer.BeginTransform(); } private void UpdateTransform() { if (_activeTransformer == null) { return; } _activeTransformer.UpdateTransform(); } private void EndTransform() { if (_activeTransformer == null) { return; } _activeTransformer.EndTransform(); _activeTransformer = null; } protected override void OnDisable() { if (_started) { EndTransform(); } base.OnDisable(); } #region Inject public void InjectOptionalOneGrabTransformer(ITransformer transformer) { _oneGrabTransformer = transformer as UnityEngine.Object; OneGrabTransformer = transformer; } public void InjectOptionalTwoGrabTransformer(ITransformer transformer) { _twoGrabTransformer = transformer as UnityEngine.Object; TwoGrabTransformer = transformer; } public void InjectOptionalTargetTransform(Transform targetTransform) { _targetTransform = targetTransform; } #endregion } } ā1.3KViews0likes0CommentsUnity Help Needed: Preserving Object Position After Grab and Instantiating New Object
I renamed HandGrabInteractable to HandleLeft and confirmed that the grab functionality is working well. Additionally, I want to save the position when HandleLeft is grabbed and moved, and create a new object at that position. So, I wanted to add a public bool DropDown variable inside the Grabbable script and set DropDown = true during EndTransform(), but it keeps getting deleted automatically. I'm not sure how to solve this issue. Please help.. + the PointableElement, IGrabbable properties are not enabled. (The font color does not change.) Note: Visual Studio 2022, Unity 2022.03.20f1, meta XR interaction SDK 63.00 /* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * Licensed under the Oculus SDK License Agreement (the "License"); * you may not use the Oculus SDK except in compliance with the License, * which is provided at the time of installation or download, or which * otherwise accompanies this software in either electronic or hard copy form. * * You may obtain a copy of the License at * * https://developer.oculus.com/licenses/oculussdk/ * * Unless required by applicable law or agreed to in writing, the Oculus SDK * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System.Collections.Generic; using UnityEngine; namespace Oculus.Interaction { /// <summary> /// Moves the object it's attached to when an Interactor selects that object. /// </summary> public class Grabbable : PointableElement, IGrabbable { /// <summary> /// A One Grab...Transformer component, which should be attached to the grabbable object. Defaults to One Grab Free Transformer. /// If you set the Two Grab Transformer property and still want to use one hand for grabs, you must set this property as well. /// </summary> [Tooltip("A One Grab...Transformer component, which should be attached to the grabbable object. Defaults to One Grab Free Transformer. If you set the Two Grab Transformer property and still want to use one hand for grabs, you must set this property as well.")] [SerializeField, Interface(typeof(ITransformer))] [Optional(OptionalAttribute.Flag.AutoGenerated)] private UnityEngine.Object _oneGrabTransformer = null; /// <summary> /// A Two Grab...Transformer component, which should be attached to the grabbable object. /// If you set this property but also want to use one hand for grabs, you must set the One Grab Transformer property. /// </summary> [Tooltip("A Two Grab...Transformer component, which should be attached to the grabbable object. If you set this property but also want to use one hand for grabs, you must set the One Grab Transformer property.")] [SerializeField, Interface(typeof(ITransformer)), Optional] private UnityEngine.Object _twoGrabTransformer = null; [Tooltip("The target transform of the Grabbable. If unassigned, " + "the transform of this GameObject will be used.")] [SerializeField] [Optional(OptionalAttribute.Flag.AutoGenerated)] private Transform _targetTransform; /// <summary> /// The maximum number of grab points. Can be either -1 (unlimited), 1, or 2. /// </summary> [Tooltip("The maximum number of grab points. Can be either -1 (unlimited), 1, or 2.")] [SerializeField] private int _maxGrabPoints = -1; public int MaxGrabPoints { get { return _maxGrabPoints; } set { _maxGrabPoints = value; } } public Transform Transform => _targetTransform; public List<Pose> GrabPoints => _selectingPoints; private ITransformer _activeTransformer = null; private ITransformer OneGrabTransformer; private ITransformer TwoGrabTransformer; protected override void Awake() { base.Awake(); OneGrabTransformer = _oneGrabTransformer as ITransformer; TwoGrabTransformer = _twoGrabTransformer as ITransformer; } protected override void Start() { this.BeginStart(ref _started, () => base.Start()); if (_targetTransform == null) { _targetTransform = transform; } if (_oneGrabTransformer != null) { this.AssertField(OneGrabTransformer, nameof(OneGrabTransformer)); OneGrabTransformer.Initialize(this); } if (_twoGrabTransformer != null) { this.AssertField(TwoGrabTransformer, nameof(TwoGrabTransformer)); TwoGrabTransformer.Initialize(this); } // Create a default if no transformers assigned if (OneGrabTransformer == null && TwoGrabTransformer == null) { OneGrabFreeTransformer defaultTransformer = gameObject.AddComponent<OneGrabFreeTransformer>(); _oneGrabTransformer = defaultTransformer; OneGrabTransformer = defaultTransformer; OneGrabTransformer.Initialize(this); } this.EndStart(ref _started); } public override void ProcessPointerEvent(PointerEvent evt) { switch (evt.Type) { case PointerEventType.Select: EndTransform(); break; case PointerEventType.Unselect: ForceMove(evt); EndTransform(); break; case PointerEventType.Cancel: EndTransform(); break; } base.ProcessPointerEvent(evt); switch (evt.Type) { case PointerEventType.Select: BeginTransform(); break; case PointerEventType.Unselect: BeginTransform(); break; case PointerEventType.Move: UpdateTransform(); break; } } private void ForceMove(PointerEvent releaseEvent) { PointerEvent moveEvent = new PointerEvent(releaseEvent.Identifier, PointerEventType.Move, releaseEvent.Pose, releaseEvent.Data); ProcessPointerEvent(moveEvent); } // Whenever we change the number of grab points, we save the // current transform data private void BeginTransform() { // End the transform on any existing transformer before we // begin the new one EndTransform(); int useGrabPoints = _selectingPoints.Count; if (_maxGrabPoints != -1) { useGrabPoints = Mathf.Min(useGrabPoints, _maxGrabPoints); } switch (useGrabPoints) { case 1: _activeTransformer = OneGrabTransformer; break; case 2: _activeTransformer = TwoGrabTransformer; break; default: _activeTransformer = null; break; } if (_activeTransformer == null) { return; } _activeTransformer.BeginTransform(); } private void UpdateTransform() { if (_activeTransformer == null) { return; } _activeTransformer.UpdateTransform(); } private void EndTransform() { if (_activeTransformer == null) { return; } _activeTransformer.EndTransform(); _activeTransformer = null; } protected override void OnDisable() { if (_started) { EndTransform(); } base.OnDisable(); } #region Inject public void InjectOptionalOneGrabTransformer(ITransformer transformer) { _oneGrabTransformer = transformer as UnityEngine.Object; OneGrabTransformer = transformer; } public void InjectOptionalTwoGrabTransformer(ITransformer transformer) { _twoGrabTransformer = transformer as UnityEngine.Object; TwoGrabTransformer = transformer; } public void InjectOptionalTargetTransform(Transform targetTransform) { _targetTransform = targetTransform; } #endregion } }890Views0likes1CommentHand grab interaction fails if OVRCameraRig is child of high speed moving object
Hi all, I'm facing an unexpected scenario while using the grab feature provided by the Meta Interaction SDK. It looks like that if the OVRCameraRig object (with OVRHands and/or OVRControllerHands properly configured with HandGrabInteractors) is set as child of a "moving object" (together with the objects designed to be grabbed), depending on the speed of this object the grab actions fail. The scenario I'm working on is a train cabin moving along binaries designed as a spline path, with the VR user/player (represented by the OVRCameraRig object) parented to this cabin, since it must be inside the moving train. Inside the cabin I have a lever that must be grabbed to modify the speed of the train. At slow speeds the lever can be grabbed without problems, while increasing a little bit the speed, the lever can't be grabbed anymore! I tested it multiple times, trying to understand the root cause of the failure. I guess it's something related to the frequency of checks for the hands vs the lever intersections/collisions made by the Meta scripts. However I couldn't find any solution. Is that something I'm missing in the documentation? Maybe some script property to be set or fine tuned? NOTE: I don't think it would be acceptable, in a 3D application, to invert the scenario where the train is still and the whole environment is moving towards it.... Of course in this case both the objects to grab and the "player" would be still and the grabbing action should work like a charm. But I still believe it is an ugly workaround. Is someone having any clue on how to fix this "misbehaviour"? Thanks in advance!1.4KViews0likes2Comments[Unity] Instantiate prefab while selecting an object
Hi, How can i instantiate a grabbable prefab when i select a grabbable object? For example, i would instantiate on my hand a sphere after i grabbed a cube, without move the cube. The instantiated sphere will be a grabbable object of course, so i can interact with the world or simply throw it š849Views0likes0CommentsProblem: Position constraints of an object with HandTracking (using "OneGrabTranslateTransformer")
(Message a little long to try to explain as well as possible, don't panic, the problem comes down to the question ^^) I also want to say that if you have another solution to this problem, that is to say another method than mine, I'm interested too. The most important thing is that I can implement what I want. Not necessarily the way I imagine it! Thanks in advance for your answers. Hello, In a VR application, where the player uses HandTracking. I want to make him take an object in a bag (The bag is hung on a wall to avoid complicating the problem, and it can't be grabbed). Of course, I don't want the object to go through the bag, so I want to force the player to remove the object from the bottom. For this, I used the script "One Grab Translate Transformer", which allowed me to get the result. I then added a Cube with a box collider, and the option "Is Trigger" checked, to trigger an event when the object comes in contact with it. Here, the event resets the values of "One Grab Translate Transformer" to 0. To disable the constraints. And it works! But unfortunately there is a problem. Of course, after this event, I can move my object in space on the X, Y and Z axes. But my object does not rotate anymore! Why not? Here is a video of the problem : https://youtu.be/U9RYa2u8lsQ In this video (https://www.youtube.com/watch?v=PU8SQ2Obviw), I saw that using a "Box Collider" can prevent objects from passing through other objects. But this doesn't seem to apply to hand-held objects. But I'm probably wrong, so maybe there is a simpler solution on this side. ---- Here is a last video using the objects from the official Oculus example scene, and showing what I want to avoid with a box. Since in the end, my problem can be applied to any box, in any situation: https://youtu.be/WxSXLrMELXw ---- Finally, here is the code: For the "OneGrabTranslateTransformer" script, I didn't change anything, except adding getters and setters to the constraints: public class OneGrabTranslateTransformer : MonoBehaviour, ITransformer { [Serializable] public class OneGrabTranslateConstraints { public bool constraintsAreRelative; public FloatConstraint minX; public FloatConstraint maxX; public FloatConstraint minY; public FloatConstraint maxY; public FloatConstraint minZ; public FloatConstraint maxZ; public bool ConstraintsAreRelative { get => constraintsAreRelative; set => constraintsAreRelative = value; } public FloatConstraint MinX { get => minX; set => minX = value; } public FloatConstraint MaxX { get => maxX; set => maxX = value; } public FloatConstraint MinY { get => minY; set => minY = value; } public FloatConstraint MaxY { get => maxY; set => maxY = value; } public FloatConstraint MinZ { get => minZ; set => minZ = value; } public FloatConstraint MaxZ { get => maxZ; set => maxZ = value; } } ⦠---------------- For the "FloatConstraint" script, I added a "resetValue()" function that allows to reset the constraint values to 0: namespace Oculus.Interaction { [Serializable] public class FloatConstraint { public bool Constrain = false; public float Value = 0.0f; public void resetValue() { this.Constrain = false; this.Value = 0.0f; } } } --------------- In the Trigger cube script, I simply used the "OnTriggerEnter" function, checking the object tag to avoid triggering the script anyhow: public class EnterTriggerCagoule : MonoBehaviour { public DisableConstraint disable; public string tag = ""; private void OnTriggerEnter(Collider other) { if (other.CompareTag(tag)) { disable.disableConstraint(); } } } ----------------- Finally, this is what my disableConstraint() function looks like: public void disableConstraint() { constraints.MinX.resetValue(); constraints.MaxX.resetValue(); constraints.MinY.resetValue(); constraints.MaxY.resetValue(); constraints.MinZ.resetValue(); constraints.MaxZ.resetValue(); } As you can see, my scripts are not very complicated, and I NEVER touch the rotation values, and I never apply constraints to them. So I am surprised by the problem. Hopefully someone can help me. Sincerely, Xameal.1.4KViews1like0CommentsHand Grab Interactable grab Event?
hey I am having trouble finding out which event I need to catch from the HandgGrabInteractable to then from that event call a function. In my case the Photon.RequestOwnership(), on the grabbed object. Here is what I have until now, with help from ChatGPT, and my own research as to what exists and what it just made up and trying to adjust it acordingly: What it should do is, using the PhotonView component and the Hand Grab Interactable, catch the grab event and then get the target of that grab event (being the object being grabbed) to then find the Objects PhotonView component and then call the RequestOwnership() method on it. Alternative Solutions to come to the same result or advice for it is also welcome.2KViews1like0CommentsDistanceGrab Example, the object does not stay still in my hand when I move during the grab
Hi everyone, I have a problem with object grab, I'm using Unity 2022 and Oculus integration 0.46 I take the official oculus example : DistanceGrab Problem: when I grab an object and move, the object doesn't stay still in my hand but moves to the opposite side, I attach the video so it's clearer. Is there a solution to this? Thanks for support.2.7KViews0likes4Comments