首页 > 解决方案 > 子对象的统一移动

问题描述

我正在创建一个小型演示,其中对象应根据来自 FOVE VR 耳机的眼动仪数据移动。

当我尝试移动我的两个对象时(“Gaze Responder - Target”和“Gaze Responder - Fixation”):它们不移动,碰撞器停止工作。

我在 Unity3d (2017.4.40f1) 中有以下层次结构

Unity3d中的层次结构

以下代码附加到 GazeContingenVisualField

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VisualField_test : FOVEBehavior
{
    private GameObject Target;
    private GameObject Fixation;

    private GameObject TargetGazeObj;
    private GameObject FixationGazeObj;

    private Collider collider_Fixation;
    private Collider collider_Target;

    private float TimeShowFix;

    private float T_ShowStim = 5.1f;
    private float T_TimeOut = 10.0f;

    private float[] StimPos_H_deg = { 0, 0, 0, 10, -10, 10, 10, -10, -10 };
    private float[] StimPos_V_deg = { 0, 10, -10, 0, 0, 10, -10, 10, -10 };
    private float[] StimPos_H = new float[100];
    private float[] StimPos_V = new float[100];


    private Material materialTarget;
    private Material materialFixaton;

    public enum StateTypes { WaitStart, TargetOn, TargetTimeOut, TargetSeen };
    public StateTypes CurrentState = StateTypes.WaitStart;
    public int idx_stimpos = 0;


    // Use this for initialization
    void Start()
    {
        for (int i = 0; i < StimPos_H_deg.Length; i++)
        {
            StimPos_H[i] = Mathf.Tan(StimPos_H_deg[i] / 180.0F * Mathf.PI) * 20.0F;
            StimPos_V[i] = Mathf.Tan(StimPos_V_deg[i] / 180.0F * Mathf.PI) * 20.0F;
        }

        Target = transform.Find("Gaze Responder - Target").gameObject;
        Fixation = transform.Find("Gaze Responder - Fixation").gameObject;

        TargetGazeObj = Target.transform.Find("Gazable object").gameObject;
        FixationGazeObj = Fixation.transform.Find("Gazable object").gameObject;

        materialTarget = TargetGazeObj.GetComponent<Renderer>().material;
        materialFixaton = FixationGazeObj.GetComponent<Renderer>().material;

        collider_Fixation = FixationGazeObj.GetComponent<Collider>();
        collider_Target = TargetGazeObj.GetComponent<Collider>();

        materialTarget.DisableKeyword("_EMISSION");

        materialFixaton.EnableKeyword("_EMISSION");
        materialFixaton.SetColor("_EmissionColor", Color.green);

    }

    // Update is called once per frame
    void Update()
    {

        switch (CurrentState)
        {
            case StateTypes.WaitStart:
                if (FoveInterface.Gazecast(collider_Fixation))
                {
                    CurrentState = StateTypes.TargetOn;
                    TimeShowFix = Time.time;

                    materialFixaton.EnableKeyword("_EMISSION");
                    materialFixaton.SetColor("_EmissionColor", Color.white);

                }

                break;
            case StateTypes.TargetOn:
                if (FoveInterface.Gazecast(collider_Target))
                {
                    CurrentState = StateTypes.TargetSeen;
                    materialTarget.EnableKeyword("_EMISSION");
                    materialTarget.SetColor("_EmissionColor", Color.yellow);
                }

               else if (Time.time <= TimeShowFix + T_ShowStim)
                {
                    materialTarget.EnableKeyword("_EMISSION");
                    materialTarget.SetColor("_EmissionColor", Color.white);
                }
                else
                {
                    materialTarget.DisableKeyword("_EMISSION");
                }

                if (Time.time >= TimeShowFix + T_TimeOut)
                {
                    CurrentState = StateTypes.TargetTimeOut;
                }


                break;
            case StateTypes.TargetTimeOut:
                idx_stimpos = (idx_stimpos +1) % StimPos_H.Length ;
                materialTarget.DisableKeyword("_EMISSION");
                Target.transform.localPosition = new Vector3(StimPos_H[idx_stimpos], StimPos_V[idx_stimpos], 0.0f);
                CurrentState = StateTypes.TargetOn;
                TimeShowFix = Time.time;
                break;

            case StateTypes.TargetSeen:
                idx_stimpos = (idx_stimpos + 1) % StimPos_H.Length;
                materialTarget.DisableKeyword("_EMISSION");

                Fixation.transform.localPosition = Target.transform.localPosition;
                Target.transform.localPosition = new Vector3(StimPos_H[idx_stimpos], StimPos_V[idx_stimpos], 5.0f);
                CurrentState = StateTypes.TargetOn;
                TimeShowFix = Time.time;

                break;
        }
    }
}

using Fove.Unity;
using UnityEngine;

public class FOVEBehavior: MonoBehaviour
{
    private static FoveInterface foveInterface;
    public static FoveInterface FoveInterface
    {
        get
        {
            if (foveInterface == null)
            {
                // returns the first FoveInterface found here but you should adapt this code to your game
                // especially in the case where you could have no or several FoveInterface in your game
                foveInterface = FindObjectOfType<FoveInterface>();
            }

            return foveInterface;
        }
    }
}

标签: c#unity3d

解决方案


我不确定 FOVE 是如何工作的,但它是否以某种方式重置了“-Target”对象变换?

当我使用 AR 时,一些游戏对象(目标)无法移动,因为它们的变换由库处理,并且试图这样做会导致各种奇怪的问题。

也许你想要移动的是实际的“Gazable Objects”(我知道这是 VR,但也许是同一个问题)。

如果有的话,在最后一个 case 语句中,您将 Fixation 的本地位置设置为 TargetGazeObj 的本地位置,但它们的坐标参考可能不同,因此您可能希望在那里使用全局位置。


推荐阅读