Search Unity

Question Center object on raycast from playerCamera to hitPoint breaks on camera tilt

Discussion in 'Scripting' started by afransella, Jan 28, 2023.

  1. afransella

    afransella

    Joined:
    Mar 16, 2017
    Posts:
    2
    Hey there, I'm trying to essentially have a disc/ring appear to be centered in front of a hitPoint. The hitpoint location is determined by a raycast from the right controller of a VR headset. To center it in front of the playerCamera I am casting a ray from the playerCamera to the hitPoint. I've tried a number of different methods for this, and they all mostly work except for one thing: when I tilt my head sideways, the ring always looks to shift up/down relative to the hitPoint. If I pause it and edit the Z-Axis rotation of the ring it seems to recenter it, but of course then it's off center when I'm not tilted.

    I'm assuming this has something to do with the peculiarities of complex rotations and what's considered 'up' and 'forward' in Unity, but it's above my understanding. Has anyone done this before? Pasting one approach to this part of the code below. Thanks!


    Code (CSharp):
    1. if (Physics.Raycast(rightHand.position, rightHand.forward, out hit, maxDistance, layerMask))
    2.         {
    3.              if (isAnimating == false)
    4.             {
    5.             hitPoint = hit.point;
    6.             CameraParent.position = hitPoint;
    7.              // Calculate the direction from the camera to the hitpoint to position mask objects
    8.             Vector3 direction = hitPoint - playerCamera.position;
    9.             Vector3 directionR = hitPoint - playerCameraR.position;
    10.             Vector3 camToHit = hitPoint - playerCamera.position;
    11.             Vector3 objectPos = playerCamera.position + camToHit.normalized * distance;
    12.             discParentL.position = objectPos;
    13.             discParentL.LookAt(hitPoint);
    14.             }
    15.         }
     
    Last edited: Jan 28, 2023
  2. afransella

    afransella

    Joined:
    Mar 16, 2017
    Posts:
    2
    Nvm, answered my own question! I wrote a script to place an empty object directly between the two VR player cameras, then rotate that object by the average of the two cameras. Then I rotate the disc/ring by that amount, but only on the z-axis. This keeps everything nicely lined up.
    Code (CSharp):
    1. //rotate the camera center to stay in line with the two cameras
    2.             Quaternion rotation = Quaternion.Lerp(playerCamera.rotation, playerCameraR.rotation, 0.5f);
    3.             playerCameraCenter.rotation = rotation;
    4.             // Here we copy the z-axis rotation of playerCameraCenter to discParentL
    5.             Quaternion currentRotation = discParentL.rotation;
    6.             Quaternion targetRotation = playerCameraCenter.rotation;
    7.             discParentL.rotation = Quaternion.Euler(currentRotation.eulerAngles.x, currentRotation.eulerAngles.y, targetRotation.eulerAngles.z);
    8.  
    9.             Quaternion currentRotationR = discParentR.rotation;
    10.             Quaternion targetRotationR = playerCameraCenter.rotation;
    11.             discParentR.rotation = Quaternion.Euler(currentRotationR.eulerAngles.x, currentRotationR.eulerAngles.y, targetRotationR.eulerAngles.z);
    Note that I kept the code from above where I was positioning the disc on the raycast.