first commit

main
NoahLan 10 months ago
commit 3ebed1c113

12
.gitignore vendored

@ -0,0 +1,12 @@
TextMesh Pro.meta
TextMesh Pro
*.tss
Library
Logs
obj
ProjectSettings
Temp
UserSettings

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: be73703fd634493a802aa566748c4ad7
timeCreated: 1706068125

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: fcda1fbb0f0fbc34fbdeb59390ceab77
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
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
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: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
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: 0
spriteTessellationDetail: -1
textureType: 0
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: 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: WebGL
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: 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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: d18e152926310e94abcfa098f562ce48
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
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
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: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
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: 0
spriteTessellationDetail: -1
textureType: 0
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: 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: WebGL
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: 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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: 3782841ccd5a3c74daa021cca43aeb5e
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
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
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: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
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: 0
spriteTessellationDetail: -1
textureType: 0
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: 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: WebGL
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: 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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6dea77c2a1ae4f8191bb160dedae9698
timeCreated: 1706072392

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 999c9af62a23403d8fa73c48186331eb
timeCreated: 1706078264

@ -0,0 +1,28 @@
using System;
using UnityEngine;
using EVM = LanLib.EventManager;
namespace Samples.EventManager
{
public struct TestEvent
{
}
public class TestSubscribeEvent : MonoBehaviour
{
private void Awake()
{
EVM.EventManager.Instance.Subscribe<TestEvent>(OnTest);
}
private void OnDestroy()
{
EVM.EventManager.Instance.Unsubscribe<TestEvent>(OnTest);
}
private void OnTest(TestEvent evt)
{
print("TestEvent trigger!!!");
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b05de2395e1c417999ed736f88328f7e
timeCreated: 1706078287

@ -0,0 +1,13 @@
using UnityEngine;
using EVM = LanLib.EventManager;
namespace Samples.EventManager
{
public class TestTriggerEvent : MonoBehaviour
{
public void TriggerTestEvent()
{
EVM.EventManager.Instance.TriggerEvent(new TestEvent());
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7d0eaab3f34c46f99c55ceb0ac3a5a10
timeCreated: 1706078443

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0fa287cc7edd40bfaf62f5b2c85f7ab4
timeCreated: 1706078223

@ -0,0 +1,12 @@
using UnityEngine;
namespace Samples.Singleton
{
public class TestInvokeSingleton : MonoBehaviour
{
private void Start()
{
Test.Instance.SayHello();
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cf4ef1e6e942495abea0a35afe666d29
timeCreated: 1706077670

@ -0,0 +1,12 @@
using LanLib.Singleton;
namespace Samples.Singleton
{
public class Test : Singleton<Test>
{
public void SayHello()
{
print("hello world");
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c92b5e87a29a478fb5e5cbd1392995b3
timeCreated: 1706072406

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a3a9e9657ac442bbb6b9d7344cd5548d
timeCreated: 1706081266

@ -0,0 +1,33 @@
using LanLib.UpdateManager;
using UnityEngine;
namespace Samples.UpdateManager
{
public class TestFollowTarget : AManagedBehaviour, IUpdatable
{
[SerializeField] private Camera camera;
private void Awake()
{
if (!camera)
{
camera = Camera.main;
}
}
public void ManagedUpdate()
{
if (!Input.GetMouseButton(0))
{
return;
}
var ray = camera.ScreenPointToRay(Input.mousePosition);
var xz = new Plane(transform.up * 10, transform.position);
if (xz.Raycast(ray, out float z))
{
transform.position = ray.GetPoint(z);
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4d371b37033144c0a654d2d4de3409b4
timeCreated: 1706081361

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: daed5a3ce25c0a04e99b527f5f96ff92
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,998 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 705507994}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 500
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 2
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &120179636
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 120179637}
- component: {fileID: 120179639}
- component: {fileID: 120179638}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &120179637
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 120179636}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1288773903}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &120179638
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 120179636}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Trigger Test Event
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 0
m_fontSizeMax: 0
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 0
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 0
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &120179639
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 120179636}
m_CullTransparentMesh: 1
--- !u!1 &705507993
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 705507995}
- component: {fileID: 705507994}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &705507994
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 705507993}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 1
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &705507995
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 705507993}
serializedVersion: 2
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &870642445
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 870642447}
- component: {fileID: 870642446}
m_Layer: 0
m_Name: InvokeSingleton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &870642446
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 870642445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: cf4ef1e6e942495abea0a35afe666d29, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &870642447
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 870642445}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1604846115}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &963194225
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 963194228}
- component: {fileID: 963194227}
- component: {fileID: 963194226}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &963194226
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225}
m_Enabled: 1
--- !u!20 &963194227
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &963194228
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225}
serializedVersion: 2
m_LocalRotation: {x: 0.38268343, y: 0, z: 0, w: 0.92387956}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 45, y: 0, z: 0}
--- !u!1 &1288773902
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1288773903}
- component: {fileID: 1288773907}
- component: {fileID: 1288773906}
- component: {fileID: 1288773905}
- component: {fileID: 1288773904}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1288773903
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288773902}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 120179637}
m_Father: {fileID: 1307116728}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 24.7505, y: 0}
m_SizeDelta: {x: 209.5011, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1288773904
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288773902}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7d0eaab3f34c46f99c55ceb0ac3a5a10, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1288773905
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288773902}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 1288773906}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 1288773904}
m_TargetAssemblyTypeName: Samples.EventManager.TestTriggerEvent, Assembly-CSharp
m_MethodName: TriggerTestEvent
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &1288773906
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288773902}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1288773907
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1288773902}
m_CullTransparentMesh: 1
--- !u!1 &1307116724
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1307116728}
- component: {fileID: 1307116727}
- component: {fileID: 1307116726}
- component: {fileID: 1307116725}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1307116725
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1307116724}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &1307116726
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1307116724}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &1307116727
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1307116724}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 25
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &1307116728
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1307116724}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1288773903}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &1344531107
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1344531110}
- component: {fileID: 1344531109}
- component: {fileID: 1344531108}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1344531108
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344531107}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1344531109
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344531107}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1344531110
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1344531107}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1476468604
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1476468605}
- component: {fileID: 1476468609}
- component: {fileID: 1476468608}
- component: {fileID: 1476468607}
- component: {fileID: 1476468606}
m_Layer: 0
m_Name: TestFollowTarget
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1476468605
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476468604}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1990798249}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1476468606
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476468604}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4d371b37033144c0a654d2d4de3409b4, type: 3}
m_Name:
m_EditorClassIdentifier:
camera: {fileID: 963194227}
--- !u!65 &1476468607
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476468604}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!23 &1476468608
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476468604}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &1476468609
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1476468604}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1604846114
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1604846115}
m_Layer: 0
m_Name: Singleton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1604846115
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1604846114}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 870642447}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1990798248
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1990798249}
m_Layer: 0
m_Name: UpdateManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1990798249
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1990798248}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1476468605}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 963194228}
- {fileID: 705507995}
- {fileID: 1307116728}
- {fileID: 1344531110}
- {fileID: 1604846115}
- {fileID: 1990798249}

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9fc0d4010bbf28b4594072e72b8655ab
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 799f75a2cbfb8194a8876015b0294ab7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0548a9c043447784ab1f8d22c1de045a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d176007cce4b49e89161b849ea495afe
timeCreated: 1706066595

