Changing Skybox material at runtime?

I have two materials that I’ve defined in the inspector. Both materials are using the Skybox/Cubemap shader.

They live in the Resources/Materials folder. At runtime I’m loading them up in this script. I have two different functions for changing the skybox. The first one ChangeToMaterialOne uses the unmodified material defined in the inspector. This works just fine…

However, in the second function, “ChangeToMaterialTwo” is where my problem is. I am able to get the new texture at runtime, I’ve set a breakpoint and debugged. It’s not null. However, when I’m assigning the texture to _materialTwo and then setting the skybox, something is not working properly.

Once the function is done, the change is not taking affect. Does anyone know why? We have strong possibility of having over 100 different 360 skybox textures that I will need to show and display. I’m hoping that I can figure out how to NOT have to duplicate a One-To-One mapping of 360 texture to 360 material setup… Rather just have one 360 material that can be fed different 360

I’m not positive, but I don’t think it’s the textures themselves. If at design time, I look at my material in the inspector, change it’s texture, then run the app, it will display the proper 360 image. It’s just at runtime that swapping textures does not seem to be working.

using UnityEngine;

public class ChangeSkyboxMaterial : MonoBehaviour
{

    private Material _materialOne;
    private Material _materialTwo;

    public void InitializeSkyboxChanger( )
    {
        _materialOne    = Resources.Load<Material>( "Materials/M1" );
        _materialTwo    = Resources.Load<Material>( "Materials/M2" );
    }


    /// <summary>
    /// Changes the skybox to use material one .
    /// </summary>
    public void ChangeToMaterialOne( )
    {
        RenderSettings.skybox = _materialOne;
    }


    /// <summary>
    /// Changes the skybox to use the 360 photosphere texture material
    /// </summary>
    /// <param name="sphereName">Name of the texture/image to display in the 360 skybox</param>
    public void ChangeToMaterialTwo( string sphereName )
    {
        string path = "PhotoSpheres/" + sphereName;
        Texture t = Resources.Load<Texture>( path );
        if( t != null )
        {
            _materialTwo.mainTexture = t;
            RenderSettings.skybox = _materialTwo;
        }
    }
}

I found the issue and fixed it. I was trying to set the setting mainTexture = T, you use the SetTexture( “_Tex”, t ); function. So, now the function looks like this…

    /// <summary>
    /// Changes the skybox to use the 360 photosphere texture material
    /// </summary>
    /// <param name="sphereName">Name of the texture/image to display in the 360 skybox</param>
    public void ChangeToMaterialTwo( string sphereName )
    {
        string path = "PhotoSpheres/" + sphereName;
        Texture t = Resources.Load<Texture>( path );
        if( t != null )
        {
            _materialTwo.SetTexture( "_Tex",  t );
            RenderSettings.skybox = _materialTwo;
        }
    }
5 Likes

I have a similar problem to yours, which I asked about at Load Texture from persistentDataPath - Unity Engine - Unity Discussions
I read textures from persistentDataPath so I have simple images. How do I create a generic material that is good for any image?