diff --git a/Assets/Scenes/ui animation Sample Scene.unity b/Assets/Scenes/ui animation Sample Scene.unity
new file mode 100644
index 0000000..45734bf
--- /dev/null
+++ b/Assets/Scenes/ui animation Sample Scene.unity	
@@ -0,0 +1,1712 @@
+%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: 8
+  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: 0}
+  m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 1
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 9
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_TextureWidth: 1024
+    m_TextureHeight: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 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: 0
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVRFiltering: 0
+    m_PVRFilteringMode: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousColorSigma: 1
+    m_PVRFilteringAtrousNormalSigma: 1
+    m_PVRFilteringAtrousPositionSigma: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    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
+    accuratePlacement: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &60103456
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 60103457}
+  - component: {fileID: 60103461}
+  - component: {fileID: 60103460}
+  - component: {fileID: 60103458}
+  m_Layer: 5
+  m_Name: Helicopter grow effect
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &60103457
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 60103456}
+  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_Children: []
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 1
+  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: 0, y: 0}
+  m_SizeDelta: {x: 600, y: 250}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &60103458
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 60103456}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 494ccccf65c01594b87c46d7e6a1f966, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_desiredScale: 1
+  m_timeToReachDesiredScale: 2
+  m_rotationSpeed: 5
+  m_rotationAngle: 35
+--- !u!114 &60103460
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 60103456}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 100
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 100
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Helicopter Grow Effect
+--- !u!222 &60103461
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 60103456}
+--- !u!1 &65850444
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 65850448}
+  - component: {fileID: 65850447}
+  - component: {fileID: 65850446}
+  - component: {fileID: 65850445}
+  m_Layer: 5
+  m_Name: Canvas
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &65850445
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 65850444}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_IgnoreReversedGraphics: 1
+  m_BlockingObjects: 0
+  m_BlockingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+--- !u!114 &65850446
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 65850444}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1980459831, guid: f5f67c52d1564df4a8936ccd202a3bd8, 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
+--- !u!223 &65850447
+Canvas:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 65850444}
+  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_AdditionalShaderChannelsFlag: 0
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+  m_TargetDisplay: 0
+--- !u!224 &65850448
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 65850444}
+  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_Children:
+  - {fileID: 1549637274}
+  - {fileID: 60103457}
+  - {fileID: 1326669243}
+  - {fileID: 647913274}
+  - {fileID: 1105015894}
+  - {fileID: 1170391614}
+  - {fileID: 862420478}
+  - {fileID: 1669247682}
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  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 &523868528
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 523868533}
+  - component: {fileID: 523868532}
+  - component: {fileID: 523868531}
+  - component: {fileID: 523868530}
+  - component: {fileID: 523868529}
+  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 &523868529
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 523868528}
+  m_Enabled: 1
+--- !u!124 &523868530
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 523868528}
+  m_Enabled: 1
+--- !u!92 &523868531
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 523868528}
+  m_Enabled: 1
+--- !u!20 &523868532
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 523868528}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 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_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+  m_StereoMirrorMode: 0
+--- !u!4 &523868533
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 523868528}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &588481442
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 588481443}
+  - component: {fileID: 588481445}
+  - component: {fileID: 588481444}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &588481443
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 588481442}
+  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_Children: []
+  m_Father: {fileID: 1669247682}
+  m_RootOrder: 0
+  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 &588481444
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 588481442}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Next
+--- !u!222 &588481445
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 588481442}
+--- !u!1 &647913273
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 647913274}
+  - component: {fileID: 647913277}
+  - component: {fileID: 647913276}
+  - component: {fileID: 647913275}
+  m_Layer: 5
+  m_Name: Lerp From Offset
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &647913274
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 647913273}
+  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_Children: []
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 3
+  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: 0, y: 0}
+  m_SizeDelta: {x: 600, y: 250}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &647913275
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 647913273}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8a8c268e33662234199c5b926b7dfd5b, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_effect: 4
+  m_offsetDirection: {x: 100, y: 100, z: 0}
+  m_offsetDistance: 100
+  m_timeToReachPosition: 1.5
+  m_delayStart: 0
+--- !u!114 &647913276
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 647913273}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 100
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 100
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Lerp From Offset
+--- !u!222 &647913277
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 647913273}
+--- !u!1 &764075908
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 764075909}
+  - component: {fileID: 764075911}
+  - component: {fileID: 764075910}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &764075909
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 764075908}
+  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_Children: []
+  m_Father: {fileID: 1105015894}
+  m_RootOrder: 0
+  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 &764075910
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 764075908}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Next
+--- !u!222 &764075911
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 764075908}
+--- !u!1 &862420474
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 862420478}
+  - component: {fileID: 862420477}
+  - component: {fileID: 862420476}
+  - component: {fileID: 862420475}
+  m_Layer: 5
+  m_Name: ImageFadeToLerp
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!114 &862420475
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 862420474}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    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_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_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 862420476}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1326669242}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 647913273}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+      - m_Target: {fileID: 862420474}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 1669247681}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &862420476
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 862420474}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  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
+--- !u!222 &862420477
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 862420474}
+--- !u!224 &862420478
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 862420474}
+  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_Children:
+  - {fileID: 1392838399}
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 6
+  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: 200, y: -200}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &1105015893
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1105015894}
+  - component: {fileID: 1105015897}
+  - component: {fileID: 1105015896}
+  - component: {fileID: 1105015895}
+  m_Layer: 5
+  m_Name: GrowEffectToHelicopter
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1105015894
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1105015893}
+  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_Children:
+  - {fileID: 764075909}
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 4
+  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: 200, y: -200}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1105015895
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1105015893}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    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_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_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1105015896}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1549637273}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 60103456}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+      - m_Target: {fileID: 1170391613}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+      - m_Target: {fileID: 1105015893}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1105015896
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1105015893}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  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
+--- !u!222 &1105015897
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1105015893}
+--- !u!1 &1170391613
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1170391614}
+  - component: {fileID: 1170391617}
+  - component: {fileID: 1170391616}
+  - component: {fileID: 1170391615}
+  m_Layer: 5
+  m_Name: HelicopterToImageFade
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &1170391614
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170391613}
+  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_Children:
+  - {fileID: 1851853257}
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 5
+  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: 200, y: -200}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1170391615
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170391613}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    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_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_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1170391616}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 60103456}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 1326669242}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+      - m_Target: {fileID: 1170391613}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 862420474}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1170391616
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170391613}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  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
+--- !u!222 &1170391617
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170391613}
+--- !u!1 &1326669242
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1326669243}
+  - component: {fileID: 1326669246}
+  - component: {fileID: 1326669245}
+  - component: {fileID: 1326669244}
+  m_Layer: 5
+  m_Name: Image Fade
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &1326669243
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1326669242}
+  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_Children: []
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 2
+  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: 0, y: 0}
+  m_SizeDelta: {x: 100, y: 100}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1326669244
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1326669242}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 9b6641416af12354c82ba88e2c919780, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_timeToFade: 1.5
+  m_delayTimeToStart: 0
+  m_isFadingIn: 1
+  m_doesHaveChildText: 0
+--- !u!114 &1326669245
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1326669242}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  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
+--- !u!222 &1326669246
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1326669242}
+--- !u!1 &1392838398
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1392838399}
+  - component: {fileID: 1392838401}
+  - component: {fileID: 1392838400}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1392838399
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1392838398}
+  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_Children: []
+  m_Father: {fileID: 862420478}
+  m_RootOrder: 0
+  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 &1392838400
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1392838398}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Next
+--- !u!222 &1392838401
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1392838398}
+--- !u!1 &1453411760
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1453411762}
+  - component: {fileID: 1453411761}
+  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 &1453411761
+Light:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1453411760}
+  m_Enabled: 1
+  serializedVersion: 8
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  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_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_Lightmapping: 4
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_FalloffTable:
+    m_Table[0]: 0
+    m_Table[1]: 0
+    m_Table[2]: 0
+    m_Table[3]: 0
+    m_Table[4]: 0
+    m_Table[5]: 0
+    m_Table[6]: 0
+    m_Table[7]: 0
+    m_Table[8]: 0
+    m_Table[9]: 0
+    m_Table[10]: 0
+    m_Table[11]: 0
+    m_Table[12]: 0
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1453411762
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1453411760}
+  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_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &1549637273
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1549637274}
+  - component: {fileID: 1549637277}
+  - component: {fileID: 1549637276}
+  - component: {fileID: 1549637275}
+  m_Layer: 5
+  m_Name: Grow Effect
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1549637274
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1549637273}
+  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_Children: []
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 0
+  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: 0, y: 0}
+  m_SizeDelta: {x: 600, y: 250}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1549637275
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1549637273}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 130f33757f672504992a0c2e741afbba, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_desiredScale: 1
+  m_timeToReachDesiredScale: 2
+  m_timeToDelayStart: 0
+  m_interpolationEffect: 1
+--- !u!114 &1549637276
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1549637273}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 100
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 100
+    m_Alignment: 0
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Grow Effect
+--- !u!222 &1549637277
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1549637273}
+--- !u!1 &1560749332
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1560749335}
+  - component: {fileID: 1560749334}
+  - component: {fileID: 1560749333}
+  m_Layer: 0
+  m_Name: EventSystem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1560749333
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1560749332}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1077351063, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_HorizontalAxis: Horizontal
+  m_VerticalAxis: Vertical
+  m_SubmitButton: Submit
+  m_CancelButton: Cancel
+  m_InputActionsPerSecond: 10
+  m_RepeatDelay: 0.5
+  m_ForceModuleActive: 0
+--- !u!114 &1560749334
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1560749332}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -619905303, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_FirstSelected: {fileID: 0}
+  m_sendNavigationEvents: 1
+  m_DragThreshold: 5
+--- !u!4 &1560749335
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1560749332}
+  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_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1669247681
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1669247682}
+  - component: {fileID: 1669247685}
+  - component: {fileID: 1669247684}
+  - component: {fileID: 1669247683}
+  m_Layer: 5
+  m_Name: LerpToGrow
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &1669247682
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1669247681}
+  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_Children:
+  - {fileID: 588481443}
+  m_Father: {fileID: 65850448}
+  m_RootOrder: 7
+  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: 200, y: -200}
+  m_SizeDelta: {x: 200, y: 50}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1669247683
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1669247681}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    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_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_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1669247684}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 647913273}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 1549637273}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+      - m_Target: {fileID: 1669247681}
+        m_MethodName: SetActive
+        m_Mode: 6
+        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
+      - m_Target: {fileID: 1105015893}
+        m_MethodName: SetActive
+        m_Mode: 6
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 1
+        m_CallState: 2
+    m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
+      Culture=neutral, PublicKeyToken=null
+--- !u!114 &1669247684
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1669247681}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  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
+--- !u!222 &1669247685
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1669247681}
+--- !u!1 &1851853256
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1851853257}
+  - component: {fileID: 1851853259}
+  - component: {fileID: 1851853258}
+  m_Layer: 5
+  m_Name: Text
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1851853257
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1851853256}
+  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_Children: []
+  m_Father: {fileID: 1170391614}
+  m_RootOrder: 0
+  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 &1851853258
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1851853256}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_RaycastTarget: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+    m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
+      Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+  m_FontData:
+    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
+    m_FontSize: 14
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 10
+    m_MaxSize: 40
+    m_Alignment: 4
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: Next
+--- !u!222 &1851853259
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1851853256}
diff --git a/Assets/Scenes/ui animation Sample Scene.unity.meta b/Assets/Scenes/ui animation Sample Scene.unity.meta
new file mode 100644
index 0000000..4048b51
--- /dev/null
+++ b/Assets/Scenes/ui animation Sample Scene.unity.meta	
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2145e601083d97c4ba64d70455d21a11
+timeCreated: 1594958189
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs
index bf94311..a3ae1c5 100644
--- a/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs
+++ b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs
@@ -1,35 +1,74 @@
 // adds EdgeCollider2D colliders to screen edges
 // only works with orthographic camera
 
+//Includes two different ways of implementation into your project
+//One is a method that uses cached fields on Awake() that requires this entire class but is more slightly more efficient (should use this if you plan to use the method in Update())
+//The other is a standalone method that doesn't need the rest of the class and can be copy-pasted directly into any project but is slightly less efficient
+
 using UnityEngine;
-using System.Collections;
 
 namespace UnityLibrary
 {
-  public class ScreenEdgeColliders : MonoBehaviour 
-  {
-    void Awake () 
+    public class ScreenEdgeColliders : MonoBehaviour
     {
-      AddCollider();
-    }
+        private Camera cam;
+        private EdgeCollider2D edge;
+        private Vector2[] edgePoints;
 
-    void AddCollider () 
-    {
-      if (Camera.main==null) {Debug.LogError("Camera.main not found, failed to create edge colliders"); return;}
+        void Awake()
+        {
+            if (Camera.main == null) Debug.LogError("Camera.main not found, failed to create edge colliders");
+            else cam = Camera.main;
+
+            if (!cam.orthographic) Debug.LogError("Camera.main is not Orthographic, failed to create edge colliders");
+
+            // add or use existing EdgeCollider2D
+            edge = GetComponent<EdgeCollider2D>() == null ? gameObject.AddComponent<EdgeCollider2D>() : GetComponent<EdgeCollider2D>();
+
+            edgePoints = new Vector2[5];
+
+            AddCollider();
+        }
+
+        //Use this if you're okay with using the global fields and code in Awake() (more efficient)
+        //You can just ignore/delete StandaloneAddCollider() if thats the case
+        void AddCollider()
+        {
+            //Vector2's for the corners of the screen
+            Vector2 bottomLeft = cam.ScreenToWorldPoint(new Vector3(0, 0, cam.nearClipPlane));
+            Vector2 topRight = cam.ScreenToWorldPoint(new Vector3(cam.pixelWidth, cam.pixelHeight, cam.nearClipPlane));
+            Vector2 topLeft = new Vector2(bottomLeft.x, topRight.y);
+            Vector2 bottomRight = new Vector2(topRight.x, bottomLeft.y);
+
+            //Update Vector2 array for edge collider
+            edgePoints[0] = bottomLeft;
+            edgePoints[1] = topLeft;
+            edgePoints[2] = topRight;
+            edgePoints[3] = bottomRight;
+            edgePoints[4] = bottomLeft;
+
+            edge.points = edgePoints;
+        }
+
+        //Use this if you want a single function to handle everything (less efficient)
+        //You can just ignore/delete the rest of this class if thats the case
+        void StandaloneAddCollider()
+        {
+            if (Camera.main == null) { Debug.LogError("Camera.main not found, failed to create edge colliders"); return; }
 
-      var cam = Camera.main;
-      if (!cam.orthographic) {Debug.LogError("Camera.main is not Orthographic, failed to create edge colliders"); return;}
+            var cam = Camera.main;
+            if (!cam.orthographic) { Debug.LogError("Camera.main is not Orthographic, failed to create edge colliders"); return; }
 
-      var bottomLeft = (Vector2)cam.ScreenToWorldPoint(new Vector3(0, 0, cam.nearClipPlane));
-      var topLeft = (Vector2)cam.ScreenToWorldPoint(new Vector3(0, cam.pixelHeight, cam.nearClipPlane));
-      var topRight = (Vector2)cam.ScreenToWorldPoint(new Vector3(cam.pixelWidth, cam.pixelHeight, cam.nearClipPlane));
-      var bottomRight = (Vector2)cam.ScreenToWorldPoint(new Vector3(cam.pixelWidth, 0, cam.nearClipPlane));
+            Vector2 bottomLeft = cam.ScreenToWorldPoint(new Vector3(0, 0, cam.nearClipPlane));
+            Vector2 topRight = cam.ScreenToWorldPoint(new Vector3(cam.pixelWidth, cam.pixelHeight, cam.nearClipPlane));
+            Vector2 topLeft = new Vector2(bottomLeft.x, topRight.y);
+            Vector2 bottomRight = new Vector2(topRight.x, bottomLeft.y);
 
-      // add or use existing EdgeCollider2D
-      var edge = GetComponent<EdgeCollider2D>()==null?gameObject.AddComponent<EdgeCollider2D>():GetComponent<EdgeCollider2D>();
+            // add or use existing EdgeCollider2D
+            var edge = GetComponent<EdgeCollider2D>() == null ? gameObject.AddComponent<EdgeCollider2D>() : GetComponent<EdgeCollider2D>();
 
-      var edgePoints = new [] {bottomLeft,topLeft,topRight,bottomRight, bottomLeft};
-      edge.points = edgePoints;
+            var edgePoints = new[] { bottomLeft, topLeft, topRight, bottomRight, bottomLeft };
+            edge.points = edgePoints;
+        }
     }
-  }
 }
diff --git a/Assets/Scripts/2D/Geometry/Triangle2D.cs b/Assets/Scripts/2D/Geometry/Triangle2D.cs
new file mode 100644
index 0000000..6d16785
--- /dev/null
+++ b/Assets/Scripts/2D/Geometry/Triangle2D.cs
@@ -0,0 +1,67 @@
+using UnityEngine;
+
+namespace UnityLibrary
+{
+    // if you need to run collision checks within a triangular area, the easiest
+    // way to do that in Unity is to use a polygon collider.  this is not very
+    // performant.  this class allows you to run those collision checks without
+    // the performance overhead.
+
+    public class Triangle2D
+    {
+        Vector2[] vertices = new Vector2[3];
+
+        public Triangle2D(Vector2 v1, Vector2 v2, Vector2 v3) 
+        {
+            Update(v1, v2, v3);
+        }
+
+        // update triangle by defining all its vertices
+        public void Update(Vector2 v1, Vector2 v2, Vector2 v3) 
+        {
+            vertices[0] = v1;
+            vertices[1] = v2;
+            vertices[2] = v3;
+        }
+
+        // update triangle by redefining its origin (remaining points update relative to that)
+        public void Update(Vector2 v1) 
+        {
+            Vector2 delta = v1 - vertices[0];
+            vertices[0] = v1;
+            vertices[1] += delta;
+            vertices[2] += delta;
+        }
+
+        // update triangle with rotation and pivot point
+        public void Update(Vector2 v1, Vector2 v2, Vector2 v3, float rotation, Vector2 pivot) 
+        {
+            vertices[0] = v1.Rotate(rotation, pivot);
+            vertices[1] = v2.Rotate(rotation, pivot);
+            vertices[2] = v3.Rotate(rotation, pivot);
+        }
+
+        float Sign(Vector2 p1, Vector2 p2, Vector2 p3) 
+        {
+            return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
+        }
+
+        public bool Contains(Vector2 pt, bool debug = false) 
+        {
+            float d1, d2, d3;
+            bool has_neg, has_pos;
+
+            d1 = Sign(pt, vertices[0], vertices[1]);
+            d2 = Sign(pt, vertices[1], vertices[2]);
+            d3 = Sign(pt, vertices[2], vertices[0]);
+
+            has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
+            has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
+
+            bool contains = ! (has_neg && has_pos);
+
+            return contains;
+        }
+    }
+}
+
diff --git a/Assets/Scripts/2D/Geometry/Triangle2D.cs.meta b/Assets/Scripts/2D/Geometry/Triangle2D.cs.meta
new file mode 100644
index 0000000..db09c09
--- /dev/null
+++ b/Assets/Scripts/2D/Geometry/Triangle2D.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5b3d23802c4b0df4db68d12d425fb251
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/AssetBundles/AssetBundleLoader.cs b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs
index 215d6de..db53c54 100644
--- a/Assets/Scripts/AssetBundles/AssetBundleLoader.cs
+++ b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs
@@ -2,47 +2,34 @@
 using UnityEngine;
 using UnityEngine.Networking;
 
-// AssetBundle cache checker & loader with caching
-// worsk by loading .manifest file from server and parsing hash string from it
-
 namespace UnityLibrary
 {
     public class AssetBundleLoader : MonoBehaviour
     {
         public string assetBundleURL = "http://localhost/bundle";
+        private string bundleName = "bundle";
 
         void Start()
         {
-            //StartCoroutine(DownloadAndCache(assetBundleURL));
+            StartCoroutine(DownloadAndCache(assetBundleURL));
         }
 
-        /// <summary>
-        /// load assetbundle manifest, check hash, load actual bundle with hash parameter to use caching
-        /// instantiate gameobject
-        /// </summary>
-        /// <param name="bundleURL">full url to assetbundle file</param>
-        /// <param name="assetName">optional parameter to access specific asset from assetbundle</param>
-        /// <returns></returns>
         IEnumerator DownloadAndCache(string bundleURL, string assetName = "")
         {
-            // Wait for the Caching system to be ready
             while (!Caching.ready)
             {
                 yield return null;
             }
 
-            // if you want to always load from server, can clear cache first
-            //        Caching.CleanCache();
+            // Clear cache for previous versions of the asset bundle
+            Caching.ClearOtherCachedVersions(bundleName, Hash128.Parse("0"));
 
-            // get current bundle hash from server, random value added to avoid caching
             UnityWebRequest www = UnityWebRequest.Get(bundleURL + ".manifest?r=" + (Random.value * 9999999));
-            Debug.Log("Loading manifest:" + bundleURL + ".manifest");
+            Debug.Log("Loading manifest: " + bundleURL + ".manifest");
 
-            // wait for load to finish
-            yield return www.Send();
+            yield return www.SendWebRequest();
 
-            // if received error, exit
-            if (www.isNetworkError == true)
+            if (www.isNetworkError)
             {
                 Debug.LogError("www error: " + www.error);
                 www.Dispose();
@@ -50,44 +37,39 @@ IEnumerator DownloadAndCache(string bundleURL, string assetName = "")
                 yield break;
             }
 
-            // create empty hash string
-            Hash128 hashString = (default(Hash128));// new Hash128(0, 0, 0, 0);
+            Hash128 hashString = default(Hash128);
 
-            // check if received data contains 'ManifestFileVersion'
             if (www.downloadHandler.text.Contains("ManifestFileVersion"))
             {
-                // extract hash string from the received data, TODO should add some error checking here
                 var hashRow = www.downloadHandler.text.ToString().Split("\n".ToCharArray())[5];
                 hashString = Hash128.Parse(hashRow.Split(':')[1].Trim());
 
-                if (hashString.isValid == true)
+                if (hashString.isValid)
                 {
-                    // we can check if there is cached version or not
-                    if (Caching.IsVersionCached(bundleURL, hashString) == true)
+                    if (Caching.IsVersionCached(bundleURL, hashString))
                     {
                         Debug.Log("Bundle with this hash is already cached!");
-                    } else
+                    }
+                    else
                     {
-                        Debug.Log("No cached version founded for this hash..");
+                        Debug.Log("No cached version found for this hash..");
                     }
-                } else
+                }
+                else
                 {
-                    // invalid loaded hash, just try loading latest bundle
-                    Debug.LogError("Invalid hash:" + hashString);
+                    Debug.LogError("Invalid hash: " + hashString);
                     yield break;
                 }
-
-            } else
+            }
+            else
             {
                 Debug.LogError("Manifest doesn't contain string 'ManifestFileVersion': " + bundleURL + ".manifest");
                 yield break;
             }
 
-            // now download the actual bundle, with hashString parameter it uses cached version if available
-            www = UnityWebRequest.GetAssetBundle(bundleURL + "?r=" + (Random.value * 9999999), hashString, 0);
+            www = UnityWebRequestAssetBundle.GetAssetBundle(bundleURL + "?r=" + (Random.value * 9999999), hashString, 0);
 
-            // wait for load to finish
-            yield return www.Send();
+            yield return www.SendWebRequest();
 
             if (www.error != null)
             {
@@ -97,42 +79,26 @@ IEnumerator DownloadAndCache(string bundleURL, string assetName = "")
                 yield break;
             }
 
-            // get bundle from downloadhandler
             AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
-
             GameObject bundlePrefab = null;
 
-            // if no asset name is given, take the first/main asset
             if (assetName == "")
             {
                 bundlePrefab = (GameObject)bundle.LoadAsset(bundle.GetAllAssetNames()[0]);
-            } else
-            { // use asset name to access inside bundle
+            }
+            else
+            {
                 bundlePrefab = (GameObject)bundle.LoadAsset(assetName);
             }
 
-            // if we got something out
             if (bundlePrefab != null)
             {
-
-                // instantiate at 0,0,0 and without rotation
                 Instantiate(bundlePrefab, Vector3.zero, Quaternion.identity);
-
-                /*
-                // fix pink shaders, NOTE: not always needed..
-                foreach (Renderer r in go.GetComponentsInChildren<Renderer>(includeInactive: true))
-                {
-                    // FIXME: creates multiple materials, not good
-                    var material = Shader.Find(r.material.shader.name);
-                    r.material.shader = null;
-                    r.material.shader = material;
-                }*/
             }
 
             www.Dispose();
             www = null;
 
-            // try to cleanup memory
             Resources.UnloadUnusedAssets();
             bundle.Unload(false);
             bundle = null;
diff --git a/Assets/Scripts/Camera/AutoResolution.cs b/Assets/Scripts/Camera/AutoResolution.cs
new file mode 100644
index 0000000..87fd874
--- /dev/null
+++ b/Assets/Scripts/Camera/AutoResolution.cs
@@ -0,0 +1,58 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class AutoResolution : MonoBehaviour
+{
+        public int setWidth = 1440;
+        public int setHeight = 2560;
+        
+        private void Start()
+        {
+            // Get the main camera and its current dimensions
+            Camera camera = Camera.main;
+            Rect rect = camera.rect;
+
+            // Calculate the scale height and width of the screen
+            float scaleHeight = ((float)Screen.width / Screen.height) / ((float)9 / 16);
+            float scaleWidth = 1f / scaleHeight;
+
+            // Adjust the camera's dimensions based on the scale height and width
+            if (scaleHeight < 1)
+            {
+                rect.height = scaleHeight;
+                rect.y = (1f - scaleHeight) / 2f;
+            }
+            else
+            {
+                rect.width = scaleWidth;
+                rect.x = (1f - scaleWidth) / 2f;
+            }
+            
+            camera.rect = rect;
+
+            SetResolution();
+        }
+
+        public void SetResolution()
+        {
+            // Get the current device's screen dimensions
+            int deviceWidth = Screen.width;
+            int deviceHeight = Screen.height;
+
+            // Set the screen resolution to the desired dimensions, while maintaining aspect ratio
+            Screen.SetResolution(setWidth, (int)(((float)deviceHeight / deviceWidth) * setWidth), true);
+
+            // Adjust the camera's dimensions based on the new resolution
+            if ((float)setWidth / setHeight < (float)deviceWidth / deviceHeight)
+            {
+                float newWidth = ((float)setWidth / setHeight) / ((float)deviceWidth / deviceHeight);
+                Camera.main.rect = new Rect((1f - newWidth) / 2f, 0f, newWidth, 1f);
+            }
+            else
+            {
+                float newHeight = ((float)deviceWidth / deviceHeight) / ((float)setWidth / setHeight);
+                Camera.main.rect = new Rect(0f, (1f - newHeight) / 2f, 1f, newHeight); // 새로운 Rect 적용
+            }
+        }
+}
diff --git a/Assets/Scripts/Camera/CameraShake.cs b/Assets/Scripts/Camera/CameraShake.cs
index d8814bb..48a88e6 100644
--- a/Assets/Scripts/Camera/CameraShake.cs
+++ b/Assets/Scripts/Camera/CameraShake.cs
@@ -1,58 +1,66 @@
 using UnityEngine;
 using System.Collections;
 
-// usage: attach this script into camera, call Shake() method to start
-// source: http://answers.unity3d.com/answers/992509/view.html
+/* 
+ * Usage: attach this script to a camera or any other object, call Shake() method to start shaking it
+* To turn off, change influence to zero
+* Attach the camera to an empty game object to keep its local position and rotation
+*/
 namespace UnityLibrary
 {
     public class CameraShake : MonoBehaviour
     {
-        public bool shakePosition;
-        public bool shakeRotation;
-
-        public float shakeIntensityMin = 0.1f;
-        public float shakeIntensityMax = 0.5f;
-        public float shakeDecay = 0.02f;
+        [Range(0f, 1f)]
+        public float shakeInfluence = 0.5f;
+        [Range(0f, 10f)]
+        public float rotationInfluence = 0f;
 
         private Vector3 OriginalPos;
         private Quaternion OriginalRot;
-
         private bool isShakeRunning = false;
 
-        // call this function to start shaking
-        public void Shake()
+/// <summary>
+/// Will shake the camera with a random value between minIntensity and maxIntensity for duration
+/// </summary>
+/// <param name="minIntensity"></param>
+/// <param name="maxIntensity"></param>
+/// <param name="duration"></param>
+        public void Shake(float minIntensity, float maxIntensity, float duration)
         {
+            if (isShakeRunning)
+                return;
+
             OriginalPos = transform.position;
             OriginalRot = transform.rotation;
-            StartCoroutine("ProcessShake");
+
+            float shake = Random.Range(minIntensity, maxIntensity) * shakeInfluence;
+            duration *= shakeInfluence;
+
+            StartCoroutine(ProcessShake(shake, duration));
         }
 
-        IEnumerator ProcessShake()
+        IEnumerator ProcessShake(float shake, float duration)
         {
-            if (!isShakeRunning)
+            isShakeRunning = true;
+            float countdown = duration;
+            float initialShake = shake;
+
+            while (countdown > 0)
             {
-                isShakeRunning = true;
-                float currentShakeIntensity = Random.Range(shakeIntensityMin, shakeIntensityMax);
-
-                while (currentShakeIntensity > 0)
-                {
-                    if (shakePosition)
-                    {
-                        transform.position = OriginalPos + Random.insideUnitSphere * currentShakeIntensity;
-                    }
-                    if (shakeRotation)
-                    {
-                        transform.rotation = new Quaternion(OriginalRot.x + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
-                                                             OriginalRot.y + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
-                                                             OriginalRot.z + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f,
-                                                             OriginalRot.w + Random.Range(-currentShakeIntensity, currentShakeIntensity) * .2f);
-                    }
-                    currentShakeIntensity -= shakeDecay;
-                    yield return null;
-                }
-
-                isShakeRunning = false;
+                countdown -= Time.deltaTime;
+
+                float lerpIntensity = countdown / duration;
+                shake = Mathf.Lerp(0f, initialShake, lerpIntensity);
+
+                transform.position = OriginalPos + Random.insideUnitSphere * shake;
+                transform.rotation = Quaternion.Euler(OriginalRot.eulerAngles + Random.insideUnitSphere * shake * rotationInfluence);
+
+                yield return null;
             }
+
+            transform.position = OriginalPos;
+            transform.rotation = OriginalRot;
+            isShakeRunning = false;
         }
     }
 }
\ No newline at end of file
diff --git a/Assets/Scripts/Camera/EditorCardboardCamera.cs b/Assets/Scripts/Camera/EditorCardboardCamera.cs
new file mode 100644
index 0000000..c73bd45
--- /dev/null
+++ b/Assets/Scripts/Camera/EditorCardboardCamera.cs
@@ -0,0 +1,23 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+// editor only Google Carboard VR cam simulation with left alt + mouse
+
+public class EditorCardboardCamera : MonoBehaviour
+{
+#if UNITY_EDITOR
+    Vector2 rotation = Vector2.zero;
+    public float speed = 3;
+
+    void Update()
+    {
+        if (Input.GetKey(KeyCode.LeftAlt))
+        {
+            rotation.y += Input.GetAxis("Mouse X");
+            rotation.x += -Input.GetAxis("Mouse Y");
+            transform.eulerAngles = (Vector2)rotation * speed;
+        }
+    }
+#endif
+}
diff --git a/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs b/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs
new file mode 100644
index 0000000..c10daf6
--- /dev/null
+++ b/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs
@@ -0,0 +1,208 @@
+using UnityEngine;
+
+//Marrt's simplest Mouselook for https://forum.unity.com/threads/a-free-simple-smooth-mouselook.73117/page-2#post-4652755
+
+namespace UnityLibrary
+{
+  public class MarrtsSmoothedMouseLook : MonoBehaviour 
+  {
+    [Header("CameraTransform")]
+    public	Transform	targetTrans;
+    [Header("On/Off & Settings")]
+    public	bool		inputActive		= true;
+    public	bool		controlCursor	= false;
+    [Header("Smoothing")]
+    public	bool		byPassSmoothing	= false;
+    public	float		mLambda			= 20F;	//higher = less latency but also less smoothing
+    [Header("Sensitivity")]
+    public	float		hSens			=  4F;
+    public	float		vSens			=  4F;
+    public	BufferV2	mouseBuffer		= new BufferV2();
+
+    public	enum AxisClampMode	{ None, Hard, Soft }
+
+    [Header("Restricting Look")]
+
+    public	AxisClampMode	pitchClamp		= AxisClampMode.Soft;
+    [Range(-180F,180F)]	public	float		pMin			= -80F;
+    [Range(-180F,180F)]	public	float		pMax			=  80F;
+
+
+    [Header("Yaw should be left None, Message me if you really need this functionality")]
+
+    public	AxisClampMode	yawClamp		= AxisClampMode.None;
+    [Range(-180F,180F)]	public	float		yMin			= -140F;
+    [Range(-180F,180F)]	public	float		yMax			=  140F;
+
+
+
+    //public	bool		smoothingDependence	= Timescale Framerate
+
+    void Update ()
+    {
+      //if(Input.GetKeyDown(KeyCode.Space)){inputActive = !inputActive;}
+      if(controlCursor){	//Cursor Control
+        if(  inputActive && Cursor.lockState != CursorLockMode.Locked)	{ Cursor.lockState = CursorLockMode.Locked;	}
+        if( !inputActive && Cursor.lockState != CursorLockMode.None)	{ Cursor.lockState = CursorLockMode.None;	}
+      }		
+      if(!inputActive){ return; }	//active?
+
+      //Update input
+      UpdateMouseBuffer();
+      targetTrans.rotation		= Quaternion.Euler( mouseBuffer.curAbs );
+    }
+
+    //consider late Update for applying the rotation if your game needs it (e.g. if camera parents are rotated in Update for some reason)
+    void LateUpdate() {}	
+
+    private	void UpdateMouseBuffer()
+    {
+
+      float rawPitchDelta = vSens * -Input.GetAxisRaw("Mouse Y");
+
+      switch(pitchClamp){
+        case AxisClampMode.None:	mouseBuffer.target.x += rawPitchDelta;	break;
+        case AxisClampMode.Hard:	mouseBuffer.target.x  = Mathf.Clamp(mouseBuffer.target.x +rawPitchDelta, pMin, pMax);		break;
+        case AxisClampMode.Soft:	mouseBuffer.target.x += SoftPitchClamping.DeltaMod( mouseBuffer.target.x, rawPitchDelta, Mathf.Abs(pMax*0.5F), Mathf.Abs(pMax) );	break; //symetric clamping only for now, max is used
+      }
+
+      float rawYawDelta = hSens * Input.GetAxisRaw("Mouse X");
+
+      switch(yawClamp){
+        case AxisClampMode.None:	mouseBuffer.target.y += rawYawDelta;	break;
+        case AxisClampMode.Hard:	mouseBuffer.target.y  = Mathf.Clamp(mouseBuffer.target.y +rawYawDelta, yMin, yMax);			break;
+        case AxisClampMode.Soft:	Debug.LogWarning("SoftYaw clamp should be implemented with Quaternions to work in every situation");
+                      mouseBuffer.target.y += SoftPitchClamping.DeltaMod( mouseBuffer.target.y, rawYawDelta, Mathf.Abs(yMax*0.5F), Mathf.Abs(yMax) );
+        break;
+      }
+
+      mouseBuffer.Update( mLambda, Time.deltaTime, byPassSmoothing );
+    }
+  }
+
+
+
+
+
+  #region Helpers
+  [System.Serializable]
+  public class BufferV2{
+
+    public BufferV2(){
+      this.target = Vector2.zero;
+      this.buffer = Vector2.zero;
+    }
+    public BufferV2( Vector2 targetInit, Vector2 bufferInit ) {
+      this.target = targetInit;
+      this.buffer = bufferInit;
+    }
+
+    /*private*/public	Vector2	target;
+    /*private*/public	Vector2	buffer;
+
+    public	Vector2	curDelta;	//Delta: apply difference from lastBuffer state to current BufferState		//get difference between last and new buffer
+    public	Vector2	curAbs;		//absolute
+
+
+
+    /// <summary>Update Buffer By supplying new target</summary>
+    public	void UpdateByNewTarget( Vector2 newTarget, float dampLambda, float deltaTime ){
+      this.target		= newTarget;
+      Update(dampLambda, deltaTime);
+    }
+    /// <summary>Update Buffer By supplying the rawDelta to the last target</summary>
+    public	void UpdateByDelta( Vector2 rawDelta, float dampLambda, float deltaTime ){
+      this.target		= this.target +rawDelta;	//update Target
+      Update(dampLambda, deltaTime);
+    }
+
+    /// <summary>Update Buffer</summary>
+    public	void Update( float dampLambda, float deltaTime, bool byPass = false ){
+      Vector2 last	= buffer;			//last state of Buffer
+      this.buffer		= byPass? target : DampToTargetLambda( buffer, this.target, dampLambda, deltaTime);	//damp current to target
+      this.curDelta	= buffer -last;
+      this.curAbs		= buffer;
+    }
+    public static Vector2		DampToTargetLambda( Vector2	current,		Vector2		target,		float lambda, float dt){
+      return Vector2.		Lerp(current, target, 1F -Mathf.Exp( -lambda *dt) );
+    }
+  }
+
+
+
+
+  public	static class SoftPitchClamping{
+    public	static float	DeltaMod( float currentPitch, float delta, float softMax = 45F, float hardMax = 85F ){
+
+        //doesnt work for input above 90F pitch, unity might invert roll and decrease pitch again
+
+        //transform into -180 to 180 range (allowed input range = 0-360F )
+        float wrapped		= Wrap.Float( currentPitch, -180F, 180F );
+
+        float sign			= Mathf.Sign( wrapped );
+        float absolute		= Mathf.Abs	( wrapped );
+
+        //	treat current as mapped value, so unmap it via reversing
+        //	https://rechneronline.de/function-graphs/
+        //	revert remap:	e^((((log(x/45)+1)*45)/45)-1)*45
+        //	remap:	(log(x/45)+1)*45
+
+        float remapped			= absolute;
+        if( absolute > softMax ){
+          //				 e^ ((			((		  log(       x/45	  )+1  )*45		 )		/45		) -1 )*45
+        //	remapped = Mathf.Exp((			((	Mathf.Log(remapped/softMax)+1F )*softMax )		/softMax) -1F)*softMax ;
+          remapped = Mathf.Exp((			remapped											/softMax) -1F)*softMax ;
+          //x*0.5+45*0.5
+        }
+
+        //apply delta to unmapped, sign needs to be taken into consideration for delta
+        remapped += (delta *sign);	//float raw = remapped +(delta *sign);
+
+        //remap, only needed if exceeding softrange
+        if( remapped > softMax ){
+          //								((		 log(		 x/45	 )+1  )*45		)
+          remapped =						(( Mathf.Log(remapped/softMax)+1F )*softMax );
+
+          //x*0.5+45*0.5
+
+        }
+
+        remapped *= sign;
+        remapped  = Mathf.Clamp( remapped, -hardMax, +hardMax);
+
+        float newDelta = ( remapped -wrapped );
+
+        //print( "wrapped\t"+wrapped+" (from:"+currentPitch+")"+"\nremapped\t"+remapped +" (raw :"+raw+")");
+
+        return newDelta;
+      //	return delta;
+    }
+
+    public	static class Wrap{
+
+      //can be used to clamp angles from 0-360 to 0-180 by feeding (value,-180,180)
+      //https://stackoverflow.com/questions/1628386/normalise-orientation-between-0-and-360
+
+      //Normalizes any number to an arbitrary range 
+      //by assuming the range wraps around when going below min or above max 
+      public	static float Float( float value, float start, float end ){
+        float width       = end - start   ;   // 
+        float offsetValue = value - start ;   // value relative to 0
+
+        return ( offsetValue - ( Mathf.Floor( offsetValue / width ) * width ) ) + start ;
+        // + start to reset back to start of original range
+      }
+
+      //Normalizes any number to an arbitrary range 
+      //by assuming the range wraps around when going below min or above max 
+      public	static int Int( int value, int start, int end ){
+        int width       = end - start   ;   // 
+        int offsetValue = value - start ;   // value relative to 0
+
+        return ( offsetValue - ( ( offsetValue / width ) * width ) ) + start ;
+        // + start to reset back to start of original range
+    }
+  }
+  }
+    #endregion Helpers
+}
diff --git a/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs.meta b/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs.meta
new file mode 100644
index 0000000..3eccce9
--- /dev/null
+++ b/Assets/Scripts/Camera/MarrtsSmoothedMouseLook.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 10e595b96bab7724a99b2b273e92011e
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Camera/MobileCamera.cs b/Assets/Scripts/Camera/MobileCamera.cs
new file mode 100644
index 0000000..99fd6f5
--- /dev/null
+++ b/Assets/Scripts/Camera/MobileCamera.cs
@@ -0,0 +1,135 @@
+// https://forum.unity.com/threads/mobile-touch-to-orbit-pan-and-zoom-camera-without-fix-target-in-one-script.522607/#post-3531342
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class MobileCamera : MonoBehaviour
+{
+    public Transform target;
+    public Vector3 targetOffset;
+    public float distance = 5.0f;
+    public float maxDistance = 20;
+    public float minDistance = .6f;
+    public float xSpeed = 5.0f;
+    public float ySpeed = 5.0f;
+    public int yMinLimit = -80;
+    public int yMaxLimit = 80;
+    public float zoomRate = 10.0f;
+    public float panSpeed = 0.3f;
+    public float zoomDampening = 5.0f;
+
+    private float xDeg = 0.0f;
+    private float yDeg = 0.0f;
+    private float currentDistance;
+    private float desiredDistance;
+    private Quaternion currentRotation;
+    private Quaternion desiredRotation;
+    private Quaternion rotation;
+    private Vector3 position;
+
+    private Vector3 FirstPosition;
+    private Vector3 SecondPosition;
+    private Vector3 delta;
+    private Vector3 lastOffset;
+    private Vector3 lastOffsettemp;
+    //private Vector3 CameraPosition;
+    //private Vector3 Targetposition;
+    //private Vector3 MoveDistance;
+
+    public float offsetSpeed = 0.03f;
+
+    void Start() { Init(); }
+    void OnEnable() { Init(); }
+
+    public void Init()
+    {
+        //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
+        if (!target)
+        {
+            GameObject go = new GameObject("Cam Target");
+            go.transform.position = transform.position + (transform.forward * distance);
+            target = go.transform;
+        }
+
+        distance = Vector3.Distance(transform.position, target.position);
+        currentDistance = distance;
+        desiredDistance = distance;
+
+        //be sure to grab the current rotations as starting points.
+        position = transform.position;
+        rotation = transform.rotation;
+        currentRotation = transform.rotation;
+        desiredRotation = transform.rotation;
+
+        //xDeg = Vector3.Angle(Vector3.right, transform.right);
+        //yDeg = Vector3.Angle(Vector3.up, transform.up);
+
+        xDeg = transform.eulerAngles.y + Vector3.Angle(Vector3.right, transform.right);
+        yDeg = transform.eulerAngles.x + Vector3.Angle(Vector3.up, transform.up);
+
+    }
+
+    void LateUpdate()
+    {
+        // If Control and Alt and Middle button? ZOOM!
+        if (Input.touchCount == 2)
+        {
+            Touch touchZero = Input.GetTouch(0);
+            Touch touchOne = Input.GetTouch(1);
+            Vector2 touchZeroPreviousPosition = touchZero.position - touchZero.deltaPosition;
+            Vector2 touchOnePreviousPosition = touchOne.position - touchOne.deltaPosition;
+            float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;
+            float TouchDeltaMag = (touchZero.position - touchOne.position).magnitude;
+            float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;
+            desiredDistance += deltaMagDiff * Time.deltaTime * zoomRate * 0.0025f * Mathf.Abs(desiredDistance);
+        }
+
+        // If middle mouse and left alt are selected? ORBIT
+        if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved)
+        {
+            Vector2 touchposition = Input.GetTouch(0).deltaPosition;
+            xDeg += touchposition.x * xSpeed * 0.002f;
+            yDeg -= touchposition.y * ySpeed * 0.002f;
+            yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
+
+        }
+
+        desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
+        currentRotation = transform.rotation;
+        rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
+        transform.rotation = rotation;
+
+        if (Input.GetMouseButtonDown(1))
+        {
+            FirstPosition = Input.mousePosition;
+            lastOffset = targetOffset;
+        }
+
+        if (Input.GetMouseButton(1))
+        {
+            SecondPosition = Input.mousePosition;
+            delta = SecondPosition - FirstPosition;
+            targetOffset = lastOffset + transform.right * delta.x * offsetSpeed + transform.up * delta.y * offsetSpeed;
+
+        }
+
+        ////////Orbit Position
+        // affect the desired Zoom distance if we roll the scrollwheel
+        desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
+        currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);
+        position = target.position - (rotation * Vector3.forward * currentDistance);
+        position = position - targetOffset;
+        transform.position = position;
+    }
+
+    private static float ClampAngle(float angle, float min, float max)
+    {
+        if (angle < -360)
+            angle += 360;
+        if (angle > 360)
+            angle -= 360;
+        return Mathf.Clamp(angle, min, max);
+    }
+}
+
diff --git a/Assets/Scripts/Camera/PlayerMovement.cs b/Assets/Scripts/Camera/PlayerMovement.cs
new file mode 100644
index 0000000..901af41
--- /dev/null
+++ b/Assets/Scripts/Camera/PlayerMovement.cs
@@ -0,0 +1,41 @@
+﻿using UnityEngine;
+using System.Collections.Generic;
+using System.Collections;
+
+//Script for moving a gameObject smoothly
+//Usage: Attach the character controller component to the gameobject that you want to move
+
+namespace UnityLibary
+{
+    public class PlayerMovement : MonoBehaviour
+    {
+        // place the gameobject that you want to move to the controller placeholder
+        public CharacterController controller;
+
+        public float speed = 5f;
+
+        void Update()
+        {
+            float x = Input.GetAxis("Horizontal");
+            float z = Input.GetAxis("Vertical");
+
+            Vector3 move = transform.right * x + transform.forward * z;
+
+            controller.Move(move * speed * Time.deltaTime);
+
+            //Rotate clockwise
+            if (Input.GetKey(KeyCode.E))
+            {
+                transform.RotateAround(transform.position, Vector3.up, 100 * Time.deltaTime);
+            }
+
+            // Rotate anticlockwise
+            if (Input.GetKey(KeyCode.Q))
+            {
+                transform.RotateAround(transform.position, -Vector3.up, 100 * Time.deltaTime);
+            }
+
+        }
+
+    }
+}
diff --git a/Assets/Scripts/Camera/PlayerMovement.cs.meta b/Assets/Scripts/Camera/PlayerMovement.cs.meta
new file mode 100644
index 0000000..058aaca
--- /dev/null
+++ b/Assets/Scripts/Camera/PlayerMovement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c1dd692b70ceca4439544f5a72fa7f70
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Camera/SimpleSmoothMouseLookNewInput.cs b/Assets/Scripts/Camera/SimpleSmoothMouseLookNewInput.cs
new file mode 100644
index 0000000..2864d24
--- /dev/null
+++ b/Assets/Scripts/Camera/SimpleSmoothMouseLookNewInput.cs
@@ -0,0 +1,260 @@
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+namespace UnityLibrary
+{
+    public class SimpleSmoothMouseLookNewInput : MonoBehaviour
+    {
+        [Header("Mouse Look")]
+        [Tooltip("Hold right mouse button down to rotate")]
+        public bool rotateWithRightMouse = true;
+        public Vector2 clampInDegrees = new Vector2(360, 180);
+        public bool lockCursor = false;
+        public Vector2 sensitivity = new Vector2(2, 2);
+        public Vector2 smoothing = new Vector2(3, 3);
+        Vector2 targetDirection;
+        Vector2 _mouseAbsolute;
+        Vector2 _smoothMouse;
+
+        [Header("Camera Pan")]
+        public bool enablePanning = true;
+        public float panSpeed = 40;
+
+        [Header("Camera Orbit")]
+        public bool enableOrbit = false;
+        public KeyCode orbitKey = KeyCode.LeftAlt;
+        [Tooltip("Set this to -1, if you dont require any mousebutton pressed for orbit")]
+        public int orbitMouseKey = 2;
+        public float orbitXSpeed = 400;
+        public float orbitYSpeed = 400;
+        Vector3 targetposition;
+        float orbitDistance = 10.0f;
+        private float xDeg = 0.0f;
+        private float yDeg = 0.0f;
+
+        [Header("Camera Zoom")]
+        public bool scrollZoom = false;
+        public int zoomRate = 40;
+        public float zoomDampening = 5.0f;
+        public KeyCode zoomExtends = KeyCode.F; // whole cloud
+
+        [Header("Camera Fly")]
+        public float flySpeed = 20; // default speed
+        public float accelerationRatio = 5; // when shift is pressed
+        public float slowDownRatio = 0.5f; // when ctrl is pressed
+        public KeyCode increaseSpeedKey = KeyCode.LeftShift;
+        public KeyCode decreaseSpeedKey = KeyCode.LeftControl;
+        public KeyCode upKey = KeyCode.E;
+        public KeyCode downKey = KeyCode.Q;
+        public string horizontalAxisKey = "Horizontal";
+        public string verticalAxisKey = "Vertical";
+
+        public bool moveRoot = false;
+        Transform moveTransform;
+
+        Camera cam;
+
+        void Awake()
+        {
+            cam = Camera.main;
+
+            moveTransform = moveRoot ? transform.root : transform;
+        }
+
+        private void Start()
+        {
+            
+        }
+
+        private void OnEnable()
+        {
+            // Set target direction to the camera's initial orientation, NOTE need to do this if you move camera manually elsewhere
+            targetDirection = transform.localRotation.eulerAngles;
+        }
+
+        void Update()
+        {
+            Framing();
+            if (MouseOrbit() == true) return;
+            MouseLook();
+            CameraFly();
+        }
+
+        void Framing()
+        {
+
+        }
+
+        public void GetOrbitTarget()
+        {
+            targetposition = transform.forward * orbitDistance;
+            //orbitDistance = Vector3.Distance(transform.position, targetposition);
+        }
+
+
+        bool MouseOrbit()
+        {
+            // early exit, if not enabled, or no key is pressed, or if mousekey is set, but not pressed
+            if (enableOrbit == false || Input.GetKey(orbitKey) == false || (orbitMouseKey > -1 == true && Input.GetMouseButton(orbitMouseKey) == false))
+            {
+                return false;
+            }
+
+            orbitDistance += Input.GetAxis("Mouse ScrollWheel") * zoomRate * Time.deltaTime;
+
+            xDeg = (Input.GetAxis("Mouse X") * orbitXSpeed);
+            yDeg = -(Input.GetAxis("Mouse Y") * orbitYSpeed);
+            transform.RotateAround(targetposition, Vector3.up, xDeg * Time.deltaTime);
+            transform.RotateAround(targetposition, transform.right, yDeg * Time.deltaTime);
+
+            targetDirection = transform.rotation.eulerAngles;
+
+            return true;
+        }
+
+        static float ClampAngle(float angle, float min, float max)
+        {
+            if (angle < -360)
+                angle += 360;
+            if (angle > 360)
+                angle -= 360;
+            return Mathf.Clamp(angle, min, max);
+        }
+
+        void MouseLook()
+        {
+            // Get raw mouse input for a cleaner reading on more sensitive mice.
+            //var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
+            var mouseDelta = Mouse.current.delta.ReadValue() * Time.deltaTime*3;
+
+            // panning with middle moouse button
+            if (enablePanning == true)
+            {
+                //if (Input.GetMouseButton(2))
+                if (Mouse.current.middleButton.isPressed)
+                {
+                    transform.Translate(-mouseDelta * panSpeed * Time.deltaTime, Space.Self);
+                    GetOrbitTarget(); // update orbit target
+                }
+            }
+
+            // Ensure the cursor is always locked when set
+            if (lockCursor == true) Cursor.lockState = CursorLockMode.Locked;
+
+            //if (rotateWithRightMouse == true && !Input.GetMouseButton(1)) return;
+            if (rotateWithRightMouse == true && !Mouse.current.rightButton.isPressed) return;
+
+            // Allow the script to clamp based on a desired target value.
+            Quaternion targetOrientation = Quaternion.Euler(targetDirection);
+
+            // Scale input against the sensitivity setting and multiply that against the smoothing value.
+            mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));
+            // Interpolate mouse movement over time to apply smoothing delta.
+            _smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
+            _smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);
+            // Find the absolute mouse movement value from point zero.
+            _mouseAbsolute += _smoothMouse;
+
+            // Clamp and apply the local x value first, so as not to be affected by world transforms.
+            if (clampInDegrees.x < 360) _mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);
+
+            var xRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right);
+            transform.localRotation = xRotation;
+
+            // Then clamp and apply the global y value.
+            if (clampInDegrees.y < 360) _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);
+
+            var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(Vector3.up));
+            transform.localRotation *= yRotation;
+            transform.rotation *= targetOrientation;
+        }
+
+        void CameraFly()
+        {
+            bool moved = false;
+            // shift was pressed down
+            //if (Input.GetKeyDown(increaseSpeedKey))
+            if (Keyboard.current.leftShiftKey.wasPressedThisFrame)
+            {
+                flySpeed *= accelerationRatio; // increase flyspeed
+            }
+
+            //if (Input.GetKeyUp(increaseSpeedKey))
+            if (Keyboard.current.leftShiftKey.wasReleasedThisFrame)
+            {
+                flySpeed /= accelerationRatio; // flyspeed back to normal
+            }
+
+            //if (Input.GetKeyDown(decreaseSpeedKey))
+            if (Keyboard.current.leftCtrlKey.wasPressedThisFrame)
+            {
+                flySpeed *= slowDownRatio; // decrease flyspeed
+            }
+            //if (Input.GetKeyUp(decreaseSpeedKey))
+            if (Keyboard.current.leftCtrlKey.wasReleasedThisFrame)
+            {
+                flySpeed /= slowDownRatio; // flyspeed back to normal
+            }
+
+            var vert = -Keyboard.current.sKey.ReadValue() + Keyboard.current.wKey.ReadValue();
+            if (vert != 0)
+            {
+                moveTransform.Translate(transform.forward * flySpeed * vert * Time.deltaTime, Space.World);
+                moved = true;
+            }
+
+            var horz = -Keyboard.current.aKey.ReadValue() + Keyboard.current.dKey.ReadValue();
+            if (horz != 0)
+            {
+                moveTransform.Translate(transform.right * flySpeed * horz * Time.deltaTime, Space.World);
+                moved = true;
+            }
+
+            // annoying in editor as it works from any window
+#if !UNITY_EDITOR
+            if (scrollZoom == true)
+            {
+                //if (Input.GetAxis("Mouse ScrollWheel") != 0)
+                var scrollY = Mouse.current.scroll.ReadValue().y;
+                if (scrollY != 0)
+                {
+                    transform.Translate(transform.forward * zoomRate * scrollY * Time.deltaTime, Space.World);
+                    moved = true;
+                }
+            }
+#endif
+
+            //if (Input.GetKey(upKey))
+            if (Keyboard.current.qKey.isPressed)
+            {
+                moveTransform.Translate(moveTransform.up * flySpeed * 0.5f * Time.deltaTime, Space.World);
+                moved = true;
+            }
+            //else if (Input.GetKey(downKey))
+            else if (Keyboard.current.eKey.isPressed)
+            {
+                moveTransform.Translate(-moveTransform.up * flySpeed * 0.5f * Time.deltaTime, Space.World);
+                moved = true;
+            }
+            if (moved == true) GetOrbitTarget();
+        } // CameraFly()
+
+        // https://stackoverflow.com/questions/25368259/making-an-object-fit-exactly-inside-the-camera-frustum-in-three-js
+        public void FocusCameraOnGameObject(Bounds b)
+        {
+            var height = b.max.y;
+            var width = b.max.x - b.min.x;
+            var vertical_FOV = cam.fieldOfView * (Mathf.PI / 180f);
+            var aspectRatio = Screen.width / Screen.height;
+            var horizontal_FOV = 2 * Mathf.Atan(Mathf.Tan(vertical_FOV / 2) * aspectRatio);
+            var distance_vertical = height / (2 * Mathf.Tan(vertical_FOV / 2));
+            var distance_horizontal = width / (2 * Mathf.Tan(horizontal_FOV / 2));
+            var z_distance = distance_vertical >= distance_horizontal ? distance_vertical : distance_horizontal;
+            // current viewdir
+            var viewDir = transform.forward;
+            // move camera so that object is in front
+            cam.transform.position = b.center - viewDir * z_distance * 2;
+        }
+
+    } // class 
+} // namespace
diff --git a/Assets/Editor.meta b/Assets/Scripts/Docs/Mesh.meta
similarity index 67%
rename from Assets/Editor.meta
rename to Assets/Scripts/Docs/Mesh.meta
index 9c21977..836722b 100644
--- a/Assets/Editor.meta
+++ b/Assets/Scripts/Docs/Mesh.meta
@@ -1,7 +1,7 @@
 fileFormatVersion: 2
-guid: 710e084e33216854daedf076c029ff31
+guid: dfe48b7debc5f9c4a9ab9b77ddb37e1a
 folderAsset: yes
-timeCreated: 1501225949
+timeCreated: 1594958191
 licenseType: Free
 DefaultImporter:
   userData: 
diff --git a/Assets/Scripts/Docs/Mesh/MeshExample.cs.meta b/Assets/Scripts/Docs/Mesh/MeshExample.cs.meta
new file mode 100644
index 0000000..24cd5ab
--- /dev/null
+++ b/Assets/Scripts/Docs/Mesh/MeshExample.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3292a9e48eeb600418703ec125a8ef82
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs.meta b/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs.meta
new file mode 100644
index 0000000..3f8f80c
--- /dev/null
+++ b/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a0f7bca99a1816244927583c60c3e022
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Docs/UnityEngine/NavMeshAgentExample.cs b/Assets/Scripts/Docs/UnityEngine/NavMeshAgentExample.cs
new file mode 100644
index 0000000..bae418b
--- /dev/null
+++ b/Assets/Scripts/Docs/UnityEngine/NavMeshAgentExample.cs
@@ -0,0 +1,23 @@
+// made with chatGPT
+
+using UnityEngine;
+using UnityEngine.AI;
+
+namespace UnityLibrary
+{
+    public class NavMeshAgentExample : MonoBehaviour
+    {
+        public Transform target;
+
+        private NavMeshAgent agent;
+
+        void Start()
+        {
+            // Get the NavMeshAgent component on this game object
+            agent = GetComponent<NavMeshAgent>();
+
+            // Set the destination of the NavMeshAgent to the target Transform
+            agent.destination = target.position;
+        }
+    }
+}
diff --git a/Assets/Scripts/Drawing/DrawLine.cs b/Assets/Scripts/Drawing/DrawLine.cs
index 44d6c53..6ffbfbd 100644
--- a/Assets/Scripts/Drawing/DrawLine.cs
+++ b/Assets/Scripts/Drawing/DrawLine.cs
@@ -53,8 +53,9 @@ protected virtual void Update()
             }
             if (Input.GetMouseButton(0))
             {
-                Vector3 mousePosition = m_Camera.ScreenToWorldPoint(Input.mousePosition);
-                mousePosition.z = m_LineRenderer.transform.position.z;
+                var pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, lineRenderer.transform.position.z - m_Camera.transform.position.z);
+                Vector3 mousePosition = m_Camera.ScreenToWorldPoint(pos);
+                mousePosition.z = 0;
                 if (!m_Points.Contains(mousePosition))
                 {
                     m_Points.Add(mousePosition);
diff --git a/Assets/Scripts/Editor/Animation.meta b/Assets/Scripts/Editor/Animation.meta
new file mode 100644
index 0000000..a9393f4
--- /dev/null
+++ b/Assets/Scripts/Editor/Animation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 344c9e72d34584041b61214522912d71
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Animation/LegacyAnimationCreator.meta b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator.meta
new file mode 100644
index 0000000..9fc6b69
--- /dev/null
+++ b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e78d070eb9ba01749a33425b62b0fe5c
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs
new file mode 100644
index 0000000..35f7ff2
--- /dev/null
+++ b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs
@@ -0,0 +1,28 @@
+﻿using System.IO;
+using UnityEditor;
+using UnityEngine;
+
+public class LegacyAnimationCreator
+{
+    [MenuItem("Assets/Create/Legacy Animation", priority = 402)]
+    public static void CompressSelectedAnimationClips()
+    {
+        var clip = new AnimationClip();
+        clip.legacy = true;
+        clip.name = "New Legacy Animation";
+
+        string path;
+        var selection = Selection.activeObject;
+        if (selection == null)
+            path = "Assets";
+        else
+            path = AssetDatabase.GetAssetPath(selection.GetInstanceID());
+
+        path = Path.GetDirectoryName(path);
+        path += $"/{clip.name}.anim";
+
+        ProjectWindowUtil.CreateAsset(clip, path);
+        Selection.activeObject = clip;
+        EditorUtility.SetDirty(clip);
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs.meta b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs.meta
new file mode 100644
index 0000000..5bd716f
--- /dev/null
+++ b/Assets/Scripts/Editor/Animation/LegacyAnimationCreator/LegacyAnimationCreator.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d536889e20faa9d47b7def4f46203b81
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/BatchTools/CopyGameObjectNames.cs b/Assets/Scripts/Editor/BatchTools/CopyGameObjectNames.cs
new file mode 100644
index 0000000..40bf0d0
--- /dev/null
+++ b/Assets/Scripts/Editor/BatchTools/CopyGameObjectNames.cs
@@ -0,0 +1,59 @@
+// editor tool to copy names of selected GameObjects to clipboard as a list (so you can paste them in Excel or others..)
+
+using UnityEngine;
+using UnityEditor;
+using System.Text;
+using System.Linq;
+namespace UnityLibrary.Tools
+{
+    public class CopyGameObjectNames : EditorWindow
+    {
+        private string gameObjectNames = string.Empty;
+
+        [MenuItem("Tools/Copy GameObject Names")]
+        public static void ShowWindow()
+        {
+            GetWindow<CopyGameObjectNames>("Copy GameObject Names");
+        }
+
+        private void OnGUI()
+        {
+            GUILayout.Label("Copy Names of Selected GameObjects", EditorStyles.boldLabel);
+
+            if (GUILayout.Button("Fetch Names"))
+            {
+                FetchNames();
+            }
+
+            GUILayout.Label("GameObject Names:", EditorStyles.label);
+            gameObjectNames = EditorGUILayout.TextArea(gameObjectNames, GUILayout.Height(200));
+
+            if (GUILayout.Button("Copy to Clipboard"))
+            {
+                CopyToClipboard();
+            }
+        }
+
+        private void FetchNames()
+        {
+            StringBuilder sb = new StringBuilder();
+            GameObject[] selectedObjects = Selection.gameObjects;
+
+            // Sort the selected objects by their sibling index
+            var sortedObjects = selectedObjects.OrderBy(go => go.transform.GetSiblingIndex()).ToArray();
+
+            foreach (GameObject obj in sortedObjects)
+            {
+                sb.AppendLine(obj.name);
+            }
+
+            gameObjectNames = sb.ToString();
+        }
+
+        private void CopyToClipboard()
+        {
+            EditorGUIUtility.systemCopyBuffer = gameObjectNames;
+            Debug.Log("GameObject names copied to clipboard.");
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/BatchTools/ReplaceCharacterInGameObjectNames.cs b/Assets/Scripts/Editor/BatchTools/ReplaceCharacterInGameObjectNames.cs
new file mode 100644
index 0000000..105bc74
--- /dev/null
+++ b/Assets/Scripts/Editor/BatchTools/ReplaceCharacterInGameObjectNames.cs
@@ -0,0 +1,69 @@
+// editor tool to replace string from selected GameObject names
+
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+
+namespace UnityLibrary.Tools
+{
+    public class ReplaceCharacterInGameObjectNames : EditorWindow
+    {
+        private string searchString = "|";
+        private string replaceString = "@";
+
+        [MenuItem("Tools/Replace Characters in GameObject Names")]
+        public static void ShowWindow()
+        {
+            GetWindow<ReplaceCharacterInGameObjectNames>("Replace Characters");
+        }
+
+        private void OnGUI()
+        {
+            GUILayout.Label("Replace Characters in Selected GameObject Names", EditorStyles.boldLabel);
+
+            searchString = EditorGUILayout.TextField("Search String", searchString);
+            replaceString = EditorGUILayout.TextField("Replace String", replaceString);
+
+            int selectedObjectCount = Selection.gameObjects.Length;
+            GUILayout.Label($"Selected GameObjects: {selectedObjectCount}", EditorStyles.label);
+
+            if (GUILayout.Button("Replace"))
+            {
+                ReplaceCharacters();
+            }
+        }
+
+        private void ReplaceCharacters()
+        {
+            GameObject[] selectedObjects = Selection.gameObjects;
+
+            if (selectedObjects.Length == 0)
+            {
+                Debug.LogWarning("No GameObjects selected.");
+                return;
+            }
+
+            // Start a new undo group
+            Undo.IncrementCurrentGroup();
+            Undo.SetCurrentGroupName("Replace Character in GameObject Names");
+            int undoGroup = Undo.GetCurrentGroup();
+
+            foreach (GameObject obj in selectedObjects)
+            {
+                if (obj.name.Contains(searchString))
+                {
+                    Undo.RecordObject(obj, "Replace Character in GameObject Name");
+                    obj.name = obj.name.Replace(searchString, replaceString);
+                    EditorUtility.SetDirty(obj);
+                }
+            }
+
+            // End the undo group
+            Undo.CollapseUndoOperations(undoGroup);
+
+            EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
+
+            Debug.Log($"Replaced '{searchString}' with '{replaceString}' in the names of selected GameObjects.");
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/BuildProcess/PostBuildCopyEmptyFolders.cs b/Assets/Scripts/Editor/BuildProcess/PostBuildCopyEmptyFolders.cs
new file mode 100644
index 0000000..186265b
--- /dev/null
+++ b/Assets/Scripts/Editor/BuildProcess/PostBuildCopyEmptyFolders.cs
@@ -0,0 +1,54 @@
+using System.IO;
+using UnityEditor;
+using UnityEditor.Callbacks;
+using UnityEngine;
+
+// copies empty StreamingAssets/ folders into build, as they are not automatically included
+
+namespace UnityLibrary
+{
+    public class PostBuildCopyEmptyFolders : MonoBehaviour
+    {
+        [PostProcessBuildAttribute(1)]
+        public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
+        {
+            // only for windows
+            if (target != BuildTarget.StandaloneWindows) return;
+        
+            Debug.Log("<color=#00FF00>### POSTBUILD : COPY EMPTY STREAMINGASSETS-FOLDERS ###</color>");
+            Debug.Log("Build done: " + pathToBuiltProject);
+
+            // get output root
+            var root = Path.GetDirectoryName(pathToBuiltProject);
+            var appName = Path.GetFileNameWithoutExtension(pathToBuiltProject);
+
+            // copy empty streaming asset folders to build
+            var sourcePath = Application.streamingAssetsPath;
+            var targetPath = Path.Combine(root, appName + "_Data", "StreamingAssets");
+            //Debug.Log("sourcePath= "+ sourcePath);
+            //Debug.Log("targetPath= " + targetPath);
+            CopyFolderStructure(sourcePath, targetPath);
+        }
+
+        // recursive folder copier
+        static public void CopyFolderStructure(string sourceFolder, string destFolder)
+        {
+            if (Directory.Exists(destFolder))
+            {
+
+            }
+            else
+            {
+                Directory.CreateDirectory(destFolder);
+            }
+
+            string[] folders = Directory.GetDirectories(sourceFolder);
+            foreach (string folder in folders)
+            {
+                string name = Path.GetFileName(folder);
+                string dest = Path.Combine(destFolder, name);
+                CopyFolderStructure(folder, dest);
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/ContextMenu.meta b/Assets/Scripts/Editor/ContextMenu.meta
new file mode 100644
index 0000000..bbbf7ac
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 07f01cf58a1140349bfac4f393266db1
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs b/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs
new file mode 100644
index 0000000..ce3f298
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs
@@ -0,0 +1,71 @@
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary
+{
+    public class BoxColliderFitChildren : MonoBehaviour
+    {
+        [MenuItem("CONTEXT/BoxCollider/Fit to Children")]
+        static void FitColliderToChildren(MenuCommand command)
+        {
+            BoxCollider col = (BoxCollider)command.context;
+
+            // Record undo
+            Undo.RecordObject(col.transform, "Fit Box Collider To Children");
+
+            // Get world-space bounds of all child meshes
+            var worldBounds = GetRecursiveMeshBounds(col.gameObject);
+
+            if (worldBounds.size == Vector3.zero)
+            {
+                Debug.LogWarning("No valid meshes found to fit the BoxCollider.");
+                return;
+            }
+
+            // Convert world-space center to local space
+            Vector3 localCenter = col.transform.InverseTransformPoint(worldBounds.center);
+
+            // Convert world-space size to local space
+            Vector3 localSize = col.transform.InverseTransformVector(worldBounds.size);
+
+            // Ensure size is positive
+            localSize = new Vector3(Mathf.Abs(localSize.x), Mathf.Abs(localSize.y), Mathf.Abs(localSize.z));
+
+            // Fix potential center flipping
+            if (Vector3.Dot(col.transform.right, Vector3.right) < 0)
+            {
+                localCenter.x = -localCenter.x;
+            }
+            if (Vector3.Dot(col.transform.up, Vector3.up) < 0)
+            {
+                localCenter.y = -localCenter.y;
+            }
+            if (Vector3.Dot(col.transform.forward, Vector3.forward) < 0)
+            {
+                localCenter.z = -localCenter.z;
+            }
+
+            // Apply to collider
+            col.center = localCenter;
+            col.size = localSize;
+        }
+
+        public static Bounds GetRecursiveMeshBounds(GameObject go)
+        {
+            Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
+
+            if (renderers.Length == 0)
+                return new Bounds();
+
+            // Start with the first renderer’s bounds in world space
+            Bounds worldBounds = renderers[0].bounds;
+
+            for (int i = 1; i < renderers.Length; i++)
+            {
+                worldBounds.Encapsulate(renderers[i].bounds);
+            }
+
+            return worldBounds;
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs.meta b/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs.meta
new file mode 100644
index 0000000..08e2df8
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/BoxColliderFitChildren.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 687fde9d16dc6b04e934c421806d4abb
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/ContextMenu/CreateOutlineForPanelEditor.cs.meta b/Assets/Scripts/Editor/ContextMenu/CreateOutlineForPanelEditor.cs.meta
new file mode 100644
index 0000000..e5d8f63
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/CreateOutlineForPanelEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ea3d3337d55b5bc42a40dff5480adca0
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs b/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs
index 23c6600..b15992c 100644
--- a/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs
+++ b/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs
@@ -19,7 +19,12 @@ static void DoubleMass(MenuCommand command)
                 Debug.LogError("No videoclip assigned..");
                 return;
             }
+#if UNITY_2017 
+            float aspectRatioY = v.texture.height / (float)v.texture.width;
+#else
             float aspectRatioY = v.height / (float)v.width;
+#endif
+
 
             // record undo
             Undo.RecordObject(v.transform, "Set scale");
diff --git a/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs.meta b/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs.meta
new file mode 100644
index 0000000..4aa5605
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: acde12b67d212ae42ab65f73b96ffd59
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs b/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs
new file mode 100644
index 0000000..6b58cf5
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs
@@ -0,0 +1,32 @@
+// Tries to move BoxCollider(3D)-component to match UI panel/image position, by adjusting collider pivot value
+
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary
+{
+    public class SetBoxColliderToUI : MonoBehaviour
+    {
+        [MenuItem("CONTEXT/BoxCollider/Match Position to UI")]
+        static void FixPosition(MenuCommand command)
+        {
+            BoxCollider b = (BoxCollider)command.context;
+
+            // record undo
+            Undo.RecordObject(b.transform, "Set Box Collider To UI");
+
+            // fix pos from Pivot
+            var r = b.gameObject.GetComponent<RectTransform>();
+            if (r == null) return;
+
+            //Debug.Log("pivot "+r.pivot);
+
+            var center = b.center;
+
+            center.x = 0.5f - r.pivot.x;
+            center.y = 0.5f - r.pivot.y;
+
+            b.center = center;
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs.meta b/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs.meta
new file mode 100644
index 0000000..bbc5ca4
--- /dev/null
+++ b/Assets/Scripts/Editor/ContextMenu/SetBoxColliderToUI.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 9581bb1267ccd9e48b11127704331d49
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/CustomInspector/CustomRectTransformCopyInspector.cs b/Assets/Scripts/Editor/CustomInspector/CustomRectTransformCopyInspector.cs
new file mode 100644
index 0000000..0a5de2b
--- /dev/null
+++ b/Assets/Scripts/Editor/CustomInspector/CustomRectTransformCopyInspector.cs
@@ -0,0 +1,114 @@
+#if UNITY_EDITOR
+using System;
+using System.Reflection;
+using UnityEngine;
+
+namespace UnityEditor
+{
+    [CustomEditor(typeof(RectTransform), true)]
+    [CanEditMultipleObjects]
+    public class CustomRectTransformCopyInspector : Editor
+    {
+        // Unity's built-in editor
+        Editor defaultEditor = null;
+        RectTransform rectTransform;
+
+        private static RectTransformData copiedData;
+
+        void OnEnable()
+        {
+            // Use reflection to get the default Unity RectTransform editor
+            defaultEditor = Editor.CreateEditor(targets, Type.GetType("UnityEditor.RectTransformEditor, UnityEditor"));
+            rectTransform = target as RectTransform;
+        }
+
+        void OnDisable()
+        {
+            // Destroy the default editor to avoid memory leaks
+            if (defaultEditor != null)
+            {
+                MethodInfo disableMethod = defaultEditor.GetType().GetMethod("OnDisable",
+                    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                if (disableMethod != null)
+                    disableMethod.Invoke(defaultEditor, null);
+
+                DestroyImmediate(defaultEditor);
+            }
+        }
+
+        public override void OnInspectorGUI()
+        {
+            // Draw Unity's default RectTransform Inspector
+            defaultEditor.OnInspectorGUI();
+
+            // Add Copy and Paste buttons
+            EditorGUILayout.Space();
+            GUILayout.BeginHorizontal();
+
+            if (GUILayout.Button("C", GUILayout.Width(30))) // Copy
+            {
+                CopyRectTransform(rectTransform);
+            }
+
+            if (GUILayout.Button("P", GUILayout.Width(30))) // Paste
+            {
+                PasteRectTransform(rectTransform);
+            }
+
+            GUILayout.EndHorizontal();
+        }
+
+        private void CopyRectTransform(RectTransform rectTransform)
+        {
+            copiedData = new RectTransformData(rectTransform);
+            Debug.Log("RectTransform copied!");
+        }
+
+        private void PasteRectTransform(RectTransform rectTransform)
+        {
+            if (copiedData == null)
+            {
+                Debug.LogWarning("No RectTransform data to paste!");
+                return;
+            }
+
+            Undo.RecordObject(rectTransform, "Paste RectTransform");
+
+            copiedData.ApplyTo(rectTransform);
+            Debug.Log("RectTransform pasted!");
+
+            EditorUtility.SetDirty(rectTransform);
+        }
+
+        private class RectTransformData
+        {
+            public Vector2 anchorMin;
+            public Vector2 anchorMax;
+            public Vector2 anchoredPosition;
+            public Vector2 sizeDelta;
+            public Vector2 pivot;
+            public Quaternion rotation;
+
+            public RectTransformData(RectTransform rectTransform)
+            {
+                anchorMin = rectTransform.anchorMin;
+                anchorMax = rectTransform.anchorMax;
+                anchoredPosition = rectTransform.anchoredPosition;
+                sizeDelta = rectTransform.sizeDelta;
+                pivot = rectTransform.pivot;
+                rotation = rectTransform.rotation;
+            }
+
+            public void ApplyTo(RectTransform rectTransform)
+            {
+                rectTransform.anchorMin = anchorMin;
+                rectTransform.anchorMax = anchorMax;
+                rectTransform.anchoredPosition = anchoredPosition;
+                rectTransform.sizeDelta = sizeDelta;
+                rectTransform.pivot = pivot;
+                rectTransform.rotation = rotation;
+            }
+        }
+    }
+}
+#endif
diff --git a/Assets/Scripts/Editor/CustomInspector/CustomRectTransformInspector.cs b/Assets/Scripts/Editor/CustomInspector/CustomRectTransformInspector.cs
new file mode 100644
index 0000000..02c51af
--- /dev/null
+++ b/Assets/Scripts/Editor/CustomInspector/CustomRectTransformInspector.cs
@@ -0,0 +1,294 @@
+// source https://gist.github.com/GieziJo/f80bcb24c4caa68ebfb204148ccd4b18
+// ===============================
+// AUTHOR          : J. Giezendanner
+// CREATE DATE     : 12.03.2020
+// MODIFIED DATE   : 
+// PURPOSE         : Adds helper functions to the RectTransform to align the rect to the anchors and vise-versa
+// SPECIAL NOTES   : Sources for certain informations:
+//                   Display anchors gizmos:
+//                   https://forum.unity.com/threads/recttransform-custom-editor-ontop-of-unity-recttransform-custom-editor.455925/
+//                   Draw default inspector:
+//                   https://forum.unity.com/threads/extending-instead-of-replacing-built-in-inspectors.407612/
+// ===============================
+// Change History:
+//==================================
+
+#if UNITY_EDITOR
+using System;
+using System.Reflection;
+using UnityEditor.SceneManagement;
+using UnityEngine;
+
+
+namespace UnityEditor
+{
+    [CustomEditor(typeof(RectTransform), true)]
+    [CanEditMultipleObjects]
+    public class CustomRectTransformInspector : Editor
+    {
+        //Unity's built-in editor
+        Editor defaultEditor = null;
+        RectTransform rectTransform;
+
+        bool rect2Anchors_foldout = false;
+        bool anchors2Rect_foldout = false;
+        bool rect2Anchors__previousState = false;
+        bool anchors2Rect_previousState = false;
+
+        private bool playerPrefsChecked = false;
+
+        void OnEnable()
+        {
+            //When this inspector is created, also create the built-in inspector
+            defaultEditor = Editor.CreateEditor(targets, Type.GetType("UnityEditor.RectTransformEditor, UnityEditor"));
+            rectTransform = target as RectTransform;
+        }
+
+        void OnDisable()
+        {
+            //When OnDisable is called, the default editor we created should be destroyed to avoid memory leakage.
+            //Also, make sure to call any required methods like OnDisable
+
+            if (defaultEditor != null)
+            {
+                MethodInfo disableMethod = defaultEditor.GetType().GetMethod("OnDisable",
+                    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+                if (disableMethod != null)
+                    disableMethod.Invoke(defaultEditor, null);
+                DestroyImmediate(defaultEditor);
+            }
+        }
+
+        void checkPlayerPrefs()
+        {
+            rect2Anchors_foldout = PlayerPrefs.GetInt("giezi_tools_rect2Anchors_foldout_bool", 0) != 0;
+            anchors2Rect_foldout = PlayerPrefs.GetInt("giezi_tools_anchors2Rect_foldout_bool", 0) != 0;
+
+            rect2Anchors__previousState = rect2Anchors_foldout;
+            anchors2Rect_previousState = anchors2Rect_foldout;
+        }
+
+
+        public override void OnInspectorGUI()
+        {
+            if (!playerPrefsChecked)
+            {
+                checkPlayerPrefs();
+                playerPrefsChecked = true;
+            }
+
+            defaultEditor.OnInspectorGUI();
+
+
+            if (rectTransform.parent != null)
+            {
+                var centerButtonStyle = new GUIStyle(GUI.skin.button);
+                centerButtonStyle.fontStyle = FontStyle.Bold;
+
+                EditorGUILayout.Space();
+                EditorGUILayout.LabelField("Helper Functions", EditorStyles.boldLabel);
+
+                rect2Anchors_foldout = EditorGUILayout.Foldout(rect2Anchors_foldout, "Set Rect to Anchors");
+
+                if (rect2Anchors_foldout)
+                {
+                    GUILayout.BeginHorizontal();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top Left"))
+                        setRectValue("topLeft");
+                    if (GUILayout.Button("Left"))
+                        setRectValue("left");
+                    if (GUILayout.Button("Bottom Left"))
+                        setRectValue("bottomLeft");
+                    GUILayout.EndVertical();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top"))
+                        setRectValue("top");
+                    if (GUILayout.Button("All", centerButtonStyle))
+                        setRectValue("all");
+                    if (GUILayout.Button("Bottom"))
+                        setRectValue("bottom");
+                    GUILayout.EndVertical();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top Right"))
+                        setRectValue("topRight");
+                    if (GUILayout.Button("Right"))
+                        setRectValue("right");
+                    if (GUILayout.Button("Bottom Right"))
+                        setRectValue("bottomRight");
+                    GUILayout.EndVertical();
+                    GUILayout.EndHorizontal();
+                }
+
+                anchors2Rect_foldout = EditorGUILayout.Foldout(anchors2Rect_foldout, "Set Anchors to Rect");
+
+                if (anchors2Rect_foldout)
+                {
+                    GUILayout.BeginHorizontal();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top Left"))
+                        setAnchorsToRect("topLeft");
+                    if (GUILayout.Button("Left"))
+                        setAnchorsToRect("left");
+                    if (GUILayout.Button("Bottom Left"))
+                        setAnchorsToRect("bottomLeft");
+                    GUILayout.EndVertical();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top"))
+                        setAnchorsToRect("top");
+                    if (GUILayout.Button("All", centerButtonStyle))
+                        setAnchorsToRect("all");
+                    if (GUILayout.Button("Bottom"))
+                        setAnchorsToRect("bottom");
+                    GUILayout.EndVertical();
+                    GUILayout.BeginVertical();
+                    if (GUILayout.Button("Top Right"))
+                        setAnchorsToRect("topRight");
+                    if (GUILayout.Button("Right"))
+                        setAnchorsToRect("right");
+                    if (GUILayout.Button("Bottom Right"))
+                        setAnchorsToRect("bottomRight");
+                    GUILayout.EndVertical();
+                    GUILayout.EndHorizontal();
+                }
+
+
+                if (rect2Anchors_foldout != rect2Anchors__previousState)
+                {
+                    rect2Anchors__previousState = rect2Anchors_foldout;
+                    PlayerPrefs.SetInt("giezi_tools_rect2Anchors_foldout_bool", rect2Anchors_foldout ? 1 : 0);
+                }
+
+                if (anchors2Rect_foldout != anchors2Rect_previousState)
+                {
+                    anchors2Rect_previousState = anchors2Rect_foldout;
+                    PlayerPrefs.SetInt("giezi_tools_anchors2Rect_foldout_bool", anchors2Rect_foldout ? 1 : 0);
+                }
+            }
+        }
+
+
+        private void OnSceneGUI()
+        {
+            MethodInfo onSceneGUI_Method = defaultEditor.GetType()
+                .GetMethod("OnSceneGUI", BindingFlags.NonPublic | BindingFlags.Instance);
+            onSceneGUI_Method.Invoke(defaultEditor, null);
+        }
+
+
+        private void setAnchorsToRect(string field)
+        {
+            Vector2 anchorMax = new Vector2();
+            Vector2 anchorMin = new Vector2();
+            var parent = rectTransform.parent;
+            anchorMin.x = rectTransform.offsetMin.x / parent.GetComponent<RectTransform>().rect.size.x;
+            anchorMin.y = rectTransform.offsetMin.y / parent.GetComponent<RectTransform>().rect.size.y;
+            anchorMax.x = rectTransform.offsetMax.x / parent.GetComponent<RectTransform>().rect.size.x;
+            anchorMax.y = rectTransform.offsetMax.y / parent.GetComponent<RectTransform>().rect.size.y;
+
+
+            switch (field)
+            {
+                case "topLeft":
+                    anchorMax.x = 0;
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x, 0);
+
+                    anchorMin.y = 0;
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = new Vector2(0, rectTransform.offsetMin.y);
+                    break;
+                case "top":
+                    anchorMax.x = 0;
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x, 0);
+                    break;
+                case "topRight":
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.offsetMax = Vector2.zero;
+                    break;
+                case "bottomLeft":
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = Vector2.zero;
+                    break;
+                case "bottom":
+                    anchorMin.x = 0;
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = new Vector2(rectTransform.offsetMin.x, 0);
+                    break;
+                case "bottomRight":
+                    anchorMin.x = 0;
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = new Vector2(rectTransform.offsetMin.x, 0);
+                    anchorMax.y = 0;
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.offsetMax = new Vector2(0, rectTransform.offsetMax.y);
+                    break;
+                case "left":
+                    anchorMin.y = 0;
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = new Vector2(0, rectTransform.offsetMin.y);
+                    break;
+                case "right":
+                    anchorMax.y = 0;
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.offsetMax = new Vector2(0, rectTransform.offsetMax.y);
+                    break;
+                case "all":
+                    rectTransform.anchorMax += anchorMax;
+                    rectTransform.anchorMin += anchorMin;
+                    rectTransform.offsetMin = Vector2.zero;
+                    rectTransform.offsetMax = Vector2.zero;
+                    break;
+            }
+
+            handleChange();
+        }
+
+
+        private void setRectValue(string field)
+        {
+            switch (field)
+            {
+                case "topLeft":
+                    rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x, 0);
+                    rectTransform.offsetMin = new Vector2(0, rectTransform.offsetMin.y);
+                    break;
+                case "top":
+                    rectTransform.offsetMax = new Vector2(rectTransform.offsetMax.x, 0);
+                    break;
+                case "topRight":
+                    rectTransform.offsetMax = Vector2.zero;
+                    break;
+                case "bottomLeft":
+                    rectTransform.offsetMin = Vector2.zero;
+                    break;
+                case "bottom":
+                    rectTransform.offsetMin = new Vector2(rectTransform.offsetMin.x, 0);
+                    break;
+                case "bottomRight":
+                    rectTransform.offsetMin = new Vector2(rectTransform.offsetMin.x, 0);
+                    rectTransform.offsetMax = new Vector2(0, rectTransform.offsetMax.y);
+                    break;
+                case "left":
+                    rectTransform.offsetMin = new Vector2(0, rectTransform.offsetMin.y);
+                    break;
+                case "right":
+                    rectTransform.offsetMax = new Vector2(0, rectTransform.offsetMax.y);
+                    break;
+                case "all":
+                    rectTransform.offsetMin = new Vector2(0, 0);
+                    rectTransform.offsetMax = new Vector2(0, 0);
+                    break;
+            }
+
+            handleChange();
+        }
+
+        private void handleChange()
+        {
+            EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
+        }
+    }
+}
+#endif
diff --git a/Assets/Scripts/Editor/CustomInspector/TransformEditor.cs b/Assets/Scripts/Editor/CustomInspector/TransformEditor.cs
new file mode 100644
index 0000000..152989e
--- /dev/null
+++ b/Assets/Scripts/Editor/CustomInspector/TransformEditor.cs
@@ -0,0 +1,436 @@
+// source https://gist.github.com/unitycoder/e5e6384f087639c0d9edc93aa3820468
+
+using UnityEngine;
+using UnityEditor;
+
+namespace OddTales.Framework.Core.EditorExtension
+{
+    /// <summary>
+    /// Custom inspector for Transform component. Using only DrawDefaultInspector would give different display.
+    /// Script based on Unity wiki implementation : https://wiki.unity3d.com/index.php/TransformInspector
+    /// Buttons to reset, copy, paste Transform values. 
+    /// Context menu to round/truncate values, hide/show tools.
+    /// </summary>
+    [CanEditMultipleObjects, CustomEditor(typeof(Transform))]
+    public class TransformEditor : Editor
+    {
+        private const float FIELD_WIDTH = 212.0f;
+        private const bool WIDE_MODE = true;
+
+        private const float POSITION_MAX = 100000.0f;
+
+        private static GUIContent positionGUIContent = new GUIContent(LocalString("Position"));
+        private static GUIContent rotationGUIContent = new GUIContent(LocalString("Rotation"));
+        private static GUIContent scaleGUIContent = new GUIContent(LocalString("Scale"));
+
+        private static string positionWarningText = LocalString("Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.");
+
+        private SerializedProperty positionProperty, rotationProperty, scaleProperty;
+
+        private static Vector3? positionClipboard = null;
+        private static Quaternion? rotationClipboard = null;
+        private static Vector3? scaleClipboard = null;
+
+        private const string SHOW_TOOLS_KEY = "TransformEditor_ShowTools";
+        private const string SHOW_RESET_TOOLS_KEY = "TransformEditor_ShowResetTools";
+        private const string SHOW_PASTE_TOOLS_KEY = "TransformEditor_ShowPasteTools";
+        private const string SHOW_ADVANCED_PASTE_TOOLS_KEY = "TransformEditor_ShowAdvancedPasteTools";
+        private const string SHOW_CLIPBOARD_INFORMATIONS_KEY = "TransformEditor_ShowClipboardInformations";
+        private const string SHOW_SHORTCUTS_KEY = "TransformEditor_ShowHelpbox";
+
+
+#if UNITY_2017_3_OR_NEWER
+        private static System.Reflection.MethodInfo getLocalizedStringMethod;
+#endif
+
+
+        /// <summary> Get translated Transform label </summary>
+        private static string LocalString(string text)
+        {
+#if UNITY_2017_3_OR_NEWER
+            // Since Unity 2017.3, static class LocalizationDatabase is no longer public. Need to use reflection to access it.
+            if (getLocalizedStringMethod == null)
+            {
+                System.Reflection.Assembly assembly = typeof(UnityEditor.EditorWindow).Assembly;
+                System.Type localizationDatabaseType = assembly.GetType("UnityEditor.LocalizationDatabase");
+
+                getLocalizedStringMethod = localizationDatabaseType.GetMethod("GetLocalizedString");
+            }
+
+            return (string)getLocalizedStringMethod.Invoke(null, new object[] { text });
+#else
+			return LocalizationDatabase.GetLocalizedString(text);
+#endif
+        }
+
+        public void OnEnable()
+        {
+            positionProperty = serializedObject.FindProperty("m_LocalPosition");
+            rotationProperty = serializedObject.FindProperty("m_LocalRotation");
+            scaleProperty = serializedObject.FindProperty("m_LocalScale");
+
+            // Init options
+            if (!EditorPrefs.HasKey(SHOW_TOOLS_KEY)) EditorPrefs.SetBool(SHOW_TOOLS_KEY, true);
+            if (!EditorPrefs.HasKey(SHOW_RESET_TOOLS_KEY)) EditorPrefs.SetBool(SHOW_RESET_TOOLS_KEY, true);
+            if (!EditorPrefs.HasKey(SHOW_PASTE_TOOLS_KEY)) EditorPrefs.SetBool(SHOW_PASTE_TOOLS_KEY, true);
+            if (!EditorPrefs.HasKey(SHOW_ADVANCED_PASTE_TOOLS_KEY)) EditorPrefs.SetBool(SHOW_ADVANCED_PASTE_TOOLS_KEY, true);
+            if (!EditorPrefs.HasKey(SHOW_CLIPBOARD_INFORMATIONS_KEY)) EditorPrefs.SetBool(SHOW_CLIPBOARD_INFORMATIONS_KEY, true);
+            if (!EditorPrefs.HasKey(SHOW_SHORTCUTS_KEY)) EditorPrefs.SetBool(SHOW_SHORTCUTS_KEY, true);
+        }
+
+
+        public override void OnInspectorGUI()
+        {
+            Rect beginRect = GUILayoutUtility.GetRect(0, 0);
+
+            EditorGUIUtility.wideMode = TransformEditor.WIDE_MODE;
+            EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - TransformEditor.FIELD_WIDTH; // align field to right of inspector
+
+            serializedObject.Update();
+
+            EditorGUIUtility.labelWidth = 60; // To allow float fields to expand when inspector width is increased
+
+            // Position GUI
+            EditorGUILayout.BeginHorizontal();
+            PositionPropertyField(positionProperty, positionGUIContent); // Note : Can't add generic menu if we use EditorGUILayout.PropertyField instead
+            if (EditorPrefs.GetBool(SHOW_TOOLS_KEY) && EditorPrefs.GetBool(SHOW_RESET_TOOLS_KEY))
+            {
+                if (GUILayout.Button("Reset", GUILayout.Width(50)))
+                {
+                    Undo.RecordObjects(targets, "Reset Positions");
+                    for (int i = 0; i < targets.Length; i++)
+                    {
+                        ((Transform)targets[i]).localPosition = Vector3.zero;
+                    }
+                    GUI.FocusControl(null);
+                }
+            }
+            EditorGUILayout.EndHorizontal();
+
+            // Rotation GUI
+            EditorGUILayout.BeginHorizontal();
+            RotationPropertyField(rotationProperty, rotationGUIContent); // Note : Can't add generic menu if we use EditorGUILayout.PropertyField instead
+            if (EditorPrefs.GetBool(SHOW_TOOLS_KEY) && EditorPrefs.GetBool(SHOW_RESET_TOOLS_KEY))
+            {
+                if (GUILayout.Button("Reset", GUILayout.Width(50)))
+                {
+                    Undo.RecordObjects(targets, "Reset Rotations");
+                    for (int i = 0; i < targets.Length; i++)
+                    {
+                        TransformUtils.SetInspectorRotation(((Transform)targets[i]), Vector3.zero);
+                    }
+                    GUI.FocusControl(null);
+                }
+
+            }
+            EditorGUILayout.EndHorizontal();
+
+            // Scale GUI
+            EditorGUILayout.BeginHorizontal();
+            ScalePropertyField(scaleProperty, scaleGUIContent); // Note : Can't add generic menu if we use EditorGUILayout.PropertyField instead
+            if (EditorPrefs.GetBool(SHOW_TOOLS_KEY) && EditorPrefs.GetBool(SHOW_RESET_TOOLS_KEY))
+            {
+                if (GUILayout.Button("Reset", GUILayout.Width(50)))
+                {
+                    Undo.RecordObjects(targets, "Reset Scales");
+                    for (int i = 0; i < targets.Length; i++)
+                    {
+                        ((Transform)targets[i]).localScale = Vector3.one;
+                    }
+                    GUI.FocusControl(null);
+                }
+            }
+            EditorGUILayout.EndHorizontal();
+
+
+            if (!ValidatePosition(((Transform)target).position)) EditorGUILayout.HelpBox(positionWarningText, MessageType.Warning); // Display floating-point warning message if values are too high
+
+            if (EditorPrefs.GetBool(SHOW_TOOLS_KEY))
+            {
+                // Paste Tools GUI
+                if (EditorPrefs.GetBool(SHOW_PASTE_TOOLS_KEY))
+                {
+                    GUILayout.BeginHorizontal();
+                    if (GUILayout.Button("Copy"))
+                    {
+                        positionClipboard = ((Transform)target).localPosition;
+                        rotationClipboard = ((Transform)target).localRotation;
+                        scaleClipboard = ((Transform)target).localScale;
+                    }
+
+                    if (!positionClipboard.HasValue) EditorGUI.BeginDisabledGroup(true);
+                    if (GUILayout.Button("Paste"))
+                    {
+                        Undo.RecordObjects(targets, "Paste Clipboard Values");
+                        for (int i = 0; i < targets.Length; i++)
+                        {
+                            ((Transform)targets[i]).localPosition = positionClipboard.Value;
+                            ((Transform)targets[i]).localRotation = rotationClipboard.Value;
+                            ((Transform)targets[i]).localScale = scaleClipboard.Value;
+                        }
+                        GUI.FocusControl(null);
+                    }
+                    if (!positionClipboard.HasValue) EditorGUI.EndDisabledGroup();
+                    GUILayout.EndHorizontal();
+                }
+
+                // Advanced Paste Tools GUI
+                if (EditorPrefs.GetBool(SHOW_ADVANCED_PASTE_TOOLS_KEY))
+                {
+                    GUILayout.BeginHorizontal();
+
+                    if (!positionClipboard.HasValue) EditorGUI.BeginDisabledGroup(true);
+                    if (GUILayout.Button("Paste position"))
+                    {
+                        Undo.RecordObjects(targets, "Paste Position Clipboard Value");
+                        for (int i = 0; i < targets.Length; i++)
+                        {
+                            ((Transform)targets[i]).localPosition = positionClipboard.Value;
+                        }
+                        GUI.FocusControl(null);
+                    }
+
+                    if (GUILayout.Button("Paste rotation"))
+                    {
+                        Undo.RecordObjects(targets, "Paste Rotation Clipboard Value");
+                        for (int i = 0; i < targets.Length; i++)
+                        {
+                            ((Transform)targets[i]).rotation = rotationClipboard.Value;
+                        }
+                        GUI.FocusControl(null);
+                    }
+
+                    if (GUILayout.Button("Paste scale"))
+                    {
+                        Undo.RecordObjects(targets, "Paste Scale Clipboard Value");
+                        for (int i = 0; i < targets.Length; i++)
+                        {
+                            ((Transform)targets[i]).localScale = scaleClipboard.Value;
+                        }
+                        GUI.FocusControl(null);
+                    }
+                    if (!positionClipboard.HasValue) EditorGUI.EndDisabledGroup();
+
+                    GUILayout.EndHorizontal();
+                }
+
+                // Clipboard GUI
+                if (EditorPrefs.GetBool(SHOW_CLIPBOARD_INFORMATIONS_KEY))
+                {
+                    if (positionClipboard.HasValue && rotationClipboard.HasValue && scaleClipboard.HasValue)
+                    {
+
+                        GUIStyle helpboxStyle = new GUIStyle(EditorStyles.helpBox);
+                        helpboxStyle.richText = true;
+
+                        EditorGUILayout.TextArea("Clipboard values :\n" +
+                        "Position : " + positionClipboard.Value.ToString("f2") + "\n" +
+                        "Rotation : " + rotationClipboard.Value.ToString("f2") + "\n" +
+                        "Scale : " + scaleClipboard.Value.ToString("f2"), helpboxStyle);
+                    }
+                }
+
+
+                // Shortcuts GUI - Related to InspectorShortcuts.cs https://github.com/VoxelBoy/Useful-Unity-Scripts/blob/master/InspectorShortcuts.cs
+                if (EditorPrefs.GetBool(SHOW_SHORTCUTS_KEY))
+                {
+                    EditorGUILayout.HelpBox("Inspector shortcuts :\n" +
+                    "Toggle inspector lock : Ctrl + Shift + L\n" +
+                    "Toggle inspector mode : Ctrl + Shift + D", MessageType.None);
+                }
+            }
+            Rect endRect = GUILayoutUtility.GetLastRect();
+            endRect.y += endRect.height;
+
+
+            #region Context Menu
+            Rect componentRect = new Rect(beginRect.x, beginRect.y, beginRect.width, endRect.y - beginRect.y);
+            //EditorGUI.DrawRect(componentRect, Color.green); // Debug : display GenericMenu zone
+
+            Event currentEvent = Event.current;
+
+            if (currentEvent.type == EventType.ContextClick)
+            {
+                if (componentRect.Contains(currentEvent.mousePosition))
+                {
+                    GUI.FocusControl(null);
+
+                    GenericMenu menu = new GenericMenu();
+
+                    menu.AddItem(new GUIContent("Display/Tools"), EditorPrefs.GetBool(SHOW_TOOLS_KEY), ToggleOption, SHOW_TOOLS_KEY);
+                    menu.AddSeparator("Display/");
+                    menu.AddItem(new GUIContent("Display/Reset Tools"), EditorPrefs.GetBool(SHOW_RESET_TOOLS_KEY), ToggleOption, SHOW_RESET_TOOLS_KEY);
+                    menu.AddItem(new GUIContent("Display/Paste Tools"), EditorPrefs.GetBool(SHOW_PASTE_TOOLS_KEY), ToggleOption, SHOW_PASTE_TOOLS_KEY);
+                    menu.AddItem(new GUIContent("Display/Advanced Paste Tools"), EditorPrefs.GetBool(SHOW_ADVANCED_PASTE_TOOLS_KEY), ToggleOption, SHOW_ADVANCED_PASTE_TOOLS_KEY);
+                    menu.AddItem(new GUIContent("Display/Clipboard informations"), EditorPrefs.GetBool(SHOW_CLIPBOARD_INFORMATIONS_KEY), ToggleOption, SHOW_CLIPBOARD_INFORMATIONS_KEY);
+                    menu.AddItem(new GUIContent("Display/Shortcuts informations"), EditorPrefs.GetBool(SHOW_SHORTCUTS_KEY), ToggleOption, SHOW_SHORTCUTS_KEY);
+
+                    // Round menu
+                    menu.AddItem(new GUIContent("Round/Three Decimals"), false, Round, 3);
+                    menu.AddItem(new GUIContent("Round/Two Decimals"), false, Round, 2);
+                    menu.AddItem(new GUIContent("Round/One Decimal"), false, Round, 1);
+                    menu.AddItem(new GUIContent("Round/Integer"), false, Round, 0);
+
+                    // Truncate menu
+                    menu.AddItem(new GUIContent("Truncate/Three Decimals"), false, Truncate, 3);
+                    menu.AddItem(new GUIContent("Truncate/Two Decimals"), false, Truncate, 2);
+                    menu.AddItem(new GUIContent("Truncate/One Decimal"), false, Truncate, 1);
+                    menu.AddItem(new GUIContent("Truncate/Integer"), false, Truncate, 0);
+
+                    menu.ShowAsContext();
+                    currentEvent.Use();
+                }
+            }
+            #endregion
+
+            serializedObject.ApplyModifiedProperties();
+        }
+
+
+        private bool ValidatePosition(Vector3 position)
+        {
+            if (Mathf.Abs(position.x) > POSITION_MAX) return false;
+            if (Mathf.Abs(position.y) > POSITION_MAX) return false;
+            if (Mathf.Abs(position.z) > POSITION_MAX) return false;
+            return true;
+        }
+
+        private void PositionPropertyField(SerializedProperty positionProperty, GUIContent content)
+        {
+            Transform transform = (Transform)targets[0];
+            Vector3 localPosition = transform.localPosition;
+            for (int i = 0; i < targets.Length; i++)
+            {
+                if (!localPosition.Equals(((Transform)targets[i]).localPosition))
+                {
+                    EditorGUI.showMixedValue = true;
+                    break;
+                }
+            }
+
+            EditorGUI.BeginChangeCheck();
+            Vector3 newLocalPosition = EditorGUILayout.Vector3Field(content, localPosition);
+            if (EditorGUI.EndChangeCheck())
+            {
+                Undo.RecordObjects(targets, "Position Changed");
+                for (int i = 0; i < targets.Length; i++)
+                {
+                    ((Transform)targets[i]).localPosition = newLocalPosition;
+                }
+                positionProperty.serializedObject.SetIsDifferentCacheDirty();
+            }
+            EditorGUI.showMixedValue = false;
+        }
+
+        private void RotationPropertyField(SerializedProperty rotationProperty, GUIContent content)
+        {
+            Transform transform = (Transform)targets[0];
+            Vector3 localRotation = TransformUtils.GetInspectorRotation(transform);
+
+
+            for (int i = 0; i < targets.Length; i++)
+            {
+                if (!localRotation.Equals(TransformUtils.GetInspectorRotation((Transform)targets[i])))
+                {
+                    EditorGUI.showMixedValue = true;
+                    break;
+                }
+            }
+
+            EditorGUI.BeginChangeCheck();
+            Vector3 eulerAngles = EditorGUILayout.Vector3Field(content, localRotation);
+            if (EditorGUI.EndChangeCheck())
+            {
+                Undo.RecordObjects(targets, "Rotation Changed");
+                for (int i = 0; i < targets.Length; i++)
+                {
+                    //((Transform)targets[i]).localEulerAngles = eulerAngles;
+                    TransformUtils.SetInspectorRotation(((Transform)targets[i]), eulerAngles);
+                }
+                rotationProperty.serializedObject.SetIsDifferentCacheDirty();
+            }
+            EditorGUI.showMixedValue = false;
+        }
+
+        private void ScalePropertyField(SerializedProperty scaleProperty, GUIContent content)
+        {
+            Transform transform = (Transform)targets[0];
+            Vector3 localScale = transform.localScale;
+            for (int i = 0; i < targets.Length; i++)
+            {
+                if (!localScale.Equals(((Transform)targets[i]).localScale))
+                {
+                    EditorGUI.showMixedValue = true;
+                    break;
+                }
+            }
+
+            EditorGUI.BeginChangeCheck();
+            Vector3 newLocalScale = EditorGUILayout.Vector3Field(content, localScale);
+            if (EditorGUI.EndChangeCheck())
+            {
+                Undo.RecordObjects(targets, "Scale Changed");
+                for (int i = 0; i < targets.Length; i++)
+                {
+                    ((Transform)targets[i]).localScale = newLocalScale;
+                }
+                scaleProperty.serializedObject.SetIsDifferentCacheDirty();
+            }
+            EditorGUI.showMixedValue = false;
+        }
+
+
+        #region Generic Menu Callbacks
+        private void ToggleOption(object obj)
+        {
+            EditorPrefs.SetBool(obj.ToString(), !EditorPrefs.GetBool(obj.ToString()));
+        }
+
+        /// <summary> Round all values of the Transform to a given number of decimals </summary>
+        private void Round(object objNumberOfDecimals)
+        {
+            int numberOfDecimals = (int)objNumberOfDecimals;
+
+            Undo.RecordObjects(targets, "Round to " + numberOfDecimals + " decimals");
+            for (int i = 0; i < targets.Length; i++)
+            {
+                ((Transform)targets[i]).localPosition = RoundVector(((Transform)targets[i]).localPosition, numberOfDecimals);
+                ((Transform)targets[i]).localEulerAngles = RoundVector(((Transform)targets[i]).localEulerAngles, numberOfDecimals);
+                ((Transform)targets[i]).localScale = RoundVector(((Transform)targets[i]).localScale, numberOfDecimals);
+            }
+        }
+
+        /// <summary> Round all components of a Vector3 </summary>
+        private Vector3 RoundVector(Vector3 vector, int numberOfDecimals)
+        {
+            vector.x = Mathf.Round(vector.x * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            vector.y = Mathf.Round(vector.y * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            vector.z = Mathf.Round(vector.z * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            return vector;
+        }
+
+        /// <summary> Truncate all values of the Transform to a given number of decimals </summary>
+        private void Truncate(object objNumberOfDecimals)
+        {
+            int numberOfDecimals = (int)objNumberOfDecimals;
+
+            Undo.RecordObjects(targets, "Truncate to " + numberOfDecimals + " decimals");
+            for (int i = 0; i < targets.Length; i++)
+            {
+                ((Transform)targets[i]).localPosition = TruncateVector(((Transform)targets[i]).localPosition, numberOfDecimals);
+                ((Transform)targets[i]).localEulerAngles = TruncateVector(((Transform)targets[i]).localEulerAngles, numberOfDecimals);
+                ((Transform)targets[i]).localScale = TruncateVector(((Transform)targets[i]).localScale, numberOfDecimals);
+            }
+        }
+
+        /// <summary> Truncate all components of a Vector3 </summary>
+        private Vector3 TruncateVector(Vector3 vector, int numberOfDecimals)
+        {
+            vector.x = Mathf.Floor(vector.x * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            vector.y = Mathf.Floor(vector.y * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            vector.z = Mathf.Floor(vector.z * Mathf.Pow(10.0f, (float)numberOfDecimals)) / Mathf.Pow(10.0f, (float)numberOfDecimals);
+            return vector;
+        }
+        #endregion
+    }
+}
diff --git a/Assets/Scripts/Editor/GameObject.meta b/Assets/Scripts/Editor/GameObject.meta
new file mode 100644
index 0000000..ea83061
--- /dev/null
+++ b/Assets/Scripts/Editor/GameObject.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: dda0f0ad5057e2244b9a17ccd5031e99
+folderAsset: yes
+timeCreated: 1594958191
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/GameObject/ResetTransform.cs.meta b/Assets/Scripts/Editor/GameObject/ResetTransform.cs.meta
new file mode 100644
index 0000000..0cc89a0
--- /dev/null
+++ b/Assets/Scripts/Editor/GameObject/ResetTransform.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 51c038ebd5a3e0d4b92a12f03a73b6ea
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs.meta b/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs.meta
new file mode 100644
index 0000000..d097268
--- /dev/null
+++ b/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f1bf2afb27df5364dab899f318af7f69
+timeCreated: 1594958195
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Hierarchy.meta b/Assets/Scripts/Editor/Hierarchy.meta
new file mode 100644
index 0000000..d0052a8
--- /dev/null
+++ b/Assets/Scripts/Editor/Hierarchy.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4ad868ac71006a0418c8df13616a4c3e
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Hierarchy/MoveAround.cs b/Assets/Scripts/Editor/Hierarchy/MoveAround.cs
new file mode 100644
index 0000000..1ac886c
--- /dev/null
+++ b/Assets/Scripts/Editor/Hierarchy/MoveAround.cs
@@ -0,0 +1,77 @@
+// Simple shortcuts for moving selected GameObject around in hierarchy by Factuall
+// SHIFT + CTRL + ALT +
+// W - Move it up in hierarchy
+// S - Move it down in hierarchy
+// A - Unparent it down
+// D - Parent it to next object in hierarchy
+
+using UnityEditor;
+
+namespace UnityLibrary
+{
+    public class UnparentMe
+    {
+        [MenuItem("GameObject/Unparent %#&a")]
+        static void Detach()
+        {
+            
+            if (Selection.activeGameObject != null && Selection.activeGameObject.transform.parent != null)
+            {
+                int newIndex = Selection.activeGameObject.transform.parent.GetSiblingIndex();
+                Undo.SetTransformParent(Selection.activeGameObject.transform, Selection.activeGameObject.transform.parent.parent, "unparent selection");
+                Selection.activeGameObject.transform.SetSiblingIndex(newIndex + 1);
+            }
+        }
+        [MenuItem("GameObject/ParentDown %#&d")]
+        static void ParentDown()
+        {
+            if (Selection.activeGameObject != null)
+            {
+                int parentChildCount = Selection.activeGameObject.transform.parent == null ?
+                    Selection.activeGameObject.scene.rootCount : Selection.activeGameObject.transform.parent.childCount;
+                if (Selection.activeGameObject.transform.GetSiblingIndex() == parentChildCount - 1) return;
+                if (Selection.activeGameObject.transform.parent != null)
+                {
+                    if (Selection.activeGameObject.transform.parent.childCount + 1 > Selection.activeGameObject.transform.GetSiblingIndex())
+                        Undo.SetTransformParent(Selection.activeGameObject.transform, Selection.activeGameObject.transform.parent.GetChild(Selection.activeGameObject.transform.GetSiblingIndex() + 1), "parent selection down in hierarchy");
+                    
+                }
+                else
+                {
+                    if (Selection.activeGameObject.scene.rootCount + 1 > Selection.activeGameObject.transform.GetSiblingIndex())
+                        Undo.SetTransformParent(Selection.activeGameObject.transform, Selection.activeGameObject.scene.GetRootGameObjects()[Selection.activeGameObject.transform.GetSiblingIndex() + 1].transform, "parent selection down in hierarchy");
+                }
+            }
+
+        }
+        [MenuItem("GameObject/Moveup %#&w")]
+        static void MoveUp()
+        {
+            if (Selection.activeGameObject != null)
+            {
+
+                if (Selection.activeGameObject.transform.GetSiblingIndex() != 0)
+                {
+                    Undo.RegisterCompleteObjectUndo(Selection.activeGameObject.transform, "move selction up in hierarchy");
+                    Selection.activeGameObject.transform.SetSiblingIndex(Selection.activeGameObject.transform.GetSiblingIndex() - 1);
+                }
+                
+            }
+        }
+        [MenuItem("GameObject/Movedown %#&s")]
+        static void MoveDown()
+        {
+            if (Selection.activeGameObject != null)
+            {
+                int parentChildCount = Selection.activeGameObject.transform.parent == null ?
+                    Selection.activeGameObject.scene.rootCount : Selection.activeGameObject.transform.parent.childCount;
+                if (Selection.activeGameObject.transform.GetSiblingIndex() != parentChildCount - 1)
+                {
+                    Undo.RegisterCompleteObjectUndo(Selection.activeGameObject.transform, "move selction down in hierarchy");
+                    Selection.activeGameObject.transform.SetSiblingIndex(Selection.activeGameObject.transform.GetSiblingIndex() + 1);
+                }
+
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Editor/Hierarchy/MoveAround.cs.meta b/Assets/Scripts/Editor/Hierarchy/MoveAround.cs.meta
new file mode 100644
index 0000000..41e518a
--- /dev/null
+++ b/Assets/Scripts/Editor/Hierarchy/MoveAround.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 18fe530f4fbd8b74096f07f377a4b9ff
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Hierarchy/UnparentMe.cs.meta b/Assets/Scripts/Editor/Hierarchy/UnparentMe.cs.meta
new file mode 100644
index 0000000..f0a2192
--- /dev/null
+++ b/Assets/Scripts/Editor/Hierarchy/UnparentMe.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 859aeadcffa51fe4f9cc875774621ef9
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Importers/AnimationClipListImporter.cs b/Assets/Scripts/Editor/Importers/AnimationClipListImporter.cs
new file mode 100644
index 0000000..733ac03
--- /dev/null
+++ b/Assets/Scripts/Editor/Importers/AnimationClipListImporter.cs
@@ -0,0 +1,65 @@
+// Checks for a .txt file with the same name as an imported .fbx file (in Assets/Models/ folder), containing a list of animation clips to add to the ModelImporter.
+// .txt file should be tab-delimited with the following columns: "title", "start frame", "end frame" (and optional description, not used).
+// example: 
+// Take0	10	40	asdf
+// Take1	50	80	wasdf..
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary.Importers
+{
+    public class AnimationClipListImporter : AssetPostprocessor
+    {
+        void OnPreprocessModel()
+        {
+            ModelImporter modelImporter = assetImporter as ModelImporter;
+            if (modelImporter == null) return;
+
+            string assetPath = assetImporter.assetPath;
+            if (!assetPath.StartsWith("Assets/Models") || !assetPath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase)) return;
+
+            string txtPath = Path.ChangeExtension(assetPath, ".txt");
+            if (!File.Exists(txtPath)) return;
+
+            try
+            {
+                List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>();
+                string[] lines = File.ReadAllLines(txtPath);
+
+                foreach (string line in lines)
+                {
+                    string[] parts = line.Split('\t');
+                    if (parts.Length < 3) continue; // Ensure we have at least "title, start, end"
+
+                    string title = parts[0].Trim();
+                    if (!int.TryParse(parts[1], out int startFrame) || !int.TryParse(parts[2], out int endFrame))
+                        continue;
+
+                    ModelImporterClipAnimation clip = new ModelImporterClipAnimation
+                    {
+                        name = title,
+                        firstFrame = startFrame,
+                        lastFrame = endFrame,
+                        loopTime = false
+                    };
+
+                    clips.Add(clip);
+                }
+
+                if (clips.Count > 0)
+                {
+                    modelImporter.clipAnimations = clips.ToArray();
+                    Debug.Log($"Added {clips.Count} animation clips to {assetPath}");
+                }
+            }
+            catch (Exception ex)
+            {
+                Debug.LogError($"Failed to process animation data for {assetPath}: {ex.Message}");
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Mesh.meta b/Assets/Scripts/Editor/Mesh.meta
new file mode 100644
index 0000000..bf539ea
--- /dev/null
+++ b/Assets/Scripts/Editor/Mesh.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f45eaf3f880e5c04785b1cdca6b98021
+folderAsset: yes
+timeCreated: 1594958191
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Mesh/CreatePlane.cs b/Assets/Scripts/Editor/Mesh/CreatePlane.cs
new file mode 100644
index 0000000..f2633c1
--- /dev/null
+++ b/Assets/Scripts/Editor/Mesh/CreatePlane.cs
@@ -0,0 +1,227 @@
+// editor tools to create mesh plane with adjustable resolution
+// original : http://wiki.unity3d.com/index.php?title=CreatePlane#C.23_-_CreatePlane.cs
+
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+
+namespace UnityLibrary
+{
+  public class CreatePlane : ScriptableWizard
+  {
+
+    public enum Orientation
+    {
+      Horizontal,
+      Vertical
+    }
+
+    public enum AnchorPoint
+    {
+      TopLeft,
+      TopHalf,
+      TopRight,
+      RightHalf,
+      BottomRight,
+      BottomHalf,
+      BottomLeft,
+      LeftHalf,
+      Center
+    }
+
+    public int widthSegments = 1;
+    public int lengthSegments = 1;
+    public float width = 1.0f;
+    public float length = 1.0f;
+    public Orientation orientation = Orientation.Horizontal;
+    public AnchorPoint anchor = AnchorPoint.Center;
+    public bool addCollider = false;
+    public bool createAtOrigin = true;
+    public bool flipYZ = false;
+    public bool twoSided = false;
+    public string optionalName;
+
+    static Camera cam;
+    static Camera lastUsedCam;
+
+
+    [MenuItem("GameObject/Create Other/Custom Plane...")]
+    static void CreateWizard()
+    {
+      cam = Camera.current;
+      // Hack because camera.current doesn't return editor camera if scene view doesn't have focus
+      if (!cam)
+        cam = lastUsedCam;
+      else
+        lastUsedCam = cam;
+      ScriptableWizard.DisplayWizard("Create Plane",typeof(CreatePlane));
+    }
+
+
+    void OnWizardUpdate()
+    {
+      widthSegments = Mathf.Clamp(widthSegments, 1, 254);
+      lengthSegments = Mathf.Clamp(lengthSegments, 1, 254);
+    }
+
+
+    void OnWizardCreate()
+    {
+      GameObject plane = new GameObject();
+
+      if (!string.IsNullOrEmpty(optionalName))
+        plane.name = optionalName;
+      else
+        plane.name = "Plane";
+
+      if (!createAtOrigin && cam)
+        plane.transform.position = cam.transform.position + cam.transform.forward*5.0f;
+      else
+        plane.transform.position = Vector3.zero;
+
+      Vector2 anchorOffset;
+      string anchorId;
+      switch (anchor)
+      {
+      case AnchorPoint.TopLeft:
+        anchorOffset = new Vector2(-width/2.0f,length/2.0f);
+        anchorId = "TL";
+        break;
+      case AnchorPoint.TopHalf:
+        anchorOffset = new Vector2(0.0f,length/2.0f);
+        anchorId = "TH";
+        break;
+      case AnchorPoint.TopRight:
+        anchorOffset = new Vector2(width/2.0f,length/2.0f);
+        anchorId = "TR";
+        break;
+      case AnchorPoint.RightHalf:
+        anchorOffset = new Vector2(width/2.0f,0.0f);
+        anchorId = "RH";
+        break;
+      case AnchorPoint.BottomRight:
+        anchorOffset = new Vector2(width/2.0f,-length/2.0f);
+        anchorId = "BR";
+        break;
+      case AnchorPoint.BottomHalf:
+        anchorOffset = new Vector2(0.0f,-length/2.0f);
+        anchorId = "BH";
+        break;
+      case AnchorPoint.BottomLeft:
+        anchorOffset = new Vector2(-width/2.0f,-length/2.0f);
+        anchorId = "BL";
+        break;			
+      case AnchorPoint.LeftHalf:
+        anchorOffset = new Vector2(-width/2.0f,0.0f);
+        anchorId = "LH";
+        break;			
+      case AnchorPoint.Center:
+      default:
+        anchorOffset = Vector2.zero;
+        anchorId = "C";
+        break;
+      }
+
+      MeshFilter meshFilter = (MeshFilter)plane.AddComponent(typeof(MeshFilter));
+      plane.AddComponent(typeof(MeshRenderer));
+
+      string planeAssetName = plane.name + widthSegments + "x" + lengthSegments + "W" + width + "L" + length + (orientation == Orientation.Horizontal? "H" : "V") + anchorId + ".asset";
+      Mesh m = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/Editor/" + planeAssetName,typeof(Mesh));
+
+      if (m == null)
+      {
+        m = new Mesh();
+        m.name = plane.name;
+
+        int hCount2 = widthSegments+1;
+        int vCount2 = lengthSegments+1;
+        int numTriangles = widthSegments * lengthSegments * 6;
+        if (twoSided) {
+          numTriangles *= 2;
+        }
+        int numVertices = hCount2 * vCount2;
+
+        Vector3[] vertices = new Vector3[numVertices];
+        Vector2[] uvs = new Vector2[numVertices];
+        int[] triangles = new int[numTriangles];
+
+        int index = 0;
+        float uvFactorX = 1.0f/widthSegments;
+        float uvFactorY = 1.0f/lengthSegments;
+        float scaleX = width/widthSegments;
+        float scaleY = length/lengthSegments;
+        for (float y = 0.0f; y < vCount2; y++)
+        {
+          for (float x = 0.0f; x < hCount2; x++)
+          {
+            if (orientation == Orientation.Horizontal)
+            {
+              if (flipYZ)
+              {
+                vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, y*scaleY - length/2f - anchorOffset.y, 0.0f);
+              }else{
+                vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, 0.0f, y*scaleY - length/2f - anchorOffset.y);
+              }
+            }
+            else
+            {
+              if (flipYZ)
+              {
+                vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, 0.0f, y*scaleY - length/2f - anchorOffset.y);
+              }else{
+                vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, y*scaleY - length/2f - anchorOffset.y, 0.0f);
+              }
+            }
+            uvs[index++] = new Vector2(x*uvFactorX, y*uvFactorY);
+          }
+        }
+
+        index = 0;
+        for (int y = 0; y < lengthSegments; y++)
+        {
+          for (int x = 0; x < widthSegments; x++)
+          {
+            triangles[index]   = (y     * hCount2) + x;
+            triangles[index+1] = ((y+1) * hCount2) + x;
+            triangles[index+2] = (y     * hCount2) + x + 1;
+
+            triangles[index+3] = ((y+1) * hCount2) + x;
+            triangles[index+4] = ((y+1) * hCount2) + x + 1;
+            triangles[index+5] = (y     * hCount2) + x + 1;
+            index += 6;
+          }
+          if (twoSided) {
+            // Same tri vertices with order reversed, so normals point in the opposite direction
+            for (int x = 0; x < widthSegments; x++)
+            {
+              triangles[index]   = (y     * hCount2) + x;
+              triangles[index+1] = (y     * hCount2) + x + 1;
+              triangles[index+2] = ((y+1) * hCount2) + x;
+
+              triangles[index+3] = ((y+1) * hCount2) + x;
+              triangles[index+4] = (y     * hCount2) + x + 1;
+              triangles[index+5] = ((y+1) * hCount2) + x + 1;
+              index += 6;
+            }
+          }
+        }
+
+        m.vertices = vertices;
+        m.uv = uvs;
+        m.triangles = triangles;
+        m.RecalculateNormals();
+
+        AssetDatabase.CreateAsset(m, "Assets/Editor/" + planeAssetName);
+        AssetDatabase.SaveAssets();
+      }
+
+      meshFilter.sharedMesh = m;
+      m.RecalculateBounds();
+
+      if (addCollider)
+        plane.AddComponent(typeof(BoxCollider));
+
+      Selection.activeObject = plane;
+    }
+  }
+ }
diff --git a/Assets/Scripts/Editor/Mesh/CreatePlane.cs.meta b/Assets/Scripts/Editor/Mesh/CreatePlane.cs.meta
new file mode 100644
index 0000000..e2ec4a4
--- /dev/null
+++ b/Assets/Scripts/Editor/Mesh/CreatePlane.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d1cea26cb1deacf48b0dd190be08a597
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs b/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs
new file mode 100644
index 0000000..5406c35
--- /dev/null
+++ b/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs
@@ -0,0 +1,127 @@
+// from https://forum.unity.com/threads/mesh-combine-wizard-free-unity-tool-source-code.444483/#post-5575042
+
+using UnityEngine;
+using UnityEditor;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace UnityLibrary
+{
+  public class MeshCombineWizard : ScriptableWizard
+  {
+      public GameObject parentOfObjectsToCombine;
+
+      [MenuItem("E.S. Tools/Mesh Combine Wizard")]
+      static void CreateWizard()
+      {
+          ScriptableWizard.DisplayWizard<MeshCombineWizard>("Mesh Combine Wizard");
+      }
+
+      void OnWizardCreate()
+      {
+          if (parentOfObjectsToCombine == null) return;
+
+          Vector3 originalPosition = parentOfObjectsToCombine.transform.position;
+          parentOfObjectsToCombine.transform.position = Vector3.zero;
+
+          MeshFilter[] meshFilters = parentOfObjectsToCombine.GetComponentsInChildren<MeshFilter>();
+          Dictionary<Material, List<MeshFilter>> materialToMeshFilterList = new Dictionary<Material, List<MeshFilter>>();
+          List<GameObject> combinedObjects = new List<GameObject>();
+
+          for (int i = 0; i < meshFilters.Length; i++)
+          {
+              var materials = meshFilters[i].GetComponent<MeshRenderer>().sharedMaterials;
+              if (materials == null) continue;
+              if (materials.Length > 1)
+              {
+                  parentOfObjectsToCombine.transform.position = originalPosition;
+                  Debug.LogError("Objects with multiple materials on the same mesh are not supported. Create multiple meshes from this object's sub-meshes in an external 3D tool and assign separate materials to each.");
+                  return;
+              }
+              var material = materials[0];
+              if (materialToMeshFilterList.ContainsKey(material)) materialToMeshFilterList[material].Add(meshFilters[i]);
+              else materialToMeshFilterList.Add(material, new List<MeshFilter>() { meshFilters[i] });
+          }
+
+
+          // NC 03/2020 changes the loop to create meshes smaller than 695536 vertices
+          foreach (var entry in materialToMeshFilterList)
+          {
+              // get list of each meshes order by number of vertices
+              List<MeshFilter> meshesWithSameMaterial = entry.Value.OrderByDescending(mf => mf.sharedMesh.vertexCount).ToList();
+              // split into bins of 65536 vertices max
+              int nrMeshes = meshesWithSameMaterial.Count;
+              while (nrMeshes > 0)
+              {
+                  string materialName = entry.Key.ToString().Split(' ')[0];
+                  List<MeshFilter> meshBin = new List<MeshFilter>();
+                  meshBin.Add(meshesWithSameMaterial[0]);
+                  meshesWithSameMaterial.RemoveAt(0);
+                  nrMeshes--;
+                  // add meshes in bin until 65536 vertices is reached
+                  for (int i = 0; i < meshesWithSameMaterial.Count; i++)
+                  {
+                      if (meshBin.Sum(mf => mf.sharedMesh.vertexCount) + meshesWithSameMaterial[i].sharedMesh.vertexCount < 65536)
+                      {
+                          meshBin.Add(meshesWithSameMaterial[i]);
+                          meshesWithSameMaterial.RemoveAt(i);
+                          i--;
+                          nrMeshes--;
+                      }
+                  }
+
+                  // merge this bin
+                  CombineInstance[] combine = new CombineInstance[meshBin.Count];
+                  for (int i = 0; i < meshBin.Count; i++)
+                  {
+                      combine[i].mesh = meshBin[i].sharedMesh;
+                      combine[i].transform = meshBin[i].transform.localToWorldMatrix;
+                  }
+                  Mesh combinedMesh = new Mesh();
+                  combinedMesh.CombineMeshes(combine);
+
+                  // save the mesh
+                  materialName += "_" + combinedMesh.GetInstanceID();
+                  if (meshBin.Count > 1)
+                  {
+                      AssetDatabase.CreateAsset(combinedMesh, "Assets/CombinedMeshes_" + materialName + ".asset"); ;
+                  }
+
+                  // assign the mesh to a new go
+                  string goName = (materialToMeshFilterList.Count > 1) ? "CombinedMeshes_" + materialName : "CombinedMeshes_" + parentOfObjectsToCombine.name;
+                  GameObject combinedObject = new GameObject(goName);
+                  var filter = combinedObject.AddComponent<MeshFilter>();
+                  if (meshBin.Count > 1)
+                  {
+                      filter.sharedMesh = combinedMesh;
+                  }
+                  else
+                  {
+                      filter.sharedMesh = meshBin[0].sharedMesh; // the original mesh
+                  }
+                  var renderer = combinedObject.AddComponent<MeshRenderer>();
+                  renderer.sharedMaterial = entry.Key;
+                  combinedObjects.Add(combinedObject);
+              }
+          }
+
+          GameObject resultGO = null;
+          if (combinedObjects.Count > 1)
+          {
+              resultGO = new GameObject("CombinedMeshes_" + parentOfObjectsToCombine.name);
+              foreach (var combinedObject in combinedObjects) combinedObject.transform.parent = resultGO.transform;
+          }
+          else
+          {
+              resultGO = combinedObjects[0];
+          }
+
+          Object prefab = PrefabUtility.CreateEmptyPrefab("Assets/" + resultGO.name + ".prefab");
+          PrefabUtility.ReplacePrefab(resultGO, prefab, ReplacePrefabOptions.ConnectToPrefab);
+
+          parentOfObjectsToCombine.SetActive(false);
+          parentOfObjectsToCombine.transform.position = originalPosition;
+          resultGO.transform.position = originalPosition;
+      }
+  }
+}
diff --git a/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs.meta b/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs.meta
new file mode 100644
index 0000000..69ac2e2
--- /dev/null
+++ b/Assets/Scripts/Editor/Mesh/MeshCombineWizard.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 72fbe9dd2dbf0f845ab4d30da0d8b27c
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs.meta b/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs.meta
new file mode 100644
index 0000000..d8f24d1
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 333163797deb57f4a8d7373ac970d9bf
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/CompileTime.cs b/Assets/Scripts/Editor/Tools/CompileTime.cs
new file mode 100644
index 0000000..89721bc
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/CompileTime.cs
@@ -0,0 +1,201 @@
+// compile time tracking tool (and quickly enable disable settings, and scene autosave option)
+// original source: https://gist.github.com/spajus/72a74146b1bbeddd44a66e1b8a3c829c
+// created by https://github.com/spajus twitch https://www.twitch.tv/dev_spajus
+// 02.07.2020 added unity_2018_4 check and set autosave off by default - unitycoder.com
+
+using System;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEditor.Compilation;
+using UnityEditor.SceneManagement;
+using UnityEngine;
+
+namespace UnityLibrary
+{
+    class CompileTime : EditorWindow
+    {
+        bool allowProfiler = false;
+        bool isTrackingTime;
+        bool isLockReload;
+        bool isAutoSave = false; // autosave default off
+        bool isLocked;
+        bool restartAfterCompile;
+        bool memoryWarned;
+        string lastReloadTime = "";
+        string lastCompileTime = "";
+        string lastAssCompileTime = "";
+        double startTime, finishTime, compileTime, reloadTime;
+        double assStartTime, assFinishTime, assCompileTime;
+        Dictionary<string, DateTime> startTimes = new Dictionary<string, DateTime>();
+        List<string> lastAssCompile;
+
+        [MenuItem("Tools/UnityLibrary/Compile Time")]
+        public static void Init()
+        {
+            EditorWindow.GetWindow(typeof(CompileTime));
+        }
+
+        void Update()
+        {
+            if (isLockReload) { return; }
+            if (EditorApplication.isCompiling && !isTrackingTime)
+            {
+                if (EditorApplication.isPlaying)
+                {
+                    restartAfterCompile = true;
+                    EditorApplication.isPlaying = false;
+                }
+                startTime = EditorApplication.timeSinceStartup;
+                lastReloadTime = "Reloading now";
+                lastCompileTime = "Compiling now";
+                lastAssCompile = new List<string>();
+                Debug.Log("Started compiling scripts");
+                isTrackingTime = true;
+            }
+            else if (!EditorApplication.isCompiling && isTrackingTime)
+            {
+                finishTime = EditorApplication.timeSinceStartup;
+                isTrackingTime = false;
+                EditorApplication.Beep();
+                reloadTime = finishTime - startTime;
+                lastReloadTime = reloadTime.ToString("0.000") + "s";
+                compileTime = reloadTime - assCompileTime;
+                lastCompileTime = compileTime.ToString("0.000") + "s";
+                if (isAutoSave && !EditorApplication.isPlaying)
+                {
+                    Debug.Log("Auto Saving Scene");
+                    EditorSceneManager.SaveOpenScenes();
+                }
+                if (restartAfterCompile)
+                {
+                    restartAfterCompile = false;
+                    EditorApplication.isPlaying = true;
+                }
+            }
+        }
+
+        void OnGUI()
+        {
+#if UNITY_2018_4_OR_NEWER
+        // Toggle domain reload
+        var playModeOptsEnabled = EditorSettings.enterPlayModeOptionsEnabled;
+        playModeOptsEnabled = EditorGUILayout.Toggle("Disable Domain Reload", playModeOptsEnabled);
+        EditorSettings.enterPlayModeOptionsEnabled = playModeOptsEnabled;
+#endif
+
+            if (UnityEngine.Profiling.Profiler.enabled)
+            {
+                EditorGUILayout.LabelField("PROFILER ENABLED");
+            }
+            allowProfiler = EditorGUILayout.Toggle("Allow profiler", allowProfiler);
+            if (!allowProfiler && UnityEngine.Profiling.Profiler.enabled)
+            {
+                UnityEngine.Profiling.Profiler.enabled = false;
+            }
+            EditorGUILayout.LabelField("Time", Time.realtimeSinceStartup.ToString());
+            float m1 = (UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong() / 1024f / 1024f);
+            float m2 = (UnityEngine.Profiling.Profiler.GetAllocatedMemoryForGraphicsDriver() / 1024f / 1024f);
+            float m3 = (UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong() / 1024f / 1024f);
+            float m = m1 + m2 + m3;
+            if (m > 10000 && !memoryWarned)
+            {
+                memoryWarned = true;
+                EditorApplication.Beep();
+                Debug.LogError("Memory over 10000MB!");
+                allowProfiler = false;
+                UnityEngine.Profiling.Profiler.enabled = false;
+            }
+            if (m < 8000 && memoryWarned)
+            {
+                memoryWarned = false;
+            }
+            EditorGUILayout.LabelField("Memory used:", m.ToString("0.00") + " MB");
+
+            isLockReload = EditorGUILayout.Toggle("Lock assembly reload", isLockReload);
+            isAutoSave = EditorGUILayout.Toggle("Auto Save", isAutoSave);
+            EditorGUILayout.LabelField("Full reload", lastReloadTime);
+            EditorGUILayout.LabelField("Compile", lastCompileTime);
+            if (lastAssCompileTime != null)
+            {
+                EditorGUILayout.LabelField("Assembly reload", lastAssCompileTime);
+            }
+            // For mysterious reason, iterating over a dictionary doesn't work, it gets empty!
+            if (lastAssCompile != null)
+            {
+                foreach (string s in lastAssCompile)
+                {
+                    var ss = s.Split(':');
+                    EditorGUILayout.LabelField(ss[0], ss[1]);
+                }
+            }
+
+            if (isLockReload)
+            {
+                if (!isLocked)
+                {
+                    Debug.Log("Locking reload of assemblies");
+                    EditorApplication.LockReloadAssemblies();
+                    isLocked = true;
+                }
+            }
+            else
+            {
+                if (isLocked)
+                {
+                    Debug.Log("Unlocking reload of assemblies");
+                    EditorApplication.UnlockReloadAssemblies();
+                    isLocked = false;
+                }
+            }
+        }
+
+        void OnBeforeAssemblyReload()
+        {
+            assStartTime = EditorApplication.timeSinceStartup;
+            this.ShowNotification(new GUIContent("Started assembly reload"));
+        }
+
+        void OnAfterAssemblyReload()
+        {
+            assFinishTime = EditorApplication.timeSinceStartup;
+            assCompileTime = assFinishTime - assStartTime;
+            lastAssCompileTime = assCompileTime.ToString("0.000") + "s";
+        }
+
+        void CompilationPipelineOnAssemblyCompilationStarted(string assembly)
+        {
+            Debug.Log("Assembly compile started: " + assembly);
+            startTimes[assembly] = DateTime.UtcNow;
+        }
+
+        void CompilationPipelineOnAssemblyCompilationFinished(string assembly, CompilerMessage[] arg2)
+        {
+            var time = startTimes[assembly];
+            var timeSpan = DateTime.UtcNow - startTimes[assembly];
+            var bt = string.Format("{0:0.00}s", timeSpan.TotalMilliseconds / 1000f);
+            var cleanAss = assembly.Replace("Library/ScriptAssemblies/", "");
+
+            if (lastAssCompile != null)
+            {
+                lastAssCompile.Add(cleanAss + ":" + bt);
+            }
+            Debug.Log("Assembly compile ended: " + assembly + " in " + bt);
+        }
+
+        void OnEnable()
+        {
+            AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
+            AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
+            CompilationPipeline.assemblyCompilationStarted += CompilationPipelineOnAssemblyCompilationStarted;
+            CompilationPipeline.assemblyCompilationFinished += CompilationPipelineOnAssemblyCompilationFinished;
+        }
+
+        void OnDisable()
+        {
+            AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
+            AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload;
+            CompilationPipeline.assemblyCompilationStarted -= CompilationPipelineOnAssemblyCompilationStarted;
+            CompilationPipeline.assemblyCompilationFinished -= CompilationPipelineOnAssemblyCompilationFinished;
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/CompileTime.cs.meta b/Assets/Scripts/Editor/Tools/CompileTime.cs.meta
new file mode 100644
index 0000000..30a9f44
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/CompileTime.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a15be7d1f359a614fb4f298da7a5fa9e
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/FindWhatButtonCallsMyMethod.cs b/Assets/Scripts/Editor/Tools/FindWhatButtonCallsMyMethod.cs
new file mode 100644
index 0000000..e67f45b
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/FindWhatButtonCallsMyMethod.cs
@@ -0,0 +1,69 @@
+// prints out which buttons in current scene are referencing your given method
+
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEditor;
+using UnityEngine.Events;
+using System.Reflection;
+
+namespace UnityLibrary
+{
+    public class FindWhatButtonCallsMyMethod : EditorWindow
+    {
+        private string methodName = "MyMethodHere";
+
+        [MenuItem("Tools/Find Buttons with Method")]
+        public static void ShowWindow()
+        {
+            GetWindow<FindWhatButtonCallsMyMethod>("FindWhatButtonCallsMyMethod");
+        }
+
+        private void OnGUI()
+        {
+            GUILayout.Label("Find Buttons that call Method", EditorStyles.boldLabel);
+            methodName = EditorGUILayout.TextField("Method Name:", methodName);
+
+            if (GUILayout.Button("Find Buttons"))
+            {
+                FindButtonsWithMethod();
+            }
+        }
+
+        private void FindButtonsWithMethod()
+        {
+            Button[] allButtons = FindObjectsOfType<Button>();
+
+            foreach (var button in allButtons)
+            {
+                UnityEvent clickEvent = button.onClick;
+
+                for (int i = 0; i < clickEvent.GetPersistentEventCount(); i++)
+                {
+                    Object target = clickEvent.GetPersistentTarget(i);
+                    string method = clickEvent.GetPersistentMethodName(i);
+
+                    if (method == methodName)
+                    {
+                        MethodInfo methodInfo = target.GetType().GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+                        if (methodInfo != null)
+                        {
+                            ParameterInfo[] parameters = methodInfo.GetParameters();
+
+                            // Check if the method has arguments
+                            if (parameters.Length > 0)
+                            {
+                                Debug.Log($"Button '{button.gameObject.name}' calls method '{methodName}' with parameters on object '{target.name}'", button.gameObject);
+                            }
+                            else
+                            {
+                                Debug.Log($"Button '{button.gameObject.name}' calls method '{methodName}' with no parameters on object '{target.name}'", button.gameObject);
+                            }
+                        }
+                    }
+                }
+            }
+
+            Debug.Log("Search Complete");
+        }
+    } // class
+} // namespace
diff --git a/Assets/Scripts/Editor/Tools/FindWhoReferencesThisGameObject.cs b/Assets/Scripts/Editor/Tools/FindWhoReferencesThisGameObject.cs
new file mode 100644
index 0000000..dd5b2c5
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/FindWhoReferencesThisGameObject.cs
@@ -0,0 +1,123 @@
+// find what scripts reference selected GameObject in the scene (in events, public fields..)
+
+using System.Collections.Generic;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Events;
+
+namespace UnityLibrary.Editor
+{
+    public class FindWhoReferencesThisGameObject : EditorWindow
+    {
+        private GameObject target;
+        private Vector2 scroll;
+
+        private class ReferenceResult
+        {
+            public string message;
+            public GameObject owner;
+        }
+
+        private List<ReferenceResult> results = new List<ReferenceResult>();
+
+        [MenuItem("Tools/UnityLibrary/Find References To GameObject")]
+        public static void ShowWindow()
+        {
+            var win = GetWindow<FindWhoReferencesThisGameObject>("Find References");
+            win.minSize = new Vector2(500, 300);
+        }
+
+        private void OnGUI()
+        {
+            GUILayout.Label("Find scripts that reference this GameObject", EditorStyles.boldLabel);
+            target = EditorGUILayout.ObjectField("Target GameObject", target, typeof(GameObject), true) as GameObject;
+
+            if (GUILayout.Button("Find References"))
+            {
+                results.Clear();
+                if (target != null)
+                {
+                    FindReferences(target);
+                }
+                else
+                {
+                    Debug.LogWarning("Please assign a GameObject.");
+                }
+            }
+
+            if (results.Count > 0)
+            {
+                GUILayout.Label("Results:", EditorStyles.boldLabel);
+                scroll = GUILayout.BeginScrollView(scroll, GUILayout.Height(400));
+                foreach (var res in results)
+                {
+                    if (GUILayout.Button(res.message, GUILayout.ExpandWidth(true)))
+                    {
+                        EditorGUIUtility.PingObject(res.owner);
+                        Selection.activeGameObject = res.owner;
+                    }
+                }
+                GUILayout.EndScrollView();
+            }
+        }
+
+        private void FindReferences(GameObject target)
+        {
+            var allObjects = UnityEngine.Object.FindObjectsOfType<MonoBehaviour>(true);
+
+            foreach (var mono in allObjects)
+            {
+                if (mono == null || mono.gameObject == target) continue;
+
+                var type = mono.GetType();
+                var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+
+                foreach (var field in fields)
+                {
+                    if (typeof(UnityEventBase).IsAssignableFrom(field.FieldType))
+                    {
+                        var unityEvent = field.GetValue(mono) as UnityEventBase;
+                        if (unityEvent != null)
+                        {
+                            int count = unityEvent.GetPersistentEventCount();
+                            for (int i = 0; i < count; i++)
+                            {
+                                var listener = unityEvent.GetPersistentTarget(i);
+                                if (listener == target)
+                                {
+                                    results.Add(new ReferenceResult
+                                    {
+                                        message = $"{mono.name} ({type.Name}) -> UnityEvent '{field.Name}'",
+                                        owner = mono.gameObject
+                                    });
+                                }
+                            }
+                        }
+                    }
+                    else if (typeof(UnityEngine.Object).IsAssignableFrom(field.FieldType))
+                    {
+                        var value = field.GetValue(mono) as UnityEngine.Object;
+                        if (value == target)
+                        {
+                            results.Add(new ReferenceResult
+                            {
+                                message = $"{mono.name} ({type.Name}) -> Field '{field.Name}'",
+                                owner = mono.gameObject
+                            });
+                        }
+                    }
+                }
+            }
+
+            if (results.Count == 0)
+            {
+                results.Add(new ReferenceResult
+                {
+                    message = "No references found.",
+                    owner = null
+                });
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/GameViewGridOverlay.cs b/Assets/Scripts/Editor/Tools/GameViewGridOverlay.cs
new file mode 100644
index 0000000..06acb2e
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/GameViewGridOverlay.cs
@@ -0,0 +1,57 @@
+using UnityEngine;
+
+namespace UnityLibrary.EditorTools
+{
+    [ExecuteAlways]
+    public class GameViewGridOverlay : MonoBehaviour
+    {
+#if UNITY_EDITOR
+        public bool drawGrid = true;
+
+        [Header("Grid Cell Size (visible area)")]
+        public int gridSizeX = 64;
+        public int gridSizeY = 64;
+
+        [Header("Spacing Between Cells (invisible gap)")]
+        public int spacingX = 16;
+        public int spacingY = 16;
+
+        [Header("Start Offsets")]
+        public int startOffsetX = 0;
+        public int startOffsetY = 0;
+
+        public Color gridColor = new Color(1f, 1f, 1f, 0.5f);
+
+        private void OnGUI()
+        {
+            if (!drawGrid || Application.isPlaying) return;
+
+            Color oldColor = GUI.color;
+            GUI.color = gridColor;
+
+            int cellStrideX = gridSizeX + spacingX;
+            int cellStrideY = gridSizeY + spacingY;
+
+            // Loop until start of the cell is beyond screen, not end of cell
+            for (int y = startOffsetY; y < Screen.height; y += cellStrideY)
+            {
+                for (int x = startOffsetX; x < Screen.width; x += cellStrideX)
+                {
+                    // Draw full box even if it goes beyond screen edges
+
+                    // Left
+                    GUI.DrawTexture(new Rect(x, y, 1, gridSizeY), Texture2D.whiteTexture);
+                    // Right
+                    GUI.DrawTexture(new Rect(x + gridSizeX - 1, y, 1, gridSizeY), Texture2D.whiteTexture);
+                    // Top
+                    GUI.DrawTexture(new Rect(x, y, gridSizeX, 1), Texture2D.whiteTexture);
+                    // Bottom
+                    GUI.DrawTexture(new Rect(x, y + gridSizeY - 1, gridSizeX, 1), Texture2D.whiteTexture);
+                }
+            }
+
+            GUI.color = oldColor;
+        }
+#endif
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/GetSelectedMeshInfo.cs b/Assets/Scripts/Editor/Tools/GetSelectedMeshInfo.cs
index 06aba89..066da8d 100644
--- a/Assets/Scripts/Editor/Tools/GetSelectedMeshInfo.cs
+++ b/Assets/Scripts/Editor/Tools/GetSelectedMeshInfo.cs
@@ -1,5 +1,7 @@
 // display selected gameobject mesh stats (should work on prefabs,models in project window also)
 
+using System.Collections.Generic;
+using System.Linq;
 using UnityEditor;
 using UnityEngine;
 
@@ -7,6 +9,17 @@ namespace UnityLibrary
 {
     public class GetSelectedMeshInfo : EditorWindow
     {
+        bool selectionChanged = false;
+
+        int totalMeshes = 0;
+        int totalVertices = 0;
+        int totalTris = 0;
+
+        Dictionary<int, int> topList = new Dictionary<int, int>();
+        IOrderedEnumerable<KeyValuePair<int, int>> sortedTopList;
+
+        MeshFilter[] meshes;
+
         [MenuItem("Tools/UnityLibrary/GetMeshInfo")]
         public static void ShowWindow()
         {
@@ -16,35 +29,81 @@ public static void ShowWindow()
 
         void OnGUI()
         {
+            // TODO process all selected gameobjects
             var selection = Selection.activeGameObject;
 
-            if (selection != null)
+            // if have selection
+            if (selection == null)
+            {
+                EditorGUILayout.LabelField("Select gameobject from scene or hierarchy..");
+            }
+            else
             {
                 EditorGUILayout.LabelField("Selected: " + selection.name);
 
-                int totalMeshes = 0;
-                int totalVertices = 0;
-                int totalTris = 0;
-
-                // get all meshes
-                var meshes = selection.GetComponentsInChildren<MeshFilter>();
-                for (int i = 0, length = meshes.Length; i < length; i++)
+                // update mesh info only if selection changed
+                if (selectionChanged == true)
                 {
-                    totalVertices += meshes[i].sharedMesh.vertexCount;
-                    totalTris += meshes[i].sharedMesh.triangles.Length;
-                    totalMeshes++;
+                    selectionChanged = false;
+
+                    // clear old top results
+                    topList.Clear();
+
+                    totalMeshes = 0;
+                    totalVertices = 0;
+                    totalTris = 0;
+
+                    // check all meshes
+                    meshes = selection.GetComponentsInChildren<MeshFilter>();
+                    for (int i = 0, length = meshes.Length; i < length; i++)
+                    {
+                        int verts = meshes[i].sharedMesh.vertexCount;
+                        totalVertices += verts;
+                        // not for point/line meshes
+                        if (meshes[i].sharedMesh.GetTopology(0) == MeshTopology.Triangles) totalTris += meshes[i].sharedMesh.triangles.Length / 3;
+                        totalMeshes++;
+                        topList.Add(i, verts);
+                    }
+
+                    // sort top list
+                    sortedTopList = topList.OrderByDescending(x => x.Value);
                 }
 
                 // display stats
-                EditorGUILayout.LabelField("Meshes: " + totalMeshes);
-                EditorGUILayout.LabelField("Vertices: " + totalVertices);
-                EditorGUILayout.LabelField("Triangles: " + totalTris);
-            }
+                // String.Format("{0:n0}", 9876); // No digits after the decimal point. Output: 9,876
+                EditorGUILayout.LabelField("Meshes: " + $"{totalMeshes:n0}");
+                EditorGUILayout.LabelField("Vertices: " + $"{totalVertices:n0}");
+                EditorGUILayout.LabelField("Triangles: " + $"{totalTris:n0}");
+                EditorGUILayout.Space();
+                EditorGUILayout.LabelField("TOP 20", EditorStyles.boldLabel);
 
+                // top list
+                if (meshes != null && sortedTopList != null)
+                {
+                    int i = 0;
+                    foreach (var item in sortedTopList)
+                    {
+                        int percent = (int)(item.Value / (float)totalVertices * 100f);
+                        EditorGUILayout.BeginHorizontal();
+                        // ping button
+                        if (GUILayout.Button(new GUIContent(" ", "Ping"), GUILayout.Width(16)))
+                        {
+                            EditorGUIUtility.PingObject(meshes[item.Key].transform);
+                        }
+                        EditorGUILayout.LabelField(meshes[item.Key].name + " = " + $"{item.Value:n0}" + " (" + percent + "%)");
+                        GUILayout.ExpandWidth(true);
+                        EditorGUILayout.EndHorizontal();
+
+                        // show only first 20
+                        if (++i > 20) break;
+                    }
+                }
+            }
         }
 
         void OnSelectionChange()
         {
+            selectionChanged = true;
             // force redraw window
             Repaint();
         }
diff --git a/Assets/Scripts/Editor/Tools/PasteScript.cs b/Assets/Scripts/Editor/Tools/PasteScript.cs
new file mode 100644
index 0000000..84a1561
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/PasteScript.cs
@@ -0,0 +1,85 @@
+// new version of the https://github.com/UnityCommunity/UnityLibrary/blob/master/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs
+// creates c# script from clipboard when click button
+
+using UnityEngine;
+using UnityEditor;
+using System.IO;
+using System.Text.RegularExpressions;
+
+namespace UnityLibrary.Tools
+{
+    public class PasteScript : EditorWindow
+    {
+        private string statusMessage = "";
+        private string lastCreatedScriptPath = "";
+
+        [MenuItem("Tools/UnityLibrary/Clipboard To C# Script")]
+        public static void ShowWindow()
+        {
+            GetWindow<PasteScript>("Clipboard to Script");
+        }
+
+        void OnGUI()
+        {
+            if (GUILayout.Button("Create Script from Clipboard"))
+            {
+                TryCreateScriptFromClipboard();
+            }
+
+            GUILayout.Space(10);
+
+            // Draw clickable HelpBox
+            EditorGUILayout.HelpBox(statusMessage, MessageType.Info);
+
+            Rect helpBoxRect = GUILayoutUtility.GetLastRect();
+            if (!string.IsNullOrEmpty(lastCreatedScriptPath) && Event.current.type == EventType.MouseDown && helpBoxRect.Contains(Event.current.mousePosition))
+            {
+                var asset = AssetDatabase.LoadAssetAtPath<Object>(lastCreatedScriptPath);
+                if (asset != null)
+                {
+                    EditorGUIUtility.PingObject(asset);
+                }
+                Event.current.Use(); // Consume the click
+            }
+        }
+
+        void TryCreateScriptFromClipboard()
+        {
+            string clipboard = EditorGUIUtility.systemCopyBuffer;
+
+            if (IsProbablyCSharp(clipboard))
+            {
+                string folderPath = "Assets/Scripts/Generated";
+                Directory.CreateDirectory(folderPath);
+
+                string className = GetClassName(clipboard) ?? "GeneratedScript";
+                string path = AssetDatabase.GenerateUniqueAssetPath($"{folderPath}/{className}.cs");
+
+                File.WriteAllText(path, clipboard);
+                AssetDatabase.Refresh();
+
+                statusMessage = $"Script created: {path}";
+                lastCreatedScriptPath = path;
+            }
+            else
+            {
+                statusMessage = "Clipboard does not contain valid C# code.";
+                lastCreatedScriptPath = "";
+            }
+        }
+
+        bool IsProbablyCSharp(string text)
+        {
+            if (string.IsNullOrWhiteSpace(text)) return false;
+
+            // Basic heuristic checks
+            return Regex.IsMatch(text, @"\b(class|struct|interface|using|namespace)\b");
+        }
+
+        string GetClassName(string text)
+        {
+            Match match = Regex.Match(text, @"\bclass\s+(\w+)");
+            return match.Success ? match.Groups[1].Value : null;
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/PreciseOffsetEditor.cs b/Assets/Scripts/Editor/Tools/PreciseOffsetEditor.cs
new file mode 100644
index 0000000..f3c5a44
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/PreciseOffsetEditor.cs
@@ -0,0 +1,118 @@
+// gameobject position fiddling tool (when dragging x,y,z axist in transform panel is too fast)
+
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary.SceneTools
+{
+    public class PreciseOffsetEditor : EditorWindow
+    {
+        private const string SpeedMultiplierKey = "UnityLibrary_PreciseOffset_SpeedMultiplier";
+
+        private GameObject selectedObject;
+        private Vector3 offsetSliderValues = Vector3.zero;
+        private float speedMultiplier = 0.01f;
+
+        private Vector3 originalPosition;
+        private GameObject lastSelectedObject;
+
+        [MenuItem("Tools/UnityLibrary/Precise Model Offset")]
+        public static void ShowWindow()
+        {
+            var win = GetWindow<PreciseOffsetEditor>("Precise Model Offset");
+            win.minSize = new Vector2(300, 220);
+            win.maxSize = new Vector2(300, 220);
+        }
+
+        private void OnEnable()
+        {
+            speedMultiplier = EditorPrefs.GetFloat(SpeedMultiplierKey, 0.01f);
+        }
+
+        private void OnDisable()
+        {
+            EditorPrefs.SetFloat(SpeedMultiplierKey, speedMultiplier);
+        }
+
+        private void OnGUI()
+        {
+            EditorGUILayout.LabelField("Precise Model Offset", EditorStyles.boldLabel);
+            EditorGUILayout.Space();
+
+            int selectedCount = Selection.gameObjects.Length;
+            selectedObject = Selection.activeGameObject;
+
+            if (selectedCount == 0)
+            {
+                EditorGUILayout.HelpBox("No GameObject selected.", MessageType.Warning);
+                return;
+            }
+
+            if (selectedCount == 1)
+            {
+                EditorGUILayout.LabelField("Selected: " + selectedObject.name);
+            }
+            else
+            {
+                EditorGUILayout.LabelField("Selected: (multiple)");
+            }
+
+            if (selectedObject != lastSelectedObject)
+            {
+                originalPosition = selectedObject.transform.position;
+                offsetSliderValues = Vector3.zero;
+                lastSelectedObject = selectedObject;
+            }
+
+            EditorGUILayout.Space();
+            EditorGUI.BeginChangeCheck();
+            speedMultiplier = EditorGUILayout.Slider("Speed Multiplier", speedMultiplier, 0.001f, 1f);
+            if (EditorGUI.EndChangeCheck())
+            {
+                EditorPrefs.SetFloat(SpeedMultiplierKey, speedMultiplier);
+            }
+
+            EditorGUILayout.Space();
+            EditorGUI.BeginChangeCheck();
+
+            // Store old values to detect changes
+            Vector3 oldOffset = offsetSliderValues;
+
+            offsetSliderValues.x = EditorGUILayout.Slider("X Offset", offsetSliderValues.x, -100f, 100f);
+            offsetSliderValues.y = EditorGUILayout.Slider("Y Offset", offsetSliderValues.y, -100f, 100f);
+            offsetSliderValues.z = EditorGUILayout.Slider("Z Offset", offsetSliderValues.z, -100f, 100f);
+
+            Vector3 delta = offsetSliderValues - oldOffset;
+
+            if (delta != Vector3.zero)
+            {
+                Undo.RecordObject(selectedObject.transform, "Precise Offset");
+
+                Vector3 newPosition = selectedObject.transform.position;
+
+                if (!Mathf.Approximately(delta.x, 0f))
+                    newPosition.x = originalPosition.x + offsetSliderValues.x * speedMultiplier;
+
+                if (!Mathf.Approximately(delta.y, 0f))
+                    newPosition.y = originalPosition.y + offsetSliderValues.y * speedMultiplier;
+
+                if (!Mathf.Approximately(delta.z, 0f))
+                    newPosition.z = originalPosition.z + offsetSliderValues.z * speedMultiplier;
+
+                selectedObject.transform.position = newPosition;
+
+                EditorUtility.SetDirty(selectedObject);
+            }
+
+            EditorGUILayout.Space();
+            if (GUILayout.Button("Reset Offset"))
+            {
+                offsetSliderValues = Vector3.zero;
+                if (selectedObject != null)
+                {
+                    selectedObject.transform.position = originalPosition;
+                }
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/README.md b/Assets/Scripts/Editor/Tools/README.md
new file mode 100644
index 0000000..20d6e2a
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/README.md
@@ -0,0 +1,2 @@
+### GameViewGridOverlay.cs
+![Image](https://github.com/user-attachments/assets/48fbced4-48e0-49fe-9acc-666f5449a958)
diff --git a/Assets/Scripts/Editor/Tools/RectTransformCloner.cs b/Assets/Scripts/Editor/Tools/RectTransformCloner.cs
new file mode 100644
index 0000000..fd55097
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/RectTransformCloner.cs
@@ -0,0 +1,151 @@
+// clones UI RectTransform values from one GameObject to another in Unity Editor (only for identical hierarchy)
+
+using UnityEngine;
+using UnityEditor;
+using TMPro;
+using UnityEngine.UI;
+
+namespace UnityLibrary.Tools
+{
+    public class RectTransformCloner : EditorWindow
+    {
+        private GameObject source;
+        private GameObject target;
+        private bool requireIdenticalNames = true;
+        private bool cloneTMPAlignment = false;
+
+        [MenuItem("Tools/RectTransform Cloner")]
+        private static void ShowWindow()
+        {
+            var window = GetWindow<RectTransformCloner>();
+            window.titleContent = new GUIContent("RectTransform Cloner");
+            window.Show();
+        }
+
+        private void OnGUI()
+        {
+            GUILayout.Label("Clone RectTransform", EditorStyles.boldLabel);
+
+            source = (GameObject)EditorGUILayout.ObjectField("Source", source, typeof(GameObject), true);
+            target = (GameObject)EditorGUILayout.ObjectField("Target", target, typeof(GameObject), true);
+            requireIdenticalNames = EditorGUILayout.Toggle("Require Identical Names", requireIdenticalNames);
+            cloneTMPAlignment = EditorGUILayout.Toggle("Clone TMP Alignment", cloneTMPAlignment);
+
+            if (GUILayout.Button("Clone RectTransforms"))
+            {
+                if (source == null || target == null)
+                {
+                    Debug.LogError("Source and Target must be assigned.");
+                    return;
+                }
+
+                string errorMessage;
+                if (!CompareHierarchies(source.transform, target.transform, out errorMessage))
+                {
+                    Debug.LogError("Source and Target hierarchies do not match!\n" + errorMessage, target);
+                    return;
+                }
+
+                Undo.RegisterFullObjectHierarchyUndo(target, "Clone RectTransform Values");
+                CopyRectTransforms(source.transform, target.transform);
+
+                Debug.Log("RectTransform values cloned successfully.", target);
+
+                if (target.transform.parent != null)
+                {
+                    RectTransform parentRect = target.transform.parent as RectTransform;
+                    if (parentRect != null)
+                    {
+                        LayoutRebuilder.ForceRebuildLayoutImmediate(parentRect);
+                    }
+                    else
+                    {
+                        Debug.LogWarning("Target's parent is not a RectTransform, cannot force layout rebuild.", target);
+                    }
+                }
+                else
+                {
+                    Debug.LogWarning("Target has no parent, cannot force layout rebuild.", target);
+                }
+                EditorUtility.SetDirty(target);
+                SceneView.RepaintAll();
+            }
+        }
+
+        private bool CompareHierarchies(Transform source, Transform target, out string errorMessage)
+        {
+            errorMessage = "";
+
+            if (source.childCount != target.childCount)
+            {
+                errorMessage = $"Child count mismatch at {GetTransformPath(source)}: Source has {source.childCount}, Target has {target.childCount}";
+                return false;
+            }
+
+            for (int i = 0; i < source.childCount; i++)
+            {
+                var sourceChild = source.GetChild(i);
+                var targetChild = target.GetChild(i);
+
+                if (requireIdenticalNames && sourceChild.name != targetChild.name)
+                {
+                    errorMessage = $"Child name mismatch at {GetTransformPath(sourceChild)}: Source has '{sourceChild.name}', Target has '{targetChild.name}'";
+                    return false;
+                }
+
+                if (!CompareHierarchies(sourceChild, targetChild, out errorMessage))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private void CopyRectTransforms(Transform source, Transform target)
+        {
+            var sourceRect = source as RectTransform;
+            var targetRect = target as RectTransform;
+
+            if (sourceRect != null && targetRect != null)
+            {
+                CopyRectTransformValues(sourceRect, targetRect);
+
+                if (cloneTMPAlignment)
+                {
+                    var sourceTMP = source.GetComponent<TextMeshProUGUI>();
+                    var targetTMP = target.GetComponent<TextMeshProUGUI>();
+                    if (sourceTMP != null && targetTMP != null)
+                    {
+                        Undo.RecordObject(targetTMP, "Clone TMP Alignment");
+                        targetTMP.alignment = sourceTMP.alignment;
+                    }
+                }
+            }
+
+            for (int i = 0; i < source.childCount; i++)
+            {
+                CopyRectTransforms(source.GetChild(i), target.GetChild(i));
+            }
+        }
+
+        private void CopyRectTransformValues(RectTransform source, RectTransform target)
+        {
+            target.anchoredPosition = source.anchoredPosition;
+            target.sizeDelta = source.sizeDelta;
+            target.anchorMin = source.anchorMin;
+            target.anchorMax = source.anchorMax;
+            target.pivot = source.pivot;
+            target.localRotation = source.localRotation;
+            target.localScale = source.localScale;
+            target.localPosition = source.localPosition;
+        }
+
+        private string GetTransformPath(Transform t)
+        {
+            if (t.parent == null)
+                return t.name;
+            return GetTransformPath(t.parent) + "/" + t.name;
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs b/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs
new file mode 100644
index 0000000..d61518e
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs
@@ -0,0 +1,61 @@
+// simple image viewer inside unity editor
+// use case: to keep reference image visible while working in single monitor
+
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary
+{
+    public class ReferenceImageViewer : EditorWindow
+    {
+        Texture2D tex;
+        bool keepAspectRatio = false;
+
+        [MenuItem("Window/Tools/Reference Image Viewer")]
+        static void Init()
+        {
+            ReferenceImageViewer window = (ReferenceImageViewer)EditorWindow.GetWindow(typeof(ReferenceImageViewer));
+            window.titleContent = new GUIContent("ReferenceImageViewer");
+            window.Show();
+        }
+
+        void OnGUI()
+        {
+            EditorGUILayout.BeginHorizontal();
+            EditorGUILayout.LabelField("Image", GUILayout.Width(50));
+            tex = (Texture2D)EditorGUILayout.ObjectField(tex, typeof(Texture2D), true, GUILayout.MinWidth(100));
+            GUILayout.FlexibleSpace();
+            keepAspectRatio = EditorGUILayout.ToggleLeft("KeepAspect", keepAspectRatio);
+            EditorGUILayout.EndHorizontal();
+
+            if (tex != null)
+            {
+                int topOffset = 20;
+
+                // prep
+                var maxWidth = position.width;
+                var maxHeight = position.height - topOffset;
+                var imgWidth = (float)tex.width;
+                var imgHeight = (float)tex.height;
+
+                // calc
+                var widthRatio = maxWidth / imgWidth;
+                var heightRatio = maxHeight / imgHeight;
+                var bestRatio = Mathf.Min(widthRatio, heightRatio);
+
+                // output
+                var newWidth = imgWidth * bestRatio;
+                var newHeight = imgHeight * bestRatio;
+
+                if (keepAspectRatio == true)
+                {
+                    EditorGUI.DrawPreviewTexture(new Rect(0, topOffset, newWidth, newHeight), tex);
+                }
+                else
+                {
+                    EditorGUI.DrawPreviewTexture(new Rect(0, topOffset, maxWidth, maxHeight), tex);
+                }
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs.meta b/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs.meta
new file mode 100644
index 0000000..9f770af
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/ReferenceImageViewer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 2db76a597f4fe1b4e83ee1084fd940a6
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/ReferenceImageViewer2.cs b/Assets/Scripts/Editor/Tools/ReferenceImageViewer2.cs
new file mode 100644
index 0000000..e8371c5
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/ReferenceImageViewer2.cs
@@ -0,0 +1,110 @@
+// reference image viewer from external folder
+
+using UnityEngine;
+using UnityEditor;
+using System.IO;
+
+namespace UnityLibrary.Tools
+{
+    public class ReferenceImageViewer2 : EditorWindow
+    {
+        private const string EditorPrefsKey = "ReferenceImageViewer_ImagePath";
+
+        [SerializeField]
+        private string imagePath = "";
+        [SerializeField]
+        private Texture2D loadedImage;
+
+        [MenuItem("Window/Reference Image Viewer")]
+        public static void ShowWindow()
+        {
+            GetWindow<ReferenceImageViewer2>("Reference Image Viewer");
+        }
+
+        private void OnEnable()
+        {
+            // Delay the reload to ensure Unity's layout system is ready
+            EditorApplication.delayCall += TryLoadImage;
+        }
+
+        private void OnDisable()
+        {
+            if (!string.IsNullOrEmpty(imagePath))
+                EditorPrefs.SetString(EditorPrefsKey, imagePath);
+            else
+                EditorPrefs.DeleteKey(EditorPrefsKey);
+        }
+
+        private void TryLoadImage()
+        {
+            imagePath = EditorPrefs.GetString(EditorPrefsKey, "");
+            if (!string.IsNullOrEmpty(imagePath) && File.Exists(imagePath))
+            {
+                LoadImageFromPath(imagePath);
+                Repaint(); // Ensure it's drawn
+            }
+        }
+
+        void OnGUI()
+        {
+            GUILayout.Label("Reference Image Viewer", EditorStyles.boldLabel);
+
+            if (GUILayout.Button("Browse for Image"))
+            {
+                string path = EditorUtility.OpenFilePanel("Select Image", "", "png,jpg,jpeg");
+                if (!string.IsNullOrEmpty(path))
+                {
+                    imagePath = path;
+                    EditorPrefs.SetString(EditorPrefsKey, imagePath);
+                    LoadImageFromPath(imagePath);
+                }
+            }
+
+            // Fallback in case delayCall missed
+            if (loadedImage == null && !string.IsNullOrEmpty(imagePath) && File.Exists(imagePath))
+            {
+                LoadImageFromPath(imagePath);
+                Repaint();
+            }
+
+            if (loadedImage != null)
+            {
+                GUILayout.Space(10);
+
+                float windowWidth = position.width - 20;
+                float imageAspect = (float)loadedImage.width / loadedImage.height;
+
+                float displayWidth = windowWidth;
+                float displayHeight = windowWidth / imageAspect;
+
+                if (displayHeight > position.height - 100)
+                {
+                    displayHeight = position.height - 100;
+                    displayWidth = displayHeight * imageAspect;
+                }
+
+                Rect imageRect = GUILayoutUtility.GetRect(displayWidth, displayHeight, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
+                EditorGUI.DrawPreviewTexture(imageRect, loadedImage, null, ScaleMode.ScaleToFit);
+            }
+        }
+
+        private void LoadImageFromPath(string path)
+        {
+            try
+            {
+                byte[] fileData = File.ReadAllBytes(path);
+                loadedImage = new Texture2D(2, 2, TextureFormat.RGBA32, false);
+                if (!loadedImage.LoadImage(fileData))
+                {
+                    Debug.LogError("Failed to load image.");
+                    loadedImage = null;
+                }
+            }
+            catch (System.Exception e)
+            {
+                Debug.LogError($"Could not load image from path: {path}\n{e.Message}");
+                loadedImage = null;
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/RendererTypeCounter.cs b/Assets/Scripts/Editor/Tools/RendererTypeCounter.cs
new file mode 100644
index 0000000..0cc0ce2
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/RendererTypeCounter.cs
@@ -0,0 +1,108 @@
+// shows renderer stats from selected objects in the editor
+
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityLibrary
+{
+    public class RendererTypeCounter : EditorWindow
+    {
+        private int activeMeshRendererCount;
+        private int inactiveMeshRendererCount;
+        private int activeSkinnedMeshRendererCount;
+        private int inactiveSkinnedMeshRendererCount;
+        private int activeSpriteRendererCount;
+        private int inactiveSpriteRendererCount;
+        private int totalGameObjectCount;
+
+        [MenuItem("Tools/Renderer Type Counter")]
+        public static void ShowWindow()
+        {
+            GetWindow<RendererTypeCounter>("Renderer Type Counter");
+        }
+
+        private void OnGUI()
+        {
+            if (GUILayout.Button("Count Renderers"))
+            {
+                CountRenderersInSelection();
+            }
+
+            GUILayout.Space(10);
+
+            GUILayout.Label("Active Mesh Renderers: " + activeMeshRendererCount);
+            GUILayout.Label("Inactive Mesh Renderers: " + inactiveMeshRendererCount);
+            GUILayout.Label("Active Skinned Mesh Renderers: " + activeSkinnedMeshRendererCount);
+            GUILayout.Label("Inactive Skinned Mesh Renderers: " + inactiveSkinnedMeshRendererCount);
+            GUILayout.Label("Active Sprite Renderers: " + activeSpriteRendererCount);
+            GUILayout.Label("Inactive Sprite Renderers: " + inactiveSpriteRendererCount);
+            GUILayout.Label("Total GameObjects: " + totalGameObjectCount);
+        }
+
+        private void CountRenderersInSelection()
+        {
+            activeMeshRendererCount = 0;
+            inactiveMeshRendererCount = 0;
+            activeSkinnedMeshRendererCount = 0;
+            inactiveSkinnedMeshRendererCount = 0;
+            activeSpriteRendererCount = 0;
+            inactiveSpriteRendererCount = 0;
+            totalGameObjectCount = 0;
+
+            foreach (GameObject obj in Selection.gameObjects)
+            {
+                CountRenderersRecursively(obj);
+            }
+
+            Repaint();
+        }
+
+        private void CountRenderersRecursively(GameObject obj)
+        {
+            totalGameObjectCount++;
+
+            bool isActive = obj.activeInHierarchy;
+
+            if (obj.GetComponent<MeshRenderer>())
+            {
+                if (isActive)
+                {
+                    activeMeshRendererCount++;
+                }
+                else
+                {
+                    inactiveMeshRendererCount++;
+                }
+            }
+
+            if (obj.GetComponent<SkinnedMeshRenderer>())
+            {
+                if (isActive)
+                {
+                    activeSkinnedMeshRendererCount++;
+                }
+                else
+                {
+                    inactiveSkinnedMeshRendererCount++;
+                }
+            }
+
+            if (obj.GetComponent<SpriteRenderer>())
+            {
+                if (isActive)
+                {
+                    activeSpriteRendererCount++;
+                }
+                else
+                {
+                    inactiveSpriteRendererCount++;
+                }
+            }
+
+            foreach (Transform child in obj.transform)
+            {
+                CountRenderersRecursively(child.gameObject);
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/Editor/Tools/SceneManagerWindow.cs.meta b/Assets/Scripts/Editor/Tools/SceneManagerWindow.cs.meta
new file mode 100644
index 0000000..1c85eff
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/SceneManagerWindow.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 9b6b0e046c5bb254f919f740aeb8518b
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/SceneSwitcherWindow.cs.meta b/Assets/Scripts/Editor/Tools/SceneSwitcherWindow.cs.meta
new file mode 100644
index 0000000..ce3ea39
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/SceneSwitcherWindow.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: fc44dc6a633635b4ba4ed8bfa75dc6bb
+timeCreated: 1594958195
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Editor/Tools/SelectAssetsByType.cs b/Assets/Scripts/Editor/Tools/SelectAssetsByType.cs
new file mode 100644
index 0000000..51f326b
--- /dev/null
+++ b/Assets/Scripts/Editor/Tools/SelectAssetsByType.cs
@@ -0,0 +1,160 @@
+// select multiple files or folders from Project window, then can filter by type and select all objects of that type
+
+using UnityEditor;
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace UnityLibrary
+{
+    public class SelectAssetsByType : EditorWindow
+    {
+        private Dictionary<System.Type, List<Object>> groupedObjects;
+        private List<Object> allObjects;
+
+        [MenuItem("Tools/UnityLibrary/Select Assets By Type")]
+        public static void ShowWindow()
+        {
+            GetWindow<SelectAssetsByType>("Select Assets By Type");
+        }
+
+        private void OnEnable()
+        {
+            // Automatically refresh whenever selection changes
+            Selection.selectionChanged += RefreshSelection;
+            RefreshSelection();
+        }
+
+        private void OnDisable()
+        {
+            // Unsubscribe from selection change event
+            Selection.selectionChanged -= RefreshSelection;
+        }
+
+        private void OnGUI()
+        {
+            if (groupedObjects != null)
+            {
+                foreach (var group in groupedObjects)
+                {
+                    if (group.Value.Count > 0)
+                    {
+                        // Show type and number of objects
+                        if (GUILayout.Button($"{group.Value.Count} {group.Key.Name}(s)"))
+                        {
+                            // Select objects of this type in the editor
+                            SelectObjects(group.Value);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void RefreshSelection()
+        {
+            groupedObjects = new Dictionary<System.Type, List<Object>>();
+            allObjects = new List<Object>();
+
+            // Get selected objects and their children
+            var selectedObjects = Selection.objects;
+            foreach (var obj in selectedObjects)
+            {
+                allObjects.Add(obj);
+
+                // If the object is a folder, include assets inside the folder recursively
+                if (AssetDatabase.IsValidFolder(AssetDatabase.GetAssetPath(obj)))
+                {
+                    AddFolderContents(AssetDatabase.GetAssetPath(obj));
+                }
+                else
+                {
+                    // Add children if it's a GameObject and find sprites in it
+                    if (obj is GameObject gameObject)
+                    {
+                        AddChildrenAndSprites(gameObject);
+                    }
+                    // If it's a Texture2D, load its Sprites (if any)
+                    else if (obj is Texture2D texture)
+                    {
+                        AddTextureSprites(texture);
+                    }
+                }
+            }
+
+            // Group by type
+            foreach (var obj in allObjects)
+            {
+                var type = obj.GetType();
+                if (!groupedObjects.ContainsKey(type))
+                {
+                    groupedObjects[type] = new List<Object>();
+                }
+                groupedObjects[type].Add(obj);
+            }
+
+            // Refresh the window UI
+            Repaint();
+        }
+
+        private void AddChildrenAndSprites(GameObject obj)
+        {
+            // Add the GameObject itself
+            allObjects.Add(obj);
+
+            // Check if the GameObject has a SpriteRenderer and add the Sprite
+            var spriteRenderer = obj.GetComponent<SpriteRenderer>();
+            if (spriteRenderer != null && spriteRenderer.sprite != null)
+            {
+                allObjects.Add(spriteRenderer.sprite); // Add the sprite separately
+            }
+
+            // Recursively add children and their sprites
+            foreach (Transform child in obj.transform)
+            {
+                AddChildrenAndSprites(child.gameObject);
+            }
+        }
+
+        private void AddFolderContents(string folderPath)
+        {
+            // Get all assets in the folder and subfolders
+            string[] guids = AssetDatabase.FindAssets("", new[] { folderPath });
+            foreach (string guid in guids)
+            {
+                string path = AssetDatabase.GUIDToAssetPath(guid);
+                Object asset = AssetDatabase.LoadAssetAtPath<Object>(path);
+
+                // Add the asset itself
+                if (asset != null)
+                {
+                    allObjects.Add(asset);
+
+                    // If it's a Texture2D, also add any Sprites inside it
+                    if (asset is Texture2D texture)
+                    {
+                        AddTextureSprites(texture);
+                    }
+                }
+            }
+        }
+
+        private void AddTextureSprites(Texture2D texture)
+        {
+            // Check if the texture contains any sprites (e.g., from a sprite sheet)
+            string path = AssetDatabase.GetAssetPath(texture);
+            Object[] assets = AssetDatabase.LoadAllAssetsAtPath(path);
+
+            foreach (Object asset in assets)
+            {
+                if (asset is Sprite sprite)
+                {
+                    allObjects.Add(sprite); // Add each sprite separately
+                }
+            }
+        }
+
+        private void SelectObjects(List<Object> objects)
+        {
+            Selection.objects = objects.ToArray();
+        }
+    }
+}
diff --git a/Assets/Scripts/Extensions/MonoBehaviourExtensions.meta b/Assets/Scripts/Extensions/MonoBehaviourExtensions.meta
new file mode 100644
index 0000000..92e9b6a
--- /dev/null
+++ b/Assets/Scripts/Extensions/MonoBehaviourExtensions.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 9064a058036a7004f829d31b1ec4fa7a
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example.meta b/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example.meta
new file mode 100644
index 0000000..0279a23
--- /dev/null
+++ b/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d05efc8881e8e844a8eccc6132e0ddf6
+folderAsset: yes
+timeCreated: 1594958191
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example/MonoBehaviorExtensionsExample.cs.meta b/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example/MonoBehaviorExtensionsExample.cs.meta
new file mode 100644
index 0000000..3cf25b0
--- /dev/null
+++ b/Assets/Scripts/Extensions/MonoBehaviourExtensions/Example/MonoBehaviorExtensionsExample.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 7bbf1f0c60c74ac4683995b0a507d537
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Extensions/MonoBehaviourExtensions/MonoBehaviourExtensions.cs.meta b/Assets/Scripts/Extensions/MonoBehaviourExtensions/MonoBehaviourExtensions.cs.meta
new file mode 100644
index 0000000..0c46b6b
--- /dev/null
+++ b/Assets/Scripts/Extensions/MonoBehaviourExtensions/MonoBehaviourExtensions.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 607fadb72caa2c54f833370bcf9558dc
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Extensions/StringExtensions.cs b/Assets/Scripts/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..e5ecb6a
--- /dev/null
+++ b/Assets/Scripts/Extensions/StringExtensions.cs
@@ -0,0 +1,25 @@
+using UnityEngine;
+using System.Globalization;
+
+// e.g. "#FFFFFF".ToColor()
+
+namespace UnityLibrary
+{
+    public static class StringExtensions
+    {
+        public static Color ToColor(this string hex) {
+            hex = hex.Replace("0x", "");
+            hex = hex.Replace("#", "");
+
+            byte a = 255;
+            byte r = byte.Parse(hex.Substring(0,2), NumberStyles.HexNumber);
+            byte g = byte.Parse(hex.Substring(2,2), NumberStyles.HexNumber);
+            byte b = byte.Parse(hex.Substring(4,2), NumberStyles.HexNumber);
+
+            if (hex.Length == 8)
+                a = byte.Parse(hex.Substring(6,2), NumberStyles.HexNumber);
+
+            return new Color32(r,g,b,a);
+        }
+    }
+}
diff --git a/Assets/Scripts/Extensions/Vector2Extensions.cs b/Assets/Scripts/Extensions/Vector2Extensions.cs
new file mode 100644
index 0000000..e85b0dd
--- /dev/null
+++ b/Assets/Scripts/Extensions/Vector2Extensions.cs
@@ -0,0 +1,15 @@
+using UnityEngine;
+
+namespace UnityLibrary
+{
+    static class Vector2Extensions
+    {
+        public static Vector2 Round(this Vector2 vector, int to = 0) => new Vector2(vector.x.Round(to), vector.y.Round(to)); 
+
+        public static Vector2 Rotate(this Vector2 vector, float angle, Vector2 pivot = default(Vector2)) 
+        {
+            Vector2 rotated = Quaternion.Euler(new Vector3(0f, 0f, angle)) * (vector - pivot);
+            return rotated + pivot;
+        }
+    }
+}
diff --git a/Assets/Scripts/Extensions/Vector2Extensions.cs.meta b/Assets/Scripts/Extensions/Vector2Extensions.cs.meta
new file mode 100644
index 0000000..0fef0ef
--- /dev/null
+++ b/Assets/Scripts/Extensions/Vector2Extensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 058da80b535be1d469c9998e5629a60e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs b/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs
new file mode 100644
index 0000000..5c43b88
--- /dev/null
+++ b/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs
@@ -0,0 +1,20 @@
+// shows who disabled/enabled this gameobject from another script 
+// usage: attach to gameobject that you want to track (see console stack trace)
+
+using UnityEngine;
+
+namespace UnityLibrary
+{
+    public class WhoDisabledOrEnabled : MonoBehaviour
+    {
+        private void OnDisable()
+        {
+            Debug.LogError("OnDisable: " + gameObject.name, gameObject);
+        }
+
+        private void OnEnable()
+        {
+            Debug.LogError("OnEnable: " + gameObject.name, gameObject);
+        }
+    }
+}
diff --git a/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs.meta b/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs.meta
new file mode 100644
index 0000000..664c889
--- /dev/null
+++ b/Assets/Scripts/Helpers/Debug/WhoDisabledOrEnabled.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c69c0e5bff195b040b1c86515b454544
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Helpers/Windows/WindowAlwaysOnTop.cs b/Assets/Scripts/Helpers/Windows/WindowAlwaysOnTop.cs
new file mode 100644
index 0000000..1946cc3
--- /dev/null
+++ b/Assets/Scripts/Helpers/Windows/WindowAlwaysOnTop.cs
@@ -0,0 +1,42 @@
+// keep executable window always on top, good for multiplayer testing
+
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+
+namespace UnityLibrary
+{
+    public class WindowAlwaysOnTop : MonoBehaviour
+    {
+#if !UNITY_STANDALONE_LINUX
+
+        // https://stackoverflow.com/a/34703664/5452781
+        private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
+        private const UInt32 SWP_NOSIZE = 0x0001;
+        private const UInt32 SWP_NOMOVE = 0x0002;
+        private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
+
+        [DllImport("user32.dll")]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
+
+        // https://forum.unity.com/threads/unity-window-handle.115364/#post-1650240
+        [DllImport("user32.dll")]
+        private static extern IntPtr GetActiveWindow();
+
+        public static IntPtr GetWindowHandle()
+        {
+            return GetActiveWindow();
+        }
+#endif
+
+        void Awake()
+        {
+            // TODO save current window pos to player prefs on exit, then can open into same position next time
+#if !UNITY_EDITOR && !UNITY_STANDALONE_LINUX
+        Debug.Log("Make window stay on top");
+        SetWindowPos(GetActiveWindow(), HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
+#endif
+        }
+    }
+}
diff --git a/Assets/Scripts/ImageEffects/SpriteColor.cs b/Assets/Scripts/ImageEffects/SpriteColor.cs
new file mode 100644
index 0000000..bf7cad6
--- /dev/null
+++ b/Assets/Scripts/ImageEffects/SpriteColor.cs
@@ -0,0 +1,78 @@
+﻿using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+// This script gets the color of a sprite in realtime 
+// Usage: Attach this script to any gameobject having a sprite renderer component
+
+public class SpriteColor : MonoBehaviour
+{
+    public static Color GetColor { get; set; }
+
+    public SpriteRenderer targetSprite;
+
+    Color finalColor;
+
+    void Update()
+    {
+        GetSpritePixelColorUnderMousePointer(targetSprite, out finalColor);
+    }
+
+    public bool GetSpritePixelColorUnderMousePointer(SpriteRenderer spriteRenderer, out Color color)
+    {
+        color = new Color();
+        Camera cam = Camera.main;
+        Vector2 mousePos = Input.mousePosition;
+        Vector2 viewportPos = cam.ScreenToViewportPoint(mousePos);
+        if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) return false; // out of viewport bounds
+
+        // Cast a ray from viewport point into world
+        Ray ray = cam.ViewportPointToRay(viewportPos);
+
+        // Check for intersection with sprite and get the color
+        return IntersectsSprite(spriteRenderer, ray, out color);
+    }
+
+    private bool IntersectsSprite(SpriteRenderer spriteRenderer, Ray ray, out Color color)
+    {
+        color = new Color();
+        if (spriteRenderer == null) return false;
+
+        Sprite sprite = spriteRenderer.sprite;
+        if (sprite == null) return false;
+
+        Texture2D texture = sprite.texture;
+        if (texture == null) return false;
+
+
+        // Craete a plane so it has the same orientation as the sprite transform
+        Plane plane = new Plane(transform.forward, transform.position);
+
+        // Intersect the ray and the plane
+        float rayIntersectDist; // the distance from the ray origin to the intersection point
+        if (!plane.Raycast(ray, out rayIntersectDist)) return false;
+
+        // Convert world position to sprite position
+        // worldToLocalMatrix.MultiplyPoint3x4 returns a value from based on the texture dimensions (+/- half texDimension / pixelsPerUnit) )
+        // 0, 0 corresponds to the center of the TEXTURE ITSELF, not the center of the trimmed sprite textureRect
+
+        Vector3 spritePos = spriteRenderer.worldToLocalMatrix.MultiplyPoint3x4(ray.origin + (ray.direction * rayIntersectDist));
+        Rect textureRect = sprite.textureRect;
+        float pixelsPerUnit = sprite.pixelsPerUnit;
+        float halfRealTexWidth = texture.width * 0.5f; // use the real texture width here because center is based on this -- probably won't work right for atlases
+        float halfRealTexHeight = texture.height * 0.5f;
+        // Convert to pixel position, offsetting so 0,0 is in lower left instead of center
+        int texPosX = (int)(spritePos.x * pixelsPerUnit + halfRealTexWidth);
+        int texPosY = (int)(spritePos.y * pixelsPerUnit + halfRealTexHeight);
+        // Check if pixel is within texture
+        if (texPosX < 0 || texPosX < textureRect.x || texPosX >= Mathf.FloorToInt(textureRect.xMax)) return false; // out of bounds
+        if (texPosY < 0 || texPosY < textureRect.y || texPosY >= Mathf.FloorToInt(textureRect.yMax)) return false; // out of bounds
+                                                                                                                   // Get pixel color
+        color = texture.GetPixel(texPosX, texPosY);
+        GetColor = color;
+
+        return true;
+    }
+
+}
diff --git a/Assets/Scripts/Mesh.meta b/Assets/Scripts/Mesh.meta
new file mode 100644
index 0000000..762cc6b
--- /dev/null
+++ b/Assets/Scripts/Mesh.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 14b294f417b66d44a87b73ca589bca2f
+folderAsset: yes
+timeCreated: 1594958189
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Mesh/Metaball.cs b/Assets/Scripts/Mesh/Metaball.cs
new file mode 100644
index 0000000..5bb330d
--- /dev/null
+++ b/Assets/Scripts/Mesh/Metaball.cs
@@ -0,0 +1,979 @@
+// taken from http://wiki.unity3d.com/index.php?title=MetaBalls&oldid=16461
+/**
+ * Metaball implementation by Brian R. Cowan http://www.briancowan.net/ 
+ * Metaball tables at http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
+ * Examples at http://www.briancowan.net/unity/fx
+ *
+ * Code provided as-is. You agree by using this code that I am not liable for any damage
+ * it could possibly cause to you, your machine, or anything else. And the code is not meant
+ * to be used for any medical uses or to run nuclear reactors or robots or such and so. 
+ * 
+ * Should be easily portable to any other language, all Unity Specific code is labeled so,
+ * adapt it to any other environment. To use, attach the script to an empty object with a
+ * Mesh Renderer and Mesh Filter. The created cubes will be one unit in size in XYZ.
+ * Modify Update() and Start() to change the amount and movement and size of the blobs.
+ *
+ * Id love to see any project you use the code in.
+ *
+ * Mail any comments to: brian@briancowan.net (Vector or Vector426 on #otee-unity)
+ *
+ * Cheers & God bless
+ */
+
+/**
+*There is a small bug in this code that produces 1 to 4 overlapping triangles 
+*mostly in the centre of the mesh, sometimes on a side resulting in a white patch
+*it appears in other shapes than Metaballs.
+*if it's too hard to fix the code, scanning duplicate triangles is possible
+*the duplicates occur in the 1st 4 triangles and anywhere after
+*it seems the code doesn't check duplicates for the 1st 4 triangles
+*the above issue is probably relate to the march() function doCube 1x time
+*and then sending recurse() function docube in the same space
+* so perhaps delete   if(doCube(cube)) {  condition in march() and just recurse
+*also it processes 278700 pts instead of 32768 pts if made to march all spaces
+*/
+
+/*Unity Specific*/
+using UnityEngine;
+using System.Collections;
+
+namespace UnityLibrary
+{
+    public class Metaball : MonoBehaviour
+    {
+
+        /*Amount of cubes in X/Y/Z directions, Dimension will always be from -.5f to .5f in XYZ
+          remember to call Regen() if changing!
+        */
+        int _dimX = 30;
+        int _dimY = 30;
+        int _dimZ = 30;
+
+        public int dimX
+        {
+            get { return _dimX; }
+            set { _dimX = value; Regen(); }
+        }
+        public int dimY
+        {
+            get { return _dimY; }
+            set { _dimY = value; Regen(); }
+        }
+        public int dimZ
+        {
+            get { return _dimZ; }
+            set { _dimZ = value; Regen(); }
+        }
+        /*Blobs are a staggered array of floats, where first index is blob, and second is 0=x, 1=y 2=z 3=power
+          Multidim might be slightly faster, but staggered made the code a little cleaner IMO*/
+        public float[][] blobs;
+
+        /*Cutoff intensity, where the surface of mesh will be created*/
+        public float isoLevel = .5f;
+
+        /*Scratch buffers for Vertices/Normals/Tris */
+        private Vector3[] newVertex;
+        private Vector3[] newNormal;
+        private Vector2[] newUV;
+        private int[] newTri;
+
+        /*Pointer into scratch buffers for tris and vertices(also used for UVs and Normals)
+          at the end of a frame it will give the total amount of each*/
+        private int triP = 0;
+        private int vertP = 0;
+
+        /*Generated at startup for dimX,dimY,dimZ, 
+          all the points, edges, cubes in the 3D lattice*/
+        private mcPoint[] _points;
+        private mcEdge[] _edges;
+        private mcCube[] _cubes;
+
+
+        /*Scratch buffers for use within functions, to eliminate the usage of new almost entirely each frame*/
+        private Vector3[] tada;
+        private Vector2[] tada2;
+        private int tadac, tadac2;
+        private int tadam = 50000;
+
+        /*Current frame counter*/
+        private int pctr = 0;
+
+        /*Cube Class*/
+        private class mcCube
+        {
+            public mcCube()
+            {
+                cntr = 0;
+                edges = new mcEdge[12];
+                for (int i = 0; i < 12; i++)
+                {
+                    edges[i] = null;
+                }
+                points = new mcPoint[8];
+            }
+
+            /*12 Edges, see march() for their positioning*/
+            public mcEdge[] edges;
+
+            /*8 Points, see march() for their positioning*/
+            public mcPoint[] points;
+
+            /*last frame this cube was processed*/
+            public int cntr;
+
+            /*Pointers into the latice array*/
+            public int px;
+            public int py;
+            public int pz;
+        }
+
+        /*Edge class*/
+        private class mcEdge
+        {
+            /*the vector of the calculated point*/
+            public Vector3 v3;
+
+            /*index into newVertex/Normal/Uv of calculated point*/
+            public int vi;
+
+            /*Last frame this was calculated at*/
+            public int cntr;
+
+            /*axis of edge*/
+            public int axisI;
+
+            public mcEdge(int axisI)
+            {
+                this.cntr = 0;
+                this.axisI = axisI;
+            }
+        }
+
+        /*Point (in lattice) class*/
+        public class mcPoint
+        {
+            /*Calculated Intensity or Power of point*/
+            public float _i;
+            public int px, py, pz;
+            private Metaball mcblob;
+            public int cntr;
+
+            /*Object Space position of point*/
+            public float[] index;
+
+            public mcPoint(float x, float y, float z, int px, int py, int pz, Metaball thismcblob)
+            {
+                this.index = new float[3];
+                index[0] = x; index[1] = y; index[2] = z;
+
+                this.px = px;
+                this.py = py;
+                this.pz = pz;
+                this.cntr = 0;
+                this.mcblob = thismcblob;
+            }
+
+            /*Axis letter accessors*/
+            public float x
+            {
+                get { return index[0]; }
+                set { index[0] = value; }
+            }
+            public float y
+            {
+                get { return index[1]; }
+                set { index[1] = value; }
+            }
+            public float z
+            {
+                get { return index[2]; }
+                set { index[2] = value; }
+            }
+
+            /*Calculate the power of a point only if it hasn't been calculated already for this frame*/
+            public float i()
+            {
+                float pwr;
+                if (cntr < mcblob.pctr)
+                {
+                    cntr = mcblob.pctr;
+                    pwr = 0f;
+                    for (int jc = 0; jc < this.mcblob.blobs.Length; jc++)
+                    {
+                        float[] pb = this.mcblob.blobs[jc];
+                        pwr += (1.0f / Mathf.Sqrt(((pb[0] - this.x) * (pb[0] - this.x)) + ((pb[1] - this.y) * (pb[1] - this.y)) + ((pb[2] - this.z) * (pb[2] - this.z)))) * pb[3];
+                    }
+                    this._i = pwr;
+                }
+                return this._i;
+            }
+
+            public float this[int idx]
+            {
+                get
+                {
+                    return index[idx];
+                }
+                set
+                {
+                    index[idx] = value;
+                }
+            }
+        }
+
+        /* Normals are calculated by 'averaging' all the derivatives of the Blob power functions*/
+        private Vector3 calcNormal(Vector3 pnt)
+        {
+            int jc;
+            Vector3 result = tada[tadac++];
+            result.x = 0; result.y = 0; result.z = 0;
+            for (jc = 0; jc < blobs.Length; jc++)
+            {
+                float[] pb = blobs[jc];
+
+                Vector3 current = tada[tadac++];
+                current.x = pnt.x - pb[0];
+                current.y = pnt.y - pb[1];
+                current.z = pnt.z - pb[2];
+                float mag = current.magnitude;
+                float pwr = .5f * (1f / (mag * mag * mag)) * pb[3];
+                result = result + (current * pwr);
+            }
+            return result.normalized;
+        }
+
+        /*Given xyz indices into lattice, return referring cube */
+        private mcCube getCube(int x, int y, int z)
+        {
+            if (x < 0 || y < 0 || z < 0 || x >= dimX || y >= dimY || z >= dimZ) { return null; }
+            return _cubes[z + (y * (dimZ)) + (x * (dimZ) * (dimY))];
+        }
+
+        /*Given xyz indices into lattice, return referring vertex */
+        private mcPoint getPoint(int x, int y, int z)
+        {
+            if (x < 0 || y < 0 || z < 0 || x > dimX || y > dimY || z > dimZ) { return null; }
+            return _points[z + (y * (dimZ + 1)) + (x * (dimZ + 1) * (dimY + 1))];
+        }
+
+        /*Return the interpolated position of point on an Axis*/
+        private Vector3 mPos(mcPoint a, mcPoint b, int axisI)
+        {
+            float mu = (isoLevel - a.i()) / (b.i() - a.i());
+            Vector3 tmp = tada[tadac++];
+            tmp[0] = a[0]; tmp[1] = a[1]; tmp[2] = a[2];
+            tmp[axisI] = a[axisI] + (mu * (b[axisI] - a[axisI]));
+
+            return tmp;
+        }
+
+        /*If an edge of a cube has not been processed, find the interpolated point for 
+          that edge (assumes the boundary crosses the edge) and compute the normal
+          for that point, as well as assigning it an index into the vertex list*/
+        private void genEdge(mcCube cube, int edgei, int p1i, int p2i)
+        {
+            Vector3 v;
+            mcEdge e = cube.edges[edgei];
+            if (e.cntr < pctr)
+            {
+
+                v = mPos(cube.points[p1i], cube.points[p2i], e.axisI);
+                e.v3 = v;
+                e.vi = vertP;
+                newNormal[vertP] = calcNormal(v);
+                newVertex[vertP++] = v;
+                e.cntr = pctr;
+
+            }
+        }
+
+        /*Calculate a cube:
+          First set a boolean pointer made up of all the vertices within the cube
+          then (if not all in or out of the surface) go through all the edges that 
+          are crossed by the surface and make sure that a vertex&normal is assigned 
+          at the point of crossing. Then add all the triangles that cover the surface
+          within the cube.
+          Returns true if the surface crosses the cube, false otherwise.*/
+        private bool doCube(mcCube cube)
+        {
+            int edgec, vertc;
+            edgec = 0; vertc = 0;
+
+            int cubeIndex = 0;
+
+            if (cube.points[0].i() > isoLevel) { cubeIndex |= 1; }
+            if (cube.points[1].i() > isoLevel) { cubeIndex |= 2; }
+            if (cube.points[2].i() > isoLevel) { cubeIndex |= 4; }
+            if (cube.points[3].i() > isoLevel) { cubeIndex |= 8; }
+            if (cube.points[4].i() > isoLevel) { cubeIndex |= 16; }
+            if (cube.points[5].i() > isoLevel) { cubeIndex |= 32; }
+            if (cube.points[6].i() > isoLevel) { cubeIndex |= 64; }
+            if (cube.points[7].i() > isoLevel) { cubeIndex |= 128; }
+
+            int edgeIndex = edgeTable[cubeIndex];
+            edgec += edgeIndex;
+            if (edgeIndex != 0)
+            {
+                if ((edgeIndex & 1) > 0) { genEdge(cube, 0, 0, 1); }
+                if ((edgeIndex & 2) > 0) { genEdge(cube, 1, 1, 2); }
+                if ((edgeIndex & 4) > 0) { genEdge(cube, 2, 2, 3); }
+                if ((edgeIndex & 0x8) > 0) { genEdge(cube, 3, 3, 0); }
+                if ((edgeIndex & 0x10) > 0) { genEdge(cube, 4, 4, 5); }
+                if ((edgeIndex & 0x20) > 0) { genEdge(cube, 5, 5, 6); }
+                if ((edgeIndex & 0x40) > 0) { genEdge(cube, 6, 6, 7); }
+                if ((edgeIndex & 0x80) > 0) { genEdge(cube, 7, 7, 4); }
+                if ((edgeIndex & 0x100) > 0) { genEdge(cube, 8, 0, 4); }
+                if ((edgeIndex & 0x200) > 0) { genEdge(cube, 9, 1, 5); }
+                if ((edgeIndex & 0x400) > 0) { genEdge(cube, 10, 2, 6); }
+                if ((edgeIndex & 0x800) > 0) { genEdge(cube, 11, 3, 7); }
+
+                int tpi = 0;
+                int tmp;
+                while (triTable[cubeIndex, tpi] != -1)
+                {
+                    tmp = cube.edges[triTable[cubeIndex, tpi + 2]].vi;
+                    newTri[triP++] = tmp; vertc += tmp;
+                    tmp = cube.edges[triTable[cubeIndex, tpi + 1]].vi;
+                    newTri[triP++] = tmp; vertc += tmp;
+                    tmp = cube.edges[triTable[cubeIndex, tpi]].vi;
+                    newTri[triP++] = tmp; vertc += tmp;
+                    tpi += 3;
+                }
+
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        /*Recurse all the neighboring cubes where thy contain part of the surface*/
+        /*Counter to see how many cubes where processed*/
+        int cubec;
+        private void recurseCube(mcCube cube)
+        {
+            mcCube nCube;
+            int jx, jy, jz;
+            jx = cube.px; jy = cube.py; jz = cube.pz;
+            cubec++;
+            /* Test 6 axis cases. This seems to work well, no need to test all 26 cases */
+            nCube = getCube(jx + 1, jy, jz);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+            nCube = getCube(jx - 1, jy, jz);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+            nCube = getCube(jx, jy + 1, jz);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+            nCube = getCube(jx, jy - 1, jz);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+            nCube = getCube(jx, jy, jz + 1);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+            nCube = getCube(jx, jy, jz - 1);
+            if (nCube != null && nCube.cntr < pctr) { nCube.cntr = pctr; if (doCube(nCube)) { recurseCube(nCube); } }
+        }
+
+        /*Go through all the Blobs, and travel from the center outwards in a negative Z direction
+        until we reach the surface, then begin to recurse around the surface. This isn't flawless
+        if the blob isn't completely within the lattice boundaries in the minimal Z axis and no
+        other blob that does check out is in contact with it. The blob will dissapear, but otherwise
+        works well*/
+        private void march()
+        {
+            int i, jx, jy, jz;
+            for (i = 0; i < blobs.Length; i++)
+            {
+                float[] pb = blobs[i];
+                jx = (int)((pb[0] + .5f) * dimX);
+                jy = (int)((pb[1] + .5f) * dimY);
+                jz = (int)((pb[2] + .5f) * dimZ);
+
+                while (jz >= 0)
+                {
+                    mcCube cube = getCube(jx, jy, jz);
+                    if (cube != null && cube.cntr < pctr)
+                    {
+                        if (doCube(cube))
+                        {
+                            recurseCube(cube);
+                            jz = -1;
+                        }
+                        cube.cntr = pctr;
+                    }
+                    else
+                    {
+                        jz = -1;
+                    }
+                    jz -= 1;
+                }
+            }
+        }
+
+        /*Unity and Sample Specific, scratch caches to not reallocate vertices/tris/etc...*/
+        Vector3[] fv, fn;
+        int[] ft;
+        Vector2[] fuv;
+
+        //Last Status Post
+        private float lt = 0f;
+
+        /*Unity and Sample Specific*/
+        private void renderMesh()
+        {
+            int i;
+
+            /*Clear the Vertices that don't have any real information assigned to them */
+            for (i = 0; i < vertP; i++)
+            {
+                fv[i] = newVertex[i]; fn[i] = newNormal[i];
+                fuv[i] = tada2[tadac2++];
+                Vector3 fuvt = transform.TransformPoint(fn[i]).normalized;
+                fuv[i].x = (fuvt.x + 1f) * .5f; fuv[i].y = (fuvt.y + 1f) * .5f;
+            }
+            //							  fuv[i].x=fn[i].x;fuv[i].y=fn[i].y;}
+
+            for (i = vertP; i < fv.Length; i++)
+            {
+                fv[i][0] = 0; fn[i][0] = 0; fuv[i][0] = 0;
+                fv[i][1] = 0; fn[i][1] = 0; fuv[i][1] = 0;
+                fv[i][2] = 0;
+            }
+
+            for (i = 0; i < triP; i++) { ft[i] = newTri[i]; }
+            for (i = triP; i < ft.Length; i++) { ft[i] = 0; }
+
+            Mesh mesh = ((MeshFilter)GetComponent("MeshFilter")).mesh;
+
+            mesh.vertices = fv;
+            mesh.uv = fuv;
+            mesh.triangles = ft;
+            mesh.normals = fn;
+
+            /*For Disco Ball Effect*/
+            //mesh.RecalculateNormals();	
+        }
+
+        /*What is needed to do every frame for the calculation and rendering of the Metaballs*/
+        void doFrame()
+        {
+            tadac = 0;
+            tadac2 = 0;
+            cubec = 0;
+            pctr++;
+            triP = 0;
+            vertP = 0;
+            march();
+            renderMesh();
+        }
+
+        /*Regenerate Lattice and Connections, when changing Dimensions of Lattice*/
+        void Regen()
+        {
+            startObjs();
+            startEngine();
+        }
+
+        //Unity and Sample specific
+        void Update()
+        {
+            //Update FPS and counters every second
+            //if (lt + 1 < Time.time)
+            //{
+            //	lt = Time.time;
+            //	GUIText guit = (GUIText)GameObject.Find("guit").guiText;
+            //	guit.text = "T:" + triP + " V:" + vertP + " C:" + cubec + " FPS:" + (int)(1f / Time.deltaTime);
+            //}
+
+            blobs[0][0] = .12f + .12f * (float)Mathf.Sin((float)Time.time * .50f);
+            blobs[0][2] = .06f + .23f * (float)Mathf.Cos((float)Time.time * .2f);
+            blobs[1][0] = .12f + .12f * (float)Mathf.Sin((float)Time.time * .2f);
+            blobs[1][2] = -.23f + .10f * (float)Mathf.Cos((float)Time.time * 1f);
+            blobs[2][1] = -.03f + .24f * (float)Mathf.Sin((float)Time.time * .35f);
+            blobs[3][1] = .126f + .10f * (float)Mathf.Cos((float)Time.time * .1f);
+            blobs[4][0] = .206f + .1f * (float)Mathf.Cos((float)Time.time * .5f);
+            blobs[4][1] = .056f + .2f * (float)Mathf.Sin((float)Time.time * .3f);
+            blobs[4][2] = .25f + .08f * (float)Mathf.Cos((float)Time.time * .2f);
+
+            transform.Rotate(Time.deltaTime * 10f, 0, Time.deltaTime * .6f);
+
+            doFrame();
+        }
+
+        //Unity and Sample Specific
+        void Start()
+        {
+            lt = 0f;
+            blobs = new float[5][];
+            blobs[0] = new float[] { .16f, .26f, .16f, .13f };
+            blobs[1] = new float[] { .13f, -.134f, .35f, .12f };
+            blobs[2] = new float[] { -.18f, .125f, -.25f, .16f };
+            blobs[3] = new float[] { -.13f, .23f, .255f, .13f };
+            blobs[4] = new float[] { -.18f, .125f, .35f, .12f };
+            isoLevel = 1.95f;
+            Regen();
+        }
+
+
+        /*Unity Specific starting of engine*/
+        void startEngine()
+        {
+            ((MeshFilter)GetComponent("MeshFilter")).mesh = new Mesh();
+        }
+
+        /*Generate the Cube Lattice
+          All shared vertices and edges are connected across cubes,
+          it's not perfect in that the edges along the lower index borders
+          are not connected, but all the rest are, this shouldn't make any
+          noticeable visual impact, and have no performance impact unless
+          a blob lies along those borders*/
+        private void startObjs()
+        {
+            int i;
+            float jx, jy, jz;
+            int ijx, ijy, ijz;
+            int pointCount = ((dimX + 1) * (dimY + 1) * (dimZ + 1));
+            int cubeCount = (dimX * dimY * dimZ);
+            int edgeCount = (cubeCount * 3) + ((2 * dimX * dimY) + (2 * dimX * dimZ) + (2 * dimY * dimZ)) + dimX + dimY + dimZ; //Ideal Edge Count
+            int edgeNow = edgeCount + ((dimX * dimY) + (dimY * dimZ) + (dimZ * dimX)) * 2; //Haven't combined the edges of the 0 index borders
+
+            //Should be a pretty safe amount
+            int tmpv = (int)(dimX * dimY * dimZ / 7);
+            tadam = tmpv * 4;
+            fv = new Vector3[tmpv];
+            fn = new Vector3[tmpv];
+            fuv = new Vector2[tmpv];
+
+            //Pretty save amount of Tris as well
+            ft = new int[(int)(cubeCount * .75)];
+
+            newVertex = new Vector3[300000];
+            newTri = new int[300000];
+            newNormal = new Vector3[300000];
+            tada = new Vector3[tadam * 2];
+            tada2 = new Vector2[tadam * 2];
+
+            //newUV=new Vector2[300000];
+            _cubes = new mcCube[cubeCount];
+            _points = new mcPoint[pointCount];
+            _edges = new mcEdge[edgeNow];
+
+            for (i = 0; i < tadam * 2; i++)
+            {
+                tada[i] = new Vector3(0, 0, 0);
+                tada2[i] = new Vector2(0, 0);
+            }
+
+            for (i = 0; i < edgeNow; i++)
+            {
+                _edges[i] = new mcEdge(-1);
+            }
+
+
+            i = 0;
+            for (jx = 0.0f; jx <= dimX; jx++)
+            {
+                for (jy = 0.0f; jy <= dimY; jy++)
+                {
+                    for (jz = 0.0f; jz <= dimZ; jz++)
+                    {
+                        _points[i] = new mcPoint((jx / dimX) - .5f, (jy / dimY) - .5f, (jz / dimZ) - .5f, (int)jx, (int)jy, (int)jz, this);
+
+                        i++;
+                    }
+                }
+            }
+
+            for (i = 0; i < cubeCount; i++)
+            {
+                _cubes[i] = new mcCube();
+            }
+            int ep = 0;
+
+            mcCube c;
+            mcCube tc;
+            i = 0;
+
+            int topo = 0;
+            for (ijx = 0; ijx < dimX; ijx++)
+            {
+                for (ijy = 0; ijy < dimY; ijy++)
+                {
+                    for (ijz = 0; ijz < dimZ; ijz++)
+                    {
+                        c = _cubes[i];
+                        i++;
+                        c.px = ijx; c.py = ijy; c.pz = ijz;
+
+                        mcPoint[] cpt = c.points;
+                        cpt[0] = getPoint(ijx, ijy, ijz);
+                        cpt[1] = getPoint(ijx + 1, ijy, ijz);
+                        cpt[2] = getPoint(ijx + 1, ijy + 1, ijz);
+                        cpt[3] = getPoint(ijx, ijy + 1, ijz);
+                        cpt[4] = getPoint(ijx, ijy, ijz + 1);
+                        cpt[5] = getPoint(ijx + 1, ijy, ijz + 1);
+                        cpt[6] = getPoint(ijx + 1, ijy + 1, ijz + 1);
+                        cpt[7] = getPoint(ijx, ijy + 1, ijz + 1);
+
+                        mcEdge[] e = c.edges;
+                        e[5] = _edges[ep++]; e[5].axisI = 1;
+                        e[6] = _edges[ep++]; e[6].axisI = 0;
+                        e[10] = _edges[ep++]; e[10].axisI = 2;
+
+                        tc = getCube(ijx + 1, ijy, ijz);
+                        if (tc != null) { tc.edges[11] = e[10]; tc.edges[7] = e[5]; }
+
+                        tc = getCube(ijx, ijy + 1, ijz);
+                        if (tc != null) { tc.edges[4] = c.edges[6]; tc.edges[9] = c.edges[10]; }
+
+                        tc = getCube(ijx, ijy + 1, ijz + 1);
+                        if (tc != null) { tc.edges[0] = c.edges[6]; }
+
+                        tc = getCube(ijx + 1, ijy, ijz + 1);
+                        if (tc != null) { tc.edges[3] = c.edges[5]; }
+
+                        tc = getCube(ijx + 1, ijy + 1, ijz);
+                        if (tc != null) { tc.edges[8] = c.edges[10]; }
+
+                        tc = getCube(ijx, ijy, ijz + 1);
+                        if (tc != null) { tc.edges[1] = c.edges[5]; tc.edges[2] = c.edges[6]; }
+
+                        if (e[0] == null)
+                        {
+                            e[0] = _edges[ep++]; e[0].axisI = 0;
+                        }
+                        if (e[1] == null)
+                        {
+                            e[1] = _edges[ep++]; e[1].axisI = 1;
+                        }
+                        if (e[2] == null)
+                        {
+                            e[2] = _edges[ep++]; e[2].axisI = 0;
+                        }
+                        else { topo++; }
+                        if (e[3] == null)
+                        {
+                            e[3] = _edges[ep++]; e[3].axisI = 1;
+                        }
+                        if (e[4] == null)
+                        {
+                            e[4] = _edges[ep++]; e[4].axisI = 0;
+                        }
+                        if (e[7] == null)
+                        {
+                            e[7] = _edges[ep++]; e[7].axisI = 1;
+                        }
+                        if (e[8] == null)
+                        {
+                            e[8] = _edges[ep++]; e[8].axisI = 2;
+                        }
+                        if (e[9] == null)
+                        {
+                            e[9] = _edges[ep++]; e[9].axisI = 2;
+                        }
+                        if (e[11] == null)
+                        {
+                            e[11] = _edges[ep++]; e[11].axisI = 2;
+                        }
+                    }
+                }
+            }
+        }
+
+        /*Courtesy of http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/*/
+        private int[,] triTable = new int[,]
+            {{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+        {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+        {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+        {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+        {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
+        {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+        {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+        {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+        {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+        {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
+        {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
+        {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
+        {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+        {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+        {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+        {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+        {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
+        {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+        {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+        {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
+        {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
+        {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
+        {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+        {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+        {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+        {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+        {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
+        {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
+        {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
+        {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+        {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
+        {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+        {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
+        {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+        {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
+        {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
+        {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
+        {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+        {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
+        {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+        {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
+        {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+        {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+        {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
+        {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+        {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
+        {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+        {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
+        {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+        {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+        {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
+        {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
+        {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
+        {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+        {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+        {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
+        {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
+        {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+        {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
+        {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
+        {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
+        {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
+
+
+        {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+        {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+        {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+        {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
+        {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+        {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
+        {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+        {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
+        {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
+        {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
+        {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+        {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+        {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
+        {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
+        {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+        {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
+        {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+        {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+        {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
+        {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
+        {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
+        {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
+        {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
+        {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+        {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+        {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+        {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
+        {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+        {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
+        {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
+        {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+        {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
+        {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
+        {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+        {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+        {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
+        {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
+        {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
+        {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
+        {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+        {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
+        {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+
+
+        {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
+        {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+        {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
+        {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+        {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+        {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
+        {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+        {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
+        {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
+        {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
+        {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
+        {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
+        {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
+        {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
+        {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
+        {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
+        {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
+        {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
+        {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+        {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
+        {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
+        {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
+        {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
+        {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
+        {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
+        {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
+        {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+        {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
+        {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
+        {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
+        {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
+        {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
+        {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
+        {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
+        {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
+        {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
+        {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+        {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
+        {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
+        {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
+        {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+        {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+        {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+        {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
+        {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
+        {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
+        {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
+        {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
+        {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
+        {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
+        {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+        {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
+        {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
+        {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
+        {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+        {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
+        {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
+        {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
+        {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
+        {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
+        {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+        {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
+        {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
+        {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
+        {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
+        {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+        {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
+        {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+        {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+        {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+        {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
+        {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+        {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
+        {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+        {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
+
+
+        private int[] edgeTable = new int[] {
+        0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
+        0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
+        0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
+        0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
+        0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
+        0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
+        0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
+        0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
+        0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
+        0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
+        0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
+        0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
+        0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
+        0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
+        0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
+        0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
+        0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
+        0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
+        0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
+        0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
+        0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
+        0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
+        0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
+        0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
+        0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
+        0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
+        0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
+        0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
+        0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
+        0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
+        0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
+        0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0   };
+    }
+}
diff --git a/Assets/Scripts/Mesh/Metaball.cs.meta b/Assets/Scripts/Mesh/Metaball.cs.meta
new file mode 100644
index 0000000..90b6b2e
--- /dev/null
+++ b/Assets/Scripts/Mesh/Metaball.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f055b957fef29374d98e499595efe8c3
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/ObjectPooling/IPoolActions.cs b/Assets/Scripts/ObjectPooling/IPoolActions.cs
new file mode 100644
index 0000000..846d211
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/IPoolActions.cs
@@ -0,0 +1,10 @@
+﻿namespace UnityHelper.Pooling
+{
+    /// <summary>
+    /// Interface to remind you to add the return to pool function
+    /// </summary>
+    public interface IPoolActions
+    {
+        void ReturnObjectToPool();
+    }
+}
diff --git a/Assets/Scripts/ObjectPooling/IPoolActions.cs.meta b/Assets/Scripts/ObjectPooling/IPoolActions.cs.meta
new file mode 100644
index 0000000..50206f2
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/IPoolActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3e21db0c60302f24b927bcadd6fc6112
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/ObjectPooling/Images/Initialization.PNG b/Assets/Scripts/ObjectPooling/Images/Initialization.PNG
new file mode 100644
index 0000000..62f31dc
Binary files /dev/null and b/Assets/Scripts/ObjectPooling/Images/Initialization.PNG differ
diff --git a/Assets/Scripts/ObjectPooling/Images/PoolObject.PNG b/Assets/Scripts/ObjectPooling/Images/PoolObject.PNG
new file mode 100644
index 0000000..f530287
Binary files /dev/null and b/Assets/Scripts/ObjectPooling/Images/PoolObject.PNG differ
diff --git a/Assets/Scripts/ObjectPooling/Images/PoolObjectLook.PNG b/Assets/Scripts/ObjectPooling/Images/PoolObjectLook.PNG
new file mode 100644
index 0000000..57ed200
Binary files /dev/null and b/Assets/Scripts/ObjectPooling/Images/PoolObjectLook.PNG differ
diff --git a/Assets/Scripts/ObjectPooling/Images/SpawnObject.PNG b/Assets/Scripts/ObjectPooling/Images/SpawnObject.PNG
new file mode 100644
index 0000000..8641e8d
Binary files /dev/null and b/Assets/Scripts/ObjectPooling/Images/SpawnObject.PNG differ
diff --git a/Assets/Scripts/ObjectPooling/Pool.cs b/Assets/Scripts/ObjectPooling/Pool.cs
new file mode 100644
index 0000000..817ca60
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/Pool.cs
@@ -0,0 +1,84 @@
+﻿using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace UnityHelper.Pooling
+{
+    [Serializable]
+    public class Pool
+    {
+        /// <summary>
+        /// The objects that you want to add to the pool
+        /// </summary>
+        public List<PoolObject> objects_to_pool = new List<PoolObject>();
+
+        /// <summary>
+        /// All the objects that were added to the pool
+        /// </summary>
+        private List<GameObject> pool_objects = new List<GameObject>();
+
+        /// <summary>
+        /// Initializes the pool in your scene
+        /// </summary>
+        public void Start_Pool()
+        {
+            var pool = new GameObject("Pool");
+
+            foreach (var item in objects_to_pool)
+            {
+                var sub_parent = new GameObject(item.obj_to_pool.name);
+
+                for (int i = 0; i < item.amount_to_pool; i++)
+                {
+                    var _obj = UnityEngine.Object.Instantiate(item.obj_to_pool);
+                    _obj.transform.SetParent(sub_parent.transform, false);
+                    _obj.SetActive(false);
+                    pool_objects.Add(_obj);
+                }
+
+                sub_parent.transform.SetParent(pool.transform, false);
+            }
+        }
+
+        /// <summary>
+        /// Gets the item from the pool and spawns it at the required position
+        /// </summary>
+        /// <param name="type">The type of script in the pool that you need to spawn</param>
+        /// <param name="position">The position where you want the item to spawn</param>
+        /// <returns>A component of the needed type</returns>
+        public Component Spawn_Item(Type type, Vector3 position, Quaternion direction)
+        {
+            foreach (GameObject item in pool_objects)
+            {
+                Component comp = null;
+                item.TryGetComponent(type, out comp);
+
+                if (comp == null)
+                    continue;
+
+                if (item.activeSelf)
+                    continue;
+
+                item.transform.position = position;
+                item.transform.rotation = direction;
+                item.SetActive(true);
+                return comp;
+
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Brings the item back to the pool
+        /// </summary>
+        /// <param name="item">The item to bring back to the pool</param>
+        public void Return_Item(GameObject item)
+        {
+            item.SetActive(false);
+            item.transform.position = Vector3.zero;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/ObjectPooling/Pool.cs.meta b/Assets/Scripts/ObjectPooling/Pool.cs.meta
new file mode 100644
index 0000000..ac6cbc2
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/Pool.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fa158cddf415eb0449d203dbd26ec022
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/ObjectPooling/PoolObject.cs b/Assets/Scripts/ObjectPooling/PoolObject.cs
new file mode 100644
index 0000000..fa2cdf6
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/PoolObject.cs
@@ -0,0 +1,22 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace UnityHelper.Pooling
+{
+    [Serializable]
+    public class PoolObject
+    {
+        /// <summary>
+        /// The gameobject that you want to spawn
+        /// </summary>
+        public GameObject obj_to_pool;
+        /// <summary>
+        /// The amount of objects that you want to spawn
+        /// </summary>
+        public int amount_to_pool;
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/ObjectPooling/PoolObject.cs.meta b/Assets/Scripts/ObjectPooling/PoolObject.cs.meta
new file mode 100644
index 0000000..a654e61
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/PoolObject.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b201e930468ede54195a559247b03027
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/ObjectPooling/README.md b/Assets/Scripts/ObjectPooling/README.md
new file mode 100644
index 0000000..695b61d
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/README.md
@@ -0,0 +1,39 @@
+<h1> Object pooling helper class </h1>
+<br>
+<h3> These scripts help you set up an object pooling system in your game. It's pretty simple to use, let me show you how: </h3>
+
+<br>
+
+
+<h3> 1. Initializing the pool </h3>
+<a> As you can see in the image bellow, you can initialize the pool by creating a new pool and then calling it in the start. </a>
+
+![Init Image](https://github.com/LesserKnownThings/UnityLibrary/blob/object_pooling/Assets/Scripts/ObjectPooling/Images/Initialization.PNG)
+
+ You'll also have to add the namespace that the pool class is in **using UnityHelper.Pooling;**
+ 
+ <h3> 2. Before you start the game </h3>
+ You will have to add the objects that you want the pool to instantiate when it starts. As you can see in the image bellow, the pool object looks like this in the editor:
+ 
+ ![Look Image](https://github.com/LesserKnownThings/UnityLibrary/blob/object_pooling/Assets/Scripts/ObjectPooling/Images/PoolObjectLook.PNG)
+ 
+ The pool contains a List of objects that you want to instantiate in the scene. The objects are of type **PoolObject** which you can see here:
+ 
+  ![List Image](https://github.com/LesserKnownThings/UnityLibrary/blob/object_pooling/Assets/Scripts/ObjectPooling/Images/PoolObject.PNG)
+  
+  The **obj_to_pool** is the gameobject that you want to instantiate and the **amount_to_pool** is the amount of objects that you want to instantiate.
+  
+  <h3> 3. Spawning the objects in the scene </h3>
+  Spawning an object is very easy, the **Pool** class comes with a function called **Spawn_Item(Type type, Vector3 position, Quaternion direction)** it returns a **Component** so you can get direct reference to the object. Here's how you do it:
+  
+  ![Spawn Image](https://github.com/LesserKnownThings/UnityLibrary/blob/object_pooling/Assets/Scripts/ObjectPooling/Images/SpawnObject.PNG)
+  
+  In my example I have a custom Object created by me called **CubeObj** it doesn't do much, but it helps with the example. So when you spawn an item in the scene you have to give the function the following parameters:
+  
+  >**Type** the typeof object that the list needs to look for and spawn it in the scene
+  
+  >**Position** the position where the item should spawn
+  
+  >**Rotation** the rotation of the item
+  
+   One more thing to remember. Pool has a function to bring back the objects to the pool, but it requires the object as a parameter. That's why I made an interface called **IPoolActions** that comes with **ReturnObjectToPool** void and will help you return the items to the pool. It's pretty easy, to return an item you simply have to **gameobject.SetActive(false)** and also reset its position **transform.position = Vector3.zero**. 
diff --git a/Assets/Scripts/ObjectPooling/README.md.meta b/Assets/Scripts/ObjectPooling/README.md.meta
new file mode 100644
index 0000000..a7a1a90
--- /dev/null
+++ b/Assets/Scripts/ObjectPooling/README.md.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 39978d1555c9ede47adb909257a1bb01
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Texture.meta b/Assets/Scripts/Texture.meta
new file mode 100644
index 0000000..25ffb0f
--- /dev/null
+++ b/Assets/Scripts/Texture.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 21723003e773f1d44a6ff8203e46f395
+folderAsset: yes
+timeCreated: 1594958189
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Texture/GradientTextureMaker.cs.meta b/Assets/Scripts/Texture/GradientTextureMaker.cs.meta
new file mode 100644
index 0000000..eb407b4
--- /dev/null
+++ b/Assets/Scripts/Texture/GradientTextureMaker.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8fd686556c4ac49449e619d0aa69b9da
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Texture/WebCamDisplay.cs b/Assets/Scripts/Texture/WebCamDisplay.cs
new file mode 100644
index 0000000..12bf6c8
--- /dev/null
+++ b/Assets/Scripts/Texture/WebCamDisplay.cs
@@ -0,0 +1,21 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+// usage: attach this script to any gameobject in which you want to render the webcam display
+// create a material, use Unlit/Texture as a shader and place it to the gameobject's material placeholder in the mesh renderer component
+
+namespace UnityLibrary
+{
+    public class WebCamDisplay : MonoBehaviour
+    {
+        void Start()
+        {
+            WebCamTexture webCam = new WebCamTexture();
+            webCam.deviceName = WebCamTexture.devices[0].name;
+            this.GetComponent<MeshRenderer>().material.mainTexture = webCam;
+            webCam.Play();
+        }
+    }
+}
+
diff --git a/Assets/Scripts/Texture/WebCamDisplay.cs.meta b/Assets/Scripts/Texture/WebCamDisplay.cs.meta
new file mode 100644
index 0000000..9976b84
--- /dev/null
+++ b/Assets/Scripts/Texture/WebCamDisplay.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c15440579c94fd245b85260bce402884
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Tools.meta b/Assets/Scripts/Tools.meta
new file mode 100644
index 0000000..406b9bb
--- /dev/null
+++ b/Assets/Scripts/Tools.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4887b891f87d1bc47a7ae210331d1ea7
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Tools/TerrainTreeReplacer.cs.meta b/Assets/Scripts/Tools/TerrainTreeReplacer.cs.meta
new file mode 100644
index 0000000..daa176e
--- /dev/null
+++ b/Assets/Scripts/Tools/TerrainTreeReplacer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 91b800e4892ad554dbc156f9543e2402
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation.meta b/Assets/Scripts/UI/Animation.meta
new file mode 100644
index 0000000..deaf7f5
--- /dev/null
+++ b/Assets/Scripts/UI/Animation.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b234f75726460ce46b93b19b770c8385
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/GrowEffect.cs b/Assets/Scripts/UI/Animation/GrowEffect.cs
new file mode 100644
index 0000000..1f02171
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/GrowEffect.cs
@@ -0,0 +1,70 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+/// <summary>
+/// Script that when attached to an object will cause it to grow until it reaches the desired Scale
+/// </summary>
+public class GrowEffect : MonoBehaviour
+{
+    private enum Effect
+    {
+        BOUNCE_IN_OUT,
+        ELASTIC_IN_OUT,
+        LINEAR,
+        CIRCULAR_IN_OUT
+    }
+
+    [Header("Configuration")]
+    [Tooltip("The desired scale to grow to")]
+    [SerializeField] float m_desiredScale = 1.0f;
+    [Tooltip("How much time it will take to reach the desired scale")]
+    [SerializeField] float m_timeToReachDesiredScale = 1.0f;
+    [Tooltip("How much time it takes before the grow effect starts")]
+    [SerializeField] float m_timeToDelayStart = 0.0f;
+    [Tooltip("Effect on the grow animation")]
+    [SerializeField] Effect m_interpolationEffect = Effect.ELASTIC_IN_OUT;
+
+    //private member variables
+    private float m_currentTime = 0.0f;
+
+    private void OnEnable()
+    {
+        //set the local scale to zero so it can grow
+        transform.localScale = Vector3.zero;
+        m_currentTime = 0.0f;
+    }
+
+    void Update()
+    {
+        if (m_timeToDelayStart <= 0.0)
+        {
+            //increment current time by DT
+            m_currentTime += Time.deltaTime;
+
+            if (!(m_currentTime > m_timeToReachDesiredScale))
+            {
+                //Switch as to which effect will happen
+                switch (m_interpolationEffect)
+                {
+                    case Effect.BOUNCE_IN_OUT:
+                        gameObject.transform.localScale = (Vector3.one * Mathf.LerpUnclamped(0, m_desiredScale, Interpolation.BounceInOut(m_currentTime / m_timeToReachDesiredScale)));
+                        break;
+                    case Effect.ELASTIC_IN_OUT:
+                        gameObject.transform.localScale = (Vector3.one * Mathf.LerpUnclamped(0, m_desiredScale, Interpolation.ElasticInOut(m_currentTime / m_timeToReachDesiredScale)));
+                        break;
+                    case Effect.LINEAR:
+                        gameObject.transform.localScale = (Vector3.one * Mathf.LerpUnclamped(0, m_desiredScale, Interpolation.Linear(m_currentTime / m_timeToReachDesiredScale)));
+                        break;
+                    case Effect.CIRCULAR_IN_OUT:
+                        gameObject.transform.localScale = (Vector3.one * Mathf.LerpUnclamped(0, m_desiredScale, Interpolation.CircularInOut(m_currentTime / m_timeToReachDesiredScale)));
+                        break;
+                }
+            }
+        }
+        else
+        {
+            //reduce the delay start by DT
+            m_timeToDelayStart -= Time.deltaTime;
+        }
+    }
+}
diff --git a/Assets/Scripts/UI/Animation/GrowEffect.cs.meta b/Assets/Scripts/UI/Animation/GrowEffect.cs.meta
new file mode 100644
index 0000000..f0976a4
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/GrowEffect.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 4cc1ed66c8e377c40a814dec093b6f2e
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs b/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs
new file mode 100644
index 0000000..07b1323
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs
@@ -0,0 +1,52 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HelicopterGrowEffect : MonoBehaviour
+{
+    [Header("Configuration")]
+    [Tooltip("The desired Scale to reach")]
+    [SerializeField] float m_desiredScale = 1.0f;
+    [Tooltip("How much time it will take to reach the desired scale")]
+    [SerializeField] float m_timeToReachDesiredScale = 1.0f;
+    [Tooltip("How fast the helicopter effect will spin")]
+    [SerializeField] float m_rotationSpeed = 2.0f;
+    [Tooltip("the angle of rotation per frame")]
+    [SerializeField] float m_rotationAngle = 10.0f;
+
+    //private member variables
+    private float m_currentTime = 0.0f;
+    private Quaternion startingRotation = Quaternion.identity;
+
+    private void OnEnable()
+    {
+        m_currentTime = 0.0f;
+        //set the base transform to 0 so it can grow
+        transform.localScale = Vector3.zero;
+        //set the staring rotation variable to the current rotation
+        startingRotation = transform.rotation;
+        
+    }
+
+    void Update()
+    {
+        //increment current time by delta time
+        m_currentTime += Time.deltaTime;
+        if (m_currentTime <= m_timeToReachDesiredScale)
+        {
+            //rotate the object by the rotation angle and rotation speed
+            gameObject.transform.Rotate(Vector3.forward, (m_rotationAngle * (m_rotationSpeed * Time.deltaTime)));
+            //lerp the scale to the desired scale
+            gameObject.transform.localScale = (Vector3.one * Mathf.LerpUnclamped(0, m_desiredScale, Interpolation.ElasticInOut(m_currentTime/m_timeToReachDesiredScale)));
+            //leave the function
+            return;
+        }
+        else
+        {
+            //when the lerping is done set the rotation to the starting rotation
+            gameObject.transform.rotation = startingRotation;
+            //set the scale to the desired scale
+            gameObject.transform.localScale = Vector3.one * m_desiredScale;
+        }
+    }
+}
diff --git a/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs.meta b/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs.meta
new file mode 100644
index 0000000..100a5b6
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/HelicopterGrowEffect.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0e6ad0b8ea027294985b17ecc5ae35b0
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/ImageFade.cs b/Assets/Scripts/UI/Animation/ImageFade.cs
new file mode 100644
index 0000000..ee1a2ff
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/ImageFade.cs
@@ -0,0 +1,150 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+/// <summary>
+/// Component that when attached to an Image will fade in or out based on isFadingIn
+/// </summary>
+[RequireComponent(typeof(Image))]
+public class ImageFade : MonoBehaviour
+{
+    [Header("Configuration")]
+    [Tooltip("The Time it takes for the object to fade")]
+    [SerializeField] float m_timeToFade = 1.5f;
+    [Tooltip("The Time it takes before the object begins its fading")]
+    [SerializeField] float m_delayTimeToStart = 1.5f;
+    [Tooltip("Boolean to determing if the image is fading in or out")]
+    [SerializeField] bool m_isFadingIn = true;
+    [Tooltip("Boolean to determing if the image is a button or out")]
+    [SerializeField] bool m_doesHaveChildText = false;
+
+    //Sibling Components
+    private Image m_image;
+    private Text m_text;
+
+    //Member variables
+    private Color m_startColor;
+    private Color m_buttonTextStartColor;
+    private Color m_desiredEndColor;
+    private float m_timeElapsed = 0.0f;
+
+    private void OnEnable()
+    {
+        m_timeElapsed = 0.0f;
+        GetSiblingComponents();
+        //set the starting color to the color of the object
+        SetStartingColor();
+        //Start the Fade Coroutine
+        StartCoroutine(Fade());
+    }
+
+    //Function that sets the image color value determined on if you want to fade in or out
+    private void SetStartingColor()
+    {
+        //start color is set to the images current color
+        m_startColor = m_image.color;
+        //create new varibles to be messed with later
+        Color modifiedColor = m_startColor;
+        Color modifiedTextColor = new Color();
+        if (m_doesHaveChildText)
+        {
+            //if this had childed text component buttonTextStartcolor is set to the text's current color
+            m_buttonTextStartColor = m_text.color;
+            modifiedTextColor = m_buttonTextStartColor;
+        }
+        //sets the starting colors alpha values
+        if (m_isFadingIn)
+        {
+            //if it is fading in set alpha values to 0
+            modifiedColor.a = 0.0f;
+            modifiedTextColor.a = 0.0f;
+        }
+        //Set the current colors to be the modified colors for fading
+        m_image.color = modifiedColor;
+        if (m_doesHaveChildText)
+        {
+            m_text.color = modifiedTextColor;
+        }
+    }
+
+    /// <summary>
+    /// Gets the Required Sibling components
+    /// </summary>
+    private void GetSiblingComponents()
+    {
+        m_image = GetComponent<Image>();
+        if (m_doesHaveChildText)
+        {
+            m_text = GetComponentInChildren<Text>();
+        }
+    }
+
+    /// <summary>
+    /// Coroutine that fades the Image by lerping the alpha from either 1-0 or 0-1
+    /// </summary>
+    IEnumerator Fade()
+    {
+        //Wait for the delay 
+        yield return new WaitForSeconds(m_delayTimeToStart);
+        //create new color
+        Color newColor = m_startColor;
+        Color newTextColor = new Color();
+        if (m_doesHaveChildText)
+        {
+            newTextColor = m_text.color;
+        }
+        while (m_timeElapsed < m_timeToFade)
+        {
+            float time = m_timeElapsed / m_timeToFade;
+            if (m_isFadingIn)
+            {
+                //set new colors alpha to the lerp value of time
+                newColor.a = Mathf.Lerp(0, m_startColor.a, time);
+                if (m_doesHaveChildText)
+                {
+                    newTextColor.a = Mathf.Lerp(0, m_buttonTextStartColor.a, time);
+                }
+            }
+            else
+            {
+                //set new colors alpha to the lerp value of time
+                newColor.a = Mathf.Lerp(m_startColor.a, 0, time);
+                if (m_doesHaveChildText)
+                {
+                    newTextColor.a = Mathf.Lerp(m_buttonTextStartColor.a, 0, time);
+                }
+            }
+            //set image color to the new color
+            if (m_doesHaveChildText)
+            {
+                m_text.color = newTextColor;
+            }
+            m_image.color = newColor;
+            //add deltaTime to time elapsed
+            m_timeElapsed += Time.deltaTime;
+            yield return null;
+        }
+        //when the loop finishes set the colors to be what they are supposed to be
+        if (m_isFadingIn)
+        {
+            m_image.color = m_startColor;
+            if (m_doesHaveChildText)
+            {
+                m_text.color = m_buttonTextStartColor;
+            }
+        }
+        else
+        {
+            //if not is fading in set the alpha values to 0
+            Color desiredColor = m_startColor;
+            desiredColor.a = 0.0f;
+            m_image.color = desiredColor;
+            if(m_doesHaveChildText)
+            {
+                desiredColor = m_buttonTextStartColor;
+                desiredColor.a = 0.0f;
+                m_text.color = desiredColor;
+            }
+        }
+    }
+}
diff --git a/Assets/Scripts/UI/Animation/ImageFade.cs.meta b/Assets/Scripts/UI/Animation/ImageFade.cs.meta
new file mode 100644
index 0000000..379c833
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/ImageFade.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b538d7b1930f56747a8f9bb73ad5c33b
+timeCreated: 1594958194
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/LerpFromOffset.cs b/Assets/Scripts/UI/Animation/LerpFromOffset.cs
new file mode 100644
index 0000000..80d74de
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/LerpFromOffset.cs
@@ -0,0 +1,108 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class LerpFromOffset : MonoBehaviour
+{
+    /// <summary>
+    /// Effect Enum only to be used by this class, for chossing which interpolation effect to use
+    /// </summary>
+    private enum Effect
+    {
+        BOUNCE_OUT,
+        ELASTIC_OUT,
+        LINEAR,
+        CIRCULAR_OUT,
+        CIRCULAR_IN,
+        CIRCULAR_IN_OUT,
+        INVERSE_CIRCULAR_IN_OUT
+    }
+
+    [Header("Configuration")]
+    [Tooltip("The The Effect you would like to happen")]
+    [SerializeField] Effect m_effect = Effect.LINEAR;
+    [Tooltip("The direction you want the object to lerp from")]
+    [SerializeField] Vector3 m_offsetDirection = Vector3.zero;
+    [Tooltip("The the distnace you want to multiply the direction by")]
+    [SerializeField] float m_offsetDistance = 1.0f;
+    [Tooltip("How much time it will take for the object to reach its original position")]
+    [SerializeField] float m_timeToReachPosition = 1.5f;
+    [Tooltip("How much time it will take to start moving")]
+    [SerializeField] float m_delayStart = 1.5f;
+
+
+    //Memeber variables
+    private Vector3 m_offset = Vector3.zero;
+    private Vector3 m_desiredPos = Vector3.zero;
+    private float m_currentTime = 0.0f;
+
+    void OnEnable()
+    {
+        m_offset = Vector3.zero;
+        m_desiredPos = Vector3.zero;
+        m_currentTime = 0.0f;
+
+        Setup();
+    }
+    /// <summary>
+    /// Method that sets up all of the needed things and places the object at the calcuated offset
+    /// </summary>
+    void Setup()
+    {
+        //calculate offset position
+        m_offset = m_offsetDirection.normalized * m_offsetDistance;
+        //set the desired position to the current position
+        m_desiredPos = transform.position;
+        //move the object to the offset position to begin lerping
+        transform.position = m_desiredPos + m_offset;
+    }
+
+    void Update()
+    {
+        if (m_delayStart <= 0.0f)
+        {
+            //add deltaTime to the current time
+            m_currentTime += Time.deltaTime;
+            if (m_currentTime < m_timeToReachPosition)
+            {
+                //based on which effect is selected this will lerp from the curretn position to the desired position
+                switch (m_effect)
+                {
+                    //Lerps using the BouceOut Interpolation
+                    case Effect.BOUNCE_OUT:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.BounceOut(m_currentTime / m_timeToReachPosition));
+                        break;
+                    //Lerps using the ElasticOut Interpolation
+                    case Effect.ELASTIC_OUT:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.ElasticOut(m_currentTime / m_timeToReachPosition));
+                        break;
+                    //Lerps using the Linear Interpolation
+                    case Effect.LINEAR:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.Linear(m_currentTime / m_timeToReachPosition));
+                        break;
+                    //Lerps using the CircularOut Interpolation
+                    case Effect.CIRCULAR_OUT:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.CircularOut(m_currentTime / m_timeToReachPosition));
+                        break;
+                    //Lerps using the CircularInOut Interpolation
+                    case Effect.CIRCULAR_IN_OUT:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.CircularInOut(m_currentTime / m_timeToReachPosition));
+                        break;
+                    //Lerps using the CircularIn Interpolation
+                    case Effect.CIRCULAR_IN:
+                        transform.position = Vector3.LerpUnclamped(m_desiredPos + m_offset, m_desiredPos, Interpolation.SineIn(m_currentTime / m_timeToReachPosition));
+                        break;
+                }
+
+                return;
+            }
+            //set the current position to the desired position
+            transform.position = m_desiredPos;
+        }
+        else
+        {
+            //remove Deltatime from the m_delayStart
+            m_delayStart -= Time.deltaTime;
+        }
+    }
+}
diff --git a/Assets/Scripts/UI/Animation/LerpFromOffset.cs.meta b/Assets/Scripts/UI/Animation/LerpFromOffset.cs.meta
new file mode 100644
index 0000000..d8ca5be
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/LerpFromOffset.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f461de9f20f87e64ea1c52f11e14a559
+timeCreated: 1594958195
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/Shared.meta b/Assets/Scripts/UI/Animation/Shared.meta
new file mode 100644
index 0000000..86f437c
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/Shared.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4318a6e62d3fa9b4e80b0a7ce121d0f3
+folderAsset: yes
+timeCreated: 1594958191
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/UI/Animation/Shared/Interpolation.cs b/Assets/Scripts/UI/Animation/Shared/Interpolation.cs
new file mode 100644
index 0000000..e441366
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/Shared/Interpolation.cs
@@ -0,0 +1,220 @@
+﻿using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+/// <summary>
+/// Methods that make LERPs nice
+/// </summary>
+static public class Interpolation
+{
+
+    static public float Linear(float t)
+    {
+        return t;
+    }
+
+    static public float SmoothStep(float t)
+    {
+        return t * t * (3.0f - 2.0f * t);
+    }
+
+    static public float SmootherStep(float t)
+    {
+        return t * t * t * (t * (6.0f * t - 15.0f) + 10.0f);
+    }
+
+    static public float SineIn(float t)
+    {
+        return Mathf.Sin((t - 1.0f) * Mathf.PI * 0.5f) + 1.0f;
+    }
+
+    static public float SineOut(float t)
+    {
+        return Mathf.Sin(t * Mathf.PI * 0.5f);
+    }
+
+    static public float SineInOut(float t)
+    {
+        return (1.0f - Mathf.Cos(t * Mathf.PI)) * 0.5f;
+    }
+
+    static public float QuadraticIn(float t)
+    {
+        return t * t;
+    }
+
+    static public float QuadraticOut(float t)
+    {
+        return -(t * (t - 2.0f));
+    }
+
+    static public float QuadraticInOut(float t)
+    {
+        return (t < 0.5f) ? 2.0f * (t * t) : (-2.0f * t * t) + (4 * t) - 1;
+    }
+
+    static public float CubicIn(float t)
+    {
+        return Mathf.Pow(t, 3);
+    }
+
+    static public float CubicOut(float t)
+    {
+        return 1.0f - Mathf.Pow(1.0f - t, 3);
+    }
+
+    static public float CubicInOut(float t)
+    {
+        return (t < 0.5f) ? Mathf.Pow(t * 2.0f, 3) * 0.5f : 1.0f - Mathf.Pow((1.0f - t) * 2.0f, 3) * 0.5f;
+    }
+
+    static public float QuarticIn(float t)
+    {
+        return Mathf.Pow(t, 4);
+    }
+
+    static public float QuarticOut(float t)
+    {
+        return 1.0f - Mathf.Pow(1.0f - t, 4);
+    }
+
+    static public float QuarticInOut(float t)
+    {
+        return (t < 0.5f) ? Mathf.Pow(t * 2.0f, 4) * 0.5f : 1.0f - Mathf.Pow((1.0f - t) * 2.0f, 4) * 0.5f;
+    }
+
+    static public float QuinticIn(float t)
+    {
+        return Mathf.Pow(t, 5);
+    }
+
+    static public float QuinticOut(float t)
+    {
+        return 1.0f - Mathf.Pow(1.0f - t, 5);
+    }
+
+    static public float QuinticInOut(float t)
+    {
+        return (t < 0.5f) ? Mathf.Pow(t * 2.0f, 5) * 0.5f : 1.0f - Mathf.Pow((1.0f - t) * 2.0f, 5) * 0.5f;
+    }
+
+    static public float CircularIn(float t)
+    {
+        return 1.0f - Mathf.Sqrt(1.0f - (t * t));
+    }
+
+    static public float CircularOut(float t)
+    {
+        return Mathf.Sqrt((2.0f - t) * t);
+    }
+
+    static public float CircularInOut(float t)
+    {
+        return (t < 0.5f) ? (1.0f - Mathf.Sqrt(1.0f - 4.0f * (t * t ))) * 0.5f : (Mathf.Sqrt(-((t * 2.0f) - 3.0f) * ((t * 2.0f) - 1.0f)) + 1.0f) * 0.5f;
+    }
+
+    static public float ExpoIn(float t)
+    {
+        return (t == 0.0f) ? 0.0f : Mathf.Pow(2, 10.0f * (t - 1.0f));
+    }
+
+    static public float ExpoOut(float t)
+    {
+        return (t == 1.0f) ? 1.0f : 1.0f - Mathf.Pow(2, -10.0f * t);
+    }
+
+    static public float ExpoInOut(float t)
+    {
+        if (t == 0.0f || t == 1.0f) return t;
+
+        t = t * 2.0f;
+        if (t < 1.0f)
+        {
+            return Mathf.Pow(1024.0f, t - 1.0f) * 0.5f;
+        }
+
+        return (-Mathf.Pow(2.0f, -10.0f * (t - 1.0f)) + 2.0f) * 0.5f;
+    }
+
+    static public float BackIn(float t)
+    {
+        float s = 1.70158f;
+
+        return t * t * ((s + 1.0f) * t - s);
+    }
+
+    static public float BackOut(float t)
+    {
+        float s = 1.70158f;
+
+        t = (t - 1.0f);
+        return t * t * ((s + 1.0f) * t + s) + 1.0f;
+    }
+
+    static public float BackInOut(float t)
+    {
+        float s = 1.70158f * 1.525f;
+
+        t = t * 2.0f;
+        if (t < 1.0f)
+        {
+            return (t * t * ((s + 1.0f) * t - s)) * 0.5f;
+        }
+
+        t = t - 2.0f;
+        return (t * t * ((s + 1.0f) * t + s) + 2.0f) * 0.5f;
+    }
+    
+    static public float BounceIn(float t)
+    {
+        return 1.0f - BounceOut(1.0f - t);
+    }
+
+    static public float BounceOut(float t)
+    {
+        if (t < (1.0f / 2.75f))         return 7.5625f * t * t;
+        else if (t < (2.0f / 2.75f))    return 7.5625f * (t -= (1.5f / 2.75f)) * t + 0.75f;
+        else if (t < (2.5f / 2.75f))    return 7.5625f * (t -= (2.25f / 2.75f)) * t + 0.9375f;
+
+        return 7.5625f * (t -= (2.625f / 2.75f)) * t + 0.984375f;
+    }
+
+    static public float BounceInOut(float t)
+    {
+        if (t < 0.5f) return BounceIn(t * 2.0f) * 0.5f;
+
+        return BounceOut(t * 2.0f - 1.0f) * 0.5f + 0.5f;
+    }
+
+    static public float ElasticIn(float t)
+    {
+        if (t == 0.0f || t == 1.0f) return t;
+
+        return -Mathf.Pow(2.0f, 10.0f * (t - 1.0f)) * Mathf.Sin((t - 1.1f) * 5.0f * Mathf.PI);
+    }
+
+    static public float ElasticOut(float t)
+    {
+        if (t == 0.0f || t == 1.0f) return t;
+
+        return Mathf.Pow(2.0f, -10.0f * t) * Mathf.Sin((t - 0.1f) * 5.0f * Mathf.PI) + 1.0f;
+    }
+
+    static public float ElasticInOut(float t)
+    {
+        if (t == 0.0f || t == 1.0f) return t;
+
+        t = t * 2.0f;
+        if (t < 1.0f)
+        {
+            return Mathf.Pow(2, 10.0f * (t - 1)) * Mathf.Sin((t - 1.1f) * 5.0f * Mathf.PI) * -0.5f;
+        }
+
+        return (Mathf.Pow(2.0f, -10.0f * (t - 1)) * Mathf.Sin((t - 1.1f) * 5.0f * Mathf.PI) * 0.5f) + 1.0f;
+    }
+
+    static public float CatmullRom(float t, float p0, float p1, float p2, float p3)
+    {
+        return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t * t + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t * t * t);
+    }
+}
diff --git a/Assets/Scripts/UI/Animation/Shared/Interpolation.cs.meta b/Assets/Scripts/UI/Animation/Shared/Interpolation.cs.meta
new file mode 100644
index 0000000..1479c95
--- /dev/null
+++ b/Assets/Scripts/UI/Animation/Shared/Interpolation.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0bafe5c15fee7b64f84801f9b22ff905
+timeCreated: 1594958193
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Utilities/GlobalVariables.cs b/Assets/Scripts/Utilities/GlobalVariables.cs
new file mode 100644
index 0000000..b1ab699
--- /dev/null
+++ b/Assets/Scripts/Utilities/GlobalVariables.cs
@@ -0,0 +1,65 @@
+using System.Collections.Generic;
+
+/// <summary>
+/// A simple static class to get and set globally accessible variables through a key-value approach.
+/// </summary>
+/// <remarks>
+/// <para>Uses a key-value approach (dictionary) for storing and modifying variables.</para>
+/// <para>It also uses a lock to ensure consistency between the threads.</para>
+/// </remarks>
+public static class GlobalVariables
+{
+
+    private static readonly object lockObject = new object();
+    private static Dictionary<string, object> variablesDictionary = new Dictionary<string, object>();
+
+    /// <summary>
+    /// The underlying key-value storage (dictionary).
+    /// </summary>
+    /// <value>Gets the underlying variables dictionary</value>
+    public static Dictionary<string, object> VariablesDictionary => variablesDictionary;
+
+    /// <summary>
+    /// Retrieves all global variables.
+    /// </summary>
+    /// <returns>The global variables dictionary object.</returns>
+    public static Dictionary<string, object> GetAll()
+    {
+        return variablesDictionary;
+    }
+
+    /// <summary>
+    /// Gets a variable and casts it to the provided type argument.
+    /// </summary>
+    /// <typeparam name="T">The type of the variable</typeparam>
+    /// <param name="key">The variable key</param>
+    /// <returns>The casted variable value</returns>
+    public static T Get<T>(string key)
+    {
+        if (variablesDictionary == null || !variablesDictionary.ContainsKey(key))
+        {
+            return default(T);
+        }
+
+        return (T)variablesDictionary[key];
+    }
+
+    /// <summary>
+    /// Sets the variable, the existing value gets overridden.
+    /// </summary>
+    /// <remarks>It uses a lock under the hood to ensure consistensy between threads</remarks>
+    /// <param name="key">The variable name/key</param>
+    /// <param name="value">The variable value</param>
+    public static void Set(string key, object value)
+    {
+        lock (lockObject)
+        {
+            if (variablesDictionary == null)
+            {
+                variablesDictionary = new Dictionary<string, object>();
+            }
+            variablesDictionary[key] = value;
+        }
+    }
+
+}
diff --git a/Assets/Scripts/Utilities/SaveUtility.cs b/Assets/Scripts/Utilities/SaveUtility.cs
new file mode 100644
index 0000000..96bb9b0
--- /dev/null
+++ b/Assets/Scripts/Utilities/SaveUtility.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Utilities
+{
+    public static class SaveUtility
+    {
+        /*  --- Usage ----
+         
+        -- Lets say we have a serialized class called Save --
+        
+        [System.Serializable]
+        public class Save
+        {
+            public int testInt;
+            public List<string> TestStrings = new List<string>();
+        }
+        
+        -- For saving this class we would do the following -->> --
+        
+        Save save = new Save();
+        save.testInt = 5;
+        save.TestStrings.Add("Hello");
+        
+        SaveUtility.Save(save, "testPath");
+        
+        -- For loading this class we would do the following --> --
+        
+        Save save = SaveUtility.Load<Save, string>("testPath");
+        
+        Important : Since save operation uses PlayerPrefs and does not contain any encrypting. Dont save&load any confidential data using this class.
+        
+        --- End of Usage ---- */
+        
+        
+        /// <summary>
+        /// Saves any serialized class on the specified savepath.
+        /// </summary>
+        public static void Save<T>(this T save, string savePath)
+            where T : class
+        {
+            var data = JsonUtility.ToJson(save);
+            PlayerPrefs.SetString(savePath, data);
+        }
+
+        /// <summary>
+        /// Loads and returns the saved class on the specified savepath.
+        /// If no save is found, it will return a new instance of the class.
+        /// </summary>
+        /// <returns>Loaded serialized save class</returns>
+        public static T Load<T,TSt>(TSt path)
+            where T : class, new()
+            where TSt : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>
+        {
+            var data = new T();
+
+            if (PlayerPrefs.HasKey(path as string) == false)
+            {
+                data.Save(path as string);
+            }
+
+            {
+                data = JsonUtility.FromJson<T>(PlayerPrefs.GetString(path as string));
+            }
+            return data;
+        }
+    }
+}
diff --git a/Assets/Scripts/Utilities/SaveUtility.cs.meta b/Assets/Scripts/Utilities/SaveUtility.cs.meta
new file mode 100644
index 0000000..390ab63
--- /dev/null
+++ b/Assets/Scripts/Utilities/SaveUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7d8aad24cf3d7485c9507bf763b79d42
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Debug.meta b/Assets/Shaders/2D/Debug.meta
new file mode 100644
index 0000000..5150edd
--- /dev/null
+++ b/Assets/Shaders/2D/Debug.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 31f63f34ba5d21c4d8ad3c2a63a85220
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Debug/HSVDebugger.shader.meta b/Assets/Shaders/2D/Debug/HSVDebugger.shader.meta
new file mode 100644
index 0000000..e9b9382
--- /dev/null
+++ b/Assets/Shaders/2D/Debug/HSVDebugger.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3454bedd801ec8049958fc2054f6265e
+timeCreated: 1594958198
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Effects/ColorCycle.shader b/Assets/Shaders/2D/Effects/ColorCycle.shader
new file mode 100644
index 0000000..3d0c754
--- /dev/null
+++ b/Assets/Shaders/2D/Effects/ColorCycle.shader
@@ -0,0 +1,64 @@
+Shader "UnityLibrary/2D/Effects/ColorCycle"
+{
+	Properties
+	{
+		_MainTex ("Grayscale", 2D) = "white" {}
+		_GradientTex ("Gradient", 2D) = "white" {}
+		_Speed("Speed",float) = 1
+	}
+
+	SubShader
+	{
+		Tags { "RenderType"="Opaque" }
+		LOD 100
+
+		Pass
+		{
+			CGPROGRAM
+			#pragma vertex vert
+			#pragma fragment frag
+			
+			#include "UnityCG.cginc"
+
+			struct appdata
+			{
+				float4 vertex : POSITION;
+				float2 uv : TEXCOORD0;
+			};
+
+			struct v2f
+			{
+				float2 uv : TEXCOORD0;
+				float4 vertex : SV_POSITION;
+			};
+
+			sampler2D _MainTex;
+			sampler2D _GradientTex;
+			float4 _MainTex_ST;
+			float _Speed;
+
+			v2f vert (appdata v)
+			{
+				v2f o;
+				o.vertex = UnityObjectToClipPos(v.vertex);
+				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
+				return o;
+			}
+			
+			fixed4 frag (v2f i) : SV_Target
+			{
+				// get (grayscale texture) pixel color
+				float gray = tex2D(_MainTex, i.uv).r;
+
+				// get scrolling
+				float scroll = frac(gray + _Time.x*_Speed);
+
+				// get gradient color from texture
+				fixed4 col = tex2D(_GradientTex,float2(scroll,0.5));
+
+				return col;
+			}
+			ENDCG
+		}
+	}
+}
diff --git a/Assets/Shaders/2D/Effects/ColorCycle.shader.meta b/Assets/Shaders/2D/Effects/ColorCycle.shader.meta
new file mode 100644
index 0000000..133c82f
--- /dev/null
+++ b/Assets/Shaders/2D/Effects/ColorCycle.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 330b6be9f3a469e42a73504b34d499c6
+timeCreated: 1594958198
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Effects/Glow.shader b/Assets/Shaders/2D/Effects/Glow.shader
index 775b7d2..97da796 100644
--- a/Assets/Shaders/2D/Effects/Glow.shader
+++ b/Assets/Shaders/2D/Effects/Glow.shader
@@ -1,117 +1,31 @@
-﻿Shader "Custom/Glow" {
-
- 
-
+@@ -1,117 +1,30 @@
+Shader "Custom/Glow" {
     Properties {
-
- 
-
         _Color ("Color", Color) = (1,1,1,1)
-
- 
-
     }
 
- 
-
     SubShader {
-
- 
-
         Tags { "RenderType"="Transparent" }
-
- 
-
         LOD 200
-
- 
-
         ZTest Always
-
- 
-
         Cull Off
 
- 
-
-        
-
- 
-
- 
-
- 
-
         CGPROGRAM
-
- 
-
         #pragma surface surf Lambert decal:add
 
- 
-
- 
-
- 
-
         float4 _Color;
 
- 
-
- 
-
- 
-
         struct Input {
-
- 
-
             float3 viewDir;
-
- 
-
             float3 worldNormal;
-
- 
-
         };
 
- 
-
- 
-
- 
-
         void surf (Input IN, inout SurfaceOutput o) {
-
- 
-
-            o.Alpha = _Color.a * pow(abs(dot(normalize(IN.viewDir),
-
- 
-
-                normalize(IN.worldNormal))),4.0);
-
- 
-
+            o.Alpha = _Color.a * pow(abs(dot(normalize(IN.viewDir), normalize(IN.worldNormal))), 4.0);
             o.Emission = _Color.rgb * o.Alpha;
-
- 
-
         }
-
- 
-
         ENDCG
-
- 
-
-    } 
-
- 
+    }
 
     FallBack "Diffuse"
-
- 
-
 }
diff --git a/Assets/Shaders/2D/LineRenderer/LineRenderer_ClipStartEnd.shader b/Assets/Shaders/2D/LineRenderer/LineRenderer_ClipStartEnd.shader
new file mode 100644
index 0000000..7971f3c
--- /dev/null
+++ b/Assets/Shaders/2D/LineRenderer/LineRenderer_ClipStartEnd.shader
@@ -0,0 +1,62 @@
+Shader "UnityLibrary/LineRenderer/ClipStartEnd"
+{
+	Properties
+	{
+		_MainTex ("Texture", 2D) = "white" {}
+		_Start ("Start", Range (0.0,1.0)) = 0.25
+		_End ("End", Range (0.0,1.0)) = 0.75
+	}
+
+	SubShader
+	{
+		Tags { "RenderType"="Opaque" }
+		LOD 100
+
+		Pass
+		{
+		CGPROGRAM
+		#pragma vertex vert
+		#pragma fragment frag
+
+		#include "UnityCG.cginc"
+
+		struct appdata
+		{
+			float4 vertex : POSITION;
+			float2 uv : TEXCOORD0;
+			float4 color : COLOR;
+		};
+
+		struct v2f
+		{
+			float2 uv : TEXCOORD0;
+			float4 vertex : SV_POSITION;
+			float4 color : COLOR;
+		};
+
+		sampler2D _MainTex;
+		float4 _MainTex_ST;
+		float _Start;
+		float _End;
+
+
+		v2f vert (appdata v)
+		{
+			v2f o;
+			o.vertex = UnityObjectToClipPos(v.vertex);
+			o.uv = TRANSFORM_TEX(v.uv, _MainTex);
+			o.color = v.color;
+			return o;
+		}
+
+		fixed4 frag(v2f i) : SV_Target
+		{
+			fixed4 col = tex2D(_MainTex, i.uv)*i.color;
+			clip(-(i.uv.x <_Start || i.uv.x > _End));
+			// return fixed4(i.uv.x,0,0,0); // view UV x
+			return col;
+		}
+		ENDCG
+		}
+	}
+} 
\ No newline at end of file
diff --git a/Assets/Shaders/2D/Patterns.meta b/Assets/Shaders/2D/Patterns.meta
new file mode 100644
index 0000000..cb80a0f
--- /dev/null
+++ b/Assets/Shaders/2D/Patterns.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 399c75202c145034baa2c9d01212a27c
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Patterns/CirclesPattern.shader b/Assets/Shaders/2D/Patterns/CirclesPattern.shader
new file mode 100644
index 0000000..1ed7c16
--- /dev/null
+++ b/Assets/Shaders/2D/Patterns/CirclesPattern.shader
@@ -0,0 +1,68 @@
+// draws circle pattern
+Shader "UnityLibrary/2D/Patterns/Circles"
+{
+    Properties
+    {
+        _Color ("Color", Color) = (1,1,1,1)
+        _CircleSize("Size", Range(0,1)) = 0.5
+        _Circles("Amount", Range(1,64)) = 8
+    }
+
+    SubShader
+    {
+        Tags { "RenderType"="Opaque" }
+        LOD 200
+
+        CGPROGRAM
+        #pragma surface surf Standard fullforwardshadows vertex:vert
+        #pragma target 3.0
+
+        struct Input
+        {
+            float2 texcoord : TEXCOORD0;
+        };
+
+        sampler2D _MainTex;
+        float _Circles;
+        float _CircleSize;
+
+        half _Glossiness;
+        half _Metallic;
+        fixed4 _Color;
+
+        UNITY_INSTANCING_BUFFER_START(Props)
+        UNITY_INSTANCING_BUFFER_END(Props)
+
+        // https://thebookofshaders.com/09/
+        float2 tile(float2 _st, float _zoom)
+        {
+            _st *= _zoom;
+            return frac(_st);
+        }
+
+        // https://thebookofshaders.com/07/
+        float Circle(float2 _st, float _radius)
+        {
+            float2 dist = _st - float2(0.5, 0.5);
+            return 1. - smoothstep(_radius - (_radius * 0.01), _radius + (_radius * 0.01), dot(dist, dist) * 4.0);
+        }
+
+        void vert(inout appdata_full v, out Input o) 
+        {
+            UNITY_INITIALIZE_OUTPUT(Input, o);
+            o.texcoord = v.texcoord;
+        }
+
+        void surf (Input IN, inout SurfaceOutputStandard o)
+        {
+            float2 st = IN.texcoord.xy;
+            float c = Circle(tile(st, round(_Circles)), _CircleSize);
+            o.Albedo = c.rrr* _Color;
+            o.Metallic = _Metallic;
+            o.Smoothness = _Glossiness;
+            o.Alpha = c.r;
+        }
+        ENDCG
+    }
+    FallBack "Diffuse"
+}
diff --git a/Assets/Shaders/2D/Patterns/CirclesPattern.shader.meta b/Assets/Shaders/2D/Patterns/CirclesPattern.shader.meta
new file mode 100644
index 0000000..2c456fe
--- /dev/null
+++ b/Assets/Shaders/2D/Patterns/CirclesPattern.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6a51e5184b408be4b8a27b34dfca55d2
+timeCreated: 1594958200
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Patterns/ScrollingFill.shader b/Assets/Shaders/2D/Patterns/ScrollingFill.shader
new file mode 100644
index 0000000..f6e685e
--- /dev/null
+++ b/Assets/Shaders/2D/Patterns/ScrollingFill.shader
@@ -0,0 +1,70 @@
+// animated scrolling texture with fill amount
+// https://unitycoder.com/blog/2020/03/13/shader-scrolling-texture-with-fill-amount/
+
+Shader "UnityLibrary/Patterns/ScrollingFill"
+{
+    Properties
+    {
+        _MainTex ("Texture", 2D) = "white" {}
+        _Fill("Fill", Range(0.0,1.0)) = 0.5
+        _Speed("Speed", float) = 5
+    }
+
+    SubShader
+    {
+        Tags { "RenderType"="Opaque" }
+        LOD 100
+
+        Pass
+        {
+            CGPROGRAM
+            #pragma vertex vert
+            #pragma fragment frag
+
+            #include "UnityCG.cginc"
+
+            struct appdata
+            {
+                float4 vertex : POSITION;
+                float2 uv : TEXCOORD0;
+            };
+
+            struct v2f
+            {
+                float2 uv : TEXCOORD0;
+                float4 vertex : SV_POSITION;
+            };
+
+            sampler2D _MainTex;
+            float4 _MainTex_ST;
+            float _Fill;
+            float _Speed;
+
+            v2f vert (appdata v)
+            {
+                v2f o;
+                o.vertex = UnityObjectToClipPos(v.vertex);
+                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
+                return o;
+            }
+
+            fixed4 frag(v2f i) : SV_Target
+            {
+                // get scroll value
+                float2 scroll = float2(0, frac(_Time.x*_Speed));
+
+                // sample texture
+                fixed4 col = tex2D(_MainTex, i.uv -scroll);
+
+                // discard if uv.y is below below cut value
+                clip(step(i.uv.y, _Fill * _MainTex_ST.y)-0.1);
+
+                return col;
+
+                // make un-animated part black
+                //return col*step(i.uv.y, _Cut * _MainTex_ST.y);
+            }
+            ENDCG
+        }
+    }
+}
diff --git a/Assets/Shaders/2D/Patterns/ScrollingFill.shader.meta b/Assets/Shaders/2D/Patterns/ScrollingFill.shader.meta
new file mode 100644
index 0000000..f42b404
--- /dev/null
+++ b/Assets/Shaders/2D/Patterns/ScrollingFill.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 34a3246941ff91e4d9a6bf3a8c9bbf56
+timeCreated: 1594958198
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Special.meta b/Assets/Shaders/2D/Special.meta
new file mode 100644
index 0000000..01540e4
--- /dev/null
+++ b/Assets/Shaders/2D/Special.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 52b47187126304f448c235620a02b491
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Special/RayMarching.shader b/Assets/Shaders/2D/Special/RayMarching.shader
new file mode 100644
index 0000000..fa70a89
--- /dev/null
+++ b/Assets/Shaders/2D/Special/RayMarching.shader
@@ -0,0 +1,108 @@
+// "ShaderToy Tutorial - Ray Marching for Dummies!"  https://www.shadertoy.com/view/XlGBW3
+// by Martijn Steinrucken aka BigWings/CountFrolic - 2018
+// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
+// This shader is part of a tutorial on YouTube https://youtu.be/PGtv-dBi2wE
+// 01-10-2019 converted to unity shader (with some adjusted variable names) : unitycoder.com
+
+Shader "UnityLibrary/2D/Special/RayMarching"
+{
+    SubShader
+    {
+        Tags { "RenderType"="Opaque" }
+        LOD 100
+
+        Pass
+        {
+            CGPROGRAM
+            #pragma vertex vert
+            #pragma fragment frag
+
+			      #define MAX_STEPS 100 // maximum raycast loops
+			      #define MAX_DIST 100. // ray cannot go further than this distance
+			      #define SURF_DIST .01 // how near to surface we should raycast to
+
+            struct appdata
+            {
+                float4 vertex : POSITION;
+                float2 uv : TEXCOORD0;
+            };
+
+            struct v2f
+            {
+                float4 vertex : SV_POSITION;
+				        float2 uv : TEXCOORD0;
+			      };
+
+            // returns distance to the scene objects (we have 2 objects here, sphere and ground plane)
+            float GetDist(float3 p) 
+            {
+              float4 sphere = float4(0, 1, 6, 1); // x,y,z,radius
+              float sphereDist = length(p - sphere.xyz) - sphere.w;
+              float planeDist = p.y;
+              float distance = min(sphereDist, planeDist); // return closest distance
+              return distance;
+            }
+
+
+            // jump along the ray until we get close enough to some of our objects
+            float RayMarch(float3 rayOrigin, float3 rayDirection)
+            {
+              float distanceOrigin = 0.;
+              for (int i = 0; i < MAX_STEPS; i++) 
+              {
+                float3 p = rayOrigin + rayDirection * distanceOrigin;
+                float dS = GetDist(p);
+                distanceOrigin += dS;
+                if (distanceOrigin > MAX_DIST || dS < SURF_DIST) break;
+              }
+              return distanceOrigin;
+            }
+
+            float3 GetNormal(float3 p) 
+            {
+              float d = GetDist(p);
+              float2 e = float2(.01, 0);
+              float3 n = d - float3(GetDist(p - e.xyy),GetDist(p - e.yxy),GetDist(p - e.yyx));
+              return normalize(n);
+            }
+
+            float GetLight(float3 p) 
+            {
+              float3 lightPos = float3(0, 5, 6);
+              lightPos.xz += float2(sin(_Time.y), cos(_Time.y)) * 2.0;
+              float3 l = normalize(lightPos - p);
+              float3 n = GetNormal(p);
+              float dif = clamp(dot(n, l), 0.0, 1.0);
+              float d = RayMarch(p + n * SURF_DIST * 2.0, l);
+              if (d < length(lightPos - p)) dif *= 0.1;
+              return dif;
+            }
+
+            v2f vert (appdata v)
+            {
+                v2f o;
+                o.vertex = UnityObjectToClipPos(v.vertex);
+			        	o.uv = v.uv;
+                return o;
+            }
+
+            fixed4 frag(v2f i) : SV_Target
+            {
+              float2 uv = (i.uv - 0.5);
+              float3 col = float3(0,0,0);
+
+              float3 rayOrigin = float3(0,1,0);
+              float3 rayDirection = normalize(float3(uv.x, uv.y, 1));
+
+              float distance = RayMarch(rayOrigin, rayDirection);
+              float3 p = rayOrigin + rayDirection * distance;
+
+              float dif = GetLight(p);
+              col = float3(dif,dif,dif);
+
+              return float4(col,1);
+            }
+            ENDCG
+        } // pass
+    } // subshader
+} // shader
diff --git a/Assets/Shaders/2D/Special/RayMarching.shader.meta b/Assets/Shaders/2D/Special/RayMarching.shader.meta
new file mode 100644
index 0000000..b0a2666
--- /dev/null
+++ b/Assets/Shaders/2D/Special/RayMarching.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 80f5dea6657e52b43b3c354aae5371e3
+timeCreated: 1594958202
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/2D/Sprites/Diffuse (2 Sided Light).shader b/Assets/Shaders/2D/Sprites/Diffuse (2 Sided Light).shader
new file mode 100644
index 0000000..cf47668
--- /dev/null
+++ b/Assets/Shaders/2D/Sprites/Diffuse (2 Sided Light).shader	
@@ -0,0 +1,79 @@
+// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
+// lights up sprites from both sides
+
+Shader "Sprites/Diffuse (2 Sided Light)"
+{
+	Properties
+	{
+		[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
+		_Color("Tint", Color) = (1,1,1,1)
+		[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
+		[HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
+		[HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
+		[PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
+		[PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
+	}
+
+		SubShader
+		{
+			Tags
+			{
+				"Queue" = "Transparent"
+				"IgnoreProjector" = "True"
+				"RenderType" = "Transparent"
+				"PreviewType" = "Plane"
+				"CanUseSpriteAtlas" = "True"
+			}
+
+			Cull Off
+			Lighting Off
+			ZWrite Off
+			Blend One OneMinusSrcAlpha
+
+			CGPROGRAM
+			//#pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
+			#pragma surface surf TwoSidedLambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
+			#pragma multi_compile_local _ PIXELSNAP_ON
+			#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
+			#include "UnitySprites.cginc"
+
+			struct Input
+			{
+				float2 uv_MainTex;
+				fixed4 color;
+			};
+
+			// added "abs" 2 sided lighting
+			half4 LightingTwoSidedLambert(SurfaceOutput s, half3 lightDir, half atten) {
+				half NdotL = abs(dot(s.Normal, lightDir));
+				half4 c;
+				c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten);
+				c.a = s.Alpha;
+				return c;
+			}
+
+			void vert(inout appdata_full v, out Input o)
+			{
+				v.vertex = UnityFlipSprite(v.vertex, _Flip);
+
+				#if defined(PIXELSNAP_ON)
+				v.vertex = UnityPixelSnap(v.vertex);
+				#endif
+
+				//v.normal.z *= -1;
+
+				UNITY_INITIALIZE_OUTPUT(Input, o);
+				o.color = v.color * _Color * _RendererColor;
+			}
+
+			void surf(Input IN, inout SurfaceOutput o)
+			{
+				fixed4 c = SampleSpriteTexture(IN.uv_MainTex) * IN.color;
+				o.Albedo = c.rgb * c.a;
+				o.Alpha = c.a;
+			}
+			ENDCG
+		}
+
+			Fallback "Transparent/VertexLit"
+}
diff --git a/Assets/Shaders/2D/Sprites/FlipBook.shader.meta b/Assets/Shaders/2D/Sprites/FlipBook.shader.meta
new file mode 100644
index 0000000..044c4e0
--- /dev/null
+++ b/Assets/Shaders/2D/Sprites/FlipBook.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4ebeb70d938436745afc3679d29342ee
+timeCreated: 1594958199
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Effects.meta b/Assets/Shaders/3D/Effects.meta
new file mode 100644
index 0000000..9729063
--- /dev/null
+++ b/Assets/Shaders/3D/Effects.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 721c02c14478d394eb2cd50453c1dd46
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Effects/Diffuse Stipple Transparency.shader b/Assets/Shaders/3D/Effects/Diffuse Stipple Transparency.shader
new file mode 100644
index 0000000..853c4cf
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/Diffuse Stipple Transparency.shader	
@@ -0,0 +1,52 @@
+// Diffuse shader with stipple transparency
+// by Alex Ocias - https://ocias.com
+// source: https://ocias.com/blog/unity-stipple-transparency-shader/
+// based on an article by Digital Rune: https://www.digitalrune.com/Blog/Post/1743/Screen-Door-Transparency
+
+// Simplified Diffuse shader. Differences from regular Diffuse one:
+// - no Main Color
+// - fully supports only 1 directional light. Other lights can affect it, but it will be per-vertex/SH.
+
+Shader "Ocias/Diffuse (Stipple Transparency)" {
+Properties {
+	_MainTex ("Base (RGB)", 2D) = "white" {}
+	_Transparency ("Transparency", Range(0,1)) = 1.0
+}
+SubShader {
+	Tags { "RenderType"="Opaque" }
+	LOD 150
+
+CGPROGRAM
+#pragma surface surf Lambert noforwardadd
+
+sampler2D _MainTex;
+
+struct Input {
+	float2 uv_MainTex;
+	float4 screenPos;
+};
+
+half _Transparency;
+
+void surf (Input IN, inout SurfaceOutput o) {
+	fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
+	o.Albedo = c.rgb;
+	o.Alpha = c.a;
+
+	// Screen-door transparency: Discard pixel if below threshold.
+	float4x4 thresholdMatrix =
+	{  1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
+	  13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
+	   4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
+	  16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
+	};
+	float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
+	float2 pos = IN.screenPos.xy / IN.screenPos.w;
+	pos *= _ScreenParams.xy; // pixel position
+	clip(_Transparency - thresholdMatrix[fmod(pos.x, 4)] * _RowAccess[fmod(pos.y, 4)]);
+}
+ENDCG
+}
+
+Fallback "Mobile/VertexLit"
+}
diff --git a/Assets/Shaders/3D/Effects/Standard Stipple Transparency.shader b/Assets/Shaders/3D/Effects/Standard Stipple Transparency.shader
new file mode 100644
index 0000000..2e312da
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/Standard Stipple Transparency.shader	
@@ -0,0 +1,58 @@
+// Standard shader with stipple transparency
+// by Alex Ocias - https://ocias.com
+// source: https://ocias.com/blog/unity-stipple-transparency-shader/
+// based on an article by Digital Rune: https://www.digitalrune.com/Blog/Post/1743/Screen-Door-Transparency
+
+Shader "Ocias/Standard (Stipple Transparency)" {
+	Properties {
+		_Color ("Color", Color) = (1,1,1,1)
+		_MainTex ("Albedo (RGB)", 2D) = "white" {}
+		_Glossiness ("Smoothness", Range(0,1)) = 0.5
+		_Metallic ("Metallic", Range(0,1)) = 0.0
+	}
+	SubShader {
+		Tags { "RenderType"="Opaque" }
+		LOD 100
+		
+		CGPROGRAM
+		// Physically based Standard lighting model, and enable shadows on all light types
+		#pragma surface surf Standard fullforwardshadows
+
+		// Use shader model 3.0 target, to get nicer looking lighting
+		#pragma target 3.0
+
+		sampler2D _MainTex;
+
+		struct Input {
+			float2 uv_MainTex;
+			float4 screenPos;
+		};
+
+		half _Glossiness;
+		half _Metallic;
+		fixed4 _Color;
+
+		void surf (Input IN, inout SurfaceOutputStandard o) {
+			// Albedo comes from a texture tinted by color
+			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
+			o.Albedo = c.rgb;
+			// Metallic and smoothness come from slider variables
+			o.Metallic = _Metallic;
+			o.Smoothness = _Glossiness;
+
+			// Screen-door transparency: Discard pixel if below threshold.
+			float4x4 thresholdMatrix =
+			{  1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
+			  13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
+			   4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
+			  16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
+			};
+			float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
+			float2 pos = IN.screenPos.xy / IN.screenPos.w;
+			pos *= _ScreenParams.xy; // pixel position
+			clip(c.a - thresholdMatrix[fmod(pos.x, 4)] * _RowAccess[fmod(pos.y, 4)]);
+		}
+		ENDCG
+	}
+	FallBack "Diffuse"
+}
diff --git a/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader b/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader
new file mode 100644
index 0000000..e519887
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader
@@ -0,0 +1,116 @@
+// 2 pass shader to draw object with blurry texture and slightly transparent when behind walls
+
+Shader "UnityLibrary/Standard/Effects/SeeThroughWalls"
+{
+	Properties
+	{
+		_Color("Color", Color) = (1,1,1,1)
+		_MainTex("Albedo (RGB)", 2D) = "white" {}
+		_Glossiness("Smoothness", Range(0,1)) = 0.5
+		_Metallic("Metallic", Range(0,1)) = 0.0
+		_BlurSize("BlurSize", float) = 10
+		_SeeThroughOpacity("SeeThroughOpacityAdjust", Range(0,1)) = 0.5
+	}
+
+		SubShader
+		{
+			// Regular Pass
+			Tags { "RenderType" = "Opaque" }
+			LOD 200
+
+			CGPROGRAM
+			// Physically based Standard lighting model, and enable shadows on all light types
+			#pragma surface surf Standard fullforwardshadows
+
+			// Use shader model 3.0 target, to get nicer looking lighting
+			#pragma target 3.0
+
+			sampler2D _MainTex;
+
+			struct Input
+			{
+				float2 uv_MainTex;
+			};
+
+			half _Glossiness;
+			half _Metallic;
+			fixed4 _Color;
+
+			// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
+			// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
+			// #pragma instancing_options assumeuniformscaling
+			UNITY_INSTANCING_BUFFER_START(Props)
+				// put more per-instance properties here
+			UNITY_INSTANCING_BUFFER_END(Props)
+
+			void surf(Input IN, inout SurfaceOutputStandard o)
+			{
+				// Albedo comes from a texture tinted by color
+				fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
+				o.Albedo = c.rgb;
+				// Metallic and smoothness come from slider variables
+				o.Metallic = _Metallic;
+				o.Smoothness = _Glossiness;
+				o.Alpha = c.a;
+			}
+			ENDCG
+
+			// see through pass
+
+			Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
+			LOD 200
+//			Blend OneMinusDstColor One // Soft Additive
+			Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
+//			Blend One OneMinusSrcAlpha // Premultiplied transparency
+//			Blend One One // Additive
+//			Blend OneMinusDstColor One // Soft Additive
+//			Blend DstColor Zero // Multiplicative
+//			Blend DstColor SrcColor // 2x Multiplicative
+
+			ZWrite Off
+			ZTest Greater
+
+			CGPROGRAM
+			// Physically based Standard lighting model, and enable shadows on all light types
+			#pragma surface surf Standard alpha:fade
+
+			// Use shader model 3.0 target, to get nicer looking lighting
+			#pragma target 3.0
+
+			sampler2D _MainTex;
+			float4 _MainTex_TexelSize;
+			float _BlurSize;
+			float _SeeThroughOpacity;
+
+			struct Input
+			{
+				float2 uv_MainTex;
+			};
+
+			half _Glossiness;
+			half _Metallic;
+			fixed4 _Color;
+
+			UNITY_INSTANCING_BUFFER_START(Props)
+				// put more per-instance properties here
+				UNITY_INSTANCING_BUFFER_END(Props)
+
+				void surf(Input IN, inout SurfaceOutputStandard o)
+				{
+				// small blur effect on the texture
+				fixed4 cR = tex2D(_MainTex, float2(IN.uv_MainTex.x + _MainTex_TexelSize.x * _BlurSize,IN.uv_MainTex.y));
+				fixed4 cL = tex2D(_MainTex, float2(IN.uv_MainTex.x - _MainTex_TexelSize.x * _BlurSize,IN.uv_MainTex.y));
+				fixed4 cT = tex2D(_MainTex, float2(IN.uv_MainTex.x,IN.uv_MainTex.y + _MainTex_TexelSize.y * _BlurSize));
+				fixed4 cB = tex2D(_MainTex, float2(IN.uv_MainTex.x,IN.uv_MainTex.y - _MainTex_TexelSize.y * _BlurSize));
+				fixed4 c = (cR + cL + cT + cB) * 0.25;
+				o.Albedo = c;
+				o.Metallic = _Metallic;
+				o.Smoothness = _Glossiness;
+				// make object also bit transparent
+				o.Alpha = c.a* _SeeThroughOpacity;
+			}
+			ENDCG
+
+		} // subshader
+			FallBack "Diffuse"
+} // shader
diff --git a/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader.meta b/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader.meta
new file mode 100644
index 0000000..be7cbb5
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/Standard-SeeThroughWalls.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 353df71fa3c6e5846a31afbe285baf57
+timeCreated: 1594958198
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader b/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader
new file mode 100644
index 0000000..6b8dbb7
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader
@@ -0,0 +1,127 @@
+// similar to height fog effect, but starts fading from camera.Y distance (with some offset)
+// modified standard shader, with custom lighting pass to make faded part completely black
+
+Shader "UnityLibrary/Standard/Effects/VerticalCameraDistance"
+{
+	Properties
+	{
+		_Color("Color", Color) = (1,1,1,1)
+		_MainTex("Albedo (RGB)", 2D) = "white" {}
+		//_BumpMap("Normalmap", 2D) = "bump" {}
+		_Glossiness("Smoothness", Range(0,1)) = 0.5
+		_Metallic("Metallic", Range(0,1)) = 0.0
+		_FadeToColor("FadeToColor", Color) = (0,0,0,1)
+		_FadeStartY("FadeStartFromCameraY", Float) = -2
+		_FadeEndY("FadeEndFromCameraY", Float) = -4
+	}
+
+	SubShader
+	{
+		Tags { "RenderType" = "Opaque" }
+		LOD 200
+
+		CGPROGRAM
+
+//			#pragma surface surf Standard fullforwardshadows vertex:vert
+		#pragma surface surf Custom fullforwardshadows // vertex:vert
+		#include "UnityPBSLighting.cginc"
+
+		struct appdata {
+			float4 vertex : POSITION;
+			float4 tangent : TANGENT;
+			float3 normal : NORMAL;
+			float2 texcoord : TEXCOORD0;
+			float2 texcoord1 : TEXCOORD1;
+			float2 texcoord2 : TEXCOORD2;
+		};
+
+		struct Input {
+			float2 uv_MainTex;
+			//float2 uv_BumpMap;
+			float3 worldPos;
+		};
+
+			// Metallic workflow
+			// modified from UnityPBSLighting.cginc
+			struct SurfaceOutputStandardCustom
+			{
+				fixed3 Albedo;      // base (diffuse or specular) color
+				float3 Normal;      // tangent space normal, if written
+				half3 Emission;
+				half Metallic;      // 0=non-metal, 1=metal
+				half Smoothness;    // 0=rough, 1=smooth
+				half Occlusion;     // occlusion (default 1)
+				fixed Alpha;        // alpha for transparencies
+				float Fader; // test
+			};
+
+			sampler2D _MainTex;
+			//sampler2D _BumpMap;
+
+			half _Glossiness;
+			half _Metallic;
+			fixed4 _Color;
+			fixed4 _FadeToColor;
+			float _FadeStartY;
+			float _FadeEndY;
+
+			float remap(float source, float sourceFrom, float sourceTo, float targetFrom, float targetTo)
+			{
+				return targetFrom + (source - sourceFrom)*(targetTo - targetFrom) / (sourceTo - sourceFrom);
+			}
+
+			// from UnityPBSLighting.cginc
+			inline half4 LightingCustom(SurfaceOutputStandardCustom s, float3 viewDir, UnityGI gi)
+			{
+				s.Normal = normalize(s.Normal);
+
+				half oneMinusReflectivity;
+				half3 specColor;
+				s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
+
+				// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
+				// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
+				half outputAlpha;
+				s.Albedo = PreMultiplyAlpha(s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
+
+				half4 c = UNITY_BRDF_PBS(s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
+				c.a = outputAlpha;
+
+				// make it black if outside range
+				return c*(1 - s.Fader);
+			}
+
+			inline void LightingCustom_GI(SurfaceOutputStandardCustom s,UnityGIInput data,inout UnityGI gi)
+			{
+				#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
+				gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal);
+				#else
+				Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Metallic));
+				gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
+				#endif
+			}
+
+			void surf(Input IN, inout SurfaceOutputStandardCustom o)
+			{
+				fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
+
+				// fade
+				float fadeStartY = _WorldSpaceCameraPos.y + _FadeStartY;
+				float fadeEndY = _WorldSpaceCameraPos.y + _FadeEndY;
+				float pixelY = clamp(IN.worldPos.y, fadeEndY, fadeStartY);
+				float distanceY = remap(pixelY, fadeStartY, fadeEndY, 0, 1);
+				c.rgb = lerp(c.rgb, _FadeToColor, distanceY);
+
+				o.Fader = distanceY;
+				o.Albedo = c.rgb;
+				// Metallic and smoothness come from slider variables
+				o.Metallic = _Metallic;
+				o.Smoothness = _Glossiness;
+				//o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
+				o.Alpha = c.a;
+
+			}
+			ENDCG
+	}
+	FallBack "Diffuse"
+}
diff --git a/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader.meta b/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader.meta
new file mode 100644
index 0000000..d4a4687
--- /dev/null
+++ b/Assets/Shaders/3D/Effects/VerticalCameraDistanceFade.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4b3fdf02746e56f4a87156674e1b493c
+timeCreated: 1594958199
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Standard.meta b/Assets/Shaders/3D/Standard.meta
new file mode 100644
index 0000000..61a16ba
--- /dev/null
+++ b/Assets/Shaders/3D/Standard.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2bc68b9180eac9c4584bd64f091ef2d3
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Standard/HueContrastSaturation.shader b/Assets/Shaders/3D/Standard/HueContrastSaturation.shader
new file mode 100644
index 0000000..ede2a56
--- /dev/null
+++ b/Assets/Shaders/3D/Standard/HueContrastSaturation.shader
@@ -0,0 +1,89 @@
+// source https://forum.unity.com/threads/adding-hue-saturation-and-contrast-to-standardshader.843697/#post-5572063
+
+Shader "UnityLibrary/Standard/HueContrastSaturation"
+{
+    Properties
+    {
+        _Color ("Color", Color) = (1,1,1,1)
+        _MainTex ("Albedo Map", 2D) = "black" {}
+        _BumpMap ("Normal Map", 2D) = "bump" {}
+        _MetallicGlossMap ("Metallic (R) Smoothness (A) Map", 2D) = "black" {}
+        _Hue ("Hue", Float) = 1.0
+        _Contrast ("Contrast", Float) = 1.0
+        _Saturation ("Saturation", Float) = 1.0      
+    }
+
+    Subshader
+    {
+        Tags { "RenderType" = "Opaque" }
+        CGPROGRAM
+        #pragma surface SurfaceShader Standard fullforwardshadows addshadow
+
+        sampler2D _MainTex, _BumpMap, _MetallicGlossMap;
+        float4 _Color;
+        float _Hue, _Contrast, _Saturation;
+
+        float4x4 contrastMatrix (float c)
+        {
+            float t = (1.0 - c) * 0.5;
+            return float4x4 (c, 0, 0, 0, 0, c, 0, 0, 0, 0, c, 0, t, t, t, 1);
+        }
+
+        float3 RGBToHSV(float3 c)
+        {
+            float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+            float4 p = lerp( float4( c.bg, K.wz ), float4( c.gb, K.xy ), step( c.b, c.g ) );
+            float4 q = lerp( float4( p.xyw, c.r ), float4( c.r, p.yzx ), step( p.x, c.r ) );
+            float d = q.x - min( q.w, q.y );
+            float e = 1.0e-10;
+            return float3( abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+        }
+
+        float3 HSVToRGB( float3 c )
+        {
+            float4 K = float4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
+            float3 p = abs( frac( c.xxx + K.xyz ) * 6.0 - K.www );
+            return c.z * lerp( K.xxx, saturate( p - K.xxx ), c.y );
+        }
+
+        float3 Hue( float3 p, float v )
+        {
+            p = RGBToHSV(p);
+            p.x *= v;
+            return HSVToRGB(p);
+        }
+
+        float3 Saturation( float3 p, float v )
+        {
+            p = RGBToHSV(p);
+            p.y *= v;
+            return HSVToRGB(p);
+        }
+
+        float3 Contrast( float3 p, float v )
+        {
+            return mul(float4(p,1.0), contrastMatrix(v)).rgb;
+        }
+
+        struct Input
+        {
+            float2 uv_MainTex;
+            float2 uv_BumpMap;
+            float2 uv_MetallicGlossMap;
+        };
+
+        void SurfaceShader (Input IN, inout SurfaceOutputStandard o)
+        {
+            float4 color = tex2D(_MainTex,IN.uv_MainTex) * _Color;
+            color.rgb = Hue(color.rgb, _Hue);
+            color.rgb = Saturation(color.rgb, _Saturation);
+            color.rgb = Contrast(color.rgb, _Contrast);
+            o.Albedo = color;
+            o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
+            o.Metallic = tex2D(_MetallicGlossMap, IN.uv_MetallicGlossMap).r;
+            o.Smoothness = tex2D(_MetallicGlossMap, IN.uv_MetallicGlossMap).a;
+        }
+
+        ENDCG
+    }
+}
diff --git a/Assets/Shaders/3D/Standard/HueContrastSaturation.shader.meta b/Assets/Shaders/3D/Standard/HueContrastSaturation.shader.meta
new file mode 100644
index 0000000..cc6cc14
--- /dev/null
+++ b/Assets/Shaders/3D/Standard/HueContrastSaturation.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6f585f7124fa4094fa1b503ac78e757b
+timeCreated: 1594958201
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader b/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader
new file mode 100644
index 0000000..6bcbf0e
--- /dev/null
+++ b/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader
@@ -0,0 +1,76 @@
+Shader "Unlit/Reverse_Disintegrate"
+{
+    Properties
+    {
+        _MainTex ("Texture", 2D) = "white" {}
+        _color("Color",color)=(1,1,1,1)
+        _Transparent("Transparency",float)=0.0
+        
+    }
+    SubShader
+    {
+        Tags {"Queue"="Transparent" "RenderType"="Transparent"}
+        LOD 100
+        ZWrite Off
+        Blend SrcAlpha OneMinusSrcAlpha
+         
+        Lighting Off
+        ColorMask RGB
+
+
+        Pass
+        {
+            CGPROGRAM
+            #pragma vertex vert
+            #pragma fragment frag
+            // make fog work
+            #pragma multi_compile_fog
+
+            #include "UnityCG.cginc"
+
+            struct appdata
+            {
+                float4 vertex : POSITION;
+                float2 uv : TEXCOORD0;
+            };
+
+sampler2D _MainTex;
+float4 _color;
+float _Transparent;
+            struct v2f
+            {
+                float2 uv : TEXCOORD0;
+                UNITY_FOG_COORDS(1)
+                float4 vertex : SV_POSITION;
+            };
+
+          
+            v2f vert (appdata v)
+            {
+                v2f o;
+                o.vertex = UnityObjectToClipPos(v.vertex);
+                o.uv = v.uv;
+                UNITY_TRANSFER_FOG(o,o.vertex);
+                return o;
+            }
+
+            fixed4 frag (v2f i) : SV_Target
+            {
+                // sample the texture
+                fixed4 col = tex2D(_MainTex, i.uv)*_color ;
+                
+                        
+                        _Transparent=_Transparent*(_Time.y*5000);
+                        if(_Transparent<8)
+                {
+                        col.a=_Transparent;
+                }
+                
+                // apply fog
+                UNITY_APPLY_FOG(i.fogCoord, col);
+                return col;
+            }
+            ENDCG
+        }
+    }
+}
diff --git a/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader.meta b/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader.meta
new file mode 100644
index 0000000..1ed747b
--- /dev/null
+++ b/Assets/Shaders/3D/Unlit/Reverse-DisIntegrate-Shader.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9c8f6c7a074ca5e42add15300bee781a
+timeCreated: 1594958191
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Water.meta b/Assets/Shaders/3D/Water.meta
new file mode 100644
index 0000000..dc054a6
--- /dev/null
+++ b/Assets/Shaders/3D/Water.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6f78ac9f8e56a074a9b3398b55a3798b
+folderAsset: yes
+timeCreated: 1594958190
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Shaders/3D/Water/WaterBox.shader b/Assets/Shaders/3D/Water/WaterBox.shader
new file mode 100644
index 0000000..ce38468
--- /dev/null
+++ b/Assets/Shaders/3D/Water/WaterBox.shader
@@ -0,0 +1,89 @@
+// water waves on a single mesh box
+// single mesh approach. It's a single 64x64x1 unit box with 128x128 divisions.
+// The shader is checking if the starting y for the vertex is >0.5 before it modifies the position,
+// and checking the normal is facing up before modifying that
+// source: @bgolus https://forum.unity.com/threads/intersect-box-with-wave-plane.826761/#post-5475174
+
+Shader "Custom/WaterBox"
+{
+    Properties
+    {
+        _Color ("Color", Color) = (1,1,1,1)
+        _Color2 ("Color 2", Color) = (1,1,1,1)
+        _Glossiness ("Smoothness", Range(0,1)) = 0.5
+    }
+    SubShader
+    {
+        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
+        LOD 200
+
+        CGINCLUDE
+        struct Input
+        {
+            float h;
+        };
+
+        half _Glossiness;
+        fixed4 _Color, _Color2;
+
+        void waves(inout appdata_full v, inout Input IN)
+        {
+            IN.h = 0.0;
+
+            float s0x, c0x, s1x, c1x;
+            float s0y, c0y, s1y, c1y;
+            sincos(v.vertex.x * 0.6 + _Time.y + v.vertex.z * 0.1, s0x, c0x);
+            sincos(v.vertex.z * 0.5 + _Time.y * 2.0 + v.vertex.x * 0.1, s0y, c0y);
+            sincos(v.vertex.x * 0.3 + _Time.y - v.vertex.z * 0.1, s1x, c1x);
+            sincos(v.vertex.z * 0.21 + _Time.y * 2.0 - v.vertex.x * 0.1, s1y, c1y);
+
+            float offset = (s0x + s0y) * 0.15 + (s1x + s1y) * 1.0 + 1.5;
+            if (v.vertex.y > 0.5)
+            {
+                v.vertex.y += offset;
+                IN.h = 0.0;
+                if (v.normal.y > 0.7)
+                {
+                    v.normal = normalize(v.normal + float3(c0y * 0.15 + c1y * 0.3, 0.0, c0x * 0.15 + c1x * 0.3));
+                }
+            }
+            else
+            {
+                IN.h = offset + 1.0;
+            }
+        }
+
+        void surf (Input IN, inout SurfaceOutputStandard o)
+        {
+            fixed4 color = lerp(_Color2, _Color, smoothstep(1.5, 0.0, pow(IN.h, 0.5)));
+            o.Albedo = color.rgb;
+            o.Metallic = 0;
+            o.Smoothness = _Glossiness;
+            o.Alpha = color.a;
+        }
+        ENDCG
+
+        Cull Front
+        CGPROGRAM
+        #pragma surface surf Standard alpha:premul vertex:vert
+        #pragma target 3.0
+
+        void vert(inout appdata_full v, out Input IN)
+        {
+           waves(v, IN);
+           v.normal = -v.normal;
+        }
+        ENDCG
+
+        Cull Back
+        CGPROGRAM
+        #pragma surface surf Standard alpha:premul vertex:vert
+        #pragma target 3.0
+
+        void vert(inout appdata_full v, out Input IN)
+        {
+           waves(v, IN);
+        }
+        ENDCG
+    }
+}
diff --git a/Assets/Shaders/3D/Water/WaterBox.shader.meta b/Assets/Shaders/3D/Water/WaterBox.shader.meta
new file mode 100644
index 0000000..ed4a685
--- /dev/null
+++ b/Assets/Shaders/3D/Water/WaterBox.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d43f18bcc0c85024ba6a0410b601cbee
+timeCreated: 1594958204
+licenseType: Free
+ShaderImporter:
+  defaultTextures: []
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Logos/Unity_Library_Black.png b/Logos/Unity_Library_Black.png
new file mode 100644
index 0000000..b5761a5
Binary files /dev/null and b/Logos/Unity_Library_Black.png differ
diff --git a/Logos/Unity_Library_White.png b/Logos/Unity_Library_White.png
new file mode 100644
index 0000000..f0d5651
Binary files /dev/null and b/Logos/Unity_Library_White.png differ
diff --git a/Logs/Packages-Update.log b/Logs/Packages-Update.log
new file mode 100644
index 0000000..b2e8054
--- /dev/null
+++ b/Logs/Packages-Update.log
@@ -0,0 +1,67 @@
+
+=== Fri Jul 17 09:30:37 2020
+
+Packages were changed.
+Update Mode: resetToDefaultDependencies
+
+The following packages were added:
+  com.unity.analytics@3.2.2
+  com.unity.purchasing@2.0.3
+  com.unity.ads@2.0.8
+  com.unity.textmeshpro@1.3.0
+  com.unity.package-manager-ui@2.0.7
+  com.unity.collab-proxy@1.2.15
+  com.unity.modules.ai@1.0.0
+  com.unity.modules.animation@1.0.0
+  com.unity.modules.assetbundle@1.0.0
+  com.unity.modules.audio@1.0.0
+  com.unity.modules.cloth@1.0.0
+  com.unity.modules.director@1.0.0
+  com.unity.modules.imageconversion@1.0.0
+  com.unity.modules.imgui@1.0.0
+  com.unity.modules.jsonserialize@1.0.0
+  com.unity.modules.particlesystem@1.0.0
+  com.unity.modules.physics@1.0.0
+  com.unity.modules.physics2d@1.0.0
+  com.unity.modules.screencapture@1.0.0
+  com.unity.modules.terrain@1.0.0
+  com.unity.modules.terrainphysics@1.0.0
+  com.unity.modules.tilemap@1.0.0
+  com.unity.modules.ui@1.0.0
+  com.unity.modules.uielements@1.0.0
+  com.unity.modules.umbra@1.0.0
+  com.unity.modules.unityanalytics@1.0.0
+  com.unity.modules.unitywebrequest@1.0.0
+  com.unity.modules.unitywebrequestassetbundle@1.0.0
+  com.unity.modules.unitywebrequestaudio@1.0.0
+  com.unity.modules.unitywebrequesttexture@1.0.0
+  com.unity.modules.unitywebrequestwww@1.0.0
+  com.unity.modules.vehicles@1.0.0
+  com.unity.modules.video@1.0.0
+  com.unity.modules.vr@1.0.0
+  com.unity.modules.wind@1.0.0
+  com.unity.modules.xr@1.0.0
+
+=== Fri Jul 17 09:51:50 2020
+
+Packages were changed.
+Update Mode: updateDependencies
+
+The following packages were added:
+  com.unity.2d.sprite@1.0.0
+  com.unity.2d.tilemap@1.0.0
+  com.unity.ide.rider@1.1.4
+  com.unity.ide.vscode@1.1.4
+  com.unity.modules.androidjni@1.0.0
+  com.unity.multiplayer-hlapi@1.0.4
+  com.unity.test-framework@1.1.11
+  com.unity.timeline@1.2.12
+  com.unity.ugui@1.0.0
+  com.unity.xr.legacyinputhelpers@1.3.8
+The following packages were updated:
+  com.unity.analytics from version 3.2.2 to 3.3.5
+  com.unity.collab-proxy from version 1.2.15 to 1.2.16
+  com.unity.purchasing from version 2.0.3 to 2.0.6
+  com.unity.textmeshpro from version 1.3.0 to 2.0.1
+The following packages were removed:
+  com.unity.package-manager-ui@2.0.7
diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset
deleted file mode 100644
index da61125..0000000
--- a/ProjectSettings/AudioManager.asset
+++ /dev/null
@@ -1,17 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!11 &1
-AudioManager:
-  m_ObjectHideFlags: 0
-  m_Volume: 1
-  Rolloff Scale: 1
-  Doppler Factor: 1
-  Default Speaker Mode: 2
-  m_SampleRate: 0
-  m_DSPBufferSize: 0
-  m_VirtualVoiceCount: 512
-  m_RealVoiceCount: 32
-  m_SpatializerPlugin: 
-  m_AmbisonicDecoderPlugin: 
-  m_DisableAudio: 0
-  m_VirtualizeEffects: 1
diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset
deleted file mode 100644
index e7886b2..0000000
--- a/ProjectSettings/ClusterInputManager.asset
+++ /dev/null
@@ -1,6 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!236 &1
-ClusterInputManager:
-  m_ObjectHideFlags: 0
-  m_Inputs: []
diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset
deleted file mode 100644
index 1931946..0000000
--- a/ProjectSettings/DynamicsManager.asset
+++ /dev/null
@@ -1,19 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!55 &1
-PhysicsManager:
-  m_ObjectHideFlags: 0
-  serializedVersion: 3
-  m_Gravity: {x: 0, y: -9.81, z: 0}
-  m_DefaultMaterial: {fileID: 0}
-  m_BounceThreshold: 2
-  m_SleepThreshold: 0.005
-  m_DefaultContactOffset: 0.01
-  m_DefaultSolverIterations: 6
-  m_DefaultSolverVelocityIterations: 1
-  m_QueriesHitBackfaces: 0
-  m_QueriesHitTriggers: 1
-  m_EnableAdaptiveForce: 0
-  m_EnablePCM: 1
-  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-  m_AutoSimulation: 1
diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset
deleted file mode 100644
index 6dc24f7..0000000
--- a/ProjectSettings/EditorBuildSettings.asset
+++ /dev/null
@@ -1,7 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!1045 &1
-EditorBuildSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 2
-  m_Scenes: []
diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset
deleted file mode 100644
index f33b6fb..0000000
--- a/ProjectSettings/EditorSettings.asset
+++ /dev/null
@@ -1,16 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!159 &1
-EditorSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 4
-  m_ExternalVersionControlSupport: Visible Meta Files
-  m_SerializationMode: 2
-  m_DefaultBehaviorMode: 0
-  m_SpritePackerMode: 0
-  m_SpritePackerPaddingPower: 1
-  m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd
-  m_ProjectGenerationRootNamespace: 
-  m_UserGeneratedProjectSuffix: 
-  m_CollabEditorSettings:
-    inProgressEnabled: 1
diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset
deleted file mode 100644
index 74d7b53..0000000
--- a/ProjectSettings/GraphicsSettings.asset
+++ /dev/null
@@ -1,61 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!30 &1
-GraphicsSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 12
-  m_Deferred:
-    m_Mode: 1
-    m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
-  m_DeferredReflections:
-    m_Mode: 1
-    m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
-  m_ScreenSpaceShadows:
-    m_Mode: 1
-    m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
-  m_LegacyDeferred:
-    m_Mode: 1
-    m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
-  m_DepthNormals:
-    m_Mode: 1
-    m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
-  m_MotionVectors:
-    m_Mode: 1
-    m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
-  m_LightHalo:
-    m_Mode: 1
-    m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
-  m_LensFlare:
-    m_Mode: 1
-    m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
-  m_AlwaysIncludedShaders:
-  - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
-  - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
-  - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
-  - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
-  - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
-  - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
-  m_PreloadedShaders: []
-  m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
-    type: 0}
-  m_CustomRenderPipeline: {fileID: 0}
-  m_TransparencySortMode: 0
-  m_TransparencySortAxis: {x: 0, y: 0, z: 1}
-  m_DefaultRenderingPath: 1
-  m_DefaultMobileRenderingPath: 1
-  m_TierSettings: []
-  m_LightmapStripping: 0
-  m_FogStripping: 0
-  m_InstancingStripping: 0
-  m_LightmapKeepPlain: 1
-  m_LightmapKeepDirCombined: 1
-  m_LightmapKeepDynamicPlain: 1
-  m_LightmapKeepDynamicDirCombined: 1
-  m_LightmapKeepShadowMask: 1
-  m_LightmapKeepSubtractive: 1
-  m_FogKeepLinear: 1
-  m_FogKeepExp: 1
-  m_FogKeepExp2: 1
-  m_AlbedoSwatchInfos: []
-  m_LightsUseLinearIntensity: 0
-  m_LightsUseColorTemperature: 0
diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset
deleted file mode 100644
index 17c8f53..0000000
--- a/ProjectSettings/InputManager.asset
+++ /dev/null
@@ -1,295 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!13 &1
-InputManager:
-  m_ObjectHideFlags: 0
-  serializedVersion: 2
-  m_Axes:
-  - serializedVersion: 3
-    m_Name: Horizontal
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: left
-    positiveButton: right
-    altNegativeButton: a
-    altPositiveButton: d
-    gravity: 3
-    dead: 0.001
-    sensitivity: 3
-    snap: 1
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Vertical
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: down
-    positiveButton: up
-    altNegativeButton: s
-    altPositiveButton: w
-    gravity: 3
-    dead: 0.001
-    sensitivity: 3
-    snap: 1
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire1
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: left ctrl
-    altNegativeButton: 
-    altPositiveButton: mouse 0
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire2
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: left alt
-    altNegativeButton: 
-    altPositiveButton: mouse 1
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire3
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: left shift
-    altNegativeButton: 
-    altPositiveButton: mouse 2
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Jump
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: space
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Mouse X
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: 
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 0
-    dead: 0
-    sensitivity: 0.1
-    snap: 0
-    invert: 0
-    type: 1
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Mouse Y
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: 
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 0
-    dead: 0
-    sensitivity: 0.1
-    snap: 0
-    invert: 0
-    type: 1
-    axis: 1
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Mouse ScrollWheel
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: 
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 0
-    dead: 0
-    sensitivity: 0.1
-    snap: 0
-    invert: 0
-    type: 1
-    axis: 2
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Horizontal
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: 
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 0
-    dead: 0.19
-    sensitivity: 1
-    snap: 0
-    invert: 0
-    type: 2
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Vertical
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: 
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 0
-    dead: 0.19
-    sensitivity: 1
-    snap: 0
-    invert: 1
-    type: 2
-    axis: 1
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire1
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: joystick button 0
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire2
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: joystick button 1
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Fire3
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: joystick button 2
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Jump
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: joystick button 3
-    altNegativeButton: 
-    altPositiveButton: 
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Submit
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: return
-    altNegativeButton: 
-    altPositiveButton: joystick button 0
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Submit
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: enter
-    altNegativeButton: 
-    altPositiveButton: space
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
-  - serializedVersion: 3
-    m_Name: Cancel
-    descriptiveName: 
-    descriptiveNegativeName: 
-    negativeButton: 
-    positiveButton: escape
-    altNegativeButton: 
-    altPositiveButton: joystick button 1
-    gravity: 1000
-    dead: 0.001
-    sensitivity: 1000
-    snap: 0
-    invert: 0
-    type: 0
-    axis: 0
-    joyNum: 0
diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset
deleted file mode 100644
index 6dd520f..0000000
--- a/ProjectSettings/NavMeshAreas.asset
+++ /dev/null
@@ -1,89 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!126 &1
-NavMeshProjectSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 2
-  areas:
-  - name: Walkable
-    cost: 1
-  - name: Not Walkable
-    cost: 1
-  - name: Jump
-    cost: 2
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  - name: 
-    cost: 1
-  m_LastAgentTypeID: -887442657
-  m_Settings:
-  - serializedVersion: 2
-    agentTypeID: 0
-    agentRadius: 0.5
-    agentHeight: 2
-    agentSlope: 45
-    agentClimb: 0.75
-    ledgeDropHeight: 0
-    maxJumpAcrossDistance: 0
-    minRegionArea: 2
-    manualCellSize: 0
-    cellSize: 0.16666667
-    manualTileSize: 0
-    tileSize: 256
-    accuratePlacement: 0
-  m_SettingNames:
-  - Humanoid
diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset
deleted file mode 100644
index 5dc6a83..0000000
--- a/ProjectSettings/NetworkManager.asset
+++ /dev/null
@@ -1,8 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!149 &1
-NetworkManager:
-  m_ObjectHideFlags: 0
-  m_DebugLevel: 0
-  m_Sendrate: 15
-  m_AssetToPrefab: {}
diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset
deleted file mode 100644
index e3b2d0b..0000000
--- a/ProjectSettings/Physics2DSettings.asset
+++ /dev/null
@@ -1,36 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!19 &1
-Physics2DSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 3
-  m_Gravity: {x: 0, y: -9.81}
-  m_DefaultMaterial: {fileID: 0}
-  m_VelocityIterations: 8
-  m_PositionIterations: 3
-  m_VelocityThreshold: 1
-  m_MaxLinearCorrection: 0.2
-  m_MaxAngularCorrection: 8
-  m_MaxTranslationSpeed: 100
-  m_MaxRotationSpeed: 360
-  m_BaumgarteScale: 0.2
-  m_BaumgarteTimeOfImpactScale: 0.75
-  m_TimeToSleep: 0.5
-  m_LinearSleepTolerance: 0.01
-  m_AngularSleepTolerance: 2
-  m_DefaultContactOffset: 0.01
-  m_AutoSimulation: 1
-  m_QueriesHitTriggers: 1
-  m_QueriesStartInColliders: 1
-  m_ChangeStopsCallbacks: 0
-  m_CallbacksOnDisable: 1
-  m_AlwaysShowColliders: 0
-  m_ShowColliderSleep: 1
-  m_ShowColliderContacts: 0
-  m_ShowColliderAABB: 0
-  m_ContactArrowScale: 0.2
-  m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
-  m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
-  m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
-  m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
-  m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset
deleted file mode 100644
index c373cfb..0000000
--- a/ProjectSettings/ProjectSettings.asset
+++ /dev/null
@@ -1,595 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!129 &1
-PlayerSettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 12
-  productGUID: 36f97d821ecfac149ae5eae5c4496e56
-  AndroidProfiler: 0
-  defaultScreenOrientation: 4
-  targetDevice: 2
-  useOnDemandResources: 0
-  accelerometerFrequency: 60
-  companyName: DefaultCompany
-  productName: UnityLibrary
-  defaultCursor: {fileID: 0}
-  cursorHotspot: {x: 0, y: 0}
-  m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
-  m_ShowUnitySplashScreen: 1
-  m_ShowUnitySplashLogo: 1
-  m_SplashScreenOverlayOpacity: 1
-  m_SplashScreenAnimation: 1
-  m_SplashScreenLogoStyle: 1
-  m_SplashScreenDrawMode: 0
-  m_SplashScreenBackgroundAnimationZoom: 1
-  m_SplashScreenLogoAnimationZoom: 1
-  m_SplashScreenBackgroundLandscapeAspect: 1
-  m_SplashScreenBackgroundPortraitAspect: 1
-  m_SplashScreenBackgroundLandscapeUvs:
-    serializedVersion: 2
-    x: 0
-    y: 0
-    width: 1
-    height: 1
-  m_SplashScreenBackgroundPortraitUvs:
-    serializedVersion: 2
-    x: 0
-    y: 0
-    width: 1
-    height: 1
-  m_SplashScreenLogos: []
-  m_SplashScreenBackgroundLandscape: {fileID: 0}
-  m_SplashScreenBackgroundPortrait: {fileID: 0}
-  m_VirtualRealitySplashScreen: {fileID: 0}
-  m_HolographicTrackingLossScreen: {fileID: 0}
-  defaultScreenWidth: 1024
-  defaultScreenHeight: 768
-  defaultScreenWidthWeb: 960
-  defaultScreenHeightWeb: 600
-  m_StereoRenderingPath: 0
-  m_ActiveColorSpace: 0
-  m_MTRendering: 1
-  m_MobileMTRendering: 0
-  m_StackTraceTypes: 010000000100000001000000010000000100000001000000
-  iosShowActivityIndicatorOnLoading: -1
-  androidShowActivityIndicatorOnLoading: -1
-  tizenShowActivityIndicatorOnLoading: -1
-  iosAppInBackgroundBehavior: 0
-  displayResolutionDialog: 1
-  iosAllowHTTPDownload: 1
-  allowedAutorotateToPortrait: 1
-  allowedAutorotateToPortraitUpsideDown: 1
-  allowedAutorotateToLandscapeRight: 1
-  allowedAutorotateToLandscapeLeft: 1
-  useOSAutorotation: 1
-  use32BitDisplayBuffer: 1
-  disableDepthAndStencilBuffers: 0
-  defaultIsFullScreen: 1
-  defaultIsNativeResolution: 1
-  runInBackground: 0
-  captureSingleScreen: 0
-  muteOtherAudioSources: 0
-  Prepare IOS For Recording: 0
-  Force IOS Speakers When Recording: 0
-  submitAnalytics: 1
-  usePlayerLog: 1
-  bakeCollisionMeshes: 0
-  forceSingleInstance: 0
-  resizableWindow: 0
-  useMacAppStoreValidation: 0
-  macAppStoreCategory: public.app-category.games
-  gpuSkinning: 0
-  graphicsJobs: 0
-  xboxPIXTextureCapture: 0
-  xboxEnableAvatar: 0
-  xboxEnableKinect: 0
-  xboxEnableKinectAutoTracking: 0
-  xboxEnableFitness: 0
-  visibleInBackground: 1
-  allowFullscreenSwitch: 1
-  graphicsJobMode: 0
-  macFullscreenMode: 2
-  d3d9FullscreenMode: 1
-  d3d11FullscreenMode: 1
-  xboxSpeechDB: 0
-  xboxEnableHeadOrientation: 0
-  xboxEnableGuest: 0
-  xboxEnablePIXSampling: 0
-  n3dsDisableStereoscopicView: 0
-  n3dsEnableSharedListOpt: 1
-  n3dsEnableVSync: 0
-  ignoreAlphaClear: 0
-  xboxOneResolution: 0
-  xboxOneMonoLoggingLevel: 0
-  xboxOneLoggingLevel: 1
-  xboxOneDisableEsram: 0
-  videoMemoryForVertexBuffers: 0
-  psp2PowerMode: 0
-  psp2AcquireBGM: 1
-  wiiUTVResolution: 0
-  wiiUGamePadMSAA: 1
-  wiiUSupportsNunchuk: 0
-  wiiUSupportsClassicController: 0
-  wiiUSupportsBalanceBoard: 0
-  wiiUSupportsMotionPlus: 0
-  wiiUSupportsProController: 0
-  wiiUAllowScreenCapture: 1
-  wiiUControllerCount: 0
-  m_SupportedAspectRatios:
-    4:3: 1
-    5:4: 1
-    16:10: 1
-    16:9: 1
-    Others: 1
-  bundleVersion: 1.0
-  preloadedAssets: []
-  metroInputSource: 0
-  m_HolographicPauseOnTrackingLoss: 1
-  xboxOneDisableKinectGpuReservation: 0
-  xboxOneEnable7thCore: 0
-  vrSettings:
-    cardboard:
-      depthFormat: 0
-      enableTransitionView: 0
-    daydream:
-      depthFormat: 0
-      useSustainedPerformanceMode: 0
-    hololens:
-      depthFormat: 1
-  protectGraphicsMemory: 0
-  useHDRDisplay: 0
-  targetPixelDensity: 0
-  resolutionScalingMode: 0
-  applicationIdentifier: {}
-  buildNumber: {}
-  AndroidBundleVersionCode: 1
-  AndroidMinSdkVersion: 16
-  AndroidTargetSdkVersion: 0
-  AndroidPreferredInstallLocation: 1
-  aotOptions: 
-  stripEngineCode: 1
-  iPhoneStrippingLevel: 0
-  iPhoneScriptCallOptimization: 0
-  ForceInternetPermission: 0
-  ForceSDCardPermission: 0
-  CreateWallpaper: 0
-  APKExpansionFiles: 0
-  keepLoadedShadersAlive: 0
-  StripUnusedMeshComponents: 0
-  VertexChannelCompressionMask:
-    serializedVersion: 2
-    m_Bits: 238
-  iPhoneSdkVersion: 988
-  iOSTargetOSVersionString: 
-  tvOSSdkVersion: 0
-  tvOSRequireExtendedGameController: 0
-  tvOSTargetOSVersionString: 
-  uIPrerenderedIcon: 0
-  uIRequiresPersistentWiFi: 0
-  uIRequiresFullScreen: 1
-  uIStatusBarHidden: 1
-  uIExitOnSuspend: 0
-  uIStatusBarStyle: 0
-  iPhoneSplashScreen: {fileID: 0}
-  iPhoneHighResSplashScreen: {fileID: 0}
-  iPhoneTallHighResSplashScreen: {fileID: 0}
-  iPhone47inSplashScreen: {fileID: 0}
-  iPhone55inPortraitSplashScreen: {fileID: 0}
-  iPhone55inLandscapeSplashScreen: {fileID: 0}
-  iPadPortraitSplashScreen: {fileID: 0}
-  iPadHighResPortraitSplashScreen: {fileID: 0}
-  iPadLandscapeSplashScreen: {fileID: 0}
-  iPadHighResLandscapeSplashScreen: {fileID: 0}
-  appleTVSplashScreen: {fileID: 0}
-  tvOSSmallIconLayers: []
-  tvOSLargeIconLayers: []
-  tvOSTopShelfImageLayers: []
-  tvOSTopShelfImageWideLayers: []
-  iOSLaunchScreenType: 0
-  iOSLaunchScreenPortrait: {fileID: 0}
-  iOSLaunchScreenLandscape: {fileID: 0}
-  iOSLaunchScreenBackgroundColor:
-    serializedVersion: 2
-    rgba: 0
-  iOSLaunchScreenFillPct: 100
-  iOSLaunchScreenSize: 100
-  iOSLaunchScreenCustomXibPath: 
-  iOSLaunchScreeniPadType: 0
-  iOSLaunchScreeniPadImage: {fileID: 0}
-  iOSLaunchScreeniPadBackgroundColor:
-    serializedVersion: 2
-    rgba: 0
-  iOSLaunchScreeniPadFillPct: 100
-  iOSLaunchScreeniPadSize: 100
-  iOSLaunchScreeniPadCustomXibPath: 
-  iOSDeviceRequirements: []
-  iOSURLSchemes: []
-  iOSBackgroundModes: 0
-  iOSMetalForceHardShadows: 0
-  metalEditorSupport: 1
-  metalAPIValidation: 1
-  iOSRenderExtraFrameOnPause: 0
-  appleDeveloperTeamID: 
-  iOSManualSigningProvisioningProfileID: 
-  tvOSManualSigningProvisioningProfileID: 
-  appleEnableAutomaticSigning: 0
-  AndroidTargetDevice: 0
-  AndroidSplashScreenScale: 0
-  androidSplashScreen: {fileID: 0}
-  AndroidKeystoreName: 
-  AndroidKeyaliasName: 
-  AndroidTVCompatibility: 1
-  AndroidIsGame: 1
-  androidEnableBanner: 1
-  m_AndroidBanners:
-  - width: 320
-    height: 180
-    banner: {fileID: 0}
-  androidGamepadSupportLevel: 0
-  resolutionDialogBanner: {fileID: 0}
-  m_BuildTargetIcons: []
-  m_BuildTargetBatching: []
-  m_BuildTargetGraphicsAPIs: []
-  m_BuildTargetVRSettings: []
-  openGLRequireES31: 0
-  openGLRequireES31AEP: 0
-  webPlayerTemplate: APPLICATION:Default
-  m_TemplateCustomTags: {}
-  wiiUTitleID: 0005000011000000
-  wiiUGroupID: 00010000
-  wiiUCommonSaveSize: 4096
-  wiiUAccountSaveSize: 2048
-  wiiUOlvAccessKey: 0
-  wiiUTinCode: 0
-  wiiUJoinGameId: 0
-  wiiUJoinGameModeMask: 0000000000000000
-  wiiUCommonBossSize: 0
-  wiiUAccountBossSize: 0
-  wiiUAddOnUniqueIDs: []
-  wiiUMainThreadStackSize: 3072
-  wiiULoaderThreadStackSize: 1024
-  wiiUSystemHeapSize: 128
-  wiiUTVStartupScreen: {fileID: 0}
-  wiiUGamePadStartupScreen: {fileID: 0}
-  wiiUDrcBufferDisabled: 0
-  wiiUProfilerLibPath: 
-  playModeTestRunnerEnabled: 1
-  actionOnDotNetUnhandledException: 1
-  enableInternalProfiler: 0
-  logObjCUncaughtExceptions: 1
-  enableCrashReportAPI: 0
-  cameraUsageDescription: 
-  locationUsageDescription: 
-  microphoneUsageDescription: 
-  switchNetLibKey: 
-  switchSocketMemoryPoolSize: 6144
-  switchSocketAllocatorPoolSize: 128
-  switchSocketConcurrencyLimit: 14
-  switchScreenResolutionBehavior: 2
-  switchUseCPUProfiler: 0
-  switchApplicationID: 0x01004b9000490000
-  switchNSODependencies: 
-  switchTitleNames_0: 
-  switchTitleNames_1: 
-  switchTitleNames_2: 
-  switchTitleNames_3: 
-  switchTitleNames_4: 
-  switchTitleNames_5: 
-  switchTitleNames_6: 
-  switchTitleNames_7: 
-  switchTitleNames_8: 
-  switchTitleNames_9: 
-  switchTitleNames_10: 
-  switchTitleNames_11: 
-  switchPublisherNames_0: 
-  switchPublisherNames_1: 
-  switchPublisherNames_2: 
-  switchPublisherNames_3: 
-  switchPublisherNames_4: 
-  switchPublisherNames_5: 
-  switchPublisherNames_6: 
-  switchPublisherNames_7: 
-  switchPublisherNames_8: 
-  switchPublisherNames_9: 
-  switchPublisherNames_10: 
-  switchPublisherNames_11: 
-  switchIcons_0: {fileID: 0}
-  switchIcons_1: {fileID: 0}
-  switchIcons_2: {fileID: 0}
-  switchIcons_3: {fileID: 0}
-  switchIcons_4: {fileID: 0}
-  switchIcons_5: {fileID: 0}
-  switchIcons_6: {fileID: 0}
-  switchIcons_7: {fileID: 0}
-  switchIcons_8: {fileID: 0}
-  switchIcons_9: {fileID: 0}
-  switchIcons_10: {fileID: 0}
-  switchIcons_11: {fileID: 0}
-  switchSmallIcons_0: {fileID: 0}
-  switchSmallIcons_1: {fileID: 0}
-  switchSmallIcons_2: {fileID: 0}
-  switchSmallIcons_3: {fileID: 0}
-  switchSmallIcons_4: {fileID: 0}
-  switchSmallIcons_5: {fileID: 0}
-  switchSmallIcons_6: {fileID: 0}
-  switchSmallIcons_7: {fileID: 0}
-  switchSmallIcons_8: {fileID: 0}
-  switchSmallIcons_9: {fileID: 0}
-  switchSmallIcons_10: {fileID: 0}
-  switchSmallIcons_11: {fileID: 0}
-  switchManualHTML: 
-  switchAccessibleURLs: 
-  switchLegalInformation: 
-  switchMainThreadStackSize: 1048576
-  switchPresenceGroupId: 0x01004b9000490000
-  switchLogoHandling: 0
-  switchReleaseVersion: 0
-  switchDisplayVersion: 1.0.0
-  switchStartupUserAccount: 0
-  switchTouchScreenUsage: 0
-  switchSupportedLanguagesMask: 0
-  switchLogoType: 0
-  switchApplicationErrorCodeCategory: 
-  switchUserAccountSaveDataSize: 0
-  switchUserAccountSaveDataJournalSize: 0
-  switchApplicationAttribute: 0
-  switchCardSpecSize: 4
-  switchCardSpecClock: 25
-  switchRatingsMask: 0
-  switchRatingsInt_0: 0
-  switchRatingsInt_1: 0
-  switchRatingsInt_2: 0
-  switchRatingsInt_3: 0
-  switchRatingsInt_4: 0
-  switchRatingsInt_5: 0
-  switchRatingsInt_6: 0
-  switchRatingsInt_7: 0
-  switchRatingsInt_8: 0
-  switchRatingsInt_9: 0
-  switchRatingsInt_10: 0
-  switchRatingsInt_11: 0
-  switchLocalCommunicationIds_0: 0x01004b9000490000
-  switchLocalCommunicationIds_1: 
-  switchLocalCommunicationIds_2: 
-  switchLocalCommunicationIds_3: 
-  switchLocalCommunicationIds_4: 
-  switchLocalCommunicationIds_5: 
-  switchLocalCommunicationIds_6: 
-  switchLocalCommunicationIds_7: 
-  switchParentalControl: 0
-  switchAllowsScreenshot: 1
-  switchDataLossConfirmation: 0
-  switchSupportedNpadStyles: 3
-  switchSocketConfigEnabled: 0
-  switchTcpInitialSendBufferSize: 32
-  switchTcpInitialReceiveBufferSize: 64
-  switchTcpAutoSendBufferSizeMax: 256
-  switchTcpAutoReceiveBufferSizeMax: 256
-  switchUdpSendBufferSize: 9
-  switchUdpReceiveBufferSize: 42
-  switchSocketBufferEfficiency: 4
-  ps4NPAgeRating: 12
-  ps4NPTitleSecret: 
-  ps4NPTrophyPackPath: 
-  ps4ParentalLevel: 11
-  ps4ContentID: ED1633-NPXX51362_00-0000000000000000
-  ps4Category: 0
-  ps4MasterVersion: 01.00
-  ps4AppVersion: 01.00
-  ps4AppType: 0
-  ps4ParamSfxPath: 
-  ps4VideoOutPixelFormat: 0
-  ps4VideoOutInitialWidth: 1920
-  ps4VideoOutBaseModeInitialWidth: 1920
-  ps4VideoOutReprojectionRate: 120
-  ps4PronunciationXMLPath: 
-  ps4PronunciationSIGPath: 
-  ps4BackgroundImagePath: 
-  ps4StartupImagePath: 
-  ps4SaveDataImagePath: 
-  ps4SdkOverride: 
-  ps4BGMPath: 
-  ps4ShareFilePath: 
-  ps4ShareOverlayImagePath: 
-  ps4PrivacyGuardImagePath: 
-  ps4NPtitleDatPath: 
-  ps4RemotePlayKeyAssignment: -1
-  ps4RemotePlayKeyMappingDir: 
-  ps4PlayTogetherPlayerCount: 0
-  ps4EnterButtonAssignment: 1
-  ps4ApplicationParam1: 0
-  ps4ApplicationParam2: 0
-  ps4ApplicationParam3: 0
-  ps4ApplicationParam4: 0
-  ps4DownloadDataSize: 0
-  ps4GarlicHeapSize: 2048
-  ps4ProGarlicHeapSize: 2560
-  ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
-  ps4pnSessions: 1
-  ps4pnPresence: 1
-  ps4pnFriends: 1
-  ps4pnGameCustomData: 1
-  playerPrefsSupport: 0
-  restrictedAudioUsageRights: 0
-  ps4UseResolutionFallback: 0
-  ps4ReprojectionSupport: 0
-  ps4UseAudio3dBackend: 0
-  ps4SocialScreenEnabled: 0
-  ps4ScriptOptimizationLevel: 0
-  ps4Audio3dVirtualSpeakerCount: 14
-  ps4attribCpuUsage: 0
-  ps4PatchPkgPath: 
-  ps4PatchLatestPkgPath: 
-  ps4PatchChangeinfoPath: 
-  ps4PatchDayOne: 0
-  ps4attribUserManagement: 0
-  ps4attribMoveSupport: 0
-  ps4attrib3DSupport: 0
-  ps4attribShareSupport: 0
-  ps4attribExclusiveVR: 0
-  ps4disableAutoHideSplash: 0
-  ps4videoRecordingFeaturesUsed: 0
-  ps4contentSearchFeaturesUsed: 0
-  ps4attribEyeToEyeDistanceSettingVR: 0
-  ps4IncludedModules: []
-  monoEnv: 
-  psp2Splashimage: {fileID: 0}
-  psp2NPTrophyPackPath: 
-  psp2NPSupportGBMorGJP: 0
-  psp2NPAgeRating: 12
-  psp2NPTitleDatPath: 
-  psp2NPCommsID: 
-  psp2NPCommunicationsID: 
-  psp2NPCommsPassphrase: 
-  psp2NPCommsSig: 
-  psp2ParamSfxPath: 
-  psp2ManualPath: 
-  psp2LiveAreaGatePath: 
-  psp2LiveAreaBackroundPath: 
-  psp2LiveAreaPath: 
-  psp2LiveAreaTrialPath: 
-  psp2PatchChangeInfoPath: 
-  psp2PatchOriginalPackage: 
-  psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui
-  psp2KeystoneFile: 
-  psp2MemoryExpansionMode: 0
-  psp2DRMType: 0
-  psp2StorageType: 0
-  psp2MediaCapacity: 0
-  psp2DLCConfigPath: 
-  psp2ThumbnailPath: 
-  psp2BackgroundPath: 
-  psp2SoundPath: 
-  psp2TrophyCommId: 
-  psp2TrophyPackagePath: 
-  psp2PackagedResourcesPath: 
-  psp2SaveDataQuota: 10240
-  psp2ParentalLevel: 1
-  psp2ShortTitle: Not Set
-  psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF
-  psp2Category: 0
-  psp2MasterVersion: 01.00
-  psp2AppVersion: 01.00
-  psp2TVBootMode: 0
-  psp2EnterButtonAssignment: 2
-  psp2TVDisableEmu: 0
-  psp2AllowTwitterDialog: 1
-  psp2Upgradable: 0
-  psp2HealthWarning: 0
-  psp2UseLibLocation: 0
-  psp2InfoBarOnStartup: 0
-  psp2InfoBarColor: 0
-  psp2ScriptOptimizationLevel: 0
-  psmSplashimage: {fileID: 0}
-  splashScreenBackgroundSourceLandscape: {fileID: 0}
-  splashScreenBackgroundSourcePortrait: {fileID: 0}
-  spritePackerPolicy: 
-  webGLMemorySize: 256
-  webGLExceptionSupport: 1
-  webGLNameFilesAsHashes: 0
-  webGLDataCaching: 0
-  webGLDebugSymbols: 0
-  webGLEmscriptenArgs: 
-  webGLModulesDirectory: 
-  webGLTemplate: APPLICATION:Default
-  webGLAnalyzeBuildSize: 0
-  webGLUseEmbeddedResources: 0
-  webGLUseWasm: 0
-  webGLCompressionFormat: 1
-  scriptingDefineSymbols:
-    1: MYCOMPANY;MYCOMPANY_MYPACKAGE
-  platformArchitecture: {}
-  scriptingBackend: {}
-  incrementalIl2cppBuild: {}
-  additionalIl2CppArgs: 
-  scriptingRuntimeVersion: 0
-  apiCompatibilityLevelPerPlatform: {}
-  m_RenderingPath: 1
-  m_MobileRenderingPath: 1
-  metroPackageName: UnityLibrary
-  metroPackageVersion: 
-  metroCertificatePath: 
-  metroCertificatePassword: 
-  metroCertificateSubject: 
-  metroCertificateIssuer: 
-  metroCertificateNotAfter: 0000000000000000
-  metroApplicationDescription: UnityLibrary
-  wsaImages: {}
-  metroTileShortName: 
-  metroCommandLineArgsFile: 
-  metroTileShowName: 0
-  metroMediumTileShowName: 0
-  metroLargeTileShowName: 0
-  metroWideTileShowName: 0
-  metroDefaultTileSize: 1
-  metroTileForegroundText: 2
-  metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
-  metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
-    a: 1}
-  metroSplashScreenUseBackgroundColor: 0
-  platformCapabilities: {}
-  metroFTAName: 
-  metroFTAFileTypes: []
-  metroProtocolName: 
-  metroCompilationOverrides: 1
-  tizenProductDescription: 
-  tizenProductURL: 
-  tizenSigningProfileName: 
-  tizenGPSPermissions: 0
-  tizenMicrophonePermissions: 0
-  tizenDeploymentTarget: 
-  tizenDeploymentTargetType: -1
-  tizenMinOSVersion: 1
-  n3dsUseExtSaveData: 0
-  n3dsCompressStaticMem: 1
-  n3dsExtSaveDataNumber: 0x12345
-  n3dsStackSize: 131072
-  n3dsTargetPlatform: 2
-  n3dsRegion: 7
-  n3dsMediaSize: 0
-  n3dsLogoStyle: 3
-  n3dsTitle: GameName
-  n3dsProductCode: 
-  n3dsApplicationId: 0xFF3FF
-  stvDeviceAddress: 
-  stvProductDescription: 
-  stvProductAuthor: 
-  stvProductAuthorEmail: 
-  stvProductLink: 
-  stvProductCategory: 0
-  XboxOneProductId: 
-  XboxOneUpdateKey: 
-  XboxOneSandboxId: 
-  XboxOneContentId: 
-  XboxOneTitleId: 
-  XboxOneSCId: 
-  XboxOneGameOsOverridePath: 
-  XboxOnePackagingOverridePath: 
-  XboxOneAppManifestOverridePath: 
-  XboxOnePackageEncryption: 0
-  XboxOnePackageUpdateGranularity: 2
-  XboxOneDescription: 
-  XboxOneLanguage:
-  - enus
-  XboxOneCapability: []
-  XboxOneGameRating: {}
-  XboxOneIsContentPackage: 0
-  XboxOneEnableGPUVariability: 0
-  XboxOneSockets: {}
-  XboxOneSplashScreen: {fileID: 0}
-  XboxOneAllowedProductIds: []
-  XboxOnePersistentLocalStorageSize: 0
-  xboxOneScriptCompiler: 0
-  vrEditorSettings:
-    daydream:
-      daydreamIconForeground: {fileID: 0}
-      daydreamIconBackground: {fileID: 0}
-  cloudServicesEnabled: {}
-  facebookSdkVersion: 7.9.4
-  apiCompatibilityLevel: 2
-  cloudProjectId: 
-  projectName: 
-  organizationId: 
-  cloudEnabled: 0
-  enableNativePlatformBackendsForNewInputSystem: 0
-  disableOldInputManagerSupport: 0
diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt
deleted file mode 100644
index ca1aa05..0000000
--- a/ProjectSettings/ProjectVersion.txt
+++ /dev/null
@@ -1 +0,0 @@
-m_EditorVersion: 2017.1.0f3
diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset
deleted file mode 100644
index 86c047f..0000000
--- a/ProjectSettings/QualitySettings.asset
+++ /dev/null
@@ -1,193 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!47 &1
-QualitySettings:
-  m_ObjectHideFlags: 0
-  serializedVersion: 5
-  m_CurrentQuality: 5
-  m_QualitySettings:
-  - serializedVersion: 2
-    name: Very Low
-    pixelLightCount: 0
-    shadows: 0
-    shadowResolution: 0
-    shadowProjection: 1
-    shadowCascades: 1
-    shadowDistance: 15
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 0
-    blendWeights: 1
-    textureQuality: 1
-    anisotropicTextures: 0
-    antiAliasing: 0
-    softParticles: 0
-    softVegetation: 0
-    realtimeReflectionProbes: 0
-    billboardsFaceCameraPosition: 0
-    vSyncCount: 0
-    lodBias: 0.3
-    maximumLODLevel: 0
-    particleRaycastBudget: 4
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  - serializedVersion: 2
-    name: Low
-    pixelLightCount: 0
-    shadows: 0
-    shadowResolution: 0
-    shadowProjection: 1
-    shadowCascades: 1
-    shadowDistance: 20
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 0
-    blendWeights: 2
-    textureQuality: 0
-    anisotropicTextures: 0
-    antiAliasing: 0
-    softParticles: 0
-    softVegetation: 0
-    realtimeReflectionProbes: 0
-    billboardsFaceCameraPosition: 0
-    vSyncCount: 0
-    lodBias: 0.4
-    maximumLODLevel: 0
-    particleRaycastBudget: 16
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  - serializedVersion: 2
-    name: Medium
-    pixelLightCount: 1
-    shadows: 1
-    shadowResolution: 0
-    shadowProjection: 1
-    shadowCascades: 1
-    shadowDistance: 20
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 0
-    blendWeights: 2
-    textureQuality: 0
-    anisotropicTextures: 1
-    antiAliasing: 0
-    softParticles: 0
-    softVegetation: 0
-    realtimeReflectionProbes: 0
-    billboardsFaceCameraPosition: 0
-    vSyncCount: 1
-    lodBias: 0.7
-    maximumLODLevel: 0
-    particleRaycastBudget: 64
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  - serializedVersion: 2
-    name: High
-    pixelLightCount: 2
-    shadows: 2
-    shadowResolution: 1
-    shadowProjection: 1
-    shadowCascades: 2
-    shadowDistance: 40
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 1
-    blendWeights: 2
-    textureQuality: 0
-    anisotropicTextures: 1
-    antiAliasing: 0
-    softParticles: 0
-    softVegetation: 1
-    realtimeReflectionProbes: 1
-    billboardsFaceCameraPosition: 1
-    vSyncCount: 1
-    lodBias: 1
-    maximumLODLevel: 0
-    particleRaycastBudget: 256
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  - serializedVersion: 2
-    name: Very High
-    pixelLightCount: 3
-    shadows: 2
-    shadowResolution: 2
-    shadowProjection: 1
-    shadowCascades: 2
-    shadowDistance: 70
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 1
-    blendWeights: 4
-    textureQuality: 0
-    anisotropicTextures: 2
-    antiAliasing: 2
-    softParticles: 1
-    softVegetation: 1
-    realtimeReflectionProbes: 1
-    billboardsFaceCameraPosition: 1
-    vSyncCount: 1
-    lodBias: 1.5
-    maximumLODLevel: 0
-    particleRaycastBudget: 1024
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  - serializedVersion: 2
-    name: Ultra
-    pixelLightCount: 4
-    shadows: 2
-    shadowResolution: 2
-    shadowProjection: 1
-    shadowCascades: 4
-    shadowDistance: 150
-    shadowNearPlaneOffset: 3
-    shadowCascade2Split: 0.33333334
-    shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
-    shadowmaskMode: 1
-    blendWeights: 4
-    textureQuality: 0
-    anisotropicTextures: 2
-    antiAliasing: 2
-    softParticles: 1
-    softVegetation: 1
-    realtimeReflectionProbes: 1
-    billboardsFaceCameraPosition: 1
-    vSyncCount: 1
-    lodBias: 2
-    maximumLODLevel: 0
-    particleRaycastBudget: 4096
-    asyncUploadTimeSlice: 2
-    asyncUploadBufferSize: 4
-    resolutionScalingFixedDPIFactor: 1
-    excludedTargetPlatforms: []
-  m_PerPlatformDefaultQuality:
-    Android: 2
-    Nintendo 3DS: 5
-    Nintendo Switch: 5
-    PS4: 5
-    PSM: 5
-    PSP2: 2
-    Samsung TV: 2
-    Standalone: 5
-    Tizen: 2
-    Web: 5
-    WebGL: 3
-    WiiU: 5
-    Windows Store Apps: 5
-    XboxOne: 5
-    iPhone: 2
-    tvOS: 2
diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset
deleted file mode 100644
index 1c92a78..0000000
--- a/ProjectSettings/TagManager.asset
+++ /dev/null
@@ -1,43 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!78 &1
-TagManager:
-  serializedVersion: 2
-  tags: []
-  layers:
-  - Default
-  - TransparentFX
-  - Ignore Raycast
-  - 
-  - Water
-  - UI
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  - 
-  m_SortingLayers:
-  - name: Default
-    uniqueID: 0
-    locked: 0
diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset
deleted file mode 100644
index 558a017..0000000
--- a/ProjectSettings/TimeManager.asset
+++ /dev/null
@@ -1,9 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!5 &1
-TimeManager:
-  m_ObjectHideFlags: 0
-  Fixed Timestep: 0.02
-  Maximum Allowed Timestep: 0.33333334
-  m_TimeScale: 1
-  Maximum Particle Timestep: 0.03
diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset
deleted file mode 100644
index 1cc5485..0000000
--- a/ProjectSettings/UnityConnectSettings.asset
+++ /dev/null
@@ -1,34 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!310 &1
-UnityConnectSettings:
-  m_ObjectHideFlags: 0
-  m_Enabled: 0
-  m_TestMode: 0
-  m_TestEventUrl: 
-  m_TestConfigUrl: 
-  m_TestInitMode: 0
-  CrashReportingSettings:
-    m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes
-    m_Enabled: 0
-    m_CaptureEditorExceptions: 1
-  UnityPurchasingSettings:
-    m_Enabled: 0
-    m_TestMode: 0
-  UnityAnalyticsSettings:
-    m_Enabled: 0
-    m_InitializeOnStartup: 1
-    m_TestMode: 0
-    m_TestEventUrl: 
-    m_TestConfigUrl: 
-  UnityAdsSettings:
-    m_Enabled: 0
-    m_InitializeOnStartup: 1
-    m_TestMode: 0
-    m_EnabledPlatforms: 4294967295
-    m_IosGameId: 
-    m_AndroidGameId: 
-    m_GameIds: {}
-    m_GameId: 
-  PerformanceReportingSettings:
-    m_Enabled: 0
diff --git a/README.md b/README.md
index d5b8e6a..f185093 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,11 @@
-# Unity Library
 
+# ![Unity Library](https://raw.githubusercontent.com/xXxT0SHIIIxXx/UnityLibrary/master/Logos/Unity_Library_White.png#gh-dark-mode-only)
+# ![Unity Library](https://raw.githubusercontent.com/xXxT0SHIIIxXx/UnityLibrary/master/Logos/Unity_Library_Black.png#gh-light-mode-only)
 :tada: Welcome to Unity Library :tada:
 
 Useful scripts, snippets and shaders here it is gathered for free.
 
-We have collected most scripts from external sources like Unity Communities (Forums, Answers) and we made it ourselves a little.
+We have collected most of the scripts from external sources like Unity Communities (Forums, Answers) and some of them are made by us.
 
 ## Getting Started
 
@@ -16,7 +17,7 @@ You can [browse this repository](#content) and find your desired utility or you
 git clone https://github.com/UnityCommunity/UnityLibrary.git
 ```
 
-and then open the folder in unity or you can find useful stuff by [browsing awesome resources in the below](#resources).
+then open the folder in unity or you can find useful stuff by [browsing awesome resources in the below](#resources).
 
 [:sparkles: Contribution is Welcome](#contribution)
 
@@ -77,7 +78,7 @@ Feel free to [:postbox: Post your ideas/comments/improvements/recommendations](h
 ## Credits
 
 - [UnityCoder (mika)](https://github.com/unitycoder) (Owner)
-- [EmpireWorld (Hasan Bayat)](https://github.com/EmpireWorld) (Owner)
+- [hasanbayatme (Hasan Bayat)](https://github.com/hasanbayatme) (Owner)
 - [Lootheo (Manuel Otheo)](https://github.com/Lootheo) (Member)
 - [igorrafael (Igor Rafael de Sousa)](https://github.com/igorrafael) (Member)
 - [nrlnd](https://github.com/nrlnd) (Member)
diff --git a/ScriptTemplates/82a-Javascript Editor Window-NewEditorScript.js.txt b/ScriptTemplates/82a-Javascript Editor Window-NewEditorScript.js.txt
deleted file mode 100644
index a0fa1bf..0000000
--- a/ScriptTemplates/82a-Javascript Editor Window-NewEditorScript.js.txt	
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma strict
-
-class #SCRIPTNAME# extends EditorWindow {
-
-	@MenuItem ("Window/#SCRIPTNAME#")
-    static function Initialize () {
-        EditorWindow.GetWindow (#SCRIPTNAME#);
-    }
-
-	function OnGUI () {
-		
-	}
-
-}
diff --git a/ScriptTemplates/82b-Javascript Custom Editor-NewCustomEditorScript.js.txt b/ScriptTemplates/82b-Javascript Custom Editor-NewCustomEditorScript.js.txt
deleted file mode 100644
index e7ec9bb..0000000
--- a/ScriptTemplates/82b-Javascript Custom Editor-NewCustomEditorScript.js.txt	
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma strict
-
-@CustomEditor (#SCRIPTNAME#)
-@CanEditMultipleObjects
-class #SCRIPTNAME# extends Editor {
-
-	function OnEnable () {
-		
-	}
-
-	function OnInspectorGUI () {
-		
-	}
-
-}
diff --git a/ScriptTemplates/82c-Javascript Property Drawer-NewPropertyDrawerScript.js.txt b/ScriptTemplates/82c-Javascript Property Drawer-NewPropertyDrawerScript.js.txt
deleted file mode 100644
index 1a79b09..0000000
--- a/ScriptTemplates/82c-Javascript Property Drawer-NewPropertyDrawerScript.js.txt	
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma strict
-
-@CustomPropertyDrawer (#SCRIPTNAME#)
-class #SCRIPTNAME# extends PropertyDrawer {
-
-	function OnGUI () {
-		
-	}
-
-}
