Milan Frinken
Milan Frinken

Reputation: 3

Why are these GameObjects in Unity VR keep spawning at 0, 0, 0?

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

Answers (1)

derHugo
derHugo

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

Related Questions