@ -0,0 +1,18 @@
{
"name": "LanLib.Singleton.Editor",
"rootNamespace": "",
"references": [
"LanLib.Singleton"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 33a22ae5db3b4773b599a297794f9b82
timeCreated: 1706067071

@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace LanLib.Singleton.EditorUtilities
{
static class SingletonManager
{
private static Dictionary<Type, SingletonCreateCondition> _lutSingletonCreation = null;
static void DestroyGameObject(GameObject go)
{
if (Application.isPlaying)
{
Object.Destroy(go);
}
else
{
Object.DestroyImmediate(go);
}
}
static void RemoveAllSingletons(Func<SingletonBase, bool> predicate)
{
if (Selection.activeGameObject?.GetComponent<SingletonBase>())
{
Selection.activeGameObject = null;
}
var instances = Resources
.FindObjectsOfTypeAll<SingletonBase>()
.Where(predicate)
.ToArray();
foreach (var inst in instances)
{
DestroyGameObject(inst.gameObject);
}
}
static Dictionary<Type, SingletonCreateCondition> GetSingletonTypes()
{
if (_lutSingletonCreation != null) return _lutSingletonCreation;
var baseType = typeof(SingletonAutoLoadAttribute);
var thisAssemblyName = baseType.Assembly.GetName().ToString();
return _lutSingletonCreation = AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly
=> assembly.GetReferencedAssemblies().Any(r => r.ToString() == thisAssemblyName)
&& assembly.GetName().ToString() != thisAssemblyName)
.SelectMany(assembly
=> assembly.GetCustomAttributes(false).OfType<SingletonAutoLoadAttribute>())
.Select(att => (att.type, att.createCondition))
.ToDictionary(d => d.type, d => d.createCondition);
}
[InitializeOnLoadMethod]
#if !UNITY_EDITOR
[RuntimeInitializeOnLoadMethod]
#endif
static void AutoCreateOnDomainReload()
{
foreach (var (t, con) in GetSingletonTypes())
{
if (con.Contains(SingletonCreateCondition.ReloadDomain))
{
t.BaseType.GetProperty("Instance", bindingFlags).GetValue(null);
}
}
}
[InitializeOnLoadMethod]
static void AutoCreateOnEnterPlayMode()
{
EditorApplication.playModeStateChanged += e =>
{
if (e == PlayModeStateChange.EnteredPlayMode)
{
foreach (var (t, con) in GetSingletonTypes())
{
if (con.Contains(SingletonCreateCondition.EnterPlay))
{
t.BaseType.GetProperty("Instance", bindingFlags).GetValue(null);
}
}
}
};
}
[InitializeOnLoadMethod]
static void CleanOnRecompileIfNeeded()
{
RemoveAllSingletons(inst => inst.shouldDestroyOnReloadDomain());
}
[InitializeOnLoadMethod]
static void CleanOnPlayModeChangeIfNeeded()
{
EditorApplication.playModeStateChanged += e =>
{
if (e == PlayModeStateChange.ExitingPlayMode)
{
RemoveAllSingletons(inst => inst.shouldDestroyOnExitPlayMode());
}
else if (e == PlayModeStateChange.ExitingEditMode)
{
RemoveAllSingletons(inst => inst.shouldDestroyOnExitEditMode());
}
else if (e == PlayModeStateChange.EnteredPlayMode)
{
var instances = Resources
.FindObjectsOfTypeAll<SingletonBase>()
.ToArray();
foreach (var inst in instances)
{
inst.DestroyOnSceneUnload = inst.DestroyOnSceneUnload;
}
}
};
}
static bool shouldDestroyOnReloadDomain(this SingletonBase singleton)
{
var t = singleton.GetType();
var isAutoCreate = GetSingletonTypes().ContainsKey(t)
&& GetSingletonTypes()[t].Contains(SingletonCreateCondition.ReloadDomain);
return singleton.DestroyCondition.Contains(SingletonDestroyCondition.ReloadDomain)
&& !isAutoCreate;
}
static bool shouldDestroyOnExitPlayMode(this SingletonBase singleton)
=> singleton.DestroyCondition.Contains(SingletonDestroyCondition.ExitPlay);
static bool shouldDestroyOnExitEditMode(this SingletonBase singleton)
=> singleton.DestroyCondition.Contains(SingletonDestroyCondition.ExitEdit);
static BindingFlags bindingFlags = 0
| BindingFlags.Static
// | BindingFlags.Instance
| BindingFlags.Public
// | BindingFlags.NonPublic
;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 50a964d0c08146eb886818b2a76c1adc
timeCreated: 1706066898

@ -0,0 +1,103 @@
using System;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace LanLib.Singleton.EditorUtilities
{
public class SingletonWindow : EditorWindow
{
const int SourceUpdateInterval = 100;
const string UIRootGuid = "f019694f4240ea24281a93f5aab2f756";
const string UIElementGuid = "a33c335b67caf3e41af9c2753dcbb734";
[MenuItem("Tools/LanLib/Singletons")]
private static void ShowWindow()
{
var window = GetWindow<SingletonWindow>();
window.titleContent = new GUIContent("Singletons");
window.Show();
}
private void CreateGUI()
{
var uiRootAsset = GetVisualTreeAssetByGUID(UIRootGuid);
var uiElementAsset = GetVisualTreeAssetByGUID(UIElementGuid);
uiRootAsset.CloneTree(rootVisualElement);
var lst = rootVisualElement.Q<ListView>("lst");
(lst.makeItem, lst.bindItem) = BindItem();
rootVisualElement.schedule.Execute(UpdateSource).Every(SourceUpdateInterval);
(Func<VisualElement>, Action<VisualElement, int>) BindItem()
{
// GameObject gameObject = null;
// Label txtName = null;
// VisualElement btnInspect = null;
// VisualElement btnDestroy = null;
// MaskField mask = null;
return (OnCreate, OnBind);
VisualElement OnCreate()
{
var ele = uiElementAsset.CloneTree();
var txtName = ele.Q<Label>("txtName");
var btnInspect = ele.Q("btnInspect");
var btnDestroy = ele.Q("btnDestroy");
var mask = ele.Q<MaskField>("mask");
mask.choices = Enum.GetNames(typeof(HideFlags))[1..^2].ToList();
mask.RegisterValueChangedCallback(e =>
{
var go = GetGameObject();
if (go) go.hideFlags = (HideFlags)e.newValue;
});
btnDestroy.RegisterCallback<ClickEvent>(_ =>
{
var go = GetGameObject();
if (go) DestroyImmediate(go);
});
btnInspect.RegisterCallback<ClickEvent>(_ =>
{
var go = GetGameObject();
if (go) Selection.activeGameObject = go;
// EditorUtility.OpenPropertyEditor(go);
});
txtName.RegisterCallback<ClickEvent>(_ =>
{
var go = GetGameObject();
if (go) Selection.activeGameObject = go;
});
return ele;
GameObject GetGameObject() => ele.userData as GameObject;
}
void OnBind(VisualElement ele, int idx)
{
var txtName = ele.Q<Label>("txtName");
var mask = ele.Q<MaskField>("mask");
var gameObject = lst.itemsSource[idx] as GameObject;
if (gameObject != null)
{
txtName.text = gameObject.name;
mask.value = (int)gameObject.hideFlags;
ele.userData = gameObject;
}
}
}
void UpdateSource()
{
lst.itemsSource = Resources.FindObjectsOfTypeAll<SingletonBase>()
.Select(comp => comp.gameObject)
.Distinct()
.Where(o => o)
.ToList();
lst.RefreshItems();
}
}
VisualTreeAsset GetVisualTreeAssetByGUID(string guid) =>
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(AssetDatabase.GUIDToAssetPath(guid));
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 411e8356e9274f64be05f7abd6793757
timeCreated: 1706066737

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 608454733aec4ec78386a7fe09ed34f0
timeCreated: 1706066616

@ -0,0 +1,10 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<Style src="project://database/Assets/Scripts/Editor/Singleton/UI/SingletonStyles.uss?fileID=7433441132597879392&amp;guid=4a537003ea359734db374f2ebda85a34&amp;type=3#SingletonStyles" />
<ui:VisualElement style="flex-direction: row; align-items: center; padding-left: 9px; padding-right: 9px; padding-top: 9px; padding-bottom: 9px;">
<ui:VisualElement name="icon" style="background-image: url(&apos;project://database/Assets/Editor%20Resources/icon_cube.png?fileID=2800000&amp;guid=fcda1fbb0f0fbc34fbdeb59390ceab77&amp;type=3#icon_cube&apos;); width: 12px; height: 12px; margin-right: 5px; margin-left: -2px; flex-grow: 0; flex-shrink: 0;" />
<ui:Label text="Label" display-tooltip-when-elided="true" name="txtName" style="flex-grow: 1; -unity-text-align: middle-left;" />
<uie:MaskField choices="1,3" name="mask" style="flex-shrink: 1; max-width: 120px;" />
<ui:VisualElement name="btnInspect" class="btn" style="background-image: url(&apos;project://database/Assets/Editor%20Resources/icon_pencil.png?fileID=2800000&amp;guid=3782841ccd5a3c74daa021cca43aeb5e&amp;type=3#icon_pencil&apos;); width: 12px; height: 12px; margin-left: 6px; margin-right: 6px;" />
<ui:VisualElement name="btnDestroy" class="btn" style="background-image: url(&apos;project://database/Assets/Editor%20Resources/icon_delete.png?fileID=2800000&amp;guid=d18e152926310e94abcfa098f562ce48&amp;type=3#icon_delete&apos;); width: 12px; height: 12px; flex-shrink: 0;" />
</ui:VisualElement>
</ui:UXML>

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a33c335b67caf3e41af9c2753dcbb734
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

@ -0,0 +1,3 @@
.btn:hover {
-unity-background-image-tint-color: rgba(161, 161, 161, 255);
}

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4a537003ea359734db374f2ebda85a34
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

@ -0,0 +1,3 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:ListView focusable="true" name="lst" fixed-item-height="25" show-alternating-row-backgrounds="All" style="margin-top: 6px; margin-left: 6px; margin-right: 6px; margin-bottom: 6px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-top-left-radius: 4px; border-bottom-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0);" />
</ui:UXML>

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f019694f4240ea24281a93f5aab2f756
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: caea7eb944356814b93c361630d839c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1093c92c33164f6883cb8b15214c5773
timeCreated: 1706062137

@ -0,0 +1,17 @@
using System;
namespace LanLib.EventManager
{
internal static class ErrorMessages
{
internal static string NullListenerSubscribed(Type eventId)
{
return $"Subscription attempt to {eventId} event had null listener.";
}
internal static string EventListenerTriggerException(Type eventId, Exception exception)
{
return $"Exception caught when triggering {eventId} event listener: {exception.Message}";
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d4199481b582435e8c2b90b33761a525
timeCreated: 1706062159

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using LanLib.Singleton;
using UnityEngine;
namespace LanLib.EventManager
{
public sealed class EventManager : Singleton<EventManager>, IEventManager
{
private readonly Dictionary<Type, Delegate> _eventDictionary = new();
public void Subscribe<T>(Action<T> listener) where T : struct
{
var eventId = typeof(T);
if (listener is null)
{
#if UNITY_EDITOR || DEVELOPMENT_BUILD
Debug.LogError(ErrorMessages.NullListenerSubscribed(eventId));
return;
#endif
}
if (_eventDictionary.ContainsKey(eventId))
{
_eventDictionary[eventId] = Delegate.Combine(_eventDictionary[eventId], listener);
return;
}
_eventDictionary[eventId] = listener;
}
public void Unsubscribe<T>(Action<T> listener) where T : struct
{
var eventId = typeof(T);
if (!_eventDictionary.ContainsKey(eventId)) return;
_eventDictionary[eventId] = Delegate.Remove(_eventDictionary[eventId], listener);
if (_eventDictionary[eventId] is null) _eventDictionary.Remove(eventId);
}
public void TriggerEvent<T>(T eventInstance) where T : struct
{
var eventId = typeof(T);
if (!_eventDictionary.ContainsKey(eventId)) return;
foreach (var listener in _eventDictionary[eventId].GetInvocationList())
{
try
{
((Action<T>)listener)?.Invoke(eventInstance);
}
catch (Exception exception)
{
#if UNITY_EDITOR || DEVELOPMENT_BUILD
Debug.LogError(ErrorMessages.EventListenerTriggerException(eventId, exception));
#endif
}
}
}
public void ClearEvent<T>() where T : struct
{
var eventId = typeof(T);
_eventDictionary.Remove(eventId);
}
public void ClearAllEvents() => _eventDictionary.Clear();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1f99278400344e10be8a7dfc1263018f
timeCreated: 1706062159

@ -0,0 +1,11 @@
namespace LanLib.EventManager
{
public interface IClearableEventManager
{
/// <summary>
/// Clears listeners from specified event.
/// </summary>
/// <typeparam name="T">The type of event to remove listeners from. Must be a struct.</typeparam>
public void ClearEvent<T>() where T : struct;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e1198f7959974c1c80fc5a10074f3817
timeCreated: 1706062160

@ -0,0 +1,11 @@
namespace LanLib.EventManager
{
/// <summary>
/// Event manager for centralized events.
/// Each event is identified by a struct type, which is also used as the event parameter for subscribed listeners.
/// </summary>
public interface IEventManager : ISubscribableEventManager, ITriggerableEventManager, IClearableEventManager,
IResettableEventManager
{
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4d489fbbb7b1474da5c23812ee290bef
timeCreated: 1706062160

@ -0,0 +1,10 @@
namespace LanLib.EventManager
{
public interface IResettableEventManager
{
/// <summary>
/// Removes all listeners from all events.
/// </summary>
public void ClearAllEvents();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 48578b7f513b424c8414c13414a35c79
timeCreated: 1706062160

@ -0,0 +1,21 @@
using System;
namespace LanLib.EventManager
{
public interface ISubscribableEventManager
{
/// <summary>
/// Subscribes a listener to an event, identified and parameterized by the struct type T.
/// </summary>
/// <param name="listener">The action to be invoked when the event is triggered.</param>
/// <typeparam name="T">The struct type that both identifies the event and serves as the parameter for the listener.</typeparam>
public void Subscribe<T>(Action<T> listener) where T : struct;
/// <summary>
/// Unsubscribes a listener from an event, identified and parameterized by the struct type T.
/// </summary>
/// <param name="listener">The action to be removed from the event's invocation list.</param>
/// <typeparam name="T">The struct type that both identifies the event and serves as the parameter for the listener.</typeparam>
public void Unsubscribe<T>(Action<T> listener) where T : struct;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4de0ac3a6f8242679fd6b76ed91cd6c2
timeCreated: 1706062160

@ -0,0 +1,12 @@
namespace LanLib.EventManager
{
public interface ITriggerableEventManager
{
/// <summary>
/// Triggers an event, identified and parameterized by the struct type T.
/// </summary>
/// <param name="eventInstance">An instance of type T that will be passed as the parameter to all subscribed listeners.</param>
/// <typeparam name="T">The struct type that both identifies the event and serves as the parameter for the listener.</typeparam>
public void TriggerEvent<T>(T eventInstance) where T : struct;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fc4941fa01454b9aad016480bf32f182
timeCreated: 1706062160

@ -0,0 +1,16 @@
{
"name": "LanLib.EventManager",
"rootNamespace": "",
"references": [
"LanLib.Singleton"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 034f4e01d3df4c01b020153c76a49314
timeCreated: 1706067128

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bd33e700f4f3460d9e122aa887e83267
timeCreated: 1706065629

@ -0,0 +1,14 @@
{
"name": "LanLib.Singleton",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a8ab48a6d12c4af8aff5f118e4d7dfd2
timeCreated: 1706068734

@ -0,0 +1,83 @@
![UnitySingleton](https://socialify.git.ci/labbbirder/UnitySingleton/image?description=1&font=Jost&forks=1&issues=1&name=1&stargazers=1&theme=Auto)
可以在Editor和Runtime混用的Unity单例模块。稳定可靠懒加载无额外开销任何情况都不会出现多实例化。
![GitHub last commit](https://img.shields.io/github/last-commit/labbbirder/unitysingleton)
![GitHub package.json version](https://img.shields.io/github/package-json/v/labbbirder/unitysingleton)
[![openupm](https://img.shields.io/npm/v/com.bbbirder.singleton?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.bbbirder.singleton/)
## Features
* 兼容所有场景,稳定可靠的提供一个单例:
* Editor和Runtime混合使用
* 中途重新编译脚本
* 不同的`Reload Domain`选项
* 场景切换
* etc
* 可以包含子物体基于MonoBehaviour可添加子GameObject
* 独立于场景单例默认使用HideFlags隐藏不属于任何场景不需要考虑入口场景
* 可检索可视化窗口检索单例列表Window/bbbirder/Singletons
## Basic Usage
只需要继承`Singleton<T>`
```csharp
using UnityEngine;
using com.bbbirder.unity;
public class YourComponent:Singleton<YourComponent>{
protected override void Awake(){
SayHello();
}
public void SayHello(){
print("hello,world");
}
}
```
需要调用的地方
```csharp
YourComponent.Instance.SayHello();
```
通过Window/bbbirder/Singletons窗口查看当前的单例
![窗口截图](Documentation/img_record.png)
## More Controls
### 指定实例化时机
```csharp
[assembly: SingletonAutoLoad(typeof(Manager))]
public class Manager:Singleton<Manager>{ //Manager 将会自动实例化
}
```
SingletonAutoLoadAttribute接收2个参数
* 目标单例类型
* 实例化时机 enum `SingletonCreateCondition`
* `LazyLoad` 懒加载通过Instance获取时才实例化。无`SingletonAutoLoad`属性时默认模式
* `DomainReload` 即时加载,在脚本开始运行前实例化。`SingletonAutoLoad`缺省选项
* `EnterPlay` 进入播放模式加载
> 使用形如`[assembly:]`的特性使得`SingletonAutoLoadAttribute`在内部检索所有单例类型时消耗小且非常迅速。可以放心的在Runtime环境下使用此模块。
### 指定销毁时机
```csharp
public class Manager:Singleton<Manager>{
public override SingletonDestroyCondition DestroyCondition => SingletonDestroyCondition.ExitEdit;
}
```
`SingletonDestroyCondition` 具有以下选项:
* Never 不自动销毁
* SceneUnload 场景卸载时
* ReloadDomain 脚本重加载时 (默认)
* ExitPlay 切出播放模式时
* ExitEdit 切出编辑模式时
### 自定义实例化方法
```csharp
public class TestSingleton : Singleton<TestSingleton>
{
protected new static TestSingleton CreateInstance(){
var go = Singleton<TestSingleton>.CreateInstance();
go.name += " (Singleton)";
return go;
}
}
```

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8440ba700d8a4b94f9a1a5e4c72b4bc0
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,118 @@
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
namespace LanLib.Singleton
{
[ExecuteInEditMode]
public class Singleton<T> : SingletonBase where T : Singleton<T>
{
private const BindingFlags BindingFlags = System.Reflection.BindingFlags.Default
| System.Reflection.BindingFlags.FlattenHierarchy
| System.Reflection.BindingFlags.Static
| System.Reflection.BindingFlags.Public
| System.Reflection.BindingFlags.NonPublic;
private static T _instance;
public static T Instance
{
get
{
if (!_instance)
{
#if UNITY_EDITOR
_instance = Resources.FindObjectsOfTypeAll<T>().FirstOrDefault(inst => inst);
#else
_instance = FindObjectOfType<T>();
#endif
}
if (!_instance)
{
_instance = (T)typeof(T).GetMethod("CreateInstance", BindingFlags)?.Invoke(null, null);
}
Assert.IsNotNull(_instance);
return _instance;
}
}
protected static T CreateInstance()
{
return new GameObject(typeof(T).Name)
{
hideFlags = HideFlags.HideAndDontSave ^ HideFlags.NotEditable
}.AddComponent<T>();
}
protected virtual void Awake()
{
if (_instance == null)
{
_instance = this as T;
if (Application.isPlaying)
{
DestroyOnSceneUnload = DestroyOnSceneUnload;
}
}
else
{
DestroySelf();
}
}
}
public abstract class SingletonBase : MonoBehaviour
{
private SingletonDestroyCondition _destroyCondition = SingletonDestroyCondition.ReloadDomain;
public virtual SingletonDestroyCondition DestroyCondition
{
get => _destroyCondition;
private set
{
var flgSceneUnload = (value ^ _destroyCondition) & SingletonDestroyCondition.SceneUnload;
if (flgSceneUnload != 0)
{
var hasFlag = 0 != (value & SingletonDestroyCondition.SceneUnload);
DestroyOnSceneUnload = hasFlag;
}
_destroyCondition = value;
}
}
public bool DestroyOnSceneUnload
{
get => DestroyCondition.Contains(SingletonDestroyCondition.SceneUnload);
set
{
if (value)
{
SceneManager.MoveGameObjectToScene(gameObject, SceneManager.GetActiveScene());
DestroyCondition |= SingletonDestroyCondition.SceneUnload;
}
else
{
DontDestroyOnLoad(gameObject);
DestroyCondition &= ~SingletonDestroyCondition.SceneUnload;
}
}
}
internal void DestroySelf()
{
if (Application.isPlaying)
{
Destroy(gameObject);
}
else
{
DestroyImmediate(gameObject);
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 52f4996b32e94a5eab7788ce97a3687c
timeCreated: 1706065918

@ -0,0 +1,18 @@
using System;
namespace LanLib.Singleton
{
public class SingletonAutoLoadAttribute : Attribute
{
public Type type { get; private set; }
public SingletonCreateCondition createCondition { get; private set; }
public SingletonAutoLoadAttribute(Type type,
SingletonCreateCondition createCondition = SingletonCreateCondition.ReloadDomain)
{
this.type = type;
this.createCondition = createCondition;
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 034696d0d99d450eb4a5257f857e721b
timeCreated: 1706065818

@ -0,0 +1,61 @@
using System;
namespace LanLib.Singleton
{
[Flags]
public enum SingletonDestroyCondition
{
/// <summary>
/// Dont destroy automatically.
/// </summary>
Never = 0,
/// <summary>
/// Destroy on scene unload.
/// </summary>
SceneUnload = 1 << 0,
/// <summary>
/// Destroy on script recompilation. [Default]
/// </summary>
ReloadDomain = 1 << 1,
/// <summary>
/// Destroy on application mode switch from play mode to editor mode.
/// </summary>
ExitPlay = 1 << 2,
/// <summary>
/// Destroy on application mode switch from editor mode to play mode.
/// </summary>
ExitEdit = 1 << 3,
}
[Flags]
public enum SingletonCreateCondition
{
/// <summary>
/// Dont instantiate automatically.
/// </summary>
LazyLoad = 0,
/// <summary>
/// Instantiate on domain reloads. More exactly, editor mode means script compiled mostly, while runtime mode means application launched.
/// </summary>
ReloadDomain = 1 << 0,
/// <summary>
/// Instantiate on enter play mode. Editor only.
/// </summary>
EnterPlay = 1 << 1,
}
public static class Extensions
{
public static bool Contains(this SingletonCreateCondition con, SingletonCreateCondition con2)
=> (con & con2) != 0;
public static bool Contains(this SingletonDestroyCondition con, SingletonDestroyCondition con2)
=> (con & con2) != 0;
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9262d72ff33f4de69ff9759d90943993
timeCreated: 1706065653

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fdf3047f31a54b4188042ffeffeaacdd
timeCreated: 1706078971

@ -0,0 +1,26 @@
using UnityEngine;
namespace LanLib.UpdateManager
{
/// <summary>
/// <see cref="MonoBehaviour"/> abstract class with automatic registration in <see cref="UpdateManager"/>.
/// </summary>
/// <remarks>
/// Instances will register themselves for updates in the <c>OnEnable</c> message and unregister in the <c>OnDisable</c> message.
/// <br/>
/// Implement <see cref="IUpdatable"/>, <see cref="ILateUpdatable"/> and/or <see cref="IFixedUpdatable"/> to be updated every frame using <see cref="UpdateManager"/>.
/// </remarks>
/// <seealso cref="UpdateManager"/>
public abstract class AManagedBehaviour : MonoBehaviour, IManagedObject
{
protected virtual void OnEnable()
{
this.RegisterInManager();
}
protected virtual void OnDisable()
{
this.UnregisterInManager();
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e413337e91b74ff68ed1d2ee9e242fb0
timeCreated: 1706080505

@ -0,0 +1,32 @@
using System;
using UnityEngine;
namespace LanLib.UpdateManager
{
/// <summary>
/// <see cref="MonoBehaviour"/> abstract class with automatic registration in <see cref="UpdateManager"/>.
/// </summary>
/// <remarks>
/// Instances will register themselves for updates in the <c>OnEnable</c> message and unregister in the <c>OnDisable</c> message.
/// </remarks>
/// <seealso cref="UpdateManager"/>
[Obsolete("Prefer inheriting AManagedBehaviour and implementing the IUpdatable/ILateUpdatable/IFixedUpdatable interfaces directly.")]
public abstract class AUpdateManagerBehaviour : MonoBehaviour, IUpdatable
{
protected virtual void OnEnable()
{
this.RegisterInManager();
}
protected virtual void OnDisable()
{
this.UnregisterInManager();
}
/// <summary>
/// Implement this for receiving managed updates from <see cref="UpdateManager"/>.
/// </summary>
/// <seealso cref="UpdateManager"/>
public abstract void ManagedUpdate();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 95570aaab68a4177886e5bfc41c0782f
timeCreated: 1706080471

@ -0,0 +1,22 @@
using UnityEngine;
namespace LanLib.UpdateManager
{
public static class ApplicationUtils
{
public static bool IsQuitting { get; private set; }
[RuntimeInitializeOnLoadMethod]
private static void InitializeMethod()
{
IsQuitting = false;
Application.quitting += OnQuitting;
}
private static void OnQuitting()
{
IsQuitting = true;
Application.quitting -= OnQuitting;
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1c6cf116c88644e4afa011ee3aafb33e
timeCreated: 1706080365

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91deabe1a4894271968127c10b2104c5
timeCreated: 1706078999

@ -0,0 +1,29 @@
using System.Collections.Generic;
namespace LanLib.UpdateManager.Extensions
{
public static class ListExtensions
{
public static void RemoveAtSwapBack<T>(this IList<T> list, int index, out T swappedValue)
{
int lastIndex = list.Count - 1;
if (lastIndex > 0 && lastIndex != index)
{
swappedValue = list[index] = list[lastIndex];
}
else
{
swappedValue = default;
}
list.RemoveAt(lastIndex);
}
public static void Swap<T>(this IList<T> list, int sourceIndex, int destinationIndex, out T newDestinationValue)
{
newDestinationValue = list[sourceIndex];
list[sourceIndex] = list[destinationIndex];
list[destinationIndex] = newDestinationValue;
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4251927f6d7b45d8862b48af6aa71178
timeCreated: 1706079245

@ -0,0 +1,16 @@
using Unity.Collections;
namespace LanLib.UpdateManager.Extensions
{
public static class NativeArrayExtensions
{
public static void DisposeIfCreated<T>(this ref NativeArray<T> array)
where T : struct
{
if (array.IsCreated)
{
array.Dispose();
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ca5285a99e744603bb10d0ca73ed66c2
timeCreated: 1706079384

@ -0,0 +1,15 @@
using UnityEngine.Jobs;
namespace LanLib.UpdateManager.Extensions
{
public static class TransformAccessArrayExtensions
{
public static void DisposeIfCreated(this ref TransformAccessArray transformArray)
{
if (transformArray.isCreated)
{
transformArray.Dispose();
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 53aeeccdbec94a348f3d37537cdb3511
timeCreated: 1706079409

@ -0,0 +1,24 @@
using System;
using System.Linq;
using LanLib.UpdateManager.Jobs;
namespace LanLib.UpdateManager.Extensions
{
public static class TypeExtensions
{
public static bool IsIUpdateJob(this Type type)
{
return typeof(IUpdateJob).IsAssignableFrom(type);
}
public static bool IsIUpdateTransformJob(this Type type)
{
return typeof(IUpdateTransformJob).IsAssignableFrom(type);
}
public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
{
return type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType);
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ba29ddc492d0419db60e7430a2f0233c
timeCreated: 1706079431

@ -0,0 +1,14 @@
namespace LanLib.UpdateManager
{
/// <summary>
/// Implement this interface and register object with <see cref="UpdateManager.Register"/> to get updated every physics frame on FixedUpdate message.
/// </summary>
public interface IFixedUpdatable : IManagedObject
{
/// <summary>
/// Method called every physics frame for objects registered in <see cref="UpdateManager"/>.
/// </summary>
/// <seealso cref="UpdateManager"/>
void ManagedFixedUpdate();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c101c50f8f5743b1b045ebb45789b70a
timeCreated: 1706080342

@ -0,0 +1,14 @@
namespace LanLib.UpdateManager
{
/// <summary>
/// Implement this interface and register object with <see cref="UpdateManager.Register"/> to get updated every frame on LateUpdate message.
/// </summary>
public interface ILateUpdatable : IManagedObject
{
/// <summary>
/// Method called every frame for objects registered in <see cref="UpdateManager"/>.
/// </summary>
/// <seealso cref="UpdateManager"/>
void ManagedLateUpdate();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8a310861232547b29673bda29663d4b7
timeCreated: 1706080323

@ -0,0 +1,28 @@
namespace LanLib.UpdateManager
{
/// <summary>Base interface for objects that <see cref="UpdateManager"/> can manage</summary>
public interface IManagedObject
{
}
public static class IUpdatableExtensions
{
/// <summary>
/// Shortcut for <c>UpdateManager.Instance.Register(<paramref name="updatable"/>)</c>.
/// </summary>
/// <seealso cref="UpdateManager.Register"/>
public static void RegisterInManager(this IManagedObject updatable)
{
UpdateManager.Instance.Register(updatable);
}
/// <summary>
/// Shortcut for <c>UpdateManager.Instance.Unregister(<paramref name="updatable"/>)</c>.
/// </summary>
/// <seealso cref="UpdateManager.Unregister"/>
public static void UnregisterInManager(this IManagedObject updatable)
{
UpdateManager.Instance.Unregister(updatable);
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f1ee1d3f5c67405994ecc7a66e8a6185
timeCreated: 1706080262

@ -0,0 +1,14 @@
namespace LanLib.UpdateManager
{
/// <summary>
/// Implement this interface and register object with <see cref="UpdateManager.Register"/> to get updated every frame on Update message.
/// </summary>
public interface IUpdatable : IManagedObject
{
/// <summary>
/// Method called every frame for objects registered in <see cref="UpdateManager"/>.
/// </summary>
/// <seealso cref="UpdateManager"/>
void ManagedUpdate();
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: eb10f2430e094d679949c4f2e0867941
timeCreated: 1706080294

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7de1457ab1e549a1a654b33f1be161e7
timeCreated: 1706078999

@ -0,0 +1,144 @@
using System.Collections;
using System.Collections.Generic;
using LanLib.UpdateManager.Extensions;
namespace LanLib.UpdateManager.Internal
{
/// <summary>Generic list with O(1) insertion and removal.</summary>
/// <remarks>
/// <list type="bullet">
/// <item>Adding duplicate values and removing items that are not present are both no-op.</item>
/// <item>
/// Items may be added and removed while the collection is being enumerated without raising exceptions.
/// This collection guarantees that all items are enumerated, even if insertions or removals happen during enumeration.
/// </item>
/// <item>
/// All enumerators reference the same list index, so avoid having more than one enumerator at the same time.
/// Creating a new enumerator resets this shared index.
/// </item>
/// </list>
/// </remarks>
public class FastRemoveList<T> : IReadOnlyList<T>
{
private readonly List<T> _list = new List<T>();
private readonly Dictionary<T, int> _indexMap = new Dictionary<T, int>();
private int _loopIndex;
/// <returns>Get the number of items contained in the <see cref="FastRemoveList{T}"/>.</returns>
public int Count => _list.Count;
/// <returns>Item registered at <paramref name="index"/> if index is valid, <see langword="default"/> otherwise.</returns>
public T this[int index] => index >= 0 && index < Count ? _list[index] : default;
/// <summary>Add <paramref name="value"/> to the end of the list.</summary>
/// <returns><see langword="true"/> if value was not already present in the list and was successfully added, <see langword="false"/> otherwise.</returns>
/// <remarks>
/// Adding a value while the collection is being enumerated is permitted and won't raise exceptions.
/// This operation is O(1).
/// </remarks>
public bool Add(T value)
{
if (_indexMap.ContainsKey(value))
{
return false;
}
_list.Add(value);
_indexMap.Add(value, _list.Count - 1);
return true;
}
/// <summary>Remove <paramref name="value"/> from the list, if found.</summary>
/// <returns><see langword="true"/> if value was present in the list and was successfully removed, <see langword="false"/> otherwise.</returns>
/// <remarks>
/// Removing a value while the collection is being enumerated is permitted and won't raise exceptions.
/// This operation is O(1).
/// </remarks>
public bool Remove(T value)
{
if (!_indexMap.TryGetValue(value, out int indexToRemove))
{
return false;
}
_indexMap.Remove(value);
// If removing the object that was just enumerated, make sure the
// new object swapped back to this index gets enumerated as well
if (indexToRemove == _loopIndex)
{
_loopIndex--;
}
// If removing an object that was already enumerated while the loop is
// still running, swap it with current loop index to make sure we
// still enumerate the last element that will be swapped back later
else if (indexToRemove < _loopIndex)
{
_list.Swap(_loopIndex, indexToRemove, out T swappedValue);
_indexMap[swappedValue] = indexToRemove;
indexToRemove = _loopIndex;
_loopIndex--;
}
_list.RemoveAtSwapBack(indexToRemove, out T swappedBack);
if (swappedBack != null)
{
_indexMap[swappedBack] = indexToRemove;
}
return true;
}
/// <summary>Removes all values from the <see cref="FastRemoveList{T}"/>.</summary>
public void Clear()
{
_list.Clear();
_indexMap.Clear();
}
/// <summary>Returns an enumerator that iterates through the <see cref="FastRemoveList{T}"/>.</summary>
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public struct Enumerator : IEnumerator<T>
{
private FastRemoveList<T> _list;
public Enumerator(FastRemoveList<T> list)
{
_list = list;
Reset();
}
public T Current => _list[_list._loopIndex];
object IEnumerator.Current => Current;
public void Dispose()
{
}
public bool MoveNext()
{
if (_list._loopIndex < _list.Count - 1)
{
_list._loopIndex++;
return true;
}
else
{
return false;
}
}
public void Reset()
{
_list._loopIndex = -1;
}
}
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 00b3295692f0444a98bf1a902e55eb4f
timeCreated: 1706079158

@ -0,0 +1,35 @@
#if (UNITY_EDITOR || DEVELOPMENT_BUILD) && !UPDATE_MANAGER_DISABLE_PROFILER_MARKERS
#define ENABLE_PROFILER_MARKERS
#endif
using System;
using System.Collections.Generic;
using Unity.Profiling;
namespace LanLib.UpdateManager.Internal
{
public static class ProfilerMarkerMap
{
#if ENABLE_PROFILER_MARKERS
public static ProfilerMarker.AutoScope Get(string method, object obj)
{
Type type = obj.GetType();
var key = (type, method);
if (!_profileMarkerCache.TryGetValue(key, out ProfilerMarker profilerMarker))
{
profilerMarker = new ProfilerMarker(type.Name + "." + method + "()");
_profileMarkerCache[key] = profilerMarker;
}
return profilerMarker.Auto();
}
private readonly static Dictionary<(Type, string), ProfilerMarker> _profileMarkerCache =
new Dictionary<(Type, string), ProfilerMarker>();
#else
public static IDisposable Get(string method, object obj)
{
return null;
}
#endif
}
}

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: feacb42d3ddf4f2dace914103a1582e8
timeCreated: 1706079348

@ -0,0 +1,81 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace LanLib.UpdateManager.Internal
{
public class SortedList<T> : IComparer<T>, IEnumerable<T> where T : IComparable<T>
{
private readonly List<T> _list = new List<T>();
public int Count => _list.Count;
public bool Add(T value)
{
int index = _list.BinarySearch(value, this);
if (index < 0)
{
_list.Insert(~index, value);
return true;
}
else
{
return false;
}
}
public bool Remove(T value)
{
int index = _list.BinarySearch(value, this);
if (index >= 0)
{
_list.RemoveAt(index);
return true;
}
else
{
return false;
}
}
public bool Contains(T value)
{
int index = _list.BinarySearch(value, this);
return index >= 0;
}
public void Clear()
{
_list.Clear();
}
public List<T>.Enumerator GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public virtual int Compare(T x, T y)
{
return x.CompareTo(y);
}
}
public class ReversedSortedList<T> : SortedList<T>
where T : IComparable<T>
{
public override int Compare(T x, T y)
{
return -x.CompareTo(y);
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save