Problem with collider transform inside coroutine, with collider attached to a bone

Hi folks. I am trying to implement a slider control that can be interacted with using a virtual finger (attached to a hand controlled by a razer hydra).

I’ve simplified here for illustration but basically I want to select a slider/button (sphere) with a finger tip and draw a line between the finger tip and the slider control. I then want to update the line as the hand moves around so it always connects the fingertip and the control.

If I do this in a coroutine CheckControl(), the line is drawn from the slider to an OFFSET position where the fingertip WAS when the scene first starts (i.e. when in T-pose)… if I move the entire humanoid, the line updates but always connects off to the side instead of where the fingertip collider actually is when I move the hands around (as though the collider is parented to the humanoid root bone instead of the finger tip bone). I can see the collider in the correct position on the fingertip in the scene view, but the line does not connect to it.

Can anyone shed any light on what I might be doing wrong?

Thanks


Simplified setup:

  • Rigged humanoid model with IK rig for the arms, which are controlled using hydra controllers
  • Empty object attached to an index finger, with a box collider and a rigidbody (no gravity)
  • A sphere (slider control) that I want to trigger. With a sphere collider and trigger=true
  • Script below attached to the sphere control (trigger)
  • When OnTriggerEnter called, I get a reference to the collider (finger tip) that triggered the sphere and use that in the coroutine (or update) to draw a line between sphere and finger tip

Code:

using UnityEngine;
using System.Collections;

public class SliderTest : MonoBehaviour
{
    protected LineRenderer m_LineRenderer = null;
    protected Collider m_Collider = null;
    protected bool m_Active = false;

    void Start()
    {
        // create connection line
        m_LineRenderer = gameObject.AddComponent<LineRenderer>();
        m_LineRenderer.material = new Material(Shader.Find("Particles/Additive"));
        m_LineRenderer.SetColors(Color.blue, Color.green);
        m_LineRenderer.SetWidth(0.01f, 0.01f);
        m_LineRenderer.SetVertexCount(0);
    }

    protected IEnumerator CheckControl()
    {
        while (m_Active)
        {
           Debug.Log("m_Collider.transform.position " + m_Collider.transform.position);

           // draw connection line
           m_LineRenderer.SetVertexCount(2);
           m_LineRenderer.SetPosition(0, m_Collider.transform.position);
           m_LineRenderer.SetPosition(1, transform.position);

           yield return null;
        }

        m_Active = false;
    }

    void OnTriggerEnter(Collider obj)
    {
        Debug.Log("Triggered By: " + obj.tag);

        if (!m_Active)
        {
            m_Collider = obj;
            m_Active = true;

            StartCoroutine(CheckControl());
        }
    }
}

After sitting on this problem for days I finally worked out the solution.

I needed to call:

yield return new WaitForFixedUpdate();

instead of:

yield return null;

…inside the coroutine. I’m not sure if the behaviour has changed from Unity version 4.4, as it was working previously without the call to WaitForFixedUpdate()

Hope this helps someone!

thanks,
Allan