Commit 38815d97 authored by KenzyAshour2's avatar KenzyAshour2

imported the tutorial canva

parent 45b90dea
fileFormatVersion: 2
guid: a8318cee1e8d00e49b0ae4ecd10882df
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: f64493dee1bdf4880ae2faf45e652b3a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b652e9617b11185469f30839f9d7cad6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 2550c34bcb002466682343c8e43106c7
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 50, y: 48, z: 50, w: 48}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c5244042df83e024c9bbc6862623bd40
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 998847c3a89ada347a8f74eb6a827627
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 05a9222bcf8727940984a43c01379d3f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9a48552680495754082bc69605e2adc3
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 3070d174e7660a04094316607cef81c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6fa6e529e8b66734ea86209368858ab6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: bffdf8cbd8232a14c9e2eb0ebe93c6c4
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 143efcb8b14d41343990b168db6db89d
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 512
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9a0afdb57d35c7343a7becf027e36082
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 632768b01156b864e890725e0c4f7624
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 64b00a79a916e0d4e92449b865fb156b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 09a084257d05bb14cb8b88d42bf86d55
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 54e75ef13792be547b93505eb806a260
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using static LeTai.TrueShadow.Math;
namespace LeTai.TrueShadow.Demo
{
[Serializable]
public class KnobValueChangedEvent : UnityEvent<float> { }
[ExecuteAlways]
public class DirectionalKnob : UIBehaviour, IDragHandler
{
public Transform knobGraphic;
public float min = 0;
public float max = 1;
public float value = .5f;
public KnobValueChangedEvent knobValueChanged;
RectTransform rectTransform;
Vector2 zeroVector;
protected override void Start()
{
rectTransform = GetComponent<RectTransform>();
}
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
value = Mathf.Clamp(value, min, max);
SetValue(value);
}
#endif
public void SetValue(float newValue)
{
value = newValue;
knobGraphic.localRotation = Quaternion.Euler(0, 0, 1 - value * 360);
knobValueChanged.Invoke(value);
}
public void OnDrag(PointerEventData eventData)
{
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform,
eventData.position,
eventData.pressEventCamera,
out var point
))
{
var angle = Angle360(Vector2.down, point);
SetValue(Mathf.InverseLerp(min, max, 1 - angle / 360f));
}
}
}
}
fileFormatVersion: 2
guid: 74ba1d2462853034eb9901e6d9315712
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.RectTransform.Edge;
namespace LeTai.TrueShadow.Demo
{
[ExecuteAlways]
public class ToggleSwitchAnimation : MonoBehaviour
{
public Color onColor = new Color(0.29f, 1, 0.26f);
public Color offColor = new Color(0.93f, 0.3f, 0.23f);
public Graphic background;
public RectTransform handle;
public float handleInset = 1.5f;
public float transitionDuration = .1f;
Coroutine anim;
void Start()
{
var isOn = GetComponent<Toggle>().isOn;
background.color = isOn ? onColor : offColor;
handle.SetInsetAndSizeFromParentEdge(isOn ? Right : Left, handleInset, handle.rect.width);
}
IEnumerator Animate(float fromX, Color fromColor)
{
var toColor = background.color;
var position = handle.position;
var toX = position.x;
var y = position.y;
var z = position.z;
var t = 0f;
do
{
t = Mathf.Min(t + Time.deltaTime / transitionDuration, 1);
var tsmoothed = Mathf.SmoothStep(0, 1, t);
handle.position = new Vector3(Mathf.Lerp(fromX, toX, tsmoothed), y, z);
background.color = Color.Lerp(fromColor, toColor, tsmoothed);
yield return null;
} while (t < 1);
}
public void Toggle(bool isOn)
{
if (!background) return;
if (!handle) return;
var fromColor = background.color;
background.color = isOn ? onColor : offColor;
var fromX = handle.position.x;
handle.SetInsetAndSizeFromParentEdge(isOn ? Right : Left, handleInset, handle.rect.width);
if (!Application.isEditor || Application.isPlaying)
{
if (anim != null) StopCoroutine(anim);
anim = StartCoroutine(Animate(fromX, fromColor));
}
}
}
}
fileFormatVersion: 2
guid: d47588945eaa90240a76a557be7bce7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 785c64398909a374bb49c1dcc71fd4d7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: fc8a61cbf832e0a46a7469ceeec8ea8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace LeTai.TrueShadow.Demo
{
[RequireComponent(typeof(BarGraph))]
public class AdsrBarGraphSource : MonoBehaviour
{
const float HOLD_TIME = 4f;
public float attack = 1;
public float decay = 1;
public float sustain = .5f;
public float release = 1;
#region EditorEventSetter
public void SetAttack(float value)
{
attack = value;
SetAdsrValues();
}
public void SetDecay(float value)
{
decay = value;
SetAdsrValues();
}
public void SetSustain(float value)
{
sustain = value;
SetAdsrValues();
}
public void SetRelease(float value)
{
release = value;
SetAdsrValues();
}
#endregion
BarGraph graph;
AdsrEnvelop adsr;
void Start()
{
graph = GetComponent<BarGraph>();
graph.Init();
adsr = new AdsrEnvelop();
SetAdsrValues();
}
void SetAdsrValues()
{
if (!graph) return;
var sampleRate = graph.barCount / HOLD_TIME;
adsr.numAttackSamples = Mathf.RoundToInt(attack * sampleRate);
adsr.numDecaySamples = Mathf.RoundToInt(decay * sampleRate);
adsr.sustainScale = sustain;
adsr.numReleaseSamples = Mathf.RoundToInt(release * sampleRate);
// int releaseIndex = graph.barCount - adsr.numReleaseSamples;
int releaseIndex = Mathf.RoundToInt(graph.barCount * .75f);
adsr.Reset();
for (var i = 0; i < graph.barCount; i++)
{
if (i == releaseIndex)
adsr.Release();
adsr.MoveNext();
graph.SetValue(i, (float) adsr.Current);
}
}
}
}
fileFormatVersion: 2
guid: 3cd1a23d80c94ecf8633bce675710720
timeCreated: 1603266114
\ No newline at end of file
using System;
using System.Collections;
using System.Collections.Generic;
namespace LeTai.TrueShadow.Demo
{
public enum AdsrStage
{
Off,
Attack,
Decay,
Sustain,
Release
};
public class AdsrEnvelop : IEnumerator<double>
{
public int numAttackSamples;
public int numDecaySamples;
public double sustainScale;
public int numReleaseSamples;
public AdsrStage CurrentStage { get; private set; } = AdsrStage.Off;
int releaseSample;
int currentSample;
public void Release()
{
CurrentStage = AdsrStage.Release;
releaseSample = currentSample;
}
public bool MoveNext()
{
currentSample++;
MaybeAdvancesStage();
switch (CurrentStage)
{
case AdsrStage.Off:
Current = 0;
break;
case AdsrStage.Attack:
Current = Map(currentSample, 0, numAttackSamples, 0, 1);
break;
case AdsrStage.Decay:
Current = Map(currentSample - numAttackSamples, 0, numDecaySamples, 1, sustainScale);
break;
case AdsrStage.Sustain:
Current = sustainScale;
break;
case AdsrStage.Release:
Current = Map(currentSample - releaseSample, 0, numReleaseSamples, sustainScale, 0);
break;
default:
throw new ArgumentOutOfRangeException();
}
return true;
}
public void Reset()
{
currentSample = 0;
CurrentStage = AdsrStage.Attack;
}
void MaybeAdvancesStage()
{
if (CurrentStage == AdsrStage.Attack)
{
if (currentSample > numAttackSamples)
CurrentStage = AdsrStage.Decay;
}
if (CurrentStage == AdsrStage.Decay)
{
if (currentSample > numAttackSamples + numDecaySamples)
CurrentStage = AdsrStage.Sustain;
}
if (CurrentStage == AdsrStage.Release)
{
if (currentSample - releaseSample > numReleaseSamples)
CurrentStage = AdsrStage.Off;
}
}
static double Map(double value, double fromLow, double fromHigh, double toLow, double toHigh)
{
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
public double Current { get; private set; }
object IEnumerator.Current => Current;
public void Dispose() { }
}
}
fileFormatVersion: 2
guid: 38d42192b995448caf026eaef4cc9c59
timeCreated: 1603266171
\ No newline at end of file
using UnityEngine;
namespace LeTai.TrueShadow.Demo
{
public class BarGraph : MonoBehaviour
{
public GameObject barPrefab;
public int barCount = 15;
public int maxValue = 7;
BarGraphBar[] bars;
public void Init()
{
bars = new BarGraphBar[barCount];
for (var i = 0; i < barCount; i++)
{
var go = Instantiate(barPrefab, transform);
var bar = go.GetComponent<BarGraphBar>();
bar.Init(maxValue);
bars[i] = bar;
}
}
public void SetValue(int index, float value)
{
bars[index].SetValue(value);
}
}
}
fileFormatVersion: 2
guid: 51b48b6db7cd5cb40abbcfab370f1f2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow.Demo
{
[RequireComponent(typeof(Slider))]
public class BarGraphBar : MonoBehaviour
{
Slider slider;
public void Init(int max)
{
slider = GetComponent<Slider>();
slider.maxValue = max;
slider.value = 0;
}
public void SetValue(float value)
{
slider.value = value * slider.maxValue;
}
}
}
fileFormatVersion: 2
guid: 9497ffaf021646caaf8805e90cdfdf39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9e166f0d0e4a9df4e9de2b95c05c8c3f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 8c869099e5fb0c34296e1a740a333c52
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Diagnostics;
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.Utils
{
[RequireComponent(typeof(Text))]
public class FpsCounter : MonoBehaviour
{
const long FPS_SAMPLE_PERIOD = 500;
string displayFormat = "{0} FPS\n{1} ms";
Text text;
int framesSinceLast;
Stopwatch stopwatch;
void Start()
{
stopwatch = Stopwatch.StartNew();
text = GetComponent<Text>();
displayFormat = text.text;
}
void Update()
{
framesSinceLast++;
var elapsedMs = stopwatch.ElapsedMilliseconds;
if (elapsedMs < FPS_SAMPLE_PERIOD)
return;
float elapsedSec = elapsedMs / 1000f;
var fps = framesSinceLast / elapsedSec;
var frameTimeMs = elapsedMs / (float)framesSinceLast;
text.text = string.Format(displayFormat, fps, frameTimeMs);
framesSinceLast = 0;
stopwatch.Restart();
}
}
}
fileFormatVersion: 2
guid: 766a0fe386669aa48894ee7a94acf0f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Image))]
public class GradientSlider : MonoBehaviour
{
public Gradient gradient;
Image image;
void Start()
{
image = GetComponent<Image>();
}
public void Set(float value)
{
if (!image) return;
image.fillAmount = value;
image.color = gradient.Evaluate(value);
}
}
fileFormatVersion: 2
guid: 7280b760bd9580c43b06285560697a5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using LeTai.SwipeView;
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow.Demo
{
public class HotDogCard : Swipable<HotDogSprite>
{
public Image content;
public override void SetData(HotDogSprite data)
{
Data = data;
content.sprite = Data.sprite;
}
}
}
fileFormatVersion: 2
guid: d0e957e6c5eb10540a2cfc76f0401717
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace LeTai.TrueShadow.Demo
{
public struct HotDogSprite
{
public Sprite sprite;
public bool isHotDog;
public override string ToString()
{
var prefix = isHotDog ? "(Hot Dog) " : "";
return prefix + sprite;
}
}
}
fileFormatVersion: 2
guid: 550cd0578a054d1a8812437691e64994
timeCreated: 1596277787
\ No newline at end of file
using System;
using System.Collections.Generic;
using LeTai.SwipeView;
using UnityEngine;
using Random = UnityEngine.Random;
namespace LeTai.TrueShadow.Demo
{
public class HotDogSwipeView : LeftRightSwipeView<HotDogSprite>
{
public Sprite[] hotdogs;
public Sprite[] notHotdogs;
public GradientSlider goodnessSlider;
float goodness = 100f;
protected override void Start()
{
Init(RandomSprites());
onSwipeToDirection.AddListener(OnSwipeToDirection);
AddGoodness(0);
}
void Update()
{
if (Application.isPlaying)
{
var reduction = Mathf.Exp(goodness * .025f + .6f);
reduction = Mathf.Max(reduction, 0);
AddGoodness(-reduction * Time.deltaTime);
}
}
void AddGoodness(float amount)
{
goodness += amount;
goodness = Mathf.Clamp(goodness, 0f, 100f);
goodnessSlider.Set(goodness / 100f);
}
void OnSwipeToDirection(SwipeDirection direction)
{
var isHotDog = TopCard.Data.isHotDog;
switch (direction)
{
case SwipeDirection.Left:
if (!isHotDog) AddGoodness(10);
else AddGoodness(-10);
break;
case SwipeDirection.Right:
if (isHotDog) AddGoodness(10);
else AddGoodness(-10);
break;
default:
throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
}
}
IEnumerable<HotDogSprite> RandomSprites()
{
int last = -1;
int nAttempt = 0;
while (true)
{
var hotDogRatio = hotdogs.Length / (float) (hotdogs.Length + notHotdogs.Length);
var array = Random.value < hotDogRatio ? hotdogs : notHotdogs;
int next;
do
{
next = Random.Range(0, array.Length);
} while (next == last && nAttempt++ < 5);
nAttempt = 0;
last = next;
yield return new HotDogSprite {
sprite = array[next],
isHotDog = array == hotdogs
};
}
}
}
}
fileFormatVersion: 2
guid: 4f81c30eceb7d04468edd80617e15f18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: bdf2919a45d9cb640b588c6fa229cde7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace LeTai.SwipeView
{
public enum SwipeDirection
{
Left,
Right
}
[Serializable]
public class CardSwipedToDirectionEvent : UnityEvent<SwipeDirection> { }
public class LeftRightSwipeView<T> : SwipeView<T>
{
public CardSwipedToDirectionEvent onSwipeToDirection;
protected override void Init(IEnumerable<T> data)
{
base.Init(data);
onSwiped.AddListener(OnSwiped);
}
void OnSwiped(Vector2 offset)
{
if (Vector2.Dot(offset, Vector2.right) >= 0)
onSwipeToDirection.Invoke(SwipeDirection.Right);
else
onSwipeToDirection.Invoke(SwipeDirection.Left);
}
}
}
fileFormatVersion: 2
guid: 9b13d0ccc8f1477a9bf7b7ef337d7a8a
timeCreated: 1596276659
\ No newline at end of file
using System;
using System.Collections;
using UnityEngine;
namespace LeTai.SwipeView
{
public abstract class Swipable<TData> : MonoBehaviour
{
public event Action<Vector2> removed;
public TData Data { get; protected set; }
internal RectTransform RectTransform { get; private set; }
internal SwipeView<TData> view;
internal Vector2 snapPosition;
internal Vector3 snapScale;
protected bool isSwiping;
protected bool isSnaping;
Coroutine runningSnap;
Vector3 currentPosVel;
Vector3 currentScaleVel;
void Awake()
{
RectTransform = GetComponent<RectTransform>();
}
protected internal void StartSnap(bool snapOut = false)
{
if (isSnaping && runningSnap != null) StopCoroutine(runningSnap);
isSnaping = true;
runningSnap = StartCoroutine(Snap(snapOut));
}
void DoTilt()
{
RectTransform.localRotation = Quaternion.LookRotation(RectTransform.forward,
RectTransform.localPosition -
view.rotationPivot.WithZ(0) *
view.canvas.scaleFactor);
}
protected IEnumerator Snap(bool snapOut)
{
var targetPosition = snapOut
? RectTransform.localPosition.normalized * view.throwDistance
: (Vector3) snapPosition;
if (snapOut)
{
OnRemoved(RectTransform.localPosition);
}
currentScaleVel = Vector3.zero;
currentPosVel = Vector3.zero;
while (!isSwiping && (RectTransform.localPosition - targetPosition).sqrMagnitude > 1e-4f)
{
RectTransform.localPosition = Vector3.SmoothDamp(RectTransform.localPosition,
targetPosition,
ref currentPosVel,
view.animationSmoothTime);
RectTransform.localScale = Vector3.SmoothDamp(RectTransform.localScale,
snapScale,
ref currentScaleVel,
view.animationSmoothTime);
DoTilt();
yield return null;
}
isSnaping = false;
if (snapOut)
{
Destroy(gameObject);
}
}
public void Swipe(Vector2 offset)
{
isSwiping = true;
RectTransform.localPosition = snapPosition + offset;
DoTilt();
}
public abstract void SetData(TData data);
internal void EndSwipe(Vector2 offset)
{
isSwiping = false;
bool willRemove = offset.magnitude > view.distanceToRemove;
StartSnap(willRemove);
}
protected virtual void OnRemoved(Vector2 offset)
{
removed?.Invoke(offset);
}
}
}
fileFormatVersion: 2
guid: 265193ed20c54a5f95ce9b3655527496
timeCreated: 1595072543
\ No newline at end of file
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace LeTai.SwipeView
{
[Serializable]
public class CardSwipedEvent : UnityEvent<Vector2> { }
public class SwipeView<TData> : Graphic, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public int stackSize = 4;
public GameObject cardPrefab;
public AnimationCurve shapeXCurve;
public AnimationCurve shapeYCurve;
public AnimationCurve sizeCurve;
public Vector2 rotationPivot = Vector2.down * 400;
public float distanceToRemove = 100f;
public float animationSmoothTime = .15f;
public CardSwipedEvent onSwiped;
public Swipable<TData> TopCard => cards.Count > 0 ? cards.Peek() : null;
protected IEnumerable<TData> data;
protected Queue<Swipable<TData>> cards;
internal float throwDistance;
IEnumerator<TData> dataEnumerator;
protected virtual void Init(IEnumerable<TData> data)
{
if (!Application.isPlaying)
return;
cards = new Queue<Swipable<TData>>(stackSize);
this.data = data;
dataEnumerator = this.data.GetEnumerator();
for (var i = 0; i < stackSize; i++) InsertNextCard();
}
void InsertNextCard()
{
if (dataEnumerator.MoveNext())
{
var obj = Instantiate(cardPrefab, transform);
var card = obj.GetComponent<Swipable<TData>>();
if (!card) throw new ArgumentException($"Card Prefab need a {nameof(Swipable<TData>)} component");
card.view = this;
card.SetData(dataEnumerator.Current);
card.removed += RemoveTopCard;
card.RectTransform.SetSiblingIndex(0);
cards.Enqueue(card);
obj.name = card.Data.ToString();
}
UpdateCardsPosition();
}
void UpdateCardsPosition()
{
int index = 0;
foreach (var card in cards)
{
var curvePosition = index++ % stackSize / (float) (stackSize - 1);
card.snapScale = Vector3.one * sizeCurve.Evaluate(curvePosition);
card.snapPosition = new Vector2(
shapeXCurve.Evaluate(curvePosition),
shapeYCurve.Evaluate(curvePosition)
);
card.StartSnap();
}
}
void RemoveTopCard(Vector2 offset)
{
onSwiped.Invoke(offset);
cards.Dequeue();
InsertNextCard();
}
Vector2 pointerStartPos;
public void OnBeginDrag(PointerEventData eventData)
{
if (!TopCard) return;
EventSystem.current.SetSelectedGameObject(TopCard.gameObject, eventData);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform,
eventData.position,
eventData.pressEventCamera,
out pointerStartPos
);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform,
Vector2.right * (Screen.width + Screen.height),
eventData.pressEventCamera,
out var farPoint
);
throwDistance = farPoint.magnitude;
}
public void OnDrag(PointerEventData eventData)
{
if (!TopCard) return;
EventSystem.current.SetSelectedGameObject(TopCard.gameObject, eventData);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform,
eventData.position,
eventData.pressEventCamera,
out var pos
);
TopCard.Swipe(pos - pointerStartPos);
}
public void OnEndDrag(PointerEventData eventData)
{
if (!TopCard) return;
EventSystem.current.SetSelectedGameObject(null);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform,
eventData.position,
eventData.pressEventCamera,
out var pos
);
TopCard.EndSwipe(pos - pointerStartPos);
}
#if UNITY_EDITOR
void OnDrawGizmosSelected()
{
UnityEditor.Handles.color = Color.green;
var rotPivotWorld = transform.TransformPoint(rotationPivot * canvas.scaleFactor);
UnityEditor.Handles.Disc(Quaternion.identity,
rotPivotWorld,
transform.forward,
UnityEditor.HandleUtility.GetHandleSize(rotPivotWorld) * .1f,
false,
0);
}
#endif
}
}
fileFormatVersion: 2
guid: cac04a9accad4830909197c18d6653b8
timeCreated: 1595068908
\ No newline at end of file
fileFormatVersion: 2
guid: 11f84f641665cf84099522a0374fc7ab
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.UI;
public class OpenUrl : MonoBehaviour
{
public string buttonURL;
Button button;
void Start()
{
button = GetComponent<Button>();
if (button)
button.onClick.AddListener(() => Open(buttonURL));
}
public void Open(string url)
{
Application.OpenURL(url);
}
}
fileFormatVersion: 2
guid: d913e19fec2d9b54da88a806aee86096
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using LeTai.TrueShadow;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
public class SymbolsManager : MonoBehaviour
{
#pragma warning disable 0649
[SerializeField] float cellSize = 100;
[SerializeField] GameObject shapePrefab;
[SerializeField] Sprite[] sprites;
[SerializeField] Color[] colors;
[SerializeField] float maxReactionDistance;
[SerializeField] AnimationCurve reactionCurve;
[SerializeField] float heightOffset;
[SerializeField] Vector2 shadowSizeMinMax;
[SerializeField] Vector2 shadowDistanceMinMax;
[SerializeField] Gradient shadowGradient;
[SerializeField] TrueShadow[] samples;
#pragma warning restore 0649
float colorScale = 1;
RectTransform selfRt;
Camera interectionCam;
Vector2[] initialPositions;
RectTransform[] rectTransforms;
TrueShadow[] shadows;
void Start()
{
interectionCam = Camera.main;
Spawn();
}
void Spawn()
{
selfRt = GetComponent<RectTransform>();
var res = GetComponentInParent<CanvasScaler>().referenceResolution;
var xCount = Mathf.CeilToInt(res.x / cellSize);
var yCount = Mathf.CeilToInt(res.y / cellSize);
var count = xCount * yCount;
initialPositions = new Vector2[count];
rectTransforms = new RectTransform[count];
shadows = new TrueShadow[count];
var randomFrom = .25f * cellSize;
var randomTo = .75f * cellSize;
for (int idY = 0; idY < yCount; idY++)
for (int idX = 0; idX < xCount; idX++)
{
var obj = Instantiate(shapePrefab, transform);
var rt = obj.GetComponent<RectTransform>();
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.zero;
rt.anchoredPosition = new Vector3(
idX * cellSize + Random.Range(randomFrom, randomTo),
idY * cellSize + Random.Range(randomFrom, randomTo),
transform.position.z
);
rt.rotation = Quaternion.Euler(0, 0, Mathf.Floor((Random.value - .5f) * 4) * 90 / 4);
rt.sizeDelta *= cellSize / 220;
var img = obj.GetComponent<Image>();
var spriteId = Random.Range(0, sprites.Length);
img.sprite = sprites[spriteId];
img.color = colors[spriteId];
var index = idY * xCount + idX;
rectTransforms[index] = rt;
initialPositions[index] = rt.anchoredPosition;
shadows[index] = img.GetComponent<TrueShadow>();
}
}
void Update()
{
React();
}
void React()
{
var count = initialPositions.Length;
RectTransformUtility.ScreenPointToLocalPointInRectangle(selfRt,
Input.mousePosition,
interectionCam,
out var mouse);
for (int i = 0; i < count; i++)
{
var position = initialPositions[i];
var dist = (position - mouse).magnitude;
var reaction = reactionCurve.Evaluate(Mathf.InverseLerp(maxReactionDistance, 0, dist));
position.y += heightOffset * reaction;
rectTransforms[i].anchoredPosition = position;
var shadow = shadows[i];
shadow.Size = Mathf.Lerp(shadowSizeMinMax.x, shadowSizeMinMax.y, reaction);
shadow.OffsetDistance = Mathf.Lerp(shadowDistanceMinMax.x, shadowDistanceMinMax.y, reaction);
var color = shadowGradient.Evaluate(reaction);
color.r *= colorScale;
color.g *= colorScale;
color.b *= colorScale;
shadow.Color = color;
}
}
public void SetMaxSize(float maxSize)
{
shadowSizeMinMax.y = maxSize;
var sampleSize = maxSize / 2f;
for (var i = 0; i < samples.Length; i++)
{
samples[i].Size = sampleSize;
}
}
public void SetColorScale(float scale)
{
colorScale = scale;
var sampleColor = Color.white * (scale / 2f + .25f);
sampleColor.a = samples[0].Color.a;
for (var i = 0; i < samples.Length; i++)
{
samples[i].Color = sampleColor;
}
}
}
fileFormatVersion: 2
guid: afae5a31ba4dd9549b7c6077d26c94ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 179b5dc57fb67c44dad8bed6b790a5cb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
#if LETAI_TRUESHADOW_DEBUG
using System;
using UnityEngine;
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
#endif
namespace LeTai.TrueShadow
{
[Serializable]
public class DebugSettings
{
const string FILE_PATH = "ProjectSettings/TrueShadowDebugSettings.json";
static DebugSettings instance;
public static DebugSettings Instance
{
get
{
if (instance == null)
{
#if UNITY_EDITOR
try
{
if (File.Exists(FILE_PATH))
instance = JsonUtility.FromJson<DebugSettings>(File.ReadAllText(FILE_PATH));
else
Create();
}
catch (Exception)
{
Create();
}
#else
Create();
#endif
}
return instance;
}
}
static void Create()
{
instance = new DebugSettings();
instance.Save();
}
public bool showObjects = true;
void Save()
{
#if UNITY_EDITOR
File.WriteAllText(FILE_PATH, JsonUtility.ToJson(this, true));
#endif
}
#if UNITY_EDITOR
[MenuItem("Tools/Show Objects")]
static void ShowObjects()
{
Instance.showObjects = true;
Instance.Save();
}
[MenuItem("Tools/Hide Objects")]
static void HideObjects()
{
Instance.showObjects = false;
Instance.Save();
}
#endif
}
}
#endif
fileFormatVersion: 2
guid: 15f8726536514604185aa6c94cb75b8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 9828472a1e7da384d91dbfc5a7cbc1b3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace LeTai.TrueShadow.Editor
{
[InitializeOnLoad]
public static class AutoCustomScriptingDefine
{
internal static readonly HashSet<string> SYMBOLS = new HashSet<string> {"LETAI_TRUESHADOW"};
static AutoCustomScriptingDefine()
{
Apply();
}
public static void Apply()
{
AddMissingSymbols(EditorUserBuildSettings.activeBuildTarget);
}
static void AddMissingSymbols(BuildTarget buildTarget)
{
var currentGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentGroup).Split(';').ToList();
var missing = SYMBOLS.Except(defines).ToList();
defines.AddRange(missing);
if (missing.Count > 0)
PlayerSettings.SetScriptingDefineSymbolsForGroup(currentGroup, string.Join(";", defines));
}
}
}
fileFormatVersion: 2
guid: 150508a406864b6ca9ad4e38e75cb333
timeCreated: 1597477199
\ No newline at end of file
using System;
using System.Globalization;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public class EditorProperty
{
public readonly SerializedProperty serializedProperty;
readonly SerializedObject serializedObject;
readonly MethodInfo propertySetter;
readonly SerializedProperty dirtyFlag;
public EditorProperty(SerializedObject obj, string name)
{
var propertyName = char.ToLowerInvariant(name[0]) + name.Substring(1);
serializedObject = obj;
serializedProperty = serializedObject.FindProperty(propertyName);
propertySetter = serializedObject.targetObject.GetType().GetProperty(name).SetMethod;
dirtyFlag = serializedObject.FindProperty("modifiedFromInspector");
}
public void Draw(params GUILayoutOption[] options)
{
using (var scope = new EditorGUI.ChangeCheckScope())
{
EditorGUILayout.PropertyField(serializedProperty, options);
if (!scope.changed)
return;
if (dirtyFlag != null)
dirtyFlag.boolValue = true;
serializedObject.ApplyModifiedProperties();
foreach (var target in serializedObject.targetObjects)
{
switch (serializedProperty.propertyType)
{
case SerializedPropertyType.Float:
propertySetter.Invoke(target, new object[] { serializedProperty.floatValue });
break;
case SerializedPropertyType.Enum:
propertySetter.Invoke(target, new object[] { serializedProperty.enumValueIndex });
break;
case SerializedPropertyType.Boolean:
propertySetter.Invoke(target, new object[] { serializedProperty.boolValue });
break;
case SerializedPropertyType.Color:
propertySetter.Invoke(target, new object[] { serializedProperty.colorValue });
break;
default: throw new NotImplementedException();
}
}
}
}
}
}
fileFormatVersion: 2
guid: 1f9db8b2544c48c2a7f13b46f27236e8
timeCreated: 1594635819
\ No newline at end of file
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public class InlineToolbar : PropertyDrawer
{
protected static Texture[] textures;
static readonly GUIStyle LABEL_STYLE = new GUIStyle(EditorStyles.label)
{alignment = TextAnchor.MiddleLeft,};
public override void OnGUI(Rect position, SerializedProperty property,
GUIContent label)
{
using (var propScope = new EditorGUI.PropertyScope(position, label, property))
{
int id = GUIUtility.GetControlID(FocusType.Keyboard, position);
var lableRect = position;
lableRect.y += (lableRect.height - EditorGUIUtility.singleLineHeight) / 2;
lableRect.height = EditorGUIUtility.singleLineHeight;
var toolbarRect = EditorGUI.PrefixLabel(lableRect, id, propScope.content, LABEL_STYLE);
toolbarRect.width = EditorGUIUtility.singleLineHeight * 4f;
toolbarRect.height = position.height;
toolbarRect.y = position.y;
using (var changeScope = new EditorGUI.ChangeCheckScope())
{
var isOn = GUI.Toolbar(toolbarRect, property.boolValue ? 1 : 0, textures) == 1;
var changed = changeScope.changed;
if (Event.current.type == EventType.KeyDown &&
GUIUtility.keyboardControl == id)
{
if (Event.current.keyCode == KeyCode.Return ||
Event.current.keyCode == KeyCode.KeypadEnter ||
Event.current.keyCode == KeyCode.Space)
{
changed = GUI.changed = true;
isOn = !isOn;
}
}
if (changed)
property.boolValue = isOn;
}
}
}
}
}
fileFormatVersion: 2
guid: ea4346ac17c04991bf233f1dc0def012
timeCreated: 1602580020
\ No newline at end of file
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(InsetToggleAttribute))]
public class InsetToggle : InlineToolbar
{
static readonly Texture OUTER_SHADOW_TEXTURE = Utility.FindEditorResource<Texture>("Outer Shadow");
static readonly Texture INNER_SHADOW_TEXTURE = Utility.FindEditorResource<Texture>("Inner Shadow");
static InsetToggle()
{
textures = new[] {OUTER_SHADOW_TEXTURE, INNER_SHADOW_TEXTURE};
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return OUTER_SHADOW_TEXTURE.height + 4;
}
}
}
fileFormatVersion: 2
guid: 89a04959b4ed4a9abee2ce76210516b9
timeCreated: 1641895407
\ No newline at end of file
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using static LeTai.TrueShadow.Math;
using EGU = UnityEditor.EditorGUIUtility;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(KnobAttribute))]
public class KnobPropertyDrawer : PropertyDrawer
{
public static bool procrastinationMode = false;
static readonly Texture2D KNOB_BG_TEXTURE = Utility.FindEditorResource<Texture2D>("Knob_BG");
static readonly Texture2D KNOB_FG_TEXTURE = Utility.FindEditorResource<Texture2D>("Knob_FG");
static readonly MethodInfo DO_FLOAT_FIELD_METHOD;
static readonly FieldInfo RECYCLED_EDITOR_PROPERTY;
static readonly FieldInfo FLOAT_FIELD_FORMAT_STRING_CONST;
static readonly Color KNOB_BG_COLOR;
static readonly Color KNOB_FG_COLOR;
static readonly Color KNOB_FG_COLOR_ACTIVE;
static KnobPropertyDrawer()
{
var editorGUIType = typeof(EditorGUI);
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static;
Type[] argumentTypes = {
Assembly.GetAssembly(editorGUIType).GetType("UnityEditor.EditorGUI+RecycledTextEditor"),
typeof(Rect),
typeof(Rect),
typeof(int),
typeof(float),
typeof(string),
typeof(GUIStyle),
typeof(bool)
};
DO_FLOAT_FIELD_METHOD = editorGUIType.GetMethod("DoFloatField", flags, null, argumentTypes, null);
RECYCLED_EDITOR_PROPERTY = editorGUIType.GetField("s_RecycledEditor", flags);
FLOAT_FIELD_FORMAT_STRING_CONST = editorGUIType.GetField("kFloatFieldFormatString", flags);
if (EGU.isProSkin)
{
KNOB_BG_COLOR = new Color(.164f, .164f, .164f);
KNOB_FG_COLOR = new Color(.701f, .701f, .701f);
KNOB_FG_COLOR_ACTIVE = new Color(.49f, .67f, .94f);
}
else
{
KNOB_BG_COLOR = new Color(.941f, .941f, .941f);
KNOB_FG_COLOR = new Color(.239f, .239f, .239f);
KNOB_FG_COLOR_ACTIVE = new Color(.054f, .274f, .549f);
}
}
static float DoFloatFieldInternal(Rect position,
Rect dragHotZone,
int id,
float value,
string formatString = null,
GUIStyle style = null,
bool draggable = true)
{
style = style ?? EditorStyles.numberField;
formatString = formatString ?? (string) FLOAT_FIELD_FORMAT_STRING_CONST.GetValue(null);
var editor = RECYCLED_EDITOR_PROPERTY.GetValue(null);
return (float) DO_FLOAT_FIELD_METHOD.Invoke(null, new[] {
editor,
position,
dragHotZone,
id,
value,
formatString,
style,
draggable
});
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (!(attribute is KnobAttribute)) return;
KnobProperty(position, label, property, Vector2.right);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return ControlHeight;
}
static float ControlHeight => EGU.singleLineHeight * 2.0f;
static float KnobSize => EGU.singleLineHeight * 2.5f;
static float KnobYOffset => (ControlHeight - KnobSize) / 2;
static Color Lighten(Color color, float amount)
{
Color.RGBToHSV(color, out var h, out var s, out var v);
return Color.HSVToRGB(h, s, v + amount);
}
public static void KnobProperty(Rect rect, GUIContent label, SerializedProperty prop, Vector2 zeroVector)
{
float angle = prop.floatValue;
float prevAngle = angle;
using (var propScope = new EditorGUI.PropertyScope(rect, label, prop))
using (var changeScope = new EditorGUI.ChangeCheckScope())
{
var labelRect = new Rect(rect) {
y = rect.y + (ControlHeight - EGU.singleLineHeight) / 2,
height = EGU.singleLineHeight
};
int fieldId = GUIUtility.GetControlID(FocusType.Keyboard, labelRect);
var fieldRect = EditorGUI.PrefixLabel(labelRect, fieldId, propScope.content);
labelRect.xMax = fieldRect.x;
fieldRect.x += ControlHeight;
fieldRect.width -= ControlHeight;
Rect knobRect = new Rect(rect.x + EGU.labelWidth + KnobYOffset,
rect.y + KnobYOffset,
KnobSize, KnobSize);
int knobId = GUIUtility.GetControlID(FocusType.Passive, knobRect);
if (Event.current != null)
{
if (Event.current.type == EventType.MouseDown && knobRect.Contains(Event.current.mousePosition))
{
GUIUtility.hotControl = knobId;
angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center);
}
else if (Event.current.type == EventType.MouseUp && GUIUtility.hotControl == knobId)
{
GUIUtility.hotControl = 0;
}
else if (Event.current.type == EventType.MouseDrag && GUIUtility.hotControl == knobId)
{
angle = Angle360(zeroVector, Event.current.mousePosition - knobRect.center);
}
else if (Event.current.type == EventType.Repaint)
{
var notRotated = GUI.matrix;
var oldColor = GUI.color;
var highlighted = GUIUtility.hotControl == knobId ||
GUIUtility.hotControl == fieldId ||
GUIUtility.keyboardControl == fieldId;
GUIUtility.RotateAroundPivot(angle, knobRect.center);
GUI.color = KNOB_BG_COLOR;
GUI.DrawTexture(knobRect, KNOB_BG_TEXTURE, ScaleMode.ScaleToFit, true, 1);
GUI.color = highlighted ? KNOB_FG_COLOR_ACTIVE : KNOB_FG_COLOR;
if (procrastinationMode) GUI.color = Color.red;
GUI.DrawTexture(knobRect, KNOB_FG_TEXTURE, ScaleMode.ScaleToFit, true, 1);
if (!procrastinationMode)
GUI.matrix = notRotated;
GUI.color = oldColor;
}
if (angle != prevAngle) GUI.changed = true;
}
angle = DoFloatFieldInternal(
fieldRect,
labelRect,
fieldId,
angle
);
if (changeScope.changed) prop.floatValue = angle;
}
}
}
}
fileFormatVersion: 2
guid: 07c24ad14ec14d40ab304c80ba6af657
timeCreated: 1594636852
\ No newline at end of file
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public class MigrateToVV1Window : EditorWindow
{
private const string SHOW_ON_START_EDITOR_PREFS_KEY = "LeTai.TrueShadow.MigrateToVV1WindowShown";
[MenuItem("Tools/TrueShadow/Migrate To v1")]
public static MigrateToVV1Window ShowWindow()
{
var window = GetWindow<MigrateToVV1Window>(true, "True Shadow");
window.position = new Rect(600, 400, 600, 400);
return window;
}
[InitializeOnLoadMethod]
private static void InitializeOnLoadMethod()
{
RegisterWindowCheck();
}
private static void RegisterWindowCheck()
{
if (!EditorApplication.isPlayingOrWillChangePlaymode)
{
EditorApplication.update += CheckShowWindow;
}
}
private static void CheckShowWindow()
{
EditorApplication.update -= CheckShowWindow;
if (EditorPrefs.GetBool(SHOW_ON_START_EDITOR_PREFS_KEY, true))
{
ShowWindow();
}
}
void OnDestroy()
{
EditorPrefs.SetBool(SHOW_ON_START_EDITOR_PREFS_KEY, false);
}
bool haveBackup;
private void OnGUI()
{
GUILayout.Label("Migrate to v1", EditorStyles.largeLabel);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox(
"In v1, Blend Mode was changed to produce better looking shadows, as well as better compatibility with 3rd parties asset. As a side effect, most shadows should now use Color Bleed Mode: <Black>. This tool attempt to do this automatically.\n\n" +
"All True Shadows in currently loaded scenes will be migrated. You may want to load all scenes you want to fix before migrating. All True Shadows in prefabs will also be migrated.\n\n" +
"All True Shadows in prefabs will also be migrated.\n\n" +
"You may access this dialog later from the Tools menu.",
MessageType.Info
);
EditorGUILayout.Separator();
EditorGUILayout.HelpBox(
"!!! MAKE SURE TO BACK UP YOUR PROJECT BEFORE USE !!!\n\n" +
"This tool will modify your project files. Please backup your project before use. If you are unsure how to do this, do NOT use this tool! Manually change any problematic shadows Color Bleed mode to Black instead!",
MessageType.Warning);
EditorGUILayout.Separator();
haveBackup = EditorGUILayout.ToggleLeft("I have backed up the project and can undo any changes done by the tool", haveBackup);
if (haveBackup)
{
if (GUILayout.Button("Migrate to v1"))
MigrateToV1();
}
}
public static void MigrateToV1()
{
var allPrefabs = AssetDatabase.FindAssets("t:Prefab");
foreach (var guid in allPrefabs)
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var prefabRoot = PrefabUtility.LoadPrefabContents(path);
var changed = false;
foreach (var shadow in prefabRoot.GetComponentsInChildren<TrueShadow>())
{
shadow.ColorBleedMode = ColorBleedMode.Black;
changed = true;
}
if (changed)
PrefabUtility.SaveAsPrefabAsset(prefabRoot, path);
PrefabUtility.UnloadPrefabContents(prefabRoot);
}
var inScene = Resources.FindObjectsOfTypeAll<TrueShadow>()
.ToArray();
Undo.RecordObjects(inScene, "Migrate to 0.5");
foreach (var shadow in inScene)
{
shadow.ColorBleedMode = ColorBleedMode.Black;
}
}
}
}
fileFormatVersion: 2
guid: 126149305ac84024ac1d713f39caf754
timeCreated: 1611560835
\ No newline at end of file
using UnityEditor;
namespace LeTai.TrueShadow.Editor
{
[InitializeOnLoad]
class PrefabEventHandler
{
static PrefabEventHandler()
{
PrefabUtility.prefabInstanceUpdated += go =>
{
var shadows = go.GetComponentsInChildren<TrueShadow>();
foreach (var shadow in shadows)
shadow.ApplySerializedData();
};
}
}
}
fileFormatVersion: 2
guid: 9806fc5a3b18445e9766a68cf69b81c9
timeCreated: 1600845150
\ No newline at end of file
using System;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using static UnityEditor.EditorGUILayout;
using static UnityEditor.EditorGUIUtility;
namespace LeTai.TrueShadow.Editor
{
[CanEditMultipleObjects]
[CustomEditor(typeof(ProjectSettings))]
public class ProjectSettingsEditor : UnityEditor.Editor
{
EditorProperty useGlobalAngleByDefault;
EditorProperty globalAngle;
EditorProperty showQuickPresetsButtons;
EditorProperty quickPresets;
ReorderableList reorderableList;
void OnEnable()
{
// Domain reload cause target to be null
if(target == null) return;
useGlobalAngleByDefault = new EditorProperty(serializedObject, nameof(ProjectSettings.UseGlobalAngleByDefault));
globalAngle = new EditorProperty(serializedObject, nameof(ProjectSettings.GlobalAngle));
showQuickPresetsButtons = new EditorProperty(serializedObject, nameof(ProjectSettings.ShowQuickPresetsButtons));
quickPresets = new EditorProperty(serializedObject, nameof(ProjectSettings.QuickPresets));
reorderableList = new ReorderableList(serializedObject, quickPresets.serializedProperty, true, true, true, true) {
drawHeaderCallback = DrawPresetsHListHeader,
drawElementCallback = DrawPresetListItems,
elementHeight = singleLineHeight * 6
+ standardVerticalSpacing * 7,
};
}
void DrawPresetsHListHeader(Rect rect)
{
EditorGUI.PrefixLabel(rect, new GUIContent(quickPresets.serializedProperty.displayName));
}
void DrawPresetListItems(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
var childRect = new Rect(rect) { height = singleLineHeight };
EditorGUI.LabelField(childRect, element.FindPropertyRelative(nameof(QuickPreset.name)).stringValue);
childRect.y += singleLineHeight + standardVerticalSpacing;
var oldLabelWidth = labelWidth;
labelWidth = Mathf.Min(labelWidth, pixelsPerPoint * 60);
foreach (var childProp in element)
{
EditorGUI.PropertyField(childRect, (SerializedProperty)childProp, true);
childRect.y += singleLineHeight + standardVerticalSpacing;
}
labelWidth = oldLabelWidth;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
useGlobalAngleByDefault.Draw();
globalAngle.Draw();
Space();
showQuickPresetsButtons.Draw();
using (new GUILayout.HorizontalScope())
{
Space(pixelsPerPoint * 8, false);
using (new GUILayout.VerticalScope(GUILayout.MaxWidth(pixelsPerPoint * 400)))
reorderableList.DoLayoutList();
Space(pixelsPerPoint * 8, false);
}
serializedObject.ApplyModifiedProperties();
}
[SettingsProvider]
public static SettingsProvider CreatSettingsProvider()
{
if (!Resources.Load(ProjectSettings.RESOURCE_PATH))
return null;
return AssetSettingsProvider.CreateProviderFromResourcePath(
"Project/True Shadow",
ProjectSettings.RESOURCE_PATH,
SettingsProvider.GetSearchKeywordsFromPath(ProjectSettings.RESOURCE_PATH)
);
}
}
class RunOnImport : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (Resources.Load(ProjectSettings.RESOURCE_PATH))
return;
foreach (var path in importedAssets)
{
var fileName = Path.GetFileNameWithoutExtension(path);
if (string.Compare(fileName,
ProjectSettings.DEFAULT_RESOURCE_PATH,
StringComparison.InvariantCulture) == 0)
{
EnsureSettingAsset(path);
break;
}
if (string.Compare(fileName,
ProjectSettings.RESOURCE_PATH,
StringComparison.InvariantCulture) == 0)
{
EditorApplication.update += NotifySettingsProviderChanged;
break;
}
}
}
static void NotifySettingsProviderChanged()
{
SettingsService.NotifySettingsProviderChanged();
EditorApplication.update -= NotifySettingsProviderChanged;
}
static void EnsureSettingAsset(string defaultPath)
{
// ReSharper disable once AssignNullToNotNullAttribute
var userPath = Path.Combine(Path.GetDirectoryName(defaultPath), ProjectSettings.RESOURCE_PATH + ".asset");
var userSettings = AssetDatabase.LoadAssetAtPath<ProjectSettings>(userPath);
if (userSettings)
return;
AssetDatabase.CopyAsset(defaultPath, userPath);
AssetDatabase.ImportAsset(userPath,
ImportAssetOptions.ForceUpdate
| ImportAssetOptions.ForceSynchronousImport);
}
}
}
fileFormatVersion: 2
guid: ce58e85c062341bdacd3d6bd0855d6ed
timeCreated: 1641808404
\ No newline at end of file
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
namespace LeTai.Asset.TrueShadow.Editor
{
class ScenceGizmoAutoDisable : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
if (!importedAssets.Any(p => p.Contains("TrueShadow")))
return;
var structAnnotation = Type.GetType("UnityEditor.Annotation, UnityEditor");
if (structAnnotation == null) return;
var fieldClassId = structAnnotation.GetField("classID");
var fieldScriptClass = structAnnotation.GetField("scriptClass");
var fieldFlags = structAnnotation.GetField("flags");
var fieldIconEnabled = structAnnotation.GetField("iconEnabled");
Type classAnnotationUtility = Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
if (classAnnotationUtility == null) return;
var methodGetAnnotations = classAnnotationUtility.GetMethod("GetAnnotations", BindingFlags.NonPublic | BindingFlags.Static);
if (methodGetAnnotations == null) return;
var methodSetIconEnabled = classAnnotationUtility.GetMethod("SetIconEnabled", BindingFlags.NonPublic | BindingFlags.Static);
if (methodSetIconEnabled == null) return;
Array annotations = (Array)methodGetAnnotations.Invoke(null, null);
foreach (var a in annotations)
{
string scriptClass = (string)fieldScriptClass.GetValue(a);
// built in types
if (string.IsNullOrEmpty(scriptClass)) continue;
int classId = (int)fieldClassId.GetValue(a);
int flags = (int)fieldFlags.GetValue(a);
int iconEnabled = (int)fieldIconEnabled.GetValue(a);
const int maskHasIcon = 1;
bool hasIconFlag = (flags & maskHasIcon) == maskHasIcon;
if (hasIconFlag
&& iconEnabled != 0
&& scriptClass.Contains("TrueShadow"))
{
methodSetIconEnabled.Invoke(null, new object[] { classId, scriptClass, 0 });
}
}
}
}
}
fileFormatVersion: 2
guid: a1266d64cf1066b47b900e5115a5b75d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
[CustomEditor(typeof(ShadowMaterial))]
public class ShadowMaterialEditor : UnityEditor.Editor
{
ShadowMaterial shadowMaterial;
MaterialEditor materialEditor;
void OnEnable()
{
shadowMaterial = (ShadowMaterial) target;
if (shadowMaterial.material != null)
{
materialEditor = (MaterialEditor) CreateEditor(shadowMaterial.material);
}
}
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(serializedObject.FindProperty("material"));
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
if (materialEditor)
{
DestroyImmediate(materialEditor);
}
if (shadowMaterial.material)
{
materialEditor = (MaterialEditor) CreateEditor(shadowMaterial.material);
}
}
if (materialEditor)
{
materialEditor.DrawHeader();
bool isDefaultMaterial = !AssetDatabase.GetAssetPath(shadowMaterial.material).StartsWith("Assets");
using (new EditorGUI.DisabledGroupScope(isDefaultMaterial))
{
EditorGUI.BeginChangeCheck();
materialEditor.OnInspectorGUI();
if (EditorGUI.EndChangeCheck())
{
shadowMaterial.OnMaterialModified();
}
}
}
}
void OnDisable()
{
if (materialEditor)
{
DestroyImmediate(materialEditor);
}
}
}
}
fileFormatVersion: 2
guid: 618f886531374376920d0f8a8ae0fc6c
timeCreated: 1632817269
\ No newline at end of file
using UnityEditor;
using UnityEngine;
using static UnityEditor.EditorGUI;
namespace LeTai.TrueShadow.Editor
{
[CustomPropertyDrawer(typeof(SpreadSliderAttribute))]
public class SpreadSliderDrawer : PropertyDrawer
{
const float SLIDER_SPACING = 5;
const float MARKER_HEIGHT = 6;
const float MARKER_ALPHA = .75f;
const float MARKER_FILLET = 2;
static readonly Vector4 START_RADII = new Vector4(MARKER_FILLET, 0, 0, MARKER_FILLET);
static readonly Vector4 END_RADII = new Vector4(0, MARKER_FILLET, MARKER_FILLET, 0);
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
using (var propScope = new PropertyScope(position, label, property))
using (var changeScope = new ChangeCheckScope())
{
var controlPosition = PrefixLabel(position, propScope.content);
var floatFieldWidth = Mathf.Min(EditorGUIUtility.fieldWidth, controlPosition.width);
var sliderPosition = new Rect(controlPosition)
{width = controlPosition.width - floatFieldWidth - SLIDER_SPACING};
const float marker1 = .8f;
const float marker2 = .95f;
DrawMarkers(sliderPosition,
(marker1, new Color(1.00000f, 0.60392f, 0.01961f, MARKER_ALPHA)),
(marker2, new Color(1.00000f, 0.25490f, 0.20784f, MARKER_ALPHA)));
var newVal = Slider(controlPosition,
GUIContent.none,
property.floatValue,
0, 1);
if (!Event.current.control && !Event.current.alt)
{
var dist1 = (newVal - marker1) * sliderPosition.width;
var dist2 = (newVal - marker2) * sliderPosition.width;
if (0 < dist1 && dist1 < 4)
newVal = marker1;
if (0 < dist2 && dist2 < 4)
newVal = marker2;
}
if (changeScope.changed)
property.floatValue = newVal;
}
}
void DrawMarkers(Rect sliderPosition, params (float, Color)[] markers)
{
var hPad = GUI.skin.horizontalSliderThumb.fixedWidth / 2f;
var markerXStart = sliderPosition.x + hPad;
var markerXEnd = sliderPosition.width - hPad * 2;
var vPad = (sliderPosition.height - MARKER_HEIGHT) / 2f;
var markerYStart = sliderPosition.y + vPad;
var markerHeight = sliderPosition.height - vPad * 2;
for (var i = 0; i < markers.Length; i++)
{
var (offset, color) = markers[i];
var x = markerXStart + markerXEnd * offset;
var width = i < markers.Length - 1
? sliderPosition.width * (markers[i + 1].Item1 - offset) - 1
: sliderPosition.xMax - x;
var position = new Rect {
x = x,
y = markerYStart,
width = width,
height = markerHeight
};
var radii = i == 0 ? START_RADII : END_RADII;
GUI.DrawTexture(position,
Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, color,
Vector4.zero, radii);
}
}
}
}
fileFormatVersion: 2
guid: 3292983b33504803ae542a485f446019
timeCreated: 1615190623
\ No newline at end of file
fileFormatVersion: 2
guid: 23d5c09d6cd32644aa9ba98410f9602d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 098c7906709c37c4bba842c34581765c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 21fab31b34964614680dcb53be2692d1
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
using System.Linq;
using System.Reflection;
using LeTai.TrueShadow.PluginInterfaces;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using static UnityEditor.EditorGUILayout;
namespace LeTai.TrueShadow.Editor
{
[CanEditMultipleObjects]
[CustomEditor(typeof(TrueShadow))]
public class TrueShadowEditor : UnityEditor.Editor
{
EditorProperty insetProp;
EditorProperty sizeProp;
EditorProperty spreadProp;
EditorProperty useGlobalAngleProp;
EditorProperty angleProp;
EditorProperty distanceProp;
EditorProperty colorProp;
EditorProperty blendModeProp;
EditorProperty multiplyCasterAlphaProp;
EditorProperty ignoreCasterColorProp;
EditorProperty colorBleedModeProp;
EditorProperty disableFitCompensationProp;
#if LETAI_TRUESHADOW_DEBUG
SerializedProperty alwayRenderProp;
#endif
GUIContent procrastinateLabel;
GUIContent editGlobalAngleLabel;
static bool showExperimental;
static bool showAdvanced;
static Texture warningIcon;
static GUIStyle hashWarningStyle;
static GUIContent hashWarningLabel;
void OnEnable()
{
insetProp = new EditorProperty(serializedObject, nameof(TrueShadow.Inset));
sizeProp = new EditorProperty(serializedObject, nameof(TrueShadow.Size));
spreadProp = new EditorProperty(serializedObject, nameof(TrueShadow.Spread));
useGlobalAngleProp = new EditorProperty(serializedObject, nameof(TrueShadow.UseGlobalAngle));
angleProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetAngle));
distanceProp = new EditorProperty(serializedObject, nameof(TrueShadow.OffsetDistance));
colorProp = new EditorProperty(serializedObject, nameof(TrueShadow.Color));
blendModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.BlendMode));
multiplyCasterAlphaProp = new EditorProperty(serializedObject, nameof(TrueShadow.UseCasterAlpha));
ignoreCasterColorProp = new EditorProperty(serializedObject, nameof(TrueShadow.IgnoreCasterColor));
colorBleedModeProp = new EditorProperty(serializedObject, nameof(TrueShadow.ColorBleedMode));
disableFitCompensationProp = new EditorProperty(serializedObject, nameof(TrueShadow.DisableFitCompensation));
#if LETAI_TRUESHADOW_DEBUG
alwayRenderProp = serializedObject.FindProperty(nameof(TrueShadow.alwaysRender));
#endif
if (EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental)))
{
showExperimental = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showExperimental), false);
showAdvanced = EditorPrefs.GetBool("LeTai_TrueShadow_" + nameof(showAdvanced), false);
}
procrastinateLabel = new GUIContent("Procrastinate", "A bug that is too fun to fix");
editGlobalAngleLabel = new GUIContent("Edit...");
if (!warningIcon)
{
warningIcon = typeof(EditorGUIUtility)
.GetProperty("warningIcon", BindingFlags.Static | BindingFlags.NonPublic)
?.GetValue(null) as Texture;
}
hashWarningLabel = new GUIContent(warningIcon);
hashWarningStyle = new GUIStyle(EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector)
.FindStyle("WordWrappedLabel")) {
richText = true
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
var ts = (TrueShadow)target;
DrawPresetButtons(ts);
Space();
insetProp.Draw();
sizeProp.Draw();
spreadProp.Draw();
useGlobalAngleProp.Draw(GUILayout.ExpandWidth(!ts.UseGlobalAngle));
if (ts.UseGlobalAngle)
{
var settingRect = GUILayoutUtility.GetLastRect();
settingRect.xMin += EditorGUIUtility.labelWidth + EditorGUIUtility.singleLineHeight;
settingRect.width = GUI.skin.button.CalcSize(editGlobalAngleLabel).x;
if (GUI.Button(settingRect, editGlobalAngleLabel))
{
SettingsService.OpenProjectSettings("Project/True Shadow");
}
}
else
{
angleProp.Draw();
}
distanceProp.Draw();
colorProp.Draw();
if (ts.UsingRendererMaterialProvider)
{
using (new EditorGUI.DisabledScope(true))
LabelField(blendModeProp.serializedProperty.displayName, "Custom Material");
}
else
{
blendModeProp.Draw();
}
DrawAdvancedSettings();
DrawHashWarning();
serializedObject.ApplyModifiedProperties();
}
void DrawPresetButtons(TrueShadow ts)
{
if (!ProjectSettings.Instance.ShowQuickPresetsButtons) return;
using (new HorizontalScope())
{
var presets = ProjectSettings.Instance.QuickPresets;
var selected = GUILayout.Toolbar(-1, presets.Select(p => p.name).ToArray());
if (selected != -1)
{
Undo.RecordObject(ts, "Apply Quick Preset on " + ts.name);
presets[selected].Apply(ts);
EditorApplication.QueuePlayerLoopUpdate();
}
if (GUILayout.Button("...", GUILayout.ExpandWidth(false)))
{
SettingsService.OpenProjectSettings("Project/True Shadow");
}
}
}
void DrawAdvancedSettings()
{
using (var change = new EditorGUI.ChangeCheckScope())
{
showAdvanced = Foldout(showAdvanced, "Advanced Settings", true);
using (new EditorGUI.IndentLevelScope())
if (showAdvanced)
{
multiplyCasterAlphaProp.Draw();
ignoreCasterColorProp.Draw();
colorBleedModeProp.Draw();
disableFitCompensationProp.Draw();
if (KnobPropertyDrawer.procrastinationMode)
{
var rot = GUI.matrix;
GUI.matrix = Matrix4x4.identity;
KnobPropertyDrawer.procrastinationMode ^= Toggle("Be Productive", false);
GUI.matrix = rot;
}
else
{
KnobPropertyDrawer.procrastinationMode |= Toggle(procrastinateLabel, false);
}
#if LETAI_TRUESHADOW_DEBUG
PropertyField(alwayRenderProp);
#endif
}
if (change.changed)
{
EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showExperimental), showExperimental);
EditorPrefs.SetBool("LeTai_TrueShadow_" + nameof(showAdvanced), showAdvanced);
}
}
}
static readonly string[] KNOWN_TYPES = {
"UnityEngine.UI.Image",
"UnityEngine.UI.RawImage",
"UnityEngine.UI.Text",
"TMPro.TextMeshProUGUI",
"Unity.VectorGraphics.SVGImage",
};
void DrawHashWarning()
{
var ts = (TrueShadow)target;
if (ts.GetComponent<ITrueShadowCustomHashProvider>() != null)
return;
var casterType = ts.GetComponent<Graphic>().GetType();
if (KNOWN_TYPES.Contains(casterType.FullName))
return;
hashWarningLabel.text = "Shadow may not update with changes";
using (var _ = new VerticalScope(EditorStyles.helpBox))
{
GUILayout.Label(hashWarningLabel);
GUILayout.Label($"True Shadow can't tell 2 <i>{casterType.Name}</i> apart." +
$" The shadow may not update when the <i>{casterType.Name}</i> changes.\n" +
$"To fix this, set the shadow CustomHash, or disable shadow caching for this element.",
hashWarningStyle);
if (GUILayout.Button("More info on CustomHash", EditorStyles.linkLabel))
{
Application.OpenURL("https://leloctai.com/trueshadow/docs/articles/integration.html#make-sure-shadow-update");
}
if (GUILayout.Button("Disable Shadow Cache for this element", EditorStyles.linkLabel))
{
Undo.AddComponent<DisableShadowCache>(ts.gameObject);
}
}
}
}
}
fileFormatVersion: 2
guid: 120b61c7775149ed9de9c782978f6d61
timeCreated: 1592985822
\ No newline at end of file
using UnityEditor;
using UnityEngine;
namespace LeTai.TrueShadow.Editor
{
public static class Utility
{
internal static T FindEditorResource<T>(string assetName) where T : Object
{
var guids = AssetDatabase.FindAssets("l:TrueShadowEditorResources " + assetName);
if (guids.Length == 0)
{
Debug.LogError(
$"Asset \"{assetName}\" not found. Make sure it have the label \"TrueShadowEditorResources\"");
return null;
}
var path = AssetDatabase.GUIDToAssetPath(guids[0]);
return AssetDatabase.LoadAssetAtPath<T>(path);
}
}
}
fileFormatVersion: 2
guid: 09b72999f3c04f898c16bf60deb38c6e
timeCreated: 1602578784
\ No newline at end of file
fileFormatVersion: 2
guid: 530284691e76dd245aa72ac6685767df
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace LeTai.Effects
{
public class BlurConfig : ScriptableObject
{
}
}
fileFormatVersion: 2
guid: 1598e613c3d69154db682bbf3c234cb2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.Rendering;
namespace LeTai.Effects
{
public interface IBlurAlgorithm
{
void Configure(BlurConfig config);
void Blur(CommandBuffer cmd,
RenderTargetIdentifier src,
Rect srcCropRegion,
RenderTexture target);
}
}
fileFormatVersion: 2
guid: 5bc98ab7243bbdc40a0c52f6d1ed58a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEngine.Rendering;
namespace LeTai.Effects
{
public class ScalableBlur : IBlurAlgorithm
{
Material material;
ScalableBlurConfig config;
static readonly int BLUE_NOISE_ID = Shader.PropertyToID("_BlueNoise");
static readonly int TARGET_SIZE_ID = Shader.PropertyToID("_TargetSize");
readonly Texture2D blueNoise;
const int BLUR_PASS = 0;
const int CROP_BLUR_PASS = 1;
const int DITHER_BLUR_PASS = 2;
public ScalableBlur()
{
blueNoise = Resources.Load<Texture2D>("True Shadow Blue Noise");
}
Material Material
{
get
{
if (material == null)
{
material = new Material(Shader.Find("Hidden/TrueShadow/Generate"));
}
return material;
}
set => material = value;
}
public void Configure(BlurConfig config)
{
this.config = (ScalableBlurConfig)config;
}
public void Blur(CommandBuffer cmd,
RenderTargetIdentifier src,
Rect srcCropRegion,
RenderTexture target)
{
float radius = config.Radius;
Material.SetFloat(ShaderProperties.blurRadius, radius);
Material.SetVector(ShaderProperties.blurTextureCropRegion, srcCropRegion.ToMinMaxVector());
int firstDownsampleFactor = config.Iteration > 0 ? 1 : 0;
int stepCount = Mathf.Max(config.Iteration * 2 - 1, 1);
int firstIRT = ShaderProperties.intermediateRT[0];
CreateTempRenderTextureFrom(cmd, firstIRT, target, firstDownsampleFactor);
// cmd.BlitFullscreenTriangle(src, firstIRT, Material, CROP_BLUR_PASS);
cmd.Blit(src, firstIRT, Material, CROP_BLUR_PASS);
for (var i = 1; i < stepCount; i++)
{
BlurAtDepth(cmd, i, target);
}
Material.SetTexture(BLUE_NOISE_ID, blueNoise);
Material.SetVector(TARGET_SIZE_ID, new Vector4(target.width, target.height));
// cmd.BlitFullscreenTriangle(ShaderProperties.intermediateRT[stepCount - 1], target, Material, BLUR_PASS);
cmd.Blit(ShaderProperties.intermediateRT[stepCount - 1], target, Material, DITHER_BLUR_PASS);
CleanupIntermediateRT(cmd, stepCount);
}
protected virtual void BlurAtDepth(CommandBuffer cmd, int depth, RenderTexture baseTexture)
{
int sizeLevel = Utility.SimplePingPong(depth, config.Iteration - 1) + 1;
sizeLevel = Mathf.Min(sizeLevel, config.MaxDepth);
CreateTempRenderTextureFrom(cmd, ShaderProperties.intermediateRT[depth], baseTexture, sizeLevel);
// cmd.BlitFullscreenTriangle(
cmd.Blit(
ShaderProperties.intermediateRT[depth - 1],
ShaderProperties.intermediateRT[depth],
Material,
BLUR_PASS
);
}
static void CreateTempRenderTextureFrom(CommandBuffer cmd,
int nameId,
RenderTexture src,
int downsampleFactor)
{
int w = src.width >> downsampleFactor; //= width / 2^downsample
int h = src.height >> downsampleFactor;
cmd.GetTemporaryRT(nameId, w, h, 0, FilterMode.Bilinear, src.format);
}
static void CleanupIntermediateRT(CommandBuffer cmd, int amount)
{
for (var i = 0; i < amount; i++)
{
cmd.ReleaseTemporaryRT(ShaderProperties.intermediateRT[i]);
}
}
}
}
fileFormatVersion: 2
guid: d72465d1220a01e4abccda77619f6763
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment