1

I have a device in my hand. I want to snap this device in my hand to the surface of the target object in a VR scene. I am using SteamVR plugin. When I bring my device closer to the target object, the device is snapped to the target object. I want to move it on the target's surface laterally and not allow it to penetrate the surface. The snapping does work but it does not snap properly. I am a beginner at this and need help. Thank you.

I expect it to snap like this (see image below) and I want to be able to move it laterally over the surface.enter image description here

How it currently snaps right now: enter image description here Device is snapped in a wrong way and also penerates the surface even though I have used colliders. I used the following script for snapping and attached it to device gameobject.

public class SnapToSurface : MonoBehaviour
{
    public bool ShouldSnap = false;

    // Assign your vr controller to this.
    public Transform HandToTrack;

    // The collider of the surface object you want to snap to.
    public Collider SurfaceToSnapTo;
    public float snapDistance = 0.1f; // The distance at which snapping should be enabled
    public Rigidbody rb;
    public float snapHeightOffset = 0.01f; // Offset to snap slightly above the surface
   
    private Vector3 initialPosition; // Initial position of the dermatoscope for resetting

    private void Update()
    {
        Vector3 p = SurfaceToSnapTo.ClosestPoint(HandToTrack.position);
        float d = Vector3.Distance(p, HandToTrack.position);
       
            if (ShouldSnap)
            {
                if (d < snapDistance)
                {
                    Debug.Log("Enters");
                    // Calculate the closest point on the mesh collider.
                    Vector3 closestPoint = SurfaceToSnapTo.ClosestPoint(HandToTrack.position);

                    

                    // Snap the device to the target surface with the desired height offset
                    this.transform.position = closestPoint + (SurfaceToSnapTo.transform.up * snapHeightOffset);
                    // Align the rotation of the device with the VR controller
                    
                    float rotY = HandToTrack.localEulerAngles.y;
                    float rotX = HandToTrack.localEulerAngles.x;
                    float rotZ = HandToTrack.localEulerAngles.z;
                    this.transform.localEulerAngles = new Vector3(rotX, rotY, rotZ);
                    rb.isKinematic = true;
                   
                    

            }
                else 
                {
                    rb.isKinematic = false;
                    
                }
            }
        
    }
   
}

Rimini23
  • 11
  • 1

2 Answers2

0

Can you provide a screenshot of the device gameobject in the scene view and its structure in the hierarchy? I am interested to see where its pivot point is, as this line

this.transform.position = closestPoint + (SurfaceToSnapTo.transform.up * snapHeightOffset);

positions the device onto the surface (with an offset distance), but with the pivot point set to the center of the object, and thus it sinks into the surface.

0

You can wrap your device model under an empty gameobject and attach your script to it. See screeshot below. The position of this empty GO will be the pivot point. (Remember to switch the handle tool from "Center" to "Pivot" to visualize the gizmo in your scene view)

Then you can adjust the transform of your device model under it without affecting the pivot's position.

This is a very common way of setting pivot for an object.

Screenshot-pivot-wrapper