在 Unity3d 中为 VR 360 度图像应用更改 Material 球体焦点

Change Material of a Sphere on Focus for VR 360 Degree Image App in Unity3d

我正在为 google-cardboard 创建一个应用程序,类似于 360 度图像的应用程序。 我创建了一个球体,并制作了 62 material 个不同的 360 度图像。 我创建了 2 个按钮,下一个和上一个,当我关注下一个按钮时,它会根据需要更改为下一个 material。但是当我专注于上一个按钮时,它会变为我不想要的最后一个 material。我要的只是前面的material.

这是我的代码。看看并告诉我我做错了什么。谢谢

using UnityEngine;
using System.Collections;

public class next : MonoBehaviour {

    public CardboardHead head;
    public Material[] myMaterials = new Material[60];
    int maxMaterials;
    int arrayPos = 0;
    public GameObject Sphere;
    public int timeToCompleteLoading = 3;
    bool wait = false;

    void Start ()
    {
        head = Camera.main.GetComponent<StereoController> ().Head;
        maxMaterials = myMaterials.Length-1;

    }

    public void ToggleVRMode() 
    {
        Cardboard.SDK.VRModeEnabled = !Cardboard.SDK.VRModeEnabled;
    }

    IEnumerator RadialProgress(float time)
    {
        wait = true;
        yield return new WaitForSeconds(time);

        float rate = 1 / time;
        float i = 0;
        while (i < 1)
        {
            i += Time.deltaTime * rate;
            gameObject.renderer.material.SetFloat("_Progress", i);

        }
        wait = false;
    }

    void updateMaterials(){
        if (collider.gameObject.tag == "next") {
            if (arrayPos == maxMaterials){
                arrayPos = 0;
            }else{

                arrayPos++;
                Sphere.renderer.material = myMaterials [arrayPos];
            }
        }
         if (collider.gameObject.tag == "previous") {
            if (arrayPos == 0){
                arrayPos = maxMaterials;
            }else{
                arrayPos--;
                Sphere.renderer.material = myMaterials [arrayPos];

            }
        }


    }


    void Update ()
    {
        RaycastHit hit;
        Collider collider = GetComponent<Collider> ();

        if (collider) {

            bool isLookAt = collider.Raycast (head.Gaze, out hit, Mathf.Infinity);
            if (isLookAt == true) {
                if(wait == false){
                    StartCoroutine (RadialProgress (timeToCompleteLoading));

                    updateMaterials();
                }
            }
        }
    }
}

你描述的有问题。有 60 个材料,所以 maxMaterial 应该是 59(0 到 59 是 60 个点)。但是你说它显示 61 和 60,那应该是越界的。此外,由于 maxMaterial 为 59 (60 -1),当您的索引为 60 或 61 时,您的 if 语句不起作用。

您可以这样评价:

 void updateMaterials(){
    if (collider.gameObject.tag == "next") {
        if (++arrayPos == myMaterials.Length){
            arrayPos = 0;
        }
    }
    else if (collider.gameObject.tag == "previous") {
        if (--arrayPos < 0){
            arrayPos = myMaterials.Length - 1;
        }
    }
    Sphere.renderer.material = myMaterials [arrayPos];
}

P.S.: 正如我在评论中提到的,协程中的 while 循环不会执行任何延迟过程:

    while (i < 1)
    {
        i += Time.deltaTime * rate;
        gameObject.renderer.material.SetFloat("_Progress", i);
    }

while 循环在单帧内运行。

    while (i < 1)
    {
        i += Time.deltaTime * rate;
        gameObject.renderer.material.SetFloat("_Progress", i);
        yield return null;
    }

现在 while 循环会运行多个帧。