在 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 循环会运行多个帧。
我正在为 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 循环会运行多个帧。