2024. 4. 18. 15:40
Unity/C#
https://ahzkwid.booth.pm/items/5632873
Automatic Shadow Distance - Wmup - BOOTH
ワールド用です DirectionalLightの影の長さをFPSに応じて自動的に変更するツールです。 動きがきれいじゃないので、キャラクターシャドウ専用に使用するのをお勧めします - Code - https://gist.githu
ahzkwid.booth.pm
여기서 다운 가능
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UdonSharp; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using VRC.SDKBase; | |
using VRC.Udon; | |
[UdonBehaviourSyncMode(BehaviourSyncMode.None)] | |
public class AutomaticShadowDistance : UdonSharpBehaviour | |
{ | |
public Light directionalLight; | |
public float frameCheckTimeCycle = 3f; | |
int playerLayerIndex = 9; | |
public Vector2 targetFps = new Vector2(30, 60); | |
public Vector2 defaultShadowDistance = new Vector2(10, 80); | |
public Vector2 playerShadowDistance = new Vector2(1,15); | |
float tPre = 2; | |
void UpdateShadowDistance(float t) | |
{ | |
var defaultShadowDistanceMin = defaultShadowDistance.x; | |
var defaultShadowDistanceMax = defaultShadowDistance.y; | |
var playerShadowDistanceMin = playerShadowDistance.x; | |
var playerShadowDistanceMax = playerShadowDistance.y; | |
var targetDistanceDefault = Mathf.Lerp(defaultShadowDistanceMin, defaultShadowDistanceMax, t); | |
var targetDistancePlayer = Mathf.Lerp(playerShadowDistanceMin, playerShadowDistanceMax, t); | |
{ | |
//QualitySettings.shadowDistance = targetDistanceDefault; | |
} | |
{ | |
var ShadowCullDistances = new float[32]; | |
//ShadowCullDistances[0] = Mathf.Lerp(ShadowCullDistances[0], targetDistanceDefault, 0.1f); | |
ShadowCullDistances[0] = targetDistanceDefault; | |
ShadowCullDistances[11] = ShadowCullDistances[0]; | |
ShadowCullDistances[13] = ShadowCullDistances[0]; | |
ShadowCullDistances[14] = ShadowCullDistances[0]; | |
ShadowCullDistances[playerLayerIndex] = targetDistancePlayer; | |
ShadowCullDistances[10] = ShadowCullDistances[playerLayerIndex]; | |
ShadowCullDistances[18] = ShadowCullDistances[playerLayerIndex]; | |
directionalLight.layerShadowCullDistances = ShadowCullDistances; | |
//Camera.main.layerCullDistances = ShadowCullDistances; | |
} | |
} | |
LightShadows shadowType = LightShadows.Soft; | |
void Start() | |
{ | |
//if (directionalLight==null) | |
//{ | |
// /* | |
// var lights = FindObjectsOfType<Light>(); | |
// foreach (var light in lights) | |
// { | |
// if (light.type==LightType.Directional) | |
// { | |
// directionalLight = light; | |
// } | |
// } | |
// */ | |
// /* | |
// var light= FindObjectOfType<Light>(); | |
// if (light.type == LightType.Directional) | |
// { | |
// directionalLight = light; | |
// } | |
// */ | |
//} | |
if (directionalLight.shadows != LightShadows.None) | |
{ | |
shadowType = directionalLight.shadows; | |
} | |
UpdateShadowDistance(0); | |
lastCheckTime = 0; | |
} | |
float lastCheckTime = 0; | |
int frameCount = 0; | |
public Toggle toggle; | |
public Slider slider; | |
public GameObject lockPanel; | |
public bool alwaysUseShdow = true; | |
bool CheckT(float t) | |
{ | |
return ((Mathf.Abs(t - tPre) > 0.1f) | |
|| ((t == 0) && (tPre < 0.1f)) | |
|| ((t == 1) && (tPre > 0.9f))); | |
} | |
void Update() | |
{ | |
var useShadowOff = !alwaysUseShdow; | |
var toggleManual = toggle; | |
lockPanel.SetActive(toggleManual.isOn == false); | |
var useShadowOffvalue = 0.1f; | |
if (toggleManual.isOn) | |
{ | |
if (slider.value > useShadowOffvalue) | |
{ | |
var t = (slider.value - useShadowOffvalue) * (1f / (1f- useShadowOffvalue)); | |
if (CheckT(t)) | |
{ | |
UpdateShadowDistance(t); | |
tPre = t; | |
} | |
if (useShadowOff) | |
{ | |
if (directionalLight.shadows == LightShadows.None) | |
{ | |
directionalLight.shadows = shadowType; | |
} | |
} | |
} | |
else | |
{ | |
if (useShadowOff) | |
{ | |
if (directionalLight.shadows != LightShadows.None) | |
{ | |
directionalLight.shadows = LightShadows.None; | |
} | |
} | |
} | |
} | |
else | |
{ | |
frameCount++; | |
if (Time.time - lastCheckTime >= frameCheckTimeCycle) | |
{ | |
var fps = 0f; | |
if (Time.deltaTime > 0) | |
{ | |
fps = 1f / Time.deltaTime; | |
} | |
if (frameCheckTimeCycle > 0.1f) | |
{ | |
fps = frameCount / frameCheckTimeCycle; | |
} | |
var min = targetFps.x; | |
var max = targetFps.y; | |
var t = (Mathf.Clamp(fps, min, max) - min) / (max - min); | |
/* | |
if ((Mathf.Abs(t - tPre) > 0.1f) | |
|| ((t == 0) && (tPre < 0.1f)) | |
|| ((t == 1) && (tPre > 0.9f))) | |
*/ | |
if (CheckT(t)) | |
{ | |
UpdateShadowDistance(t); | |
tPre = t; | |
} | |
if (Time.time > 10) | |
{ | |
if (useShadowOff) | |
{ | |
if (directionalLight.shadows == LightShadows.None) | |
{ | |
if (t > 0.8f) | |
{ | |
directionalLight.shadows = shadowType; | |
} | |
} | |
else | |
{ | |
if (fps < min / 2) | |
{ | |
directionalLight.shadows = LightShadows.None; | |
} | |
} | |
} | |
} | |
if (directionalLight.shadows == LightShadows.None) | |
{ | |
slider.value = 0f; | |
} | |
else | |
{ | |
slider.value = useShadowOffvalue + t * (1f- useShadowOffvalue); | |
} | |
frameCount = 0; | |
lastCheckTime = Time.time; | |
} | |
} | |
} | |
} |
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class AutomaticShadowDistance : UdonSharpBehaviour
{
public Light directionalLight;
public float frameCheckTimeCycle = 3f;
int playerLayerIndex = 9;
public Vector2 targetFps = new Vector2(30, 60);
public Vector2 defaultShadowDistance = new Vector2(10, 80);
public Vector2 playerShadowDistance = new Vector2(1,15);
float tPre = 2;
void UpdateShadowDistance(float t)
{
var defaultShadowDistanceMin = defaultShadowDistance.x;
var defaultShadowDistanceMax = defaultShadowDistance.y;
var playerShadowDistanceMin = playerShadowDistance.x;
var playerShadowDistanceMax = playerShadowDistance.y;
var targetDistanceDefault = Mathf.Lerp(defaultShadowDistanceMin, defaultShadowDistanceMax, t);
var targetDistancePlayer = Mathf.Lerp(playerShadowDistanceMin, playerShadowDistanceMax, t);
{
//QualitySettings.shadowDistance = targetDistanceDefault;
}
{
var ShadowCullDistances = new float[32];
//ShadowCullDistances[0] = Mathf.Lerp(ShadowCullDistances[0], targetDistanceDefault, 0.1f);
ShadowCullDistances[0] = targetDistanceDefault;
ShadowCullDistances[11] = ShadowCullDistances[0];
ShadowCullDistances[13] = ShadowCullDistances[0];
ShadowCullDistances[14] = ShadowCullDistances[0];
ShadowCullDistances[playerLayerIndex] = targetDistancePlayer;
ShadowCullDistances[10] = ShadowCullDistances[playerLayerIndex];
ShadowCullDistances[18] = ShadowCullDistances[playerLayerIndex];
directionalLight.layerShadowCullDistances = ShadowCullDistances;
//Camera.main.layerCullDistances = ShadowCullDistances;
}
}
LightShadows shadowType = LightShadows.Soft;
void Start()
{
//if (directionalLight==null)
//{
// /*
// var lights = FindObjectsOfType<Light>();
// foreach (var light in lights)
// {
// if (light.type==LightType.Directional)
// {
// directionalLight = light;
// }
// }
// */
// /*
// var light= FindObjectOfType<Light>();
// if (light.type == LightType.Directional)
// {
// directionalLight = light;
// }
// */
//}
if (directionalLight.shadows != LightShadows.None)
{
shadowType = directionalLight.shadows;
}
UpdateShadowDistance(0);
lastCheckTime = 0;
}
float lastCheckTime = 0;
int frameCount = 0;
public Toggle toggle;
public Slider slider;
public GameObject lockPanel;
public bool alwaysUseShdow = true;
bool CheckT(float t)
{
return ((Mathf.Abs(t - tPre) > 0.1f)
|| ((t == 0) && (tPre < 0.1f))
|| ((t == 1) && (tPre > 0.9f)));
}
void Update()
{
var useShadowOff = !alwaysUseShdow;
var toggleManual = toggle;
lockPanel.SetActive(toggleManual.isOn == false);
var useShadowOffvalue = 0.1f;
if (toggleManual.isOn)
{
if (slider.value > useShadowOffvalue)
{
var t = (slider.value - useShadowOffvalue) * (1f / (1f- useShadowOffvalue));
if (CheckT(t))
{
UpdateShadowDistance(t);
tPre = t;
}
if (useShadowOff)
{
if (directionalLight.shadows == LightShadows.None)
{
directionalLight.shadows = shadowType;
}
}
}
else
{
if (useShadowOff)
{
if (directionalLight.shadows != LightShadows.None)
{
directionalLight.shadows = LightShadows.None;
}
}
}
}
else
{
frameCount++;
if (Time.time - lastCheckTime >= frameCheckTimeCycle)
{
var fps = 0f;
if (Time.deltaTime > 0)
{
fps = 1f / Time.deltaTime;
}
if (frameCheckTimeCycle > 0.1f)
{
fps = frameCount / frameCheckTimeCycle;
}
var min = targetFps.x;
var max = targetFps.y;
var t = (Mathf.Clamp(fps, min, max) - min) / (max - min);
/*
if ((Mathf.Abs(t - tPre) > 0.1f)
|| ((t == 0) && (tPre < 0.1f))
|| ((t == 1) && (tPre > 0.9f)))
*/
if (CheckT(t))
{
UpdateShadowDistance(t);
tPre = t;
}
if (Time.time > 10)
{
if (useShadowOff)
{
if (directionalLight.shadows == LightShadows.None)
{
if (t > 0.8f)
{
directionalLight.shadows = shadowType;
}
}
else
{
if (fps < min / 2)
{
directionalLight.shadows = LightShadows.None;
}
}
}
}
if (directionalLight.shadows == LightShadows.None)
{
slider.value = 0f;
}
else
{
slider.value = useShadowOffvalue + t * (1f- useShadowOffvalue);
}
frameCount = 0;
lastCheckTime = Time.time;
}
}
}
}
'Unity > C#' 카테고리의 다른 글
유니티 프리팹 드래그 드랍 (0) | 2024.05.09 |
---|---|
c# Dictionary(딕셔너리) 관련 (0) | 2024.03.19 |
자주 쓰는 DateTime 코드 모음 (0) | 2023.12.19 |