TimeLine大改

Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
2025-07-18 18:43:09 +08:00
parent fc3b4d7207
commit 1b5084626d
29 changed files with 16837 additions and 17453 deletions

View File

@@ -8,62 +8,63 @@ using UnityEngine.Rendering;
public class SkyboxBlender : MonoBehaviour
{
[Tooltip("The materials you want to blend to linearly.")]
public List<Material> skyboxMaterials;
[Tooltip("Checking this will instantly make the first material your current skybox.")]
public bool makeFirstMaterialSkybox;
public List<Material> skyboxMaterials;
[Tooltip("Checking this will instantly make the first material your current skybox.")]
public bool makeFirstMaterialSkybox;
[Min(0), Tooltip("The speed of the blending between the skyboxes.")]
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;
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;
[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.")]
public bool updateReflections;
public bool updateReflections;
[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.")]
public int updateEveryFrames = 5;
public int updateEveryFrames = 5;
[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.")]
public float rotateToAngle = 180;
public float rotateToAngle = 180;
[Min(0), Tooltip("The speed of the skybox rotation.")]
public float rotationSpeed;
public float rotationSpeed;
[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
Material defaultSkyboxMaterial;
Material skyboxBlenderMaterial;
Texture currentTexture;
Material defaultSkyboxMaterial;
Material skyboxBlenderMaterial;
Texture currentTexture;
float totalBlendValue = 1f;
float totalBlendValue = 1f;
public float blendValue { private set; get; }
float defaultBlend;
float defaultRotation;
float rotationSpeedValue;
float defaultBlend;
float defaultRotation;
float rotationSpeedValue;
int index = 0;
public int CurrentIndex {
int index = 0;
public int CurrentIndex
{
get { return index; }
}
int indexToBlend;
int indexToBlend;
int usedBlend;
int LightAndReflectionFrames;
bool linearBlending;
bool currentSkyboxNotFirstMaterialBlending;
bool linearBlending;
bool currentSkyboxNotFirstMaterialBlending;
bool comingFromLoop;
bool rotateSkybox;
bool oneTickBlend = false;
bool stillRunning = false;
bool singleBlend = false;
bool rotateSkybox;
bool oneTickBlend = false;
bool stillRunning = false;
bool singleBlend = false;
bool stopped = false;
bool blendByIndex;
bool stopRotation;
@@ -72,30 +73,31 @@ public class SkyboxBlender : MonoBehaviour
bool isLinearBlend;
bool isSetReflectionProbeOnStart;
ReflectionProbe reflectionProbe;
Cubemap cubemap = null;
ReflectionProbe reflectionProbe;
Cubemap cubemap = null;
#endregion
#region UNITY METHODS
void Awake()
void Awake()
{
// load the material
skyboxBlenderMaterial = Resources.Load("Material & Shader/Skybox Blend Material", typeof(Material)) as Material;
if (skyboxBlenderMaterial)
if (skyboxBlenderMaterial)
{
defaultBlend = skyboxBlenderMaterial.GetFloat("_BlendCubemaps");
defaultRotation = skyboxBlenderMaterial.GetFloat("_Rotation");
defaultSkyboxMaterial = skyboxBlenderMaterial;
InspectorAndAwakeChanges();
}
else {
else
{
Debug.LogWarning("Can't find Skybox Blend Material in resources. Please re-import!");
}
if (updateLighting || updateReflections)
if (updateLighting || updateReflections)
{
SetReflectionProbe();
UpdateLightingAndReflections(true);
@@ -104,7 +106,8 @@ public class SkyboxBlender : MonoBehaviour
void OnValidate()
{
if (skyboxBlenderMaterial == null) {
if (skyboxBlenderMaterial == null)
{
skyboxBlenderMaterial = Resources.Load("Material & Shader/Skybox Blend Material", typeof(Material)) as Material;
}
@@ -116,24 +119,26 @@ public class SkyboxBlender : MonoBehaviour
// return the material to original blend
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", defaultBlend);
skyboxBlenderMaterial.SetFloat("_Rotation", defaultRotation);
if (currentTexture != null) {
if (currentTexture != null)
{
skyboxBlenderMaterial.SetTexture("_Tex", currentTexture);
}
RenderSettings.skybox = defaultSkyboxMaterial;
}
void Update()
void Update()
{
// when in editor mode, set the skybox material in the skybox linearBlendmaterial
if (!Application.isPlaying)
if (!Application.isPlaying)
{
if (RenderSettings.skybox == null) {
if (RenderSettings.skybox == null)
{
return;
}
if (RenderSettings.skybox.HasProperty("_Tex"))
if (RenderSettings.skybox.HasProperty("_Tex"))
{
skyboxBlenderMaterial.SetTexture("_Tex", RenderSettings.skybox.GetTexture("_Tex"));
skyboxBlenderMaterial.SetColor("_Tint", RenderSettings.skybox.GetColor("_Tint"));
@@ -142,23 +147,24 @@ public class SkyboxBlender : MonoBehaviour
return;
}
if (updateReflections && !isSetReflectionProbeOnStart)
if (updateReflections && !isSetReflectionProbeOnStart)
{
if (!SetReflectionProbeTexture()) {
if (!SetReflectionProbeTexture())
{
return;
}
}
// skybox blending linearly the list
if (linearBlending && !stopped)
if (linearBlending && !stopped)
{
// set the type of the used blending
usedBlend = 1;
blendValue += Time.deltaTime * blendSpeed;
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", blendValue);
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", blendValue);
UpdateLightingAndReflections();
if (skyboxBlenderMaterial.GetFloat("_BlendCubemaps") >= totalBlendValue)
if (skyboxBlenderMaterial.GetFloat("_BlendCubemaps") >= totalBlendValue)
{
blendFinished = true;
linearBlending = false;
@@ -170,40 +176,44 @@ public class SkyboxBlender : MonoBehaviour
SetSkyBoxes(true, index, false, 0, true);
UpdateLightingAndReflections(true);
if (comingFromLoop)
if (comingFromLoop)
{
index = 0;
}
// increment index and linearBlend if not reached end
if ((index + 1) < skyboxMaterials.Count)
if ((index + 1) < skyboxMaterials.Count)
{
if (!comingFromLoop) {
if (!comingFromLoop)
{
index++;
}
comingFromLoop = false;
SetSkyBoxes(true, index);
if (index + 1 < skyboxMaterials.Count) {
SetSkyBoxes(false, 0, true, index+1);
if (index + 1 < skyboxMaterials.Count)
{
SetSkyBoxes(false, 0, true, index + 1);
}
if (index - (skyboxMaterials.Count - 1) > 0) {
if (index - (skyboxMaterials.Count - 1) > 0)
{
if (!oneTickBlend) linearBlending = true;
}
else {
else
{
if (!oneTickBlend) StartCoroutine(WaitBeforeBlending());
}
}
// if reached end and loopable
if (index >= skyboxMaterials.Count-1)
if (index >= skyboxMaterials.Count - 1)
{
if (loop)
if (loop)
{
if (oneTickBlend)
if (oneTickBlend)
{
stillRunning = false;
return;
@@ -214,15 +224,18 @@ public class SkyboxBlender : MonoBehaviour
StartCoroutine(WaitBeforeBlending());
}
else {
else
{
stillRunning = false;
if (stopRotationOnBlendFinish) {
if (stopRotationOnBlendFinish)
{
StopRotation();
}
}
}
}
else {
else
{
blendFinished = false;
}
}
@@ -233,42 +246,45 @@ public class SkyboxBlender : MonoBehaviour
blendValue += Time.deltaTime * blendSpeed;
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", blendValue);
UpdateLightingAndReflections();
if (skyboxBlenderMaterial.GetFloat("_BlendCubemaps") >= totalBlendValue)
if (skyboxBlenderMaterial.GetFloat("_BlendCubemaps") >= totalBlendValue)
{
blendFinished = true;
singleBlend = false;
blendValue = 0f;
StopAllCoroutines();
if (blendByIndex)
if (blendByIndex)
{
index = indexToBlend;
blendByIndex = false;
}
else {
else
{
if (index + 1 < skyboxMaterials.Count) index++;
else index = 0;
}
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", 0f);
SetSkyBoxes(true, index, false, 0, true);
UpdateLightingAndReflections(true);
stillRunning = false;
if (stopRotationOnBlendFinish) {
if (stopRotationOnBlendFinish)
{
StopRotation();
}
}
else {
else
{
blendFinished = false;
}
}
// blending for if the current skybox is not the same as first material
if (currentSkyboxNotFirstMaterialBlending && !stopped)
if (currentSkyboxNotFirstMaterialBlending && !stopped)
{
// set the type of the used blending
usedBlend = 2;
@@ -276,7 +292,7 @@ public class SkyboxBlender : MonoBehaviour
blendValue += Time.deltaTime * blendSpeed;
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", blendValue);
UpdateLightingAndReflections();
if (skyboxBlenderMaterial.GetFloat("_BlendCubemaps") >= totalBlendValue)
{
blendFinished = true;
@@ -284,32 +300,37 @@ public class SkyboxBlender : MonoBehaviour
blendValue = 0f;
StopAllCoroutines();
int indexForFirst = 0;
// int indexForFirst = 0;
int indexForSecond = 1;
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", 0f);
if (skyboxMaterials.Count == 1) {
if (skyboxMaterials.Count == 1)
{
indexForSecond = 0;
}
SetSkyBoxes(true, 0, true, indexForSecond, true);
UpdateLightingAndReflections(true);
if (oneTickBlend) {
if (oneTickBlend)
{
stillRunning = false;
}
else {
else
{
StartCoroutine(WaitBeforeBlending());
}
if (stopRotationOnBlendFinish && !blendingCurrentSkyToListNotSingleBlend) {
if (stopRotationOnBlendFinish && !blendingCurrentSkyToListNotSingleBlend)
{
StopRotation();
}
blendingCurrentSkyToListNotSingleBlend = false;
}
else {
else
{
blendFinished = false;
}
}
@@ -319,14 +340,18 @@ public class SkyboxBlender : MonoBehaviour
{
rotationSpeedValue += Time.deltaTime * rotationSpeed;
if (keepRotating) {
if (keepRotating)
{
skyboxBlenderMaterial.SetFloat("_Rotation", rotationSpeedValue);
}
else {
if (skyboxBlenderMaterial.GetFloat("_Rotation") < rotateToAngle) {
else
{
if (skyboxBlenderMaterial.GetFloat("_Rotation") < rotateToAngle)
{
skyboxBlenderMaterial.SetFloat("_Rotation", rotationSpeedValue);
}
else {
else
{
rotateSkybox = false;
skyboxBlenderMaterial.SetFloat("_Rotation", rotateToAngle);
}
@@ -339,21 +364,22 @@ public class SkyboxBlender : MonoBehaviour
#region SYSTEM METHODS
// set the skybox material
void SetSkyBoxes(bool firstTex = false, int firstTexIndex = 0, bool secondTex = false, int secondTexIndex = 0, bool apply = false)
void SetSkyBoxes(bool firstTex = false, int firstTexIndex = 0, bool secondTex = false, int secondTexIndex = 0, bool apply = false)
{
if (firstTex)
if (firstTex)
{
skyboxBlenderMaterial.SetTexture("_Tex", skyboxMaterials[firstTexIndex].GetTexture("_Tex"));
skyboxBlenderMaterial.SetColor("_Tint", skyboxMaterials[firstTexIndex].GetColor("_Tint"));
}
if (secondTex)
if (secondTex)
{
skyboxBlenderMaterial.SetTexture("_Tex2", skyboxMaterials[secondTexIndex].GetTexture("_Tex"));
skyboxBlenderMaterial.SetColor("_Tint2", skyboxMaterials[secondTexIndex].GetColor("_Tint"));
}
if (apply) {
if (apply)
{
RenderSettings.skybox = skyboxBlenderMaterial;
}
}
@@ -379,30 +405,32 @@ public class SkyboxBlender : MonoBehaviour
}
// change skyboxes and material textures on inspector change and script awake
public void InspectorAndAwakeChanges()
public void InspectorAndAwakeChanges()
{
if (makeFirstMaterialSkybox)
if (makeFirstMaterialSkybox)
{
if (skyboxMaterials.Count >= 1)
if (skyboxMaterials.Count >= 1)
{
if (skyboxMaterials[0] != null)
{
if (skyboxMaterials[0] != null)
{
skyboxBlenderMaterial.SetTexture("_Tex", skyboxMaterials[0].GetTexture("_Tex"));
skyboxBlenderMaterial.SetColor("_Tint", skyboxMaterials[0].GetColor("_Tint"));
RenderSettings.skybox = skyboxBlenderMaterial;
RenderSettings.skybox = skyboxBlenderMaterial;
Debug.Log("Skybox set to the first material in the list: " + skyboxMaterials[0].name);
}
}
else {
else
{
Debug.LogWarning("You need to set a material first to make it the skybox");
}
}
if (skyboxMaterials != null)
if (skyboxMaterials != null)
{
if (skyboxMaterials.Count > 1)
if (skyboxMaterials.Count > 1)
{
if (skyboxMaterials[1] != null) {
if (skyboxMaterials[1] != null)
{
skyboxBlenderMaterial.SetTexture("_Tex2", skyboxMaterials[1].GetTexture("_Tex"));
skyboxBlenderMaterial.SetColor("_Tint2", skyboxMaterials[1].GetColor("_Tint"));
}
@@ -416,7 +444,8 @@ public class SkyboxBlender : MonoBehaviour
{
reflectionProbe = GetComponent<ReflectionProbe>();
if (reflectionProbe == null) {
if (reflectionProbe == null)
{
reflectionProbe = gameObject.AddComponent<ReflectionProbe>() as ReflectionProbe;
}
@@ -425,7 +454,7 @@ public class SkyboxBlender : MonoBehaviour
reflectionProbe.mode = ReflectionProbeMode.Realtime;
reflectionProbe.timeSlicingMode = ReflectionProbeTimeSlicingMode.NoTimeSlicing;
if (updateReflections)
if (updateReflections)
{
RenderSettings.defaultReflectionMode = DefaultReflectionMode.Custom;
cubemap = new Cubemap(reflectionProbe.resolution, reflectionProbe.hdr ? TextureFormat.RGBAHalf : TextureFormat.RGBA32, true);
@@ -433,38 +462,41 @@ public class SkyboxBlender : MonoBehaviour
}
// update the lighting and reflections of the world
void UpdateLightingAndReflections(bool forceUpdate=false)
void UpdateLightingAndReflections(bool forceUpdate = false)
{
// exit if both options are off
if (!updateReflections && !updateLighting)
if (!updateReflections && !updateLighting)
{
LightAndReflectionFrames = 0;
return;
}
if (!forceUpdate)
if (!forceUpdate)
{
// run every set frames for performance
if (LightAndReflectionFrames < updateEveryFrames) {
if (LightAndReflectionFrames < updateEveryFrames)
{
LightAndReflectionFrames++;
return;
}
}
// update the lighting if set
if (updateLighting) {
if (updateLighting)
{
DynamicGI.UpdateEnvironment();
}
// if update reflections is off then exit the function
if (!updateReflections) {
if (!updateReflections)
{
return;
}
LightAndReflectionFrames = 0;
reflectionProbe.RenderProbe();
if (reflectionProbe.texture != null)
if (reflectionProbe.texture != null)
{
Graphics.CopyTexture(reflectionProbe.texture, cubemap as Texture);
RenderSettings.customReflection = cubemap;
@@ -474,12 +506,13 @@ public class SkyboxBlender : MonoBehaviour
bool SetReflectionProbeTexture()
{
if (!isSetReflectionProbeOnStart)
if (!isSetReflectionProbeOnStart)
{
SetReflectionProbe();
UpdateLightingAndReflections(true);
if (reflectionProbe.texture != null) {
if (reflectionProbe.texture != null)
{
isSetReflectionProbeOnStart = true;
}
}
@@ -493,35 +526,41 @@ public class SkyboxBlender : MonoBehaviour
// trigger the skybox blend
public void Blend(bool singlePassBlend = false, bool rotate = true)
{
if (currentSkyboxNotFirstMaterialBlending && !stopped) {
{
if (currentSkyboxNotFirstMaterialBlending && !stopped)
{
return;
}
if (isLinearBlend && !stopped) {
if (isLinearBlend && !stopped)
{
return;
}
if (rotate) {
if (rotate)
{
rotateSkybox = true;
stopRotation = false;
}
if ((stopped || stillRunning) && !singlePassBlend) {
if ((stopped || stillRunning) && !singlePassBlend)
{
stopped = false;
if (blendFinished) {
if ((usedBlend == 1 || usedBlend == 2) && !stillRunning) {
if (blendFinished)
{
if ((usedBlend == 1 || usedBlend == 2) && !stillRunning)
{
StartCoroutine(WaitBeforeBlending());
return;
}
}
}
stopped = false;
blendByIndex = false;
@@ -529,25 +568,32 @@ public class SkyboxBlender : MonoBehaviour
currentTexture = RenderSettings.skybox.GetTexture("_Tex");
if (blendValue > 0) {
if (blendValue > 0)
{
oneTickBlend = singlePassBlend;
return;
}
if (singlePassBlend) {
if (index == 0 && currentTexture != skyboxMaterials[0].GetTexture("_Tex")) {
if (singlePassBlend)
{
if (index == 0 && currentTexture != skyboxMaterials[0].GetTexture("_Tex"))
{
PrepareMaterialForBlend(0);
currentSkyboxNotFirstMaterialBlending = true;
}
else {
else
{
int indexToTransition = index;
if (!stopped) {
if (index >= skyboxMaterials.Count - 1) {
if (!stopped)
{
if (index >= skyboxMaterials.Count - 1)
{
indexToTransition = 0;
}
else {
else
{
indexToTransition++;
}
}
@@ -555,24 +601,31 @@ public class SkyboxBlender : MonoBehaviour
PrepareMaterialForBlend(indexToTransition);
singleBlend = true;
}
RenderSettings.skybox = skyboxBlenderMaterial;
stillRunning = true;
}
else {
else
{
// if only one element then linear blend from current scene skybox to the first material
if (skyboxMaterials.Count == 1) {
if (currentTexture != skyboxMaterials[0].GetTexture("_Tex")) {
if (skyboxMaterials.Count == 1)
{
if (currentTexture != skyboxMaterials[0].GetTexture("_Tex"))
{
PrepareMaterialForBlend(0);
RenderSettings.skybox = skyboxBlenderMaterial;
}
}
else {
if (index == 0 && skyboxMaterials[0] != null) {
if (currentTexture == skyboxMaterials[0].GetTexture("_Tex")) {
else
{
if (index == 0 && skyboxMaterials[0] != null)
{
if (currentTexture == skyboxMaterials[0].GetTexture("_Tex"))
{
SetSkyBoxes(true, 0, false, 0, true);
}
else {
else
{
SetSkyBoxes(false, 0, true, 0, true);
currentSkyboxNotFirstMaterialBlending = true;
@@ -583,20 +636,23 @@ public class SkyboxBlender : MonoBehaviour
// is this the last material
if (index >= skyboxMaterials.Count - 1) {
if (index >= skyboxMaterials.Count - 1)
{
comingFromLoop = true;
}
// if the rotate parameter passed
if (rotate) {
if (rotate)
{
rotateSkybox = true;
stopRotation = false;
}
// flag some vars to start the blending in Update
if (!currentSkyboxNotFirstMaterialBlending) {
if (!currentSkyboxNotFirstMaterialBlending)
{
linearBlending = true;
stillRunning = true;
@@ -612,40 +668,44 @@ public class SkyboxBlender : MonoBehaviour
}
// call using material index
public void Blend(int skyboxIndex, bool rotate = true)
public void Blend(int skyboxIndex, bool rotate = true)
{
stopped = false;
if (stillRunning) return;
if (index == skyboxIndex) {
if (index == skyboxIndex)
{
Debug.Log("Skybox material already set on the one you're trying to call.");
return;
}
if (skyboxIndex > skyboxMaterials.Count - 1) {
if (skyboxIndex > skyboxMaterials.Count - 1)
{
Debug.Log("The passed index is bigger than the Count of the skybox materials list.");
return;
}
if (skyboxIndex < 0) {
if (skyboxIndex < 0)
{
skyboxIndex = skyboxMaterials.Count - 1;
}
if (skyboxMaterials[skyboxIndex] == null) {
if (skyboxMaterials[skyboxIndex] == null)
{
Debug.Log("There is no material in the list with the passed index.");
return;
}
StopAllCoroutines();
currentTexture = RenderSettings.skybox.GetTexture("_Tex");
blendByIndex = true;
indexToBlend = skyboxIndex;
@@ -655,9 +715,10 @@ public class SkyboxBlender : MonoBehaviour
RenderSettings.skybox = skyboxBlenderMaterial;
if (rotate) {
if (rotate)
{
rotateSkybox = true;
stopRotation = false;
}
@@ -686,34 +747,38 @@ public class SkyboxBlender : MonoBehaviour
skyboxBlenderMaterial.SetFloat("_BlendCubemaps", 0f);
SetSkyBoxes(true, index, false, 0, true);
UpdateLightingAndReflections(true);
}
// stop the blending
public void Stop(bool stopRot=true)
public void Stop(bool stopRot = true)
{
stopped = true;
StopAllCoroutines();
if (stopRot && rotateSkybox) {
if (stopRot && rotateSkybox)
{
stopRotation = true;
}
}
// resume the blending
public void Resume(bool resumeRot=true)
public void Resume(bool resumeRot = true)
{
stopped = false;
if (resumeRot) {
if (resumeRot)
{
stopRotation = false;
}
if (usedBlend == 1 || usedBlend == 2) {
if (blendFinished) {
if (usedBlend == 1 || usedBlend == 2)
{
if (blendFinished)
{
StartCoroutine(WaitBeforeBlending());
}
}
@@ -722,11 +787,13 @@ public class SkyboxBlender : MonoBehaviour
// check if blending is in process
public bool IsBlending()
{
if (stopped) {
if (stopped)
{
return false;
}
if (linearBlending|| singleBlend || currentSkyboxNotFirstMaterialBlending) {
if (linearBlending || singleBlend || currentSkyboxNotFirstMaterialBlending)
{
return true;
}