2025-07-09 01:01:06 -04:00
using UnityEngine ;
using System.Collections ;
using System.Collections.Generic ;
using UnityEngine.Rendering ;
[ExecuteInEditMode]
[AddComponentMenu("Skybox Blender/Skybox Blender")]
public class SkyboxBlender : MonoBehaviour
{
[Tooltip("The materials you want to blend to linearly.")]
2025-07-18 18:43:09 +08:00
public List < Material > skyboxMaterials ;
[Tooltip("Checking this will instantly make the first material your current skybox.")]
public bool makeFirstMaterialSkybox ;
2025-07-09 01:01:06 -04:00
[Min(0), Tooltip("The speed of the blending between the skyboxes.")]
2025-07-18 18:43:09 +08:00
public float blendSpeed = 0.5f ;
[Min(0), Tooltip("The time to wait before blending the next skybox material.")]
public float timeToWait = 0f ;
[Tooltip("If enabled, will loop the materials list. When the blender reaches the last skybox in the list, it'll blend back to the first one.")]
public bool loop = true ;
2025-07-09 01:01:06 -04:00
[Tooltip("If enabled, the lighting of the world will be updated to that of the skyboxes blending.")]
public bool updateLighting ;
[Tooltip("If enabled, the reflections of the world will be updated to that of the skyboxes blending.")]
2025-07-18 18:43:09 +08:00
public bool updateReflections ;
2025-07-09 01:01:06 -04:00
[Range(1, 30), Tooltip("Set how many frames need to pass during blend before updating the reflections & lighting each time. Updating these take a toll on performance so the higher this number is, the more performant your game will be (during blend) but the less accurate the lighting & reflections update will be. The less this number is, the slower the game will be but the accuracy increases. By average the best performance/accuracy results is setting it between 5-10.")]
2025-07-18 18:43:09 +08:00
public int updateEveryFrames = 5 ;
2025-07-09 01:01:06 -04:00
[Tooltip("Keep rotating the skybox infinetly while blending.")]
public bool keepRotating ;
[Tooltip("if you would prefer a certain degree to rotate the skybox to during blending - 360 is a full turn.")]
2025-07-18 18:43:09 +08:00
public float rotateToAngle = 180 ;
2025-07-09 01:01:06 -04:00
[Min(0), Tooltip("The speed of the skybox rotation.")]
2025-07-18 18:43:09 +08:00
public float rotationSpeed ;
2025-07-09 01:01:06 -04:00
[Tooltip("If enabled, the rotation will stop when the blend finishes. If disabled, even after blending the skybox will continue rotating. TAKE NOTE: if loop is enabled in blend options. This will not take effect.")]
public bool stopRotationOnBlendFinish ;
#region SYSTEM VARIABLES
2025-07-18 18:43:09 +08:00
Material defaultSkyboxMaterial ;
Material skyboxBlenderMaterial ;
Texture currentTexture ;
2025-07-09 01:01:06 -04:00
2025-07-18 18:43:09 +08:00
float totalBlendValue = 1f ;
2025-07-09 01:01:06 -04:00
public float blendValue { private set ; get ; }
2025-07-18 18:43:09 +08:00
float defaultBlend ;
float defaultRotation ;
float rotationSpeedValue ;
2025-07-09 01:01:06 -04:00
2025-07-18 18:43:09 +08:00
int index = 0 ;
public int CurrentIndex
{
2025-07-09 01:01:06 -04:00
get { return index ; }
}
2025-07-18 18:43:09 +08:00
int indexToBlend ;
2025-07-09 01:01:06 -04:00
int usedBlend ;
int LightAndReflectionFrames ;
2025-07-18 18:43:09 +08:00
bool linearBlending ;
bool currentSkyboxNotFirstMaterialBlending ;
2025-07-09 01:01:06 -04:00
bool comingFromLoop ;
2025-07-18 18:43:09 +08:00
bool rotateSkybox ;
bool oneTickBlend = false ;
bool stillRunning = false ;
bool singleBlend = false ;
2025-07-09 01:01:06 -04:00
bool stopped = false ;
bool blendByIndex ;
bool stopRotation ;
bool blendFinished ;
bool blendingCurrentSkyToListNotSingleBlend ;
bool isLinearBlend ;
bool isSetReflectionProbeOnStart ;
2025-07-18 18:43:09 +08:00
ReflectionProbe reflectionProbe ;
Cubemap cubemap = null ;
2025-07-09 01:01:06 -04:00
#endregion
#region UNITY METHODS
2025-07-18 18:43:09 +08:00
void Awake ( )
2025-07-09 01:01:06 -04:00
{
// load the material
skyboxBlenderMaterial = Resources . Load ( "Material & Shader/Skybox Blend Material" , typeof ( Material ) ) as Material ;
2025-07-18 18:43:09 +08:00
if ( skyboxBlenderMaterial )
2025-07-09 01:01:06 -04:00
{
defaultBlend = skyboxBlenderMaterial . GetFloat ( "_BlendCubemaps" ) ;
defaultRotation = skyboxBlenderMaterial . GetFloat ( "_Rotation" ) ;
defaultSkyboxMaterial = skyboxBlenderMaterial ;
InspectorAndAwakeChanges ( ) ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
Debug . LogWarning ( "Can't find Skybox Blend Material in resources. Please re-import!" ) ;
}
2025-07-18 18:43:09 +08:00
if ( updateLighting | | updateReflections )
2025-07-09 01:01:06 -04:00
{
SetReflectionProbe ( ) ;
UpdateLightingAndReflections ( true ) ;
}
}
void OnValidate ( )
{
2025-07-18 18:43:09 +08:00
if ( skyboxBlenderMaterial = = null )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial = Resources . Load ( "Material & Shader/Skybox Blend Material" , typeof ( Material ) ) as Material ;
}
InspectorAndAwakeChanges ( ) ;
}
void OnApplicationQuit ( )
{
// return the material to original blend
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , defaultBlend ) ;
skyboxBlenderMaterial . SetFloat ( "_Rotation" , defaultRotation ) ;
2025-07-18 18:43:09 +08:00
if ( currentTexture ! = null )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetTexture ( "_Tex" , currentTexture ) ;
}
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
RenderSettings . skybox = defaultSkyboxMaterial ;
}
2025-07-18 18:43:09 +08:00
void Update ( )
2025-07-09 01:01:06 -04:00
{
// when in editor mode, set the skybox material in the skybox linearBlendmaterial
2025-07-18 18:43:09 +08:00
if ( ! Application . isPlaying )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( RenderSettings . skybox = = null )
{
2025-07-09 01:01:06 -04:00
return ;
}
2025-07-18 18:43:09 +08:00
if ( RenderSettings . skybox . HasProperty ( "_Tex" ) )
2025-07-09 01:01:06 -04:00
{
skyboxBlenderMaterial . SetTexture ( "_Tex" , RenderSettings . skybox . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint" , RenderSettings . skybox . GetColor ( "_Tint" ) ) ;
}
return ;
}
2025-07-18 18:43:09 +08:00
if ( updateReflections & & ! isSetReflectionProbeOnStart )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( ! SetReflectionProbeTexture ( ) )
{
2025-07-09 01:01:06 -04:00
return ;
}
}
// skybox blending linearly the list
2025-07-18 18:43:09 +08:00
if ( linearBlending & & ! stopped )
2025-07-09 01:01:06 -04:00
{
// set the type of the used blending
usedBlend = 1 ;
blendValue + = Time . deltaTime * blendSpeed ;
2025-07-18 18:43:09 +08:00
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , blendValue ) ;
2025-07-09 01:01:06 -04:00
UpdateLightingAndReflections ( ) ;
2025-07-18 18:43:09 +08:00
if ( skyboxBlenderMaterial . GetFloat ( "_BlendCubemaps" ) > = totalBlendValue )
2025-07-09 01:01:06 -04:00
{
blendFinished = true ;
linearBlending = false ;
blendValue = 0f ;
StopAllCoroutines ( ) ;
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , 0f ) ;
SetSkyBoxes ( true , index , false , 0 , true ) ;
UpdateLightingAndReflections ( true ) ;
2025-07-18 18:43:09 +08:00
if ( comingFromLoop )
2025-07-09 01:01:06 -04:00
{
index = 0 ;
}
// increment index and linearBlend if not reached end
2025-07-18 18:43:09 +08:00
if ( ( index + 1 ) < skyboxMaterials . Count )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( ! comingFromLoop )
{
2025-07-09 01:01:06 -04:00
index + + ;
}
comingFromLoop = false ;
SetSkyBoxes ( true , index ) ;
2025-07-18 18:43:09 +08:00
if ( index + 1 < skyboxMaterials . Count )
{
SetSkyBoxes ( false , 0 , true , index + 1 ) ;
2025-07-09 01:01:06 -04:00
}
2025-07-18 18:43:09 +08:00
if ( index - ( skyboxMaterials . Count - 1 ) > 0 )
{
2025-07-09 01:01:06 -04:00
if ( ! oneTickBlend ) linearBlending = true ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
if ( ! oneTickBlend ) StartCoroutine ( WaitBeforeBlending ( ) ) ;
}
}
// if reached end and loopable
2025-07-18 18:43:09 +08:00
if ( index > = skyboxMaterials . Count - 1 )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( loop )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( oneTickBlend )
2025-07-09 01:01:06 -04:00
{
stillRunning = false ;
return ;
}
SetSkyBoxes ( true , index , true , 0 , true ) ;
comingFromLoop = true ;
StartCoroutine ( WaitBeforeBlending ( ) ) ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
stillRunning = false ;
2025-07-18 18:43:09 +08:00
if ( stopRotationOnBlendFinish )
{
2025-07-09 01:01:06 -04:00
StopRotation ( ) ;
}
}
}
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
blendFinished = false ;
}
}
// single blending
if ( singleBlend & & ! stopped )
{
blendValue + = Time . deltaTime * blendSpeed ;
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , blendValue ) ;
UpdateLightingAndReflections ( ) ;
2025-07-18 18:43:09 +08:00
if ( skyboxBlenderMaterial . GetFloat ( "_BlendCubemaps" ) > = totalBlendValue )
2025-07-09 01:01:06 -04:00
{
blendFinished = true ;
singleBlend = false ;
blendValue = 0f ;
StopAllCoroutines ( ) ;
2025-07-18 18:43:09 +08:00
if ( blendByIndex )
2025-07-09 01:01:06 -04:00
{
index = indexToBlend ;
blendByIndex = false ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
if ( index + 1 < skyboxMaterials . Count ) index + + ;
else index = 0 ;
}
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , 0f ) ;
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
SetSkyBoxes ( true , index , false , 0 , true ) ;
UpdateLightingAndReflections ( true ) ;
stillRunning = false ;
2025-07-18 18:43:09 +08:00
if ( stopRotationOnBlendFinish )
{
2025-07-09 01:01:06 -04:00
StopRotation ( ) ;
}
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
blendFinished = false ;
}
}
// blending for if the current skybox is not the same as first material
2025-07-18 18:43:09 +08:00
if ( currentSkyboxNotFirstMaterialBlending & & ! stopped )
2025-07-09 01:01:06 -04:00
{
// set the type of the used blending
usedBlend = 2 ;
blendValue + = Time . deltaTime * blendSpeed ;
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , blendValue ) ;
UpdateLightingAndReflections ( ) ;
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
if ( skyboxBlenderMaterial . GetFloat ( "_BlendCubemaps" ) > = totalBlendValue )
{
blendFinished = true ;
currentSkyboxNotFirstMaterialBlending = false ;
blendValue = 0f ;
StopAllCoroutines ( ) ;
2025-07-18 18:43:09 +08:00
// int indexForFirst = 0;
2025-07-09 01:01:06 -04:00
int indexForSecond = 1 ;
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , 0f ) ;
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials . Count = = 1 )
{
2025-07-09 01:01:06 -04:00
indexForSecond = 0 ;
}
SetSkyBoxes ( true , 0 , true , indexForSecond , true ) ;
UpdateLightingAndReflections ( true ) ;
2025-07-18 18:43:09 +08:00
if ( oneTickBlend )
{
2025-07-09 01:01:06 -04:00
stillRunning = false ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
StartCoroutine ( WaitBeforeBlending ( ) ) ;
}
2025-07-18 18:43:09 +08:00
if ( stopRotationOnBlendFinish & & ! blendingCurrentSkyToListNotSingleBlend )
{
2025-07-09 01:01:06 -04:00
StopRotation ( ) ;
}
blendingCurrentSkyToListNotSingleBlend = false ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
blendFinished = false ;
}
}
// skybox rotation
if ( rotateSkybox & & ! stopRotation )
{
rotationSpeedValue + = Time . deltaTime * rotationSpeed ;
2025-07-18 18:43:09 +08:00
if ( keepRotating )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetFloat ( "_Rotation" , rotationSpeedValue ) ;
}
2025-07-18 18:43:09 +08:00
else
{
if ( skyboxBlenderMaterial . GetFloat ( "_Rotation" ) < rotateToAngle )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetFloat ( "_Rotation" , rotationSpeedValue ) ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
rotateSkybox = false ;
skyboxBlenderMaterial . SetFloat ( "_Rotation" , rotateToAngle ) ;
}
}
}
}
#endregion
#region SYSTEM METHODS
// set the skybox material
2025-07-18 18:43:09 +08:00
void SetSkyBoxes ( bool firstTex = false , int firstTexIndex = 0 , bool secondTex = false , int secondTexIndex = 0 , bool apply = false )
2025-07-09 01:01:06 -04:00
{
2025-12-21 16:41:12 +08:00
try
2025-07-09 01:01:06 -04:00
{
2025-12-21 16:41:12 +08:00
if ( firstTex )
{
skyboxBlenderMaterial . SetTexture ( "_Tex" , skyboxMaterials [ firstTexIndex ] . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint" , skyboxMaterials [ firstTexIndex ] . GetColor ( "_Tint" ) ) ;
}
2025-07-09 01:01:06 -04:00
2025-12-21 16:41:12 +08:00
if ( secondTex )
{
skyboxBlenderMaterial . SetTexture ( "_Tex2" , skyboxMaterials [ secondTexIndex ] . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint2" , skyboxMaterials [ secondTexIndex ] . GetColor ( "_Tint" ) ) ;
}
}
catch
2025-07-09 01:01:06 -04:00
{
2025-12-21 16:41:12 +08:00
Debug . LogWarning ( "Skybox Blender: There was an error setting the skybox materials. Please make sure the indices are correct and the materials are assigned." ) ;
2025-07-09 01:01:06 -04:00
}
2025-07-18 18:43:09 +08:00
if ( apply )
{
2025-07-09 01:01:06 -04:00
RenderSettings . skybox = skyboxBlenderMaterial ;
}
}
// setup the skybox material before blending
void PrepareMaterialForBlend ( int skyboxIndex )
{
// set texture
skyboxBlenderMaterial . SetTexture ( "_Tex" , RenderSettings . skybox . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetTexture ( "_Tex2" , skyboxMaterials [ skyboxIndex ] . GetTexture ( "_Tex" ) ) ;
// set tint
skyboxBlenderMaterial . SetColor ( "_Tint" , RenderSettings . skybox . GetColor ( "_Tint" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint2" , skyboxMaterials [ skyboxIndex ] . GetColor ( "_Tint" ) ) ;
}
// wait for time for normal blending
IEnumerator WaitBeforeBlending ( )
{
isLinearBlend = true ;
yield return new WaitForSeconds ( timeToWait ) ;
linearBlending = true ;
}
// change skyboxes and material textures on inspector change and script awake
2025-07-18 18:43:09 +08:00
public void InspectorAndAwakeChanges ( )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( makeFirstMaterialSkybox )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials . Count > = 1 )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials [ 0 ] ! = null )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetTexture ( "_Tex" , skyboxMaterials [ 0 ] . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint" , skyboxMaterials [ 0 ] . GetColor ( "_Tint" ) ) ;
2025-07-18 18:43:09 +08:00
RenderSettings . skybox = skyboxBlenderMaterial ;
2025-07-09 01:01:06 -04:00
Debug . Log ( "Skybox set to the first material in the list: " + skyboxMaterials [ 0 ] . name ) ;
}
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
Debug . LogWarning ( "You need to set a material first to make it the skybox" ) ;
}
}
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials ! = null )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials . Count > 1 )
2025-07-09 01:01:06 -04:00
{
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials [ 1 ] ! = null )
{
2025-07-09 01:01:06 -04:00
skyboxBlenderMaterial . SetTexture ( "_Tex2" , skyboxMaterials [ 1 ] . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint2" , skyboxMaterials [ 1 ] . GetColor ( "_Tint" ) ) ;
}
}
}
}
// set reflection probe for reflections
void SetReflectionProbe ( )
{
reflectionProbe = GetComponent < ReflectionProbe > ( ) ;
2025-07-18 18:43:09 +08:00
if ( reflectionProbe = = null )
{
2025-07-09 01:01:06 -04:00
reflectionProbe = gameObject . AddComponent < ReflectionProbe > ( ) as ReflectionProbe ;
}
reflectionProbe . cullingMask = 0 ;
reflectionProbe . refreshMode = ReflectionProbeRefreshMode . ViaScripting ;
reflectionProbe . mode = ReflectionProbeMode . Realtime ;
reflectionProbe . timeSlicingMode = ReflectionProbeTimeSlicingMode . NoTimeSlicing ;
2025-07-18 18:43:09 +08:00
if ( updateReflections )
2025-07-09 01:01:06 -04:00
{
RenderSettings . defaultReflectionMode = DefaultReflectionMode . Custom ;
cubemap = new Cubemap ( reflectionProbe . resolution , reflectionProbe . hdr ? TextureFormat . RGBAHalf : TextureFormat . RGBA32 , true ) ;
}
}
// update the lighting and reflections of the world
2025-07-18 18:43:09 +08:00
void UpdateLightingAndReflections ( bool forceUpdate = false )
2025-07-09 01:01:06 -04:00
{
// exit if both options are off
2025-07-18 18:43:09 +08:00
if ( ! updateReflections & & ! updateLighting )
2025-07-09 01:01:06 -04:00
{
LightAndReflectionFrames = 0 ;
return ;
}
2025-07-18 18:43:09 +08:00
if ( ! forceUpdate )
2025-07-09 01:01:06 -04:00
{
// run every set frames for performance
2025-07-18 18:43:09 +08:00
if ( LightAndReflectionFrames < updateEveryFrames )
{
2025-07-09 01:01:06 -04:00
LightAndReflectionFrames + + ;
return ;
}
}
// update the lighting if set
2025-07-18 18:43:09 +08:00
if ( updateLighting )
{
2025-07-09 01:01:06 -04:00
DynamicGI . UpdateEnvironment ( ) ;
}
// if update reflections is off then exit the function
2025-07-18 18:43:09 +08:00
if ( ! updateReflections )
{
2025-07-09 01:01:06 -04:00
return ;
}
LightAndReflectionFrames = 0 ;
reflectionProbe . RenderProbe ( ) ;
2025-07-18 18:43:09 +08:00
if ( reflectionProbe . texture ! = null )
2025-07-09 01:01:06 -04:00
{
Graphics . CopyTexture ( reflectionProbe . texture , cubemap as Texture ) ;
2025-12-21 15:00:58 +08:00
RenderSettings . customReflectionTexture = cubemap ;
2025-07-09 01:01:06 -04:00
return ;
}
}
bool SetReflectionProbeTexture ( )
{
2025-07-18 18:43:09 +08:00
if ( ! isSetReflectionProbeOnStart )
2025-07-09 01:01:06 -04:00
{
SetReflectionProbe ( ) ;
UpdateLightingAndReflections ( true ) ;
2025-07-18 18:43:09 +08:00
if ( reflectionProbe . texture ! = null )
{
2025-07-09 01:01:06 -04:00
isSetReflectionProbeOnStart = true ;
}
}
return isSetReflectionProbeOnStart ;
}
#endregion
#region PUBLIC APIs
// trigger the skybox blend
public void Blend ( bool singlePassBlend = false , bool rotate = true )
2025-07-18 18:43:09 +08:00
{
if ( currentSkyboxNotFirstMaterialBlending & & ! stopped )
{
2025-07-09 01:01:06 -04:00
return ;
}
2025-07-18 18:43:09 +08:00
if ( isLinearBlend & & ! stopped )
{
2025-07-09 01:01:06 -04:00
return ;
}
2025-07-18 18:43:09 +08:00
if ( rotate )
{
2025-07-09 01:01:06 -04:00
rotateSkybox = true ;
stopRotation = false ;
}
2025-07-18 18:43:09 +08:00
if ( ( stopped | | stillRunning ) & & ! singlePassBlend )
{
2025-07-09 01:01:06 -04:00
stopped = false ;
2025-07-18 18:43:09 +08:00
if ( blendFinished )
{
if ( ( usedBlend = = 1 | | usedBlend = = 2 ) & & ! stillRunning )
{
2025-07-09 01:01:06 -04:00
StartCoroutine ( WaitBeforeBlending ( ) ) ;
return ;
}
}
}
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
stopped = false ;
blendByIndex = false ;
StopAllCoroutines ( ) ;
currentTexture = RenderSettings . skybox . GetTexture ( "_Tex" ) ;
2025-07-18 18:43:09 +08:00
if ( blendValue > 0 )
{
2025-07-09 01:01:06 -04:00
oneTickBlend = singlePassBlend ;
return ;
}
2025-07-18 18:43:09 +08:00
if ( singlePassBlend )
{
if ( index = = 0 & & currentTexture ! = skyboxMaterials [ 0 ] . GetTexture ( "_Tex" ) )
{
2025-07-09 01:01:06 -04:00
PrepareMaterialForBlend ( 0 ) ;
currentSkyboxNotFirstMaterialBlending = true ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
int indexToTransition = index ;
2025-07-18 18:43:09 +08:00
if ( ! stopped )
{
if ( index > = skyboxMaterials . Count - 1 )
{
2025-07-09 01:01:06 -04:00
indexToTransition = 0 ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
indexToTransition + + ;
}
}
PrepareMaterialForBlend ( indexToTransition ) ;
singleBlend = true ;
}
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
RenderSettings . skybox = skyboxBlenderMaterial ;
stillRunning = true ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
// if only one element then linear blend from current scene skybox to the first material
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials . Count = = 1 )
{
if ( currentTexture ! = skyboxMaterials [ 0 ] . GetTexture ( "_Tex" ) )
{
2025-07-09 01:01:06 -04:00
PrepareMaterialForBlend ( 0 ) ;
RenderSettings . skybox = skyboxBlenderMaterial ;
}
}
2025-07-18 18:43:09 +08:00
else
{
if ( index = = 0 & & skyboxMaterials [ 0 ] ! = null )
{
if ( currentTexture = = skyboxMaterials [ 0 ] . GetTexture ( "_Tex" ) )
{
2025-07-09 01:01:06 -04:00
SetSkyBoxes ( true , 0 , false , 0 , true ) ;
}
2025-07-18 18:43:09 +08:00
else
{
2025-07-09 01:01:06 -04:00
SetSkyBoxes ( false , 0 , true , 0 , true ) ;
currentSkyboxNotFirstMaterialBlending = true ;
blendingCurrentSkyToListNotSingleBlend = true ;
}
}
}
// is this the last material
2025-07-18 18:43:09 +08:00
if ( index > = skyboxMaterials . Count - 1 )
{
2025-07-09 01:01:06 -04:00
comingFromLoop = true ;
}
// if the rotate parameter passed
2025-07-18 18:43:09 +08:00
if ( rotate )
{
2025-07-09 01:01:06 -04:00
rotateSkybox = true ;
stopRotation = false ;
}
// flag some vars to start the blending in Update
2025-07-18 18:43:09 +08:00
if ( ! currentSkyboxNotFirstMaterialBlending )
{
2025-07-09 01:01:06 -04:00
linearBlending = true ;
stillRunning = true ;
if ( rotate ) rotateSkybox = true ;
}
isLinearBlend = true ;
}
oneTickBlend = singlePassBlend ;
}
// call using material index
2025-07-18 18:43:09 +08:00
public void Blend ( int skyboxIndex , bool rotate = true )
2025-07-09 01:01:06 -04:00
{
stopped = false ;
if ( stillRunning ) return ;
2025-07-18 18:43:09 +08:00
if ( index = = skyboxIndex )
{
2025-07-09 01:01:06 -04:00
Debug . Log ( "Skybox material already set on the one you're trying to call." ) ;
return ;
}
2025-07-18 18:43:09 +08:00
if ( skyboxIndex > skyboxMaterials . Count - 1 )
{
2025-07-09 01:01:06 -04:00
Debug . Log ( "The passed index is bigger than the Count of the skybox materials list." ) ;
return ;
}
2025-07-18 18:43:09 +08:00
if ( skyboxIndex < 0 )
{
2025-07-09 01:01:06 -04:00
skyboxIndex = skyboxMaterials . Count - 1 ;
}
2025-07-18 18:43:09 +08:00
if ( skyboxMaterials [ skyboxIndex ] = = null )
{
2025-07-09 01:01:06 -04:00
Debug . Log ( "There is no material in the list with the passed index." ) ;
return ;
}
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
StopAllCoroutines ( ) ;
currentTexture = RenderSettings . skybox . GetTexture ( "_Tex" ) ;
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
blendByIndex = true ;
indexToBlend = skyboxIndex ;
PrepareMaterialForBlend ( skyboxIndex ) ;
singleBlend = true ;
RenderSettings . skybox = skyboxBlenderMaterial ;
2025-07-18 18:43:09 +08:00
if ( rotate )
{
2025-07-09 01:01:06 -04:00
rotateSkybox = true ;
stopRotation = false ;
}
stillRunning = true ;
oneTickBlend = true ;
}
// cancel the current blend and reset the skybox to what it was before the blend
public void Cancel ( )
{
StopAllCoroutines ( ) ;
linearBlending = false ;
singleBlend = false ;
currentSkyboxNotFirstMaterialBlending = false ;
blendingCurrentSkyToListNotSingleBlend = false ;
oneTickBlend = false ;
stopped = false ;
blendValue = 0 ;
stillRunning = false ;
isLinearBlend = false ;
comingFromLoop = false ;
skyboxBlenderMaterial . SetFloat ( "_BlendCubemaps" , 0f ) ;
2025-07-18 18:43:09 +08:00
2025-07-09 01:01:06 -04:00
SetSkyBoxes ( true , index , false , 0 , true ) ;
UpdateLightingAndReflections ( true ) ;
}
// stop the blending
2025-07-18 18:43:09 +08:00
public void Stop ( bool stopRot = true )
2025-07-09 01:01:06 -04:00
{
stopped = true ;
StopAllCoroutines ( ) ;
2025-07-18 18:43:09 +08:00
if ( stopRot & & rotateSkybox )
{
2025-07-09 01:01:06 -04:00
stopRotation = true ;
}
}
// resume the blending
2025-07-18 18:43:09 +08:00
public void Resume ( bool resumeRot = true )
2025-07-09 01:01:06 -04:00
{
stopped = false ;
2025-07-18 18:43:09 +08:00
if ( resumeRot )
{
2025-07-09 01:01:06 -04:00
stopRotation = false ;
}
2025-07-18 18:43:09 +08:00
if ( usedBlend = = 1 | | usedBlend = = 2 )
{
if ( blendFinished )
{
2025-07-09 01:01:06 -04:00
StartCoroutine ( WaitBeforeBlending ( ) ) ;
}
}
}
// check if blending is in process
public bool IsBlending ( )
{
2025-07-18 18:43:09 +08:00
if ( stopped )
{
2025-07-09 01:01:06 -04:00
return false ;
}
2025-07-18 18:43:09 +08:00
if ( linearBlending | | singleBlend | | currentSkyboxNotFirstMaterialBlending )
{
2025-07-09 01:01:06 -04:00
return true ;
}
return false ;
}
// rotate the skybox only
public void Rotate ( )
{
skyboxBlenderMaterial . SetTexture ( "_Tex" , RenderSettings . skybox . GetTexture ( "_Tex" ) ) ;
skyboxBlenderMaterial . SetColor ( "_Tint" , RenderSettings . skybox . GetColor ( "_Tint" ) ) ;
RenderSettings . skybox = skyboxBlenderMaterial ;
rotateSkybox = true ;
stopRotation = false ;
}
// stop the rotation only
public void StopRotation ( )
{
rotateSkybox = false ;
stopRotation = false ;
}
#endregion
}