Reputation: 3
In my Unity VR project, I implemented an eyetracking-feature according to this tutorial: https://www.youtube.com/watch?v=ZoySn7QlMfQ
This solution requires the usage of the InteractionRigOVR (see screenshot below). Hierarchy
As long as the InteractionRig and everything inside of it is placed at 0, 0, 0 - everything works completely fine. But I need to move this setup to another location of my VR-World to let the "player" have a proper starting position.
Problem: If I just move the whole InteractionRig, the players camera is at the proper position, but the eyetracking-feature (left and right eyeInteractors) still spawns at 0, 0, 0 and is a bit offset. Same for the CameraRig. Moving the TrackingSpace changes nothing and repositioning the EyeInteractors or the ReferenceFrame lets them still spawn at 0, 0, 0.
To the EyeInteractors, following script is attached:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class EyeTrackingRay : MonoBehaviour
{
[SerializeField]
private float rayDistance = 1.0f;
[SerializeField]
private float rayWidth = 0.01f;
[SerializeField]
private LayerMask layersToInclude;
[SerializeField]
private Color rayColorDefaultState = Color.yellow;
[SerializeField]
private Color rayColorHoverState = Color.red;
private LineRenderer lineRenderer;
private List<EyeInteractable> eyeInteractables = new List<EyeInteractable>();
public GameObject location;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
SetupRay();
}
void SetupRay()
{
lineRenderer.useWorldSpace = false;
lineRenderer.positionCount = 2;
lineRenderer.startWidth = rayWidth;
lineRenderer.endWidth = rayWidth;
lineRenderer.startColor = rayColorDefaultState;
lineRenderer.endColor = rayColorDefaultState;
lineRenderer.SetPosition(0, location.transform.position);
lineRenderer.SetPosition(1, new Vector3(location.transform.position.x, location.transform.position.y, location.transform.position.z + rayDistance));
}
void FixedUpdate()
{
RaycastHit hit;
Vector3 rayCastDirection = transform.TransformDirection(Vector3.forward) * rayDistance;
if (Physics.Raycast(transform.position, rayCastDirection, out hit, Mathf.Infinity, layersToInclude))
{
UnSelect();
lineRenderer.startColor = rayColorHoverState;
lineRenderer.endColor = rayColorHoverState;
var eyeInteractable = hit.transform.GetComponent<EyeInteractable>();
eyeInteractables.Add(eyeInteractable);
eyeInteractable.IsHovered = true;
} else {
lineRenderer.startColor = rayColorDefaultState;
lineRenderer.endColor = rayColorDefaultState;
UnSelect(true);
}
}
void UnSelect(bool clear = false)
{
foreach (var interactable in eyeInteractables)
{
interactable.IsHovered = false;
}
if(clear)
{
eyeInteractables.Clear();
}
}
}
In Start(), the EyetrackingRay is getting setup with the SetupRay() method where among other things the position of the LineRenderer gets set. I tried alot playing around with those numbers in the lineRenderer.setPosition-arguments and ended up with the GameObject named "location" solution which simply refers the starting position of the LineRenderer. With this approach, the EyeTrackingRay can be spawned at a different location, but this defuses the whole eyetracking-feature.
Maybe there is someone out there, understanding what is happening here and who can post a solution for this problem or atleast can tell why it´s behaving like that. Thanks in advance.
Upvotes: 0
Views: 52
Reputation: 90570
I think the main issue is you never update the line positions.
Have in mind that Vector3
is a struct
=> Value type (like int
, bool
, etc).
The value returned by the property transform.position
is just a copy.
There is no "connection" whatsoever between the lineRenderer
positions and the transform.position
. You are just assigning a snapshot in the moment of Start
.
You rather want to keep them up-to-date
private void FixedUpdate()
{
// also note that since you are using LOCAL space you probably do not want to include the absolute worldspace positions here either
lineRenderer.SetPosition(0, Vector3.zero);
lineRenderer.SetPosition(1, Vectro3.forward * rayDistance));
// Otherwise you would rather want to keep
//lineRenderer.useWorldSpace = true;
// and use absolute positions
lineRenderer.SetPosition(0, location.transform.position);
lineRenderer.SetPosition(1, location.transform.position + transform.forward * rayDistance));
...
}
Upvotes: 0