Cycling Through a list of Materials

I am trying to build a stereo 360 photo sphere. I want the user to be able to swipe through different environments. To test I want to use the left and right arrow, and later integrate some sort of hand tracking using Oculus Quest.

For now, I am trying to build a script to hold the Materials and control which material is displayed. My initial questions are:

  1. Is there a way to, instead of saying 'Right Arrow goes to Material 1" it can say “Right Arrow goes to the next material in the list”

  2. I cant seem to get the audio clip field active

Any help is very appreciated!

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnvironmentLibrary : MonoBehaviour
{
    //public List<Environment> m_materials = null;
    public Material[] materials;
    Renderer rend;
    //public class Environment
    [Serializable]
    public class Environment
    {
        public Material m_Background = null;
        public AudioClip m_AmbientNoise = null;
    }
    void Start()
    {
        rend = GetComponent<Renderer>();
        rend.enabled = true;
        rend.sharedMaterial = materials[0];
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            rend.sharedMaterial = materials[1];
        }
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            rend.sharedMaterial = materials[0];
        }
    }
}

Use an int (starting at 0) which increases or decreases by 1 every time you press the arrow keys. Then ensure it stays in the array bounds with a little modulus trick:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnvironmentLibrary: MonoBehaviour
{
    //public List<Environment> m_materials = null;
    public Material[] materials;
    private int whichMaterial = 0; // can make public to debug

    Renderer rend;
    //public class Environment
    [Serializable]
    public class Environment
    {
        public Material m_Background = null;
        public AudioClip m_AmbientNoise = null;
    }
    void Start()
    {
        rend = GetComponent<Renderer>();
        rend.enabled = true;
        rend.sharedMaterial = materials[0];
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            whichMaterial++;
            rend.sharedMaterial = materials[Mathf.Abs(whichMaterial % materials.Length)];
        }
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            whichMaterial--;
            rend.sharedMaterial = materials[Mathf.Abs(whichMaterial % materials.Length)];
        }
    }
}

You should look into variables in C#, specifically integers. :slight_smile:

Arrays such as your materials above have a .Length property you can use to decide when you have wrapped or ended.

Well that’s not a lot to go on. AudioClips are not “Active” by themselves but rather played by AudioSources.

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

Ahh, this works very well!

Now, is there a way have one material fade to black, then have the new material fade up from black?

That’s trickier, maybe search around a bit and if you’re really stuck, make a new thread.