diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0055c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +### Unity ### +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/Assets/AssetStoreTools* + +# Visual Studio 2015 cache directory +/.vs/ +/.vscode/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb + +# Unity3D generated meta files +*.pidb.meta + +# Unity3D Generated File On Crash Reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage + +# OS Specific +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +Icon? +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/Assets/Scenes.meta b/Assets/Scenes.meta new file mode 100644 index 0000000..b845635 --- /dev/null +++ b/Assets/Scenes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e902c8c0b4e7a0d4d8453c55863a7532 +folderAsset: yes +timeCreated: 1501219179 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Test.unity b/Assets/Scenes/Test.unity new file mode 100644 index 0000000..97d6285 --- /dev/null +++ b/Assets/Scenes/Test.unity @@ -0,0 +1,360 @@ +%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.44657844, g: 0.49641222, b: 0.57481694, a: 1} +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + 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 &690944966 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 690944968} + - component: {fileID: 690944967} + 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 &690944967 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 690944966} + 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 &690944968 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 690944966} + 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 &1759122305 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1759122310} + - component: {fileID: 1759122309} + - component: {fileID: 1759122308} + - component: {fileID: 1759122307} + - component: {fileID: 1759122306} + 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 &1759122306 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1759122305} + m_Enabled: 1 +--- !u!124 &1759122307 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1759122305} + m_Enabled: 1 +--- !u!92 &1759122308 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1759122305} + m_Enabled: 1 +--- !u!20 &1759122309 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1759122305} + 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: 1 + 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 &1759122310 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1759122305} + 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 &1786072496 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1786072500} + - component: {fileID: 1786072499} + - component: {fileID: 1786072498} + - component: {fileID: 1786072497} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &1786072497 +MeshRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1786072496} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_Materials: + - {fileID: 2100000, guid: f2042e1062153334ea0a77924a7327a4, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 +--- !u!65 &1786072498 +BoxCollider: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1786072496} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!33 &1786072499 +MeshFilter: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1786072496} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1786072500 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1786072496} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -2.3581216, y: -2.0539248, z: -16.652042} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Scenes/Test.unity.meta b/Assets/Scenes/Test.unity.meta new file mode 100644 index 0000000..adbeacb --- /dev/null +++ b/Assets/Scenes/Test.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 448f40325f90d0840b15d33f2c2d8da5 +timeCreated: 1501219189 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: 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.meta b/Assets/Scripts.meta new file mode 100644 index 0000000..8cb9588 --- /dev/null +++ b/Assets/Scripts.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e402e02f02482eb4a8a4a1c3ad2f3565 +folderAsset: yes +timeCreated: 1500793393 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D.meta b/Assets/Scripts/2D.meta new file mode 100644 index 0000000..ad07dfb --- /dev/null +++ b/Assets/Scripts/2D.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a566d1d4c62efcb43b5fb1005352c895 +folderAsset: yes +timeCreated: 1500793395 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Camera.meta b/Assets/Scripts/2D/Camera.meta new file mode 100644 index 0000000..ee881f2 --- /dev/null +++ b/Assets/Scripts/2D/Camera.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f5f321f774e078d4c8d3de6e73e8d3ea +folderAsset: yes +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs b/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs new file mode 100644 index 0000000..8736ef1 --- /dev/null +++ b/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs @@ -0,0 +1,39 @@ +// pixel perfect camera helpers, from old unity 2D tutorial videos +// source: https://www.youtube.com/watch?v=rMCLWt1DuqI + +using UnityEngine; + +namespace UnityLibrary +{ + [ExecuteInEditMode] + public class PixelPerfectCamera : MonoBehaviour + { + public float pixelsToUnits = 100; + Camera cam; + + void Start() + { + cam = GetComponent(); + if (cam == null) + { + Debug.LogError("Camera not found..", gameObject); + this.enabled = false; + return; + } + SetScale(); + } + + // in editor need to update in a loop, in case of game window resizes +#if UNITY_EDITOR + void Update() + { + SetScale(); + } +#endif + + void SetScale() + { + cam.orthographicSize = Screen.height / pixelsToUnits / 2; + } + } +} diff --git a/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs.meta b/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs.meta new file mode 100644 index 0000000..11230f2 --- /dev/null +++ b/Assets/Scripts/2D/Camera/PixelPerfectCamera.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 230ad41a455ffc84982860a8ce356020 +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Camera/ScaleCamera.cs b/Assets/Scripts/2D/Camera/ScaleCamera.cs new file mode 100644 index 0000000..5330cea --- /dev/null +++ b/Assets/Scripts/2D/Camera/ScaleCamera.cs @@ -0,0 +1,43 @@ +// pixel perfect camera helpers, from old unity 2D tutorial videos +// source: https://www.youtube.com/watch?v=rMCLWt1DuqI + +using UnityEngine; + +namespace UnityLibrary +{ + [ExecuteInEditMode] + public class ScaleCamera : MonoBehaviour + { + public int targetWidth = 640; + public float pixelsToUnits = 100; + + Camera cam; + + void Start() + { + cam = GetComponent(); + if (cam == null) + { + Debug.LogError("Camera not found..", gameObject); + this.enabled = false; + return; + } + + SetScale(); + } + + // in editor need to update in a loop, in case of game window resizes +#if UNITY_EDITOR + void Update() + { + SetScale(); + } +#endif + + void SetScale() + { + int height = Mathf.RoundToInt(targetWidth / (float)Screen.width * Screen.height); + cam.orthographicSize = height / pixelsToUnits / 2; + } + } +} diff --git a/Assets/Scripts/2D/Camera/ScaleCamera.cs.meta b/Assets/Scripts/2D/Camera/ScaleCamera.cs.meta new file mode 100644 index 0000000..99882a2 --- /dev/null +++ b/Assets/Scripts/2D/Camera/ScaleCamera.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: eb79c0c2e7e8b814497e3fed8bad9dbd +timeCreated: 1500793404 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Colliders.meta b/Assets/Scripts/2D/Colliders.meta new file mode 100644 index 0000000..fedd8ba --- /dev/null +++ b/Assets/Scripts/2D/Colliders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: aabfa300fc2aee04ab2c0f4e1d33d8f8 +folderAsset: yes +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs new file mode 100644 index 0000000..a3ae1c5 --- /dev/null +++ b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs @@ -0,0 +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; + +namespace UnityLibrary +{ + public class ScreenEdgeColliders : MonoBehaviour + { + private Camera cam; + private EdgeCollider2D edge; + private Vector2[] edgePoints; + + 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() == null ? gameObject.AddComponent() : GetComponent(); + + 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; } + + 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() == null ? gameObject.AddComponent() : GetComponent(); + + var edgePoints = new[] { bottomLeft, topLeft, topRight, bottomRight, bottomLeft }; + edge.points = edgePoints; + } + } +} diff --git a/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs.meta b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs.meta new file mode 100644 index 0000000..4c59b67 --- /dev/null +++ b/Assets/Scripts/2D/Colliders/ScreenEdgeColliders.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 13a829f568060b1429e093c51a02d8d1 +timeCreated: 1500793400 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Drawing.meta b/Assets/Scripts/2D/Drawing.meta new file mode 100644 index 0000000..17ebebb --- /dev/null +++ b/Assets/Scripts/2D/Drawing.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9acbf89372e16b448a5fbda547b9e83d +folderAsset: yes +timeCreated: 1501390147 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Drawing/DrawLine2D.cs b/Assets/Scripts/2D/Drawing/DrawLine2D.cs new file mode 100644 index 0000000..b5fb834 --- /dev/null +++ b/Assets/Scripts/2D/Drawing/DrawLine2D.cs @@ -0,0 +1,112 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +namespace UnityLibrary +{ + public class DrawLine2D : MonoBehaviour + { + + [SerializeField] + protected LineRenderer m_LineRenderer; + [SerializeField] + protected bool m_AddCollider = false; + [SerializeField] + protected EdgeCollider2D m_EdgeCollider2D; + protected List m_Points; + + public virtual LineRenderer lineRenderer { + get { + return m_LineRenderer; + } + } + + public virtual bool addCollider { + get { + return m_AddCollider; + } + } + + public virtual EdgeCollider2D edgeCollider2D { + get { + return m_EdgeCollider2D; + } + } + + public virtual List points { + get { + return m_Points; + } + } + + protected virtual void Awake() + { + if (m_LineRenderer == null) + { + Debug.LogWarning("DrawLine: Line Renderer not assigned, Adding and Using default Line Renderer."); + CreateDefaultLineRenderer(); + } + if (m_EdgeCollider2D == null && m_AddCollider) + { + Debug.LogWarning("DrawLine: Edge Collider 2D not assigned, Adding and Using default Edge Collider 2D."); + CreateDefaultEdgeCollider2D(); + } + m_Points = new List(); + } + + protected virtual void Update() + { + if (Input.GetMouseButtonDown(0)) + { + Reset(); + } + if (Input.GetMouseButton(0)) + { + Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); + if (!m_Points.Contains(mousePosition)) + { + m_Points.Add(mousePosition); + m_LineRenderer.positionCount = m_Points.Count; + m_LineRenderer.SetPosition(m_LineRenderer.positionCount - 1, mousePosition); + if (m_EdgeCollider2D != null && m_AddCollider && m_Points.Count > 1) + { + m_EdgeCollider2D.points = m_Points.ToArray(); + } + } + } + } + + protected virtual void Reset() + { + if (m_LineRenderer != null) + { + m_LineRenderer.positionCount = 0; + } + if (m_Points != null) + { + m_Points.Clear(); + } + if (m_EdgeCollider2D != null && m_AddCollider) + { + m_EdgeCollider2D.Reset(); + } + } + + protected virtual void CreateDefaultLineRenderer() + { + m_LineRenderer = gameObject.AddComponent(); + m_LineRenderer.positionCount = 0; + m_LineRenderer.material = new Material(Shader.Find("Particles/Additive")); + m_LineRenderer.startColor = Color.white; + m_LineRenderer.endColor = Color.white; + m_LineRenderer.startWidth = 0.2f; + m_LineRenderer.endWidth = 0.2f; + m_LineRenderer.useWorldSpace = true; + } + + protected virtual void CreateDefaultEdgeCollider2D() + { + m_EdgeCollider2D = gameObject.AddComponent(); + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/2D/Drawing/DrawLine2D.cs.meta b/Assets/Scripts/2D/Drawing/DrawLine2D.cs.meta new file mode 100644 index 0000000..83b676e --- /dev/null +++ b/Assets/Scripts/2D/Drawing/DrawLine2D.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ac0fbbea8fa72e74e9a6e8fcb8d1c6ae +timeCreated: 1501390147 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Follow2D.cs b/Assets/Scripts/2D/Follow2D.cs new file mode 100644 index 0000000..7cc16dd --- /dev/null +++ b/Assets/Scripts/2D/Follow2D.cs @@ -0,0 +1,141 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +/// +/// Follows a GameObject in a Smooth way and with various settings +/// Author: Manuel Otheo (@Lootheo) with guidance from Hasan Bayat (EmpireWorld) +/// +/// https://www.reddit.com/r/Unity3D/comments/6iskah/movetowards_vs_lerp_vs_slerp_vs_smoothdamp/ +/// How to use: Attach it to a GameObject and then assign the target to follow and the variables like offset and speed +/// If it's not moving check the speed +/// +/// TODO: Make more efficient usage of the vector3 to vector2; +/// +/// +namespace UnityLibrary +{ + public class Follow2D : MonoBehaviour + { + + public enum FollowType + { + MoveTowards, + Lerp, + Slerp, + SmoothDamp, + Acceleration + } + + #region Fields + + public Transform target; + public FollowType followType = FollowType.MoveTowards; + public Vector2 speed; + public Vector2 time; + public Vector2 acceleration; + public Vector2 offset; + public bool bounds; + public Vector2 lowerBounds; + public Vector2 higherBounds; + #endregion + + #region Variables + + protected Vector2 velocity; + protected Vector2 step; + private Vector2 localSpeed; + + #endregion + + #region MonoBehaviour Messages + + protected virtual void Update() + { + + // Exit if the target object not specified + if (target == null) + { + return; + } + + switch (followType) + { + case FollowType.MoveTowards: + MoveTowards(); + break; + case FollowType.Lerp: + Lerp(); + break; + case FollowType.Slerp: + Slerp(); + break; + case FollowType.SmoothDamp: + SmoothDamp(); + break; + case FollowType.Acceleration: + Acceleration(); + break; + } + + if (bounds) + { + CheckForBounds(); + } + } + + #endregion + + #region Methods + + protected virtual void MoveTowards() + { + step = speed * Time.deltaTime; + transform.position = new Vector2(Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).x, Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).y); + } + + protected virtual void Lerp() + { + float posX = Mathf.Lerp(transform.position.x, target.position.x + offset.x, time.x * Time.fixedDeltaTime); + float posY = Mathf.Lerp(transform.position.y, target.position.y + offset.y, time.y * Time.fixedDeltaTime); + transform.position = new Vector3(posX, posY, transform.position.z); + } + + protected virtual void Slerp() + { + float posX = Vector3.Slerp(transform.position, (Vector3)((Vector2)target.position + offset), time.x * Time.fixedDeltaTime).x; + float posY = Vector3.Slerp(transform.position, (Vector3)((Vector2)target.position + offset), time.y * Time.fixedDeltaTime).y; + transform.position = new Vector3(posX, posY, transform.position.z); + } + + protected virtual void SmoothDamp() + { + Vector2 position; + + position.x = Mathf.SmoothDamp(transform.position.x, target.position.x + offset.x, ref velocity.x, time.x); + position.y = Mathf.SmoothDamp(transform.position.y, target.position.y + offset.y, ref velocity.y, time.y); + + transform.position = new Vector3(position.x, position.y, transform.position.z); + } + protected virtual void Acceleration() + { + if (Vector2.Distance(transform.position, (Vector2)target.position + offset) == 0) + localSpeed = Vector2.zero; + else + { + localSpeed = localSpeed + acceleration * Time.deltaTime; + step = localSpeed * Time.deltaTime; + transform.position = new Vector2(Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).x, Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).y); + } + } + + protected virtual void CheckForBounds() + { + transform.position = new Vector3(Mathf.Clamp(transform.position.x, lowerBounds.x, higherBounds.x), Mathf.Clamp(transform.position.y, lowerBounds.y, higherBounds.y), transform.position.z); + } + + #endregion + + } +} diff --git a/Assets/Scripts/2D/Follow2D.cs.meta b/Assets/Scripts/2D/Follow2D.cs.meta new file mode 100644 index 0000000..2d338b3 --- /dev/null +++ b/Assets/Scripts/2D/Follow2D.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5c3e4ae285230a7448969a1b437a0b03 +timeCreated: 1500793402 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Follow2DRigidbody.cs b/Assets/Scripts/2D/Follow2DRigidbody.cs new file mode 100644 index 0000000..754da05 --- /dev/null +++ b/Assets/Scripts/2D/Follow2DRigidbody.cs @@ -0,0 +1,141 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +/// +/// Follows a GameObject in a Smooth way and with various settings requiring the rigidbody +/// Author: Manuel Otheo (@Lootheo) with guidance from Hasan Bayat (EmpireWorld) +/// +/// https://www.reddit.com/r/Unity3D/comments/6iskah/movetowards_vs_lerp_vs_slerp_vs_smoothdamp/ +/// How to use: Attach it to a GameObject and then assign the target to follow and the variables like offset and speed +/// If it's not moving check the speed +/// +/// +namespace UnityLibrary +{ + [RequireComponent(typeof(Rigidbody2D))] + public class Follow2DRigidbody : MonoBehaviour { + + public enum FollowType { + MoveTowards, + Lerp, + Slerp, + SmoothDamp, + Acceleration + } + + #region Fields + + public Transform target; + public FollowType followType = FollowType.MoveTowards; + public Vector2 speed; + public Vector2 time; + public Vector2 offset; + public bool bounds; + public Vector2 lowerBounds; + public Vector2 higherBounds; + public Vector2 acceleration; + #endregion + + #region Variables + + protected Vector2 velocity; + protected Vector2 step; + private Vector2 localSpeed; + Rigidbody2D rb; + #endregion + + #region MonoBehaviour Messages + protected virtual void Start() + { + rb = GetComponent(); + } + + protected virtual void FixedUpdate() + { + + // Exit if the target object not specified + if (target == null) { + return; + } + + switch (followType) + { + case FollowType.MoveTowards: + MoveTowards(); + break; + case FollowType.Lerp: + Lerp(); + break; + case FollowType.Slerp: + Slerp(); + break; + case FollowType.SmoothDamp: + SmoothDamp(); + break; + case FollowType.Acceleration: + Acceleration(); + break; + } + + if (bounds) + { + CheckForBounds(); + } + } + + #endregion + + #region Methods + + protected virtual void MoveTowards() + { + step = speed * Time.deltaTime; + rb.MovePosition(new Vector2(Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).x, Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).y)); + } + + protected virtual void Lerp() + { + float posX = Mathf.Lerp(transform.position.x, target.position.x + offset.x, time.x * Time.fixedDeltaTime); + float posY = Mathf.Lerp(transform.position.y, target.position.y + offset.y, time.y * Time.fixedDeltaTime); + rb.MovePosition(new Vector3(posX, posY, transform.position.z)); + } + + protected virtual void Slerp() + { + float posX = Vector3.Slerp(transform.position, (Vector3)((Vector2)target.position + offset), time.x * Time.fixedDeltaTime).x; + float posY = Vector3.Slerp(transform.position, (Vector3)((Vector2)target.position + offset), time.y * Time.fixedDeltaTime).y; + rb.MovePosition(new Vector3(posX, posY, transform.position.z)); + } + + protected virtual void SmoothDamp() + { + Vector2 position; + + position.x = Mathf.SmoothDamp(transform.position.x, target.position.x + offset.x, ref velocity.x, time.x); + position.y = Mathf.SmoothDamp(transform.position.y, target.position.y + offset.y, ref velocity.y, time.y); + + rb.MovePosition(new Vector3(position.x, position.y, transform.position.z)); + } + protected virtual void Acceleration() + { + if (Vector2.Distance(transform.position, (Vector2)target.position + offset) == 0) + localSpeed = Vector2.zero; + else + { + localSpeed = localSpeed + acceleration * Time.deltaTime; + step = localSpeed * Time.deltaTime; + rb.MovePosition(new Vector2(Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).x, Vector2.MoveTowards(transform.position, (Vector2)target.position + offset, step.x).y)); + } + } + + protected virtual void CheckForBounds() + { + rb.MovePosition(new Vector3(Mathf.Clamp(transform.position.x, lowerBounds.x, higherBounds.x), Mathf.Clamp(transform.position.y, lowerBounds.y, higherBounds.y), transform.position.z)); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Assets/Scripts/2D/Follow2DRigidbody.cs.meta b/Assets/Scripts/2D/Follow2DRigidbody.cs.meta new file mode 100644 index 0000000..ee1020a --- /dev/null +++ b/Assets/Scripts/2D/Follow2DRigidbody.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a7e1aa39bc8f2a147a374cdb56ddfb24 +timeCreated: 1511611021 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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/2D/Tilemaps.meta b/Assets/Scripts/2D/Tilemaps.meta new file mode 100644 index 0000000..199d1ef --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 05fee6bf94c73074eba0af2df86b04c6 +folderAsset: yes +timeCreated: 1500793396 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Tilemaps/Editor.meta b/Assets/Scripts/2D/Tilemaps/Editor.meta new file mode 100644 index 0000000..cfdae7b --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 59362721e8fa09e40934df875ea5459a +folderAsset: yes +timeCreated: 1500793398 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs b/Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs similarity index 94% rename from Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs rename to Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs index 5222265..3258a03 100644 --- a/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs +++ b/Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs @@ -1,6 +1,10 @@ using UnityEngine; using UnityEditor; -using UnityEngine.TileMap; + +#if UNITY_2017_2_OR_NEWER +using UnityEngine.Tilemaps; + +//Requires Unity 2017.2 or newer // TilemapLayerHelper // Use PageDown/PageUp to select between tilemap layers @@ -57,7 +61,7 @@ void OnGUI() if (GUI.changed && tileRoot) { // get list of tilemap layers - var childTileMaps = tileRoot.GetComponentsInChildren(); + var childTileMaps = tileRoot.GetComponentsInChildren(); layerNames = new string[childTileMaps.Length]; tilemapGos = new GameObject[childTileMaps.Length]; @@ -191,9 +195,9 @@ void SetTileMapLayerColors() { if (i == selectedLayer || !fadeOtherLayers) { - tilemapGos[i].GetComponent().color = Color.white; + tilemapGos[i].GetComponent().color = Color.white; } else { - tilemapGos[i].GetComponent().color = Color.white * 0.5f; + tilemapGos[i].GetComponent().color = Color.white * 0.5f; } } } @@ -208,3 +212,12 @@ int Wrap(int i, int i_max) return ((i % i_max) + i_max) % i_max; } } +#else +public class TilemapLayerHelper : MonoBehaviour +{ + public void Start() + { + Debug.LogWarning("This version of unity doesnt support UnityEngine.Tilemaps"); + } +} +#endif \ No newline at end of file diff --git a/Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs.meta b/Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs.meta new file mode 100644 index 0000000..1e5a676 --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/Editor/TilemapLayerHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b7620f39da11c9f44a1b32c056766a4c +timeCreated: 1500793403 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/2D/Tilemaps/Icons.meta b/Assets/Scripts/2D/Tilemaps/Icons.meta new file mode 100644 index 0000000..89bf689 --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/Icons.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fe1a6407b41666346a76d2fc33ca904a +folderAsset: yes +timeCreated: 1500793398 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/2D/Tilemaps/Icons/.gitkeep b/Assets/Scripts/2D/Tilemaps/Icons/.gitkeep similarity index 100% rename from Scripts/2D/Tilemaps/Icons/.gitkeep rename to Assets/Scripts/2D/Tilemaps/Icons/.gitkeep diff --git a/Scripts/2D/Tilemaps/Icons/icon_DownArrow2.png b/Assets/Scripts/2D/Tilemaps/Icons/icon_DownArrow2.png similarity index 100% rename from Scripts/2D/Tilemaps/Icons/icon_DownArrow2.png rename to Assets/Scripts/2D/Tilemaps/Icons/icon_DownArrow2.png diff --git a/Scripts/2D/Tilemaps/Icons/icon_UpArrow2.png b/Assets/Scripts/2D/Tilemaps/Icons/icon_UpArrow2.png similarity index 100% rename from Scripts/2D/Tilemaps/Icons/icon_UpArrow2.png rename to Assets/Scripts/2D/Tilemaps/Icons/icon_UpArrow2.png diff --git a/Scripts/2D/Tilemaps/Icons/icon_tilemap.png b/Assets/Scripts/2D/Tilemaps/Icons/icon_tilemap.png similarity index 100% rename from Scripts/2D/Tilemaps/Icons/icon_tilemap.png rename to Assets/Scripts/2D/Tilemaps/Icons/icon_tilemap.png diff --git a/Scripts/2D/Tilemaps/Icons/icon_tilemap_disabled.png b/Assets/Scripts/2D/Tilemaps/Icons/icon_tilemap_disabled.png similarity index 100% rename from Scripts/2D/Tilemaps/Icons/icon_tilemap_disabled.png rename to Assets/Scripts/2D/Tilemaps/Icons/icon_tilemap_disabled.png diff --git a/Assets/Scripts/2D/Tilemaps/RandomTiles.cs b/Assets/Scripts/2D/Tilemaps/RandomTiles.cs new file mode 100644 index 0000000..39b62d0 --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/RandomTiles.cs @@ -0,0 +1,83 @@ +// tested with unity version: 2017.2.0b4 +// info: Fills tilemap with random tiles +// usage: Attach this script to empty gameobject, assign some tiles, then press play +// please make sure that you have at least version 2017.2 or the experimental 2d unity 5_5 +// https://forum.unity3d.com/threads/update-july-2017.484397/ + +using UnityEngine; +#if UNITY_2017_2_OR_NEWER +using UnityEngine.Tilemaps; +namespace UnityLibary +{ + public class RandomTiles : MonoBehaviour + { + public int width = 32; + public int height = 32; + + public Tile[] tiles; + + void Start() + { + RandomTileMap(); + } + + void RandomTileMap() + { + // validation + if (tiles == null || tiles.Length < 1) + { + Debug.LogError("Tiles not assigned", gameObject); + return; + } + + var parent = transform.parent; + if (parent == null) + { + var go = new GameObject("grid"); + go.AddComponent(); + transform.SetParent(go.transform); + } + else + { + if (parent.GetComponent() == null) + { + parent.gameObject.AddComponent(); + } + } + + TilemapRenderer tr = GetComponent(); + if (tr == null) + { + tr = gameObject.AddComponent(); + } + + Tilemap map = GetComponent(); + if (map == null) + { + map = gameObject.AddComponent(); + } + + + // random map generation + Vector3Int tilePos = Vector3Int.zero; + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + tilePos.x = x; + tilePos.y = y; + map.SetTile(tilePos, tiles[Random.Range(0, tiles.Length)]); + } + } + } + } +} +#else +public class RandomTiles : MonoBehaviour +{ + public void Start() + { + Debug.LogWarning("This version of unity doesnt support UnityEngine.Tilemaps"); + } +} +#endif diff --git a/Assets/Scripts/2D/Tilemaps/RandomTiles.cs.meta b/Assets/Scripts/2D/Tilemaps/RandomTiles.cs.meta new file mode 100644 index 0000000..e7726c3 --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/RandomTiles.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2aec585d61714a14cad8db4ae90ae900 +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs b/Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs similarity index 87% rename from Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs rename to Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs index b10c6bb..2176e9d 100644 --- a/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs +++ b/Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs @@ -1,11 +1,16 @@ using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; + // Hierarchy icons http://answers.unity3d.com/answers/1113260/view.html // displays icons for tilemaps in hierarchy // adds up/down arrows for tilemap layers (to arrange them up or down) +//requires unity 2017.2 or newer + +#if UNITY_2017_2_OR_NEWER +using UnityEngine.Tilemaps; [InitializeOnLoad] class TileMapHierarchyHelper { @@ -40,8 +45,8 @@ static void HierarchyItemCallBack(int instanceID, Rect selectionRect) GameObject go = EditorUtility.InstanceIDToObject(instanceID) as GameObject; - // if (go && Selection.activeGameObject == go && go.GetComponent()) - if (go && go.GetComponent()) + // if (go && Selection.activeGameObject == go && go.GetComponent()) + if (go && go.GetComponent()) { // buttons if (GUI.Button(r, upArrow, GUIStyle.none)) @@ -69,3 +74,12 @@ static void MoveInHierarchy(GameObject go, int delta) go.transform.SetSiblingIndex(go.transform.GetSiblingIndex() + delta); } } +#else +public class TileMapHierarchyHelper : MonoBehaviour +{ + public void Start() + { + Debug.LogWarning("This version of unity doesnt support UnityEngine.Tilemaps"); + } +} +#endif diff --git a/Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs.meta b/Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs.meta new file mode 100644 index 0000000..14edfa1 --- /dev/null +++ b/Assets/Scripts/2D/Tilemaps/TileMapHierarchyHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 992bbcd9a2e351040883f3ed6ffe7115 +timeCreated: 1500793403 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AssetBundles.meta b/Assets/Scripts/AssetBundles.meta new file mode 100644 index 0000000..78de1f8 --- /dev/null +++ b/Assets/Scripts/AssetBundles.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 21d456c6e751b564e80f9cf743f1a72f +folderAsset: yes +timeCreated: 1500793394 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AssetBundles/AssetBundleLoader.cs b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs new file mode 100644 index 0000000..db53c54 --- /dev/null +++ b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs @@ -0,0 +1,107 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.Networking; + +namespace UnityLibrary +{ + public class AssetBundleLoader : MonoBehaviour + { + public string assetBundleURL = "http://localhost/bundle"; + private string bundleName = "bundle"; + + void Start() + { + StartCoroutine(DownloadAndCache(assetBundleURL)); + } + + IEnumerator DownloadAndCache(string bundleURL, string assetName = "") + { + while (!Caching.ready) + { + yield return null; + } + + // Clear cache for previous versions of the asset bundle + Caching.ClearOtherCachedVersions(bundleName, Hash128.Parse("0")); + + UnityWebRequest www = UnityWebRequest.Get(bundleURL + ".manifest?r=" + (Random.value * 9999999)); + Debug.Log("Loading manifest: " + bundleURL + ".manifest"); + + yield return www.SendWebRequest(); + + if (www.isNetworkError) + { + Debug.LogError("www error: " + www.error); + www.Dispose(); + www = null; + yield break; + } + + Hash128 hashString = default(Hash128); + + if (www.downloadHandler.text.Contains("ManifestFileVersion")) + { + var hashRow = www.downloadHandler.text.ToString().Split("\n".ToCharArray())[5]; + hashString = Hash128.Parse(hashRow.Split(':')[1].Trim()); + + if (hashString.isValid) + { + if (Caching.IsVersionCached(bundleURL, hashString)) + { + Debug.Log("Bundle with this hash is already cached!"); + } + else + { + Debug.Log("No cached version found for this hash.."); + } + } + else + { + Debug.LogError("Invalid hash: " + hashString); + yield break; + } + } + else + { + Debug.LogError("Manifest doesn't contain string 'ManifestFileVersion': " + bundleURL + ".manifest"); + yield break; + } + + www = UnityWebRequestAssetBundle.GetAssetBundle(bundleURL + "?r=" + (Random.value * 9999999), hashString, 0); + + yield return www.SendWebRequest(); + + if (www.error != null) + { + Debug.LogError("www error: " + www.error); + www.Dispose(); + www = null; + yield break; + } + + AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle; + GameObject bundlePrefab = null; + + if (assetName == "") + { + bundlePrefab = (GameObject)bundle.LoadAsset(bundle.GetAllAssetNames()[0]); + } + else + { + bundlePrefab = (GameObject)bundle.LoadAsset(assetName); + } + + if (bundlePrefab != null) + { + Instantiate(bundlePrefab, Vector3.zero, Quaternion.identity); + } + + www.Dispose(); + www = null; + + Resources.UnloadUnusedAssets(); + bundle.Unload(false); + bundle = null; + } + } +} diff --git a/Assets/Scripts/AssetBundles/AssetBundleLoader.cs.meta b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs.meta new file mode 100644 index 0000000..bf527aa --- /dev/null +++ b/Assets/Scripts/AssetBundles/AssetBundleLoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 03cf67e7ff38596418c74e18a882150f +timeCreated: 1500793399 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Camera.meta b/Assets/Scripts/Camera.meta new file mode 100644 index 0000000..f237375 --- /dev/null +++ b/Assets/Scripts/Camera.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f6741ca26024b1140a6866a3952649b0 +folderAsset: yes +timeCreated: 1500793396 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: 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 new file mode 100644 index 0000000..48a88e6 --- /dev/null +++ b/Assets/Scripts/Camera/CameraShake.cs @@ -0,0 +1,66 @@ +using UnityEngine; +using System.Collections; + +/* + * 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 + { + [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; + +/// +/// Will shake the camera with a random value between minIntensity and maxIntensity for duration +/// +/// +/// +/// + public void Shake(float minIntensity, float maxIntensity, float duration) + { + if (isShakeRunning) + return; + + OriginalPos = transform.position; + OriginalRot = transform.rotation; + + float shake = Random.Range(minIntensity, maxIntensity) * shakeInfluence; + duration *= shakeInfluence; + + StartCoroutine(ProcessShake(shake, duration)); + } + + IEnumerator ProcessShake(float shake, float duration) + { + isShakeRunning = true; + float countdown = duration; + float initialShake = shake; + + while (countdown > 0) + { + 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/CameraShake.cs.meta b/Assets/Scripts/Camera/CameraShake.cs.meta new file mode 100644 index 0000000..57e8c96 --- /dev/null +++ b/Assets/Scripts/Camera/CameraShake.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c03cc4ef2cf2cb54c82653f431e22d78 +timeCreated: 1500793403 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Camera/CameraSwitcher.cs b/Assets/Scripts/Camera/CameraSwitcher.cs similarity index 100% rename from Scripts/Camera/CameraSwitcher.cs rename to Assets/Scripts/Camera/CameraSwitcher.cs diff --git a/Assets/Scripts/Camera/CameraSwitcher.cs.meta b/Assets/Scripts/Camera/CameraSwitcher.cs.meta new file mode 100644 index 0000000..dcf1948 --- /dev/null +++ b/Assets/Scripts/Camera/CameraSwitcher.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 06e035d5b04a4994285b8436101a9f82 +timeCreated: 1500793399 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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 + + + + /// Update Buffer By supplying new target + public void UpdateByNewTarget( Vector2 newTarget, float dampLambda, float deltaTime ){ + this.target = newTarget; + Update(dampLambda, deltaTime); + } + /// Update Buffer By supplying the rawDelta to the last target + public void UpdateByDelta( Vector2 rawDelta, float dampLambda, float deltaTime ){ + this.target = this.target +rawDelta; //update Target + Update(dampLambda, deltaTime); + } + + /// Update Buffer + 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/Scripts/Camera/SmoothMouseLook.cs b/Assets/Scripts/Camera/SmoothMouseLook.cs new file mode 100644 index 0000000..a01d008 --- /dev/null +++ b/Assets/Scripts/Camera/SmoothMouseLook.cs @@ -0,0 +1,72 @@ +// original source: http://forum.unity3d.com/threads/a-free-simple-smooth-mouselook.73117/ +// Very simple smooth mouselook modifier for the MainCamera in Unity +// by Francis R. Griffiths-Keam - www.runningdimensions.com +// Modified: Escape key for hide/show & lock/unlock mouse + +using UnityEngine; +namespace UnityLibrary +{ + public class SmoothMouseLook : MonoBehaviour + { + Vector2 _mouseAbsolute; + Vector2 _smoothMouse; + + public Vector2 clampInDegrees = new Vector2(360, 180); + public bool lockCursor; + public Vector2 sensitivity = new Vector2(2, 2); + public Vector2 smoothing = new Vector2(3, 3); + public Vector2 targetDirection; + + void Start() + { + // Set target direction to the camera's initial orientation. + targetDirection = transform.rotation.eulerAngles; + Cursor.visible = !lockCursor; + } + + void LateUpdate() + { + + // pressing esc toggles between hide/show and lock/unlock cursor + if (Input.GetKeyDown(KeyCode.Escape)) + { + lockCursor = !lockCursor; + } + + // Ensure the cursor is always locked when set + Cursor.lockState = lockCursor ? CursorLockMode.Locked : CursorLockMode.None; + Cursor.visible = !lockCursor; + + // Allow the script to clamp based on a desired target value. + Quaternion targetOrientation = Quaternion.Euler(targetDirection); + + // Get raw mouse input for a cleaner reading on more sensitive mice. + var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")); + + // 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; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Camera/SmoothMouseLook.cs.meta b/Assets/Scripts/Camera/SmoothMouseLook.cs.meta new file mode 100644 index 0000000..5931d49 --- /dev/null +++ b/Assets/Scripts/Camera/SmoothMouseLook.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 44c00afd5e9966b49a5ba1bfd4ce4ba5 +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs b/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs new file mode 100644 index 0000000..b0e17ce --- /dev/null +++ b/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs @@ -0,0 +1,104 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +// source: https://forum.unity3d.com/threads/a-free-simple-smooth-mouselook.73117/#post-3101292 +// added: lockCursor + +namespace UnityLibrary +{ + public class SmoothMouseLookAveraged : MonoBehaviour + { + [Header("Info")] + private List _rotArrayX = new List(); // TODO: could use fixed array, or queue + private List _rotArrayY = new List(); + private float rotAverageX; + private float rotAverageY; + private float mouseDeltaX; + private float mouseDeltaY; + + [Header("Settings")] + public float _sensitivityX = 1.5f; + public float _sensitivityY = 1.5f; + [Tooltip("The more steps, the smoother it will be.")] + public int _averageFromThisManySteps = 3; + public bool lockCursor = false; + + [Header("References")] + [Tooltip("Object to be rotated when mouse moves left/right.")] + public Transform _playerRootT; + [Tooltip("Object to be rotated when mouse moves up/down.")] + public Transform _cameraT; + + //============================================ + // FUNCTIONS (UNITY) + //============================================ + + void Start() + { + Cursor.visible = !lockCursor; + } + + void Update() + { + HandleCursorLock(); + MouseLookAveraged(); + } + + //============================================ + // FUNCTIONS (CUSTOM) + //============================================ + + void HandleCursorLock() + { + // pressing esc toggles between hide/show and lock/unlock cursor + if (Input.GetKeyDown(KeyCode.Escape)) + { + lockCursor = !lockCursor; + } + + // Ensure the cursor is always locked when set + Cursor.lockState = lockCursor ? CursorLockMode.Locked : CursorLockMode.None; + Cursor.visible = !lockCursor; + } + + + + void MouseLookAveraged() + { + rotAverageX = 0f; + rotAverageY = 0f; + mouseDeltaX = 0f; + mouseDeltaY = 0f; + + mouseDeltaX += Input.GetAxis("Mouse X") * _sensitivityX; + mouseDeltaY += Input.GetAxis("Mouse Y") * _sensitivityY; + + // Add current rot to list, at end + _rotArrayX.Add(mouseDeltaX); + _rotArrayY.Add(mouseDeltaY); + + // Reached max number of steps? Remove oldest from list + if (_rotArrayX.Count >= _averageFromThisManySteps) + _rotArrayX.RemoveAt(0); + + if (_rotArrayY.Count >= _averageFromThisManySteps) + _rotArrayY.RemoveAt(0); + + // Add all of these rotations together + for (int i_counterX = 0; i_counterX < _rotArrayX.Count; i_counterX++) + rotAverageX += _rotArrayX[i_counterX]; + + for (int i_counterY = 0; i_counterY < _rotArrayY.Count; i_counterY++) + rotAverageY += _rotArrayY[i_counterY]; + + // Get average + rotAverageX /= _rotArrayX.Count; + rotAverageY /= _rotArrayY.Count; + + // Apply + _playerRootT.Rotate(0f, rotAverageX, 0f, Space.World); + _cameraT.Rotate(-rotAverageY, 0f, 0f, Space.Self); + } + } +} diff --git a/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs.meta b/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs.meta new file mode 100644 index 0000000..abc151e --- /dev/null +++ b/Assets/Scripts/Camera/SmoothMouseLookAveraged.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: be1c222ad88e6b04e945a890fd33e125 +timeCreated: 1500793403 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Camera/WowCamera.cs b/Assets/Scripts/Camera/WowCamera.cs new file mode 100644 index 0000000..7a6fa93 --- /dev/null +++ b/Assets/Scripts/Camera/WowCamera.cs @@ -0,0 +1,159 @@ +using UnityEngine; +using System.Collections; + + +namespace UnityLibrary +{ + public class WowCamera : MonoBehaviour + { + public Transform target; + + public float targetHeight = 1.7f; + public float distance = 5.0f; + public float offsetFromWall = 0.1f; + + public float maxDistance = 20; + public float minDistance = .6f; + + public float xSpeed = 200.0f; + public float ySpeed = 200.0f; + public float targetSpeed = 5.0f; + + + public int yMinLimit = -80; + public int yMaxLimit = 80; + + public int zoomRate = 40; + + public float rotationDampening = 3.0f; + public float zoomDampening = 5.0f; + + public LayerMask collisionLayers = -1; + + private float xDeg = 0.0f; + private float yDeg = 0.0f; + private float currentDistance; + private float desiredDistance; + private float correctedDistance; + + void Start() + { + Vector3 angles = transform.eulerAngles; + xDeg = angles.x; + yDeg = angles.y; + + currentDistance = distance; + desiredDistance = distance; + correctedDistance = distance; + + // Make the rigid body not change rotation + if (GetComponent()) + GetComponent().freezeRotation = true; + } + + + void Update() + { + + //Move the Player with left & right button press together + if (Input.GetMouseButton(1) && Input.GetMouseButton(0)) + { + float targetRotationAngle = target.eulerAngles.y; + float currentRotationAngle = transform.eulerAngles.y; + xDeg = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime); + target.transform.Rotate(0, Input.GetAxis("Mouse X") * xSpeed * 0.02f, 0); + xDeg += Input.GetAxis("Mouse X") * targetSpeed * 0.02f; + target.transform.Translate(Vector3.forward * targetSpeed * Time.deltaTime); + } + } + + /** + * Camera logic on LateUpdate to only update after all character movement logic has been handled. + */ + void LateUpdate() + { + Vector3 vTargetOffset; + + // Don't do anything if target is not defined + if (!target) + return; + + // If either mouse buttons are down, let the mouse govern camera position + if (Input.GetMouseButton(0)) + { + xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; + yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; + } + //Reset the camera angle and Rotate the Target Around the World! + else if (Input.GetMouseButton(1)) + { + float targetRotationAngle = target.eulerAngles.y; + float currentRotationAngle = transform.eulerAngles.y; + xDeg = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime); + target.transform.Rotate(0, Input.GetAxis("Mouse X") * xSpeed * 0.02f, 0); + xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f; + } + + + // otherwise, ease behind the target if any of the directional keys are pressed + else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0) + { + float targetRotationAngle = target.eulerAngles.y; + float currentRotationAngle = transform.eulerAngles.y; + xDeg = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime); + } + + yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit); + + + // set camera rotation + Quaternion rotation = Quaternion.Euler(yDeg, xDeg, 0); + + // calculate the desired distance + desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance); + desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance); + correctedDistance = desiredDistance; + + // calculate desired camera position + vTargetOffset = new Vector3(0, -targetHeight, 0); + Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset); + + // check for collision using the true target's desired registration point as set by user using height + RaycastHit collisionHit; + Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z); + + // if there was a collision, correct the camera position and calculate the corrected distance + bool isCorrected = false; + if (Physics.Linecast(trueTargetPosition, position, out collisionHit, collisionLayers.value)) + { + // calculate the distance from the original estimated position to the collision location, + // subtracting out a safety "offset" distance from the object we hit. The offset will help + // keep the camera from being right on top of the surface we hit, which usually shows up as + // the surface geometry getting partially clipped by the camera's front clipping plane. + correctedDistance = Vector3.Distance(trueTargetPosition, collisionHit.point) - offsetFromWall; + isCorrected = true; + } + + // For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance + currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance; + + // keep within legal limits + currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance); + + // recalculate position based on the new currentDistance + position = target.position - (rotation * Vector3.forward * currentDistance + vTargetOffset); + + transform.rotation = rotation; + 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); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Camera/WowCamera.cs.meta b/Assets/Scripts/Camera/WowCamera.cs.meta new file mode 100644 index 0000000..eba07e5 --- /dev/null +++ b/Assets/Scripts/Camera/WowCamera.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3d99a01c1a910df45bea4973b72ad60b +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Camera/ZoomWithMouse.cs b/Assets/Scripts/Camera/ZoomWithMouse.cs new file mode 100644 index 0000000..45b0b1f --- /dev/null +++ b/Assets/Scripts/Camera/ZoomWithMouse.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +// Zoom forward and backward with mousewheel, Attach this script to camera + +namespace UnityLibrary +{ + public class ZoomWithMouse : MonoBehaviour + { + public float zoomSpeed = 20; + + void Update() + { + var mouseScroll = Input.GetAxis("Mouse ScrollWheel"); + + if (mouseScroll != 0) + { + transform.Translate(transform.forward * mouseScroll * zoomSpeed * Time.deltaTime, Space.Self); + } + } + } +} diff --git a/Assets/Scripts/Camera/ZoomWithMouse.cs.meta b/Assets/Scripts/Camera/ZoomWithMouse.cs.meta new file mode 100644 index 0000000..09ee286 --- /dev/null +++ b/Assets/Scripts/Camera/ZoomWithMouse.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f63c7db2f4eaccb4a8c82158ed83fc72 +timeCreated: 1500793404 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs.meta b/Assets/Scripts/Docs.meta new file mode 100644 index 0000000..3717894 --- /dev/null +++ b/Assets/Scripts/Docs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a5f32495e2dec8f4f9793a3b0c2c16cc +folderAsset: yes +timeCreated: 1502256483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/Camera.meta b/Assets/Scripts/Docs/Camera.meta new file mode 100644 index 0000000..67ee210 --- /dev/null +++ b/Assets/Scripts/Docs/Camera.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f156ebd0553293648ad08d0bb96d6a17 +folderAsset: yes +timeCreated: 1502256483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Docs/Camera/Camera_depthTextureMode.cs b/Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs similarity index 91% rename from Docs/Camera/Camera_depthTextureMode.cs rename to Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs index a1610dd..2b70930 100644 --- a/Docs/Camera/Camera_depthTextureMode.cs +++ b/Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs @@ -9,7 +9,7 @@ public class Camera_depthTextureMode : MonoBehaviour { void OnEnable() { - var cam = Getcomponent(); + var cam = GetComponent(); if (cam!=null) { // enable camera depth texture diff --git a/Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs.meta b/Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs.meta new file mode 100644 index 0000000..98beb3d --- /dev/null +++ b/Assets/Scripts/Docs/Camera/Camera_depthTextureMode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 952055200907e8b4f95a7539f6d5607f +timeCreated: 1502256483 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/Graphics.meta b/Assets/Scripts/Docs/Graphics.meta new file mode 100644 index 0000000..57ac596 --- /dev/null +++ b/Assets/Scripts/Docs/Graphics.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8f51a49ed57226740a48b0c16003d736 +folderAsset: yes +timeCreated: 1502256483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs b/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs new file mode 100644 index 0000000..6760898 --- /dev/null +++ b/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs @@ -0,0 +1,32 @@ +using UnityEngine; +using System.Collections; + +// Example: Using Graphics.Blit to draw a full screen texture, with particle shader +// Usage: Attach to Main Camera +// Optional: Assign some texture into the displayTexture field in inspector + +namespace UnityLibrary +{ + public class Graphics_Blit : MonoBehaviour + { + public Texture displayTexture; // assign texture you want to blit fullscreen + Material mat; // material(shader) to use for blitting + + void Awake() + { + if (displayTexture == null) displayTexture = Texture2D.whiteTexture; // use white texture, if nothing is set + + // use particle shader for the Blit material + var shader = Shader.Find("Particles/Multiply (Double)"); + mat = new Material(shader); + } + + // This function is called only if the script is attached to the camera and is enabled + void OnPostRender() + { + // Copies source texture into destination render texture with a shader + // Destination RenderTexture is null to blit directly to screen + Graphics.Blit(displayTexture, null, mat); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs.meta b/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs.meta new file mode 100644 index 0000000..b9cc5b1 --- /dev/null +++ b/Assets/Scripts/Docs/Graphics/Graphics_Blit.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 57240369e62ddfe4f89dbf0b4462a1ea +timeCreated: 1502256483 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/Mesh.meta b/Assets/Scripts/Docs/Mesh.meta new file mode 100644 index 0000000..836722b --- /dev/null +++ b/Assets/Scripts/Docs/Mesh.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: dfe48b7debc5f9c4a9ab9b77ddb37e1a +folderAsset: yes +timeCreated: 1594958191 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/Mesh/MeshExample.cs b/Assets/Scripts/Docs/Mesh/MeshExample.cs new file mode 100644 index 0000000..03e2799 --- /dev/null +++ b/Assets/Scripts/Docs/Mesh/MeshExample.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +/// +/// Build single triangle mesh from script, with vertex colors, normals, uvs. +/// Usage: Assign this script into empty gameobject in the scene, press play. Optional: Add point light to scene for testing lights +/// + +namespace UnityLibrary +{ + public class MeshExample : MonoBehaviour + { + + void Start() + { + // create empty gameobject with meshrenderer and meshfilter + var mr = gameObject.AddComponent(); + var mf = gameObject.AddComponent(); + + // build new mesh + Mesh mesh = new Mesh(); + // assign to meshfilter + mf.mesh = mesh; + + // create one triangle face + // 3 vertices + var vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 0, 1), new Vector3(1, 0, 1) }; + // connect vertices to build triangle face + var triangles = new int[] { 0, 1, 2 }; + // assign UV per vertex + var uvs = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) }; + // assign normal direction per vertex + var normals = new Vector3[] { Vector3.up, Vector3.up, Vector3.up }; + // assign color per vertex + var colors = new Color[] { Color.red, Color.green, Color.blue }; + + // assign values to mesh + mesh.vertices = vertices; + mesh.uv = uvs; + mesh.triangles = triangles; + mesh.normals = normals; + mesh.colors = colors; + + // if have issues of disappearing mesh, uncomment next line + //mesh.RecalculateBounds(); + + // assign sprite diffuce shader material to see vertex colors and lights + var shader = Shader.Find("Sprites/Diffuse"); + var material = new Material(shader); + mr.material = material; + } + + } +} 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/MonoBehaviour.meta b/Assets/Scripts/Docs/MonoBehaviour.meta new file mode 100644 index 0000000..e084d9a --- /dev/null +++ b/Assets/Scripts/Docs/MonoBehaviour.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9855b6fa6f6a43b468a2c8bb672a64a6 +folderAsset: yes +timeCreated: 1502256483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs b/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs new file mode 100644 index 0000000..6b0b99f --- /dev/null +++ b/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using System.Collections; + +// Example: Using OnValidate() to validate inspector fields in editor +// https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnValidate.html + +namespace UnityLibrary +{ + public class MonoBehaviour_OnValidate : MonoBehaviour + { + // try setting this number larger than 100 in inspector + public float number = 0; + + // this gets called only in editor, when inspector field is modified + void OnValidate() + { + // you can print warnings also + // if (number < 0 || number > 100) Debug.LogWarning("OnValidate: number value is invalid.."); + + // clamp number to 0-100 + number = Mathf.Clamp(number, 0, 100); + } + } +} + diff --git a/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs.meta b/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs.meta new file mode 100644 index 0000000..8b2f5ef --- /dev/null +++ b/Assets/Scripts/Docs/MonoBehaviour/MonoBehaviour_OnValidate.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a69f3fc609439c64381e334c508b0b82 +timeCreated: 1502256483 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/README.md b/Assets/Scripts/Docs/README.md new file mode 100644 index 0000000..45f96a5 --- /dev/null +++ b/Assets/Scripts/Docs/README.md @@ -0,0 +1,9 @@ +# Docs +Sometimes we see some missing, outdated or broken documentations and examples at Unity official documentation Manual or Scripting API, so we have collected some of them and made a good examples and documentations about them. + +Do you found a missing documentation or example? [File it here and let us add it](https://github.com/UnityCommunity/UnityLibrary/issues) + +## License +[MIT](https://github.com/UnityCommunity/UnityLibrary/blob/master/LICENSE.md) @ [Unity Community](https://github.com/UnityCommunity/) + +Made with :heart: by [Unity Community](https://github.com/UnityCommunity/) diff --git a/Assets/Scripts/Docs/README.md.meta b/Assets/Scripts/Docs/README.md.meta new file mode 100644 index 0000000..2d208e8 --- /dev/null +++ b/Assets/Scripts/Docs/README.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2d99c632bd78fa748850ab71f0eed232 +timeCreated: 1502256483 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/UnityEngine.meta b/Assets/Scripts/Docs/UnityEngine.meta new file mode 100644 index 0000000..1ca44cd --- /dev/null +++ b/Assets/Scripts/Docs/UnityEngine.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bb36932ec6987c54189247496091d7f6 +folderAsset: yes +timeCreated: 1511611015 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs b/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs new file mode 100644 index 0000000..a8b26ca --- /dev/null +++ b/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs @@ -0,0 +1,40 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +// usage: Attach this script to gameobject with Canvas component +// click mouse button to switch modes *note: worldspace will not be visible without scaling it +// https://docs.unity3d.com/ScriptReference/Canvas-renderMode.html + +namespace UnityLibrary +{ + public class CanvasRenderMode : MonoBehaviour + { + Canvas canvas; + + void Start() + { + canvas = GetComponent(); + if (canvas == null) + { + Debug.LogError("Canvas not found..", gameObject); + this.enabled = false; + } + } + + void Update() + { + // switch modes on left mouse click + if (Input.GetMouseButtonDown(0)) + { + if (canvas.renderMode != RenderMode.WorldSpace) + { + canvas.renderMode = RenderMode.WorldSpace; + } else + { + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + } + } + } + } +} diff --git a/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs.meta b/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs.meta new file mode 100644 index 0000000..f44cb21 --- /dev/null +++ b/Assets/Scripts/Docs/UnityEngine/CanvasRenderMode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 37aa85463a82a3448886076125e86145 +timeCreated: 1511611020 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs b/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs new file mode 100644 index 0000000..2a5f505 --- /dev/null +++ b/Assets/Scripts/Docs/UnityEngine/CullingGroupExample.cs @@ -0,0 +1,93 @@ +// gets nearby objects using CullingGroup +// Assign this script to some gameobject, that the distance is measured from + +using UnityEngine; + +namespace UnityLibrary +{ + public class CullingGroupExample : MonoBehaviour + { + // just some dummy prefab to spawn (use default sphere for example) + public GameObject prefab; + + // distance to search objects from + public float searchDistance = 3; + + public bool colorInvisibleObjects = false; + + int objectCount = 5000; + + // collection of objects + Renderer[] objects; + CullingGroup cullGroup; + BoundingSphere[] bounds; + + void Start() + { + // create culling group + cullGroup = new CullingGroup(); + cullGroup.targetCamera = Camera.main; + + // measure distance to our transform + cullGroup.SetDistanceReferencePoint(transform); + + // search distance "bands" starts from 0, so index=0 is from 0 to searchDistance + cullGroup.SetBoundingDistances(new float[] { searchDistance, float.PositiveInfinity }); + + bounds = new BoundingSphere[objectCount]; + + // spam random objects + objects = new Renderer[objectCount]; + for (int i = 0; i < objectCount; i++) + { + var pos = Random.insideUnitCircle * 30; + var go = Instantiate(prefab, pos, Quaternion.identity); + objects[i] = go.GetComponent(); + + // collect bounds for objects + var b = new BoundingSphere(); + b.position = go.transform.position; + + // get simple radius..works for our sphere + b.radius = go.GetComponent().mesh.bounds.extents.x; + bounds[i] = b; + } + + // set bounds that we track + cullGroup.SetBoundingSpheres(bounds); + cullGroup.SetBoundingSphereCount(objects.Length); + + // subscribe to event + cullGroup.onStateChanged += StateChanged; + } + + // object state has changed in culling group + void StateChanged(CullingGroupEvent e) + { + if (colorInvisibleObjects == true && e.isVisible == false) + { + objects[e.index].material.color = Color.gray; + return; + } + + // if we are in distance band index 0, that is between 0 to searchDistance + if (e.currentDistance == 0) + { + objects[e.index].material.color = Color.green; + } + else // too far, set color to red + { + objects[e.index].material.color = Color.red; + } + } + + // cleanup + private void OnDestroy() + { + cullGroup.onStateChanged -= StateChanged; + cullGroup.Dispose(); + cullGroup = null; + } + + } +} 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(); + + // Set the destination of the NavMeshAgent to the target Transform + agent.destination = target.position; + } + } +} diff --git a/Assets/Scripts/Drawing.meta b/Assets/Scripts/Drawing.meta new file mode 100644 index 0000000..d39dcb5 --- /dev/null +++ b/Assets/Scripts/Drawing.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e1c3dce8b3aafb34786d2bb6fa8a24df +folderAsset: yes +timeCreated: 1501390147 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Drawing/DrawLine.cs b/Assets/Scripts/Drawing/DrawLine.cs new file mode 100644 index 0000000..6ffbfbd --- /dev/null +++ b/Assets/Scripts/Drawing/DrawLine.cs @@ -0,0 +1,103 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +namespace UnityLibrary +{ + public class DrawLine : MonoBehaviour + { + + [SerializeField] + protected LineRenderer m_LineRenderer; + [SerializeField] + protected Camera m_Camera; + protected List m_Points; + + public virtual LineRenderer lineRenderer { + get { + return m_LineRenderer; + } + } + + public virtual new Camera camera { + get { + return m_Camera; + } + } + + public virtual List points { + get { + return m_Points; + } + } + + protected virtual void Awake() + { + if (m_LineRenderer == null) + { + Debug.LogWarning("DrawLine: Line Renderer not assigned, Adding and Using default Line Renderer."); + CreateDefaultLineRenderer(); + } + if (m_Camera == null) + { + Debug.LogWarning("DrawLine: Camera not assigned, Using Main Camera or Creating Camera if main not exists."); + CreateDefaultCamera(); + } + m_Points = new List(); + } + + protected virtual void Update() + { + if (Input.GetMouseButtonDown(0)) + { + Reset(); + } + if (Input.GetMouseButton(0)) + { + 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); + m_LineRenderer.positionCount = m_Points.Count; + m_LineRenderer.SetPosition(m_LineRenderer.positionCount - 1, mousePosition); + } + } + } + + protected virtual void Reset() + { + if (m_LineRenderer != null) + { + m_LineRenderer.positionCount = 0; + } + if (m_Points != null) + { + m_Points.Clear(); + } + } + + protected virtual void CreateDefaultLineRenderer() + { + m_LineRenderer = gameObject.AddComponent(); + m_LineRenderer.positionCount = 0; + m_LineRenderer.material = new Material(Shader.Find("Particles/Additive")); + m_LineRenderer.startColor = Color.white; + m_LineRenderer.endColor = Color.white; + m_LineRenderer.startWidth = 0.3f; + m_LineRenderer.endWidth = 0.3f; + m_LineRenderer.useWorldSpace = true; + } + + protected virtual void CreateDefaultCamera() + { + m_Camera = Camera.main; + if (m_Camera == null) + { + m_Camera = gameObject.AddComponent(); + } + m_Camera.orthographic = true; + } + + } +} diff --git a/Assets/Scripts/Drawing/DrawLine.cs.meta b/Assets/Scripts/Drawing/DrawLine.cs.meta new file mode 100644 index 0000000..ea2e2b1 --- /dev/null +++ b/Assets/Scripts/Drawing/DrawLine.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a98122fb61ecbdc42be2a513a469f129 +timeCreated: 1501390147 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor.meta b/Assets/Scripts/Editor.meta new file mode 100644 index 0000000..08253ed --- /dev/null +++ b/Assets/Scripts/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 13ed0fd2b41b56e4eae1ca4cda5ec8c7 +folderAsset: yes +timeCreated: 1500793394 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/AddDefineSymbols.cs b/Assets/Scripts/Editor/AddDefineSymbols.cs new file mode 100644 index 0000000..d04e951 --- /dev/null +++ b/Assets/Scripts/Editor/AddDefineSymbols.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEditor; + +/// +/// Adds the given define symbols to PlayerSettings define symbols. +/// Just add your own define symbols to the Symbols property at the below. +/// +[InitializeOnLoad] +public class AddDefineSymbols : Editor +{ + + /// + /// Symbols that will be added to the editor + /// + public static readonly string [] Symbols = new string[] { + "MYCOMPANY", + "MYCOMPANY_MYPACKAGE" + }; + + /// + /// Add define symbols as soon as Unity gets done compiling. + /// + static AddDefineSymbols () + { + string definesString = PlayerSettings.GetScriptingDefineSymbolsForGroup ( EditorUserBuildSettings.selectedBuildTargetGroup ); + List allDefines = definesString.Split ( ';' ).ToList (); + allDefines.AddRange ( Symbols.Except ( allDefines ) ); + PlayerSettings.SetScriptingDefineSymbolsForGroup ( + EditorUserBuildSettings.selectedBuildTargetGroup, + string.Join ( ";", allDefines.ToArray () ) ); + } + +} diff --git a/Assets/Scripts/Editor/AddDefineSymbols.cs.meta b/Assets/Scripts/Editor/AddDefineSymbols.cs.meta new file mode 100644 index 0000000..6aea040 --- /dev/null +++ b/Assets/Scripts/Editor/AddDefineSymbols.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7fe019cd59a9a6c469975bb98490ba24 +timeCreated: 1511611020 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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.meta b/Assets/Scripts/Editor/BatchTools.meta new file mode 100644 index 0000000..3d56885 --- /dev/null +++ b/Assets/Scripts/Editor/BatchTools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5b412ecce3fdda84085c2963eba28095 +folderAsset: yes +timeCreated: 1511611015 +licenseType: Free +DefaultImporter: + 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("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/MassRenameChildren.cs b/Assets/Scripts/Editor/BatchTools/MassRenameChildren.cs new file mode 100644 index 0000000..cfcf9d4 --- /dev/null +++ b/Assets/Scripts/Editor/BatchTools/MassRenameChildren.cs @@ -0,0 +1,61 @@ +// Renames child gameobjects in hierarchy (by replacting strings) +// open wizard from GameObject/MassRenameChildren menu item + +using UnityEditor; +using UnityEngine; + +namespace UnityLibrary +{ + public class MassRenameChildren : ScriptableWizard + { + public string findString = ""; + public string replaceWith = ""; + // if set false: would replace "Hand" inside "RightHandRig", if set true: would replace "Hand" only if name starts with "Hand" like "HandRigWasd" + public bool onlyIfStartsWithFindString = true; + + [MenuItem("GameObject/Mass Rename Children")] + static void CreateWizard() + { + DisplayWizard("MassRenamer", "Apply"); + } + + // user clicked create button + void OnWizardCreate() + { + if (Selection.activeTransform == null || findString == "") + { + Debug.Log(name + " Select Root Transform and set FindString first.."); + return; + } + + // get all children for the selection, NOTE: includeInactive is true, so disabled objects will get selected also + Transform[] allChildren = Selection.activeTransform.GetComponentsInChildren(includeInactive: true); + foreach (Transform child in allChildren) + { + // skip self (selection root) + if (child != Selection.activeTransform) + { + string newName = child.name; + if (onlyIfStartsWithFindString == true) + { + // string starts with our search string + if (child.name.IndexOf(findString) == 0) + { + newName = child.name.Replace(findString, replaceWith); + } + } else // replace anywhere in target string + { + newName = child.name.Replace(findString, replaceWith); + } + + // if would have any changes to name, print out and change + if (child.name != newName) + { + Debug.LogFormat("Before: {0} | After: {1}", child.name, newName); + child.name = newName; + } + } + } + } + } +} diff --git a/Assets/Scripts/Editor/BatchTools/MassRenameChildren.cs.meta b/Assets/Scripts/Editor/BatchTools/MassRenameChildren.cs.meta new file mode 100644 index 0000000..de3bd71 --- /dev/null +++ b/Assets/Scripts/Editor/BatchTools/MassRenameChildren.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c9ef2083b7d1fba4aa65c75605fbf37c +timeCreated: 1511611021 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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("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.meta b/Assets/Scripts/Editor/BuildProcess.meta new file mode 100644 index 0000000..4f602b9 --- /dev/null +++ b/Assets/Scripts/Editor/BuildProcess.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d115dabccac4e7341a0f797c709e9ee7 +folderAsset: yes +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: 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("### POSTBUILD : COPY EMPTY STREAMINGASSETS-FOLDERS ###"); + 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/Scripts/Editor/BuildProcess/PostProcessBuild.cs b/Assets/Scripts/Editor/BuildProcess/PostProcessBuild.cs similarity index 100% rename from Scripts/Editor/BuildProcess/PostProcessBuild.cs rename to Assets/Scripts/Editor/BuildProcess/PostProcessBuild.cs diff --git a/Assets/Scripts/Editor/BuildProcess/PostProcessBuild.cs.meta b/Assets/Scripts/Editor/BuildProcess/PostProcessBuild.cs.meta new file mode 100644 index 0000000..4ae3cd6 --- /dev/null +++ b/Assets/Scripts/Editor/BuildProcess/PostProcessBuild.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 650b440cfd97b6c43af9eba650d33741 +timeCreated: 1500793402 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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(); + + 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 b/Assets/Scripts/Editor/ContextMenu/CreateOutlineForPanelEditor.cs new file mode 100644 index 0000000..539fbfa --- /dev/null +++ b/Assets/Scripts/Editor/ContextMenu/CreateOutlineForPanelEditor.cs @@ -0,0 +1,59 @@ +// Custom Contect menu for UI Image component (in WorldSpace UI canvas) +// used for creating outline for panel (image) using LineRenderer + +using UnityEngine; +using UnityEditor; +using UnityEngine.UI; + +namespace UnityLibrary +{ + public class CreateOutlineForPanelEditor : MonoBehaviour + { + [MenuItem("CONTEXT/Image/Create Outline For Panel")] + static void DoubleMass(MenuCommand command) + { + // get reference + Image comp = (Image)command.context; + if (comp == null) + { + Debug.LogError("No Image component found.."); + return; + } + + // TODO check that its worlspace canvas + + // get worldspace borders, FIXME get root canvas, instead of parent + var canvasRect = comp.transform.parent.GetComponent().GetComponent(); + Vector3[] corners = new Vector3[4]; + canvasRect.GetWorldCorners(corners); + + var line = comp.transform.GetComponent(); + if (line == null) + { + Debug.LogError("Missing LineRenderer component"); + return; + } + + if (line.useWorldSpace == true) + { + Debug.LogWarning("LineRenderer has worlspace enabled, disabling it"); + line.useWorldSpace = false; + } + + // set line points + line.positionCount = corners.Length + 1; + line.SetPositions(corners); + // connect last and first + line.SetPosition(line.positionCount - 1, corners[0]); + + // convert worldspace to localspace + for (int i = 0, len = line.positionCount; i < len; i++) + { + var worldPos = line.GetPosition(i); + var localPos = canvasRect.transform.InverseTransformPoint(worldPos); + line.SetPosition(i, localPos); + } + + } + } +} 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 new file mode 100644 index 0000000..b15992c --- /dev/null +++ b/Assets/Scripts/Editor/ContextMenu/GetVideoAspectRatioEditor.cs @@ -0,0 +1,39 @@ +// Custom Contect menu for VideoPlayer component +// used for scaling quad mesh transform localscale.y to match videoplayer aspect ratio + +using UnityEngine; +using UnityEditor; +using UnityEngine.Video; + +namespace UnityLibrary +{ + public class GetVideoAspectRatioEditor : MonoBehaviour + { + [MenuItem("CONTEXT/VideoPlayer/Get Aspect Ratio for Mesh")] + static void DoubleMass(MenuCommand command) + { + // get aspect ratio + VideoPlayer v = (VideoPlayer)command.context; + if (v.clip == null) + { + 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"); + + // scale mesh + Vector3 scale = v.transform.localScale; + // fix only height + scale.y *= aspectRatioY; + v.transform.localScale = 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(); + 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().rect.size.x; + anchorMin.y = rectTransform.offsetMin.y / parent.GetComponent().rect.size.y; + anchorMax.x = rectTransform.offsetMax.x / parent.GetComponent().rect.size.x; + anchorMax.y = rectTransform.offsetMax.y / parent.GetComponent().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 +{ + /// + /// 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. + /// + [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 + + + /// Get translated Transform label + 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())); + } + + /// Round all values of the Transform to a given number of decimals + 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); + } + } + + /// Round all components of a Vector3 + 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; + } + + /// Truncate all values of the Transform to a given number of decimals + 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); + } + } + + /// Truncate all components of a Vector3 + 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/EditorShortCutKeys.cs b/Assets/Scripts/Editor/EditorShortCutKeys.cs new file mode 100644 index 0000000..d6f50fe --- /dev/null +++ b/Assets/Scripts/Editor/EditorShortCutKeys.cs @@ -0,0 +1,22 @@ +using UnityEngine; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine.SceneManagement; + +// original source by "Mavina" http://answers.unity3d.com/answers/1204307/view.html +// usage: Place this script into Editor/ folder, then you can press F5 to enter/exit Play Mode +namespace UnityLibrary +{ + public class EditorShortCutKeys : ScriptableObject + { + [MenuItem("Edit/Run _F5")] // shortcut key F5 to Play (and exit playmode also) + static void PlayGame() + { + if (!Application.isPlaying) + { + EditorSceneManager.SaveScene(SceneManager.GetActiveScene(), "", false); // optional: save before run + } + EditorApplication.ExecuteMenuItem("Edit/Play"); + } + } +} diff --git a/Assets/Scripts/Editor/EditorShortCutKeys.cs.meta b/Assets/Scripts/Editor/EditorShortCutKeys.cs.meta new file mode 100644 index 0000000..ab840e1 --- /dev/null +++ b/Assets/Scripts/Editor/EditorShortCutKeys.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f55ab5721c1f1714e8ff849ddb613432 +timeCreated: 1500793404 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: 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 b/Assets/Scripts/Editor/GameObject/ResetTransform.cs new file mode 100644 index 0000000..8726d41 --- /dev/null +++ b/Assets/Scripts/Editor/GameObject/ResetTransform.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using UnityEditor; + +// reset transform position, rotation and scale + +namespace UnityLibrary +{ + public class ResetTransform : ScriptableObject + { + [MenuItem("GameObject/Reset Transform #r")] + static public void MoveSceneViewCamera() + { + // TODO add multiple object support + var go = Selection.activeGameObject; + if (go != null) + { + // TODO: add undo + go.transform.position = Vector3.zero; + go.transform.rotation = Quaternion.identity; + go.transform.localScale = Vector3.one; + } + } + + } // class +} // namespace 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.meta b/Assets/Scripts/Editor/Gizmos.meta new file mode 100644 index 0000000..937bc2f --- /dev/null +++ b/Assets/Scripts/Editor/Gizmos.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a9b3e3cace9b2a45a7ef8a517017aa2 +folderAsset: yes +timeCreated: 1500793396 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs b/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs new file mode 100644 index 0000000..b0f87f9 --- /dev/null +++ b/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using UnityEditor; + +// draws camera frustum lines with Gizmo lines (when camera is not selected) +// Usage: add this script into Editor/ folder on your project +// WARNING: cam.transform.position does not work, DrawFrustum ignores the value, unity bug? +namespace UnityLibrary +{ + static class DrawCameraFrustumGizmos + { + [DrawGizmo(GizmoType.NotInSelectionHierarchy)]// | GizmoType.Active)] + static void DrawGizmoForMyScript(Camera cam, GizmoType gizmoType) + { + Gizmos.color = Color.red; + Gizmos.DrawFrustum(cam.transform.position, cam.fieldOfView, cam.farClipPlane, cam.nearClipPlane, cam.aspect); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs.meta b/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs.meta new file mode 100644 index 0000000..84a2501 --- /dev/null +++ b/Assets/Scripts/Editor/Gizmos/DrawCameraFrustumGizmos.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 45f18a6639b731f4caa6b5b1a01429b7 +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs b/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs new file mode 100644 index 0000000..084224f --- /dev/null +++ b/Assets/Scripts/Editor/Gizmos/RendererBoundsGizmo.cs @@ -0,0 +1,19 @@ +// attach this to mesh, draws renderer bounds when gameobject is selected +// original source: http://answers.unity.com/answers/137475/view.html + +using UnityEngine; + +namespace UnityLibrary +{ + public class RendererBoundsGizmo : MonoBehaviour + { + void OnDrawGizmosSelected() + { + Gizmos.color = Color.yellow; + //center sphere + //Gizmos.DrawSphere(transform.position, 0.1f); + var r = transform.GetComponent(); + if (r != null) Gizmos.DrawWireCube(transform.position, r.bounds.size); + } + } +} 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/GridGenerator.meta b/Assets/Scripts/Editor/GridGenerator.meta new file mode 100644 index 0000000..cd9b640 --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a6d652b3b2e09c341916f676f9620af4 +folderAsset: yes +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/GridGenerator/Editor.meta b/Assets/Scripts/Editor/GridGenerator/Editor.meta new file mode 100644 index 0000000..52d2f55 --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bfd74206b49d0814fba364735df6024b +folderAsset: yes +timeCreated: 1500793398 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs b/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs new file mode 100644 index 0000000..33a608c --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs @@ -0,0 +1,66 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using UnityEditor.SceneManagement; +using System.Linq; +namespace UnityLibrary +{ + [CustomEditor(typeof(GridGenerator))] + public class GridGeneratorEditor : Editor + { + GridGenerator t; + + private void OnEnable() + { + t = (GridGenerator)target; + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (GUILayout.Button("Cleanup")) + { + CleanUp(); + } + + if (GUILayout.Button("Generate Grid")) + { + CleanUp(); + GenerateGrid(); + } + } + + private void CleanUp() + { + List tempList = t.transform.Cast().ToList(); + tempList.ForEach(x => DestroyImmediate(x.gameObject)); + } + + private void GenerateGrid() + { + for (int x = 0; x < t.SizeX; x++) + { + for (int y = 0; y < t.SizeY; y++) + { + Vector3 localOffset = new Vector3( + t.Offset.x * x, + 0, + t.Offset.y * y + ); + + GameObject spawnedObject = Instantiate(t.PrefabToPlace); + + spawnedObject.transform.SetParent(t.transform); + spawnedObject.transform.localPosition = localOffset; + + spawnedObject.name = string.Format("{0} ({1},{2})", t.PrefabToPlace.name, x, y); + } + } + + EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); + } + + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs.meta b/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs.meta new file mode 100644 index 0000000..0c9ab35 --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator/Editor/GridGeneratorEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 62a17510090efae4591eaa951197003d +timeCreated: 1500793402 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs b/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs new file mode 100644 index 0000000..9d0d15d --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs @@ -0,0 +1,24 @@ +using UnityEngine; +namespace UnityLibrary +{ + public class GridGenerator : MonoBehaviour + { + [SerializeField] + private GameObject prefabToPlace; + + [SerializeField] + private uint sizeX = 2; + + [SerializeField] + private uint sizeY = 2; + + [SerializeField] + private Vector2 offset = Vector2.one; + + public GameObject PrefabToPlace { get { return prefabToPlace; } } + public Vector2 Offset { get { return offset; } } + + public uint SizeX { get { return sizeX; } } + public uint SizeY { get { return sizeY; } } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs.meta b/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs.meta new file mode 100644 index 0000000..c23f309 --- /dev/null +++ b/Assets/Scripts/Editor/GridGenerator/GridGenerator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 50d99d82db098f143b97912777f8c022 +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/HelpLastRelease.cs b/Assets/Scripts/Editor/HelpLastRelease.cs new file mode 100644 index 0000000..076fdce --- /dev/null +++ b/Assets/Scripts/Editor/HelpLastRelease.cs @@ -0,0 +1,556 @@ +/* + * Version: 2.4 + * Fork from the original script: https://pastebin.com/LzEHNB6U + * Purpose: Download new versions of Unity (alpha, beta, + * patches and releases) straight from the Editor. + * Shortcut in the editor for Statistics, Experimental + * Features and the Unity Roadmap. + * + * Usage: Menu, Links, Last Releases. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; +using UnityEditor; +using UnityEngine; +using Debug = UnityEngine.Debug; +namespace UnityLibrary +{ + public class HelpLastRelease : EditorWindow + { + const string statsUrl = @"http://hwstats.unity3d.com/index.html"; + const string experimenalUrl = @"http://unity3d.com/experimental"; + const string roadmapUrl = @"http://unity3d.com/unity/roadmap"; + const string archiveUrl = @"http://unity3d.com/get-unity/download/archive"; + const string betaArchiveUrl = @"http://unity3d.com/unity/beta/archive"; + const string releaseUrl = @"http://beta.unity3d.com/download/{0}/download.html"; + const string assistantUrl = @"http://beta.unity3d.com/download/{0}/UnityDownloadAssistant-{1}.{2}"; + const string serverUrl = @"http://symbolserver.unity3d.com/"; + const string historyUrl = serverUrl + @"000Admin/history.txt"; + const string finalRN = @"http://unity3d.com/unity/whats-new/unity-"; + const string betaRN = @"http://unity3d.com/unity/beta/unity"; + const string patchRN = @"http://unity3d.com/unity/qa/patch-releases"; + + const string baseName = "UnityYAMLMerge.ex"; + const string compressedName = baseName + "_"; + const string extractedName = baseName + "e"; + static string tempDir; + static WWW wwwHistory, wwwList, wwwMerger, wwwAssistant; + static readonly string zipName = Application.platform == RuntimePlatform.WindowsEditor ? "7z" : "7za"; + + static SortedList fullList; + static SortedList sortedList; + static SortedList currentList; + static int selected; + static bool assistant; + static HelpLastRelease window; + const string wndTitle = "Unity Builds"; + [SerializeField] + string search = ""; + static GUIStyle style; + const string prefsCount = "HelpLastRelease.count"; + const float minWidth = 162f; + [SerializeField] + private Vector2 scroll; + static Dictionary colors = new Dictionary() { + { "5.0.", new Color32(236, 239, 241 ,255) }, + { "5.1.", new Color32(207, 216, 220, 255) }, + { "5.2.", new Color32(176, 190, 197, 255) }, + { "5.3.", new Color32(144, 164, 174, 255) }, + { "5.4.", new Color32(120, 144, 156, 255) }, + { "5.5.", new Color32(96, 125, 139, 255) }, + { "5.6.", new Color32(84, 110, 122, 255) }, + { "2017.1.", new Color32(69, 90, 100, 255) }, + { "2017.2.", new Color32(55, 71, 79, 255) }, + { "2017.3.", new Color32(38, 50, 56, 255) } + }; + + static Dictionary textColors = new Dictionary() { + { "5.0.", new Color32(0, 0, 0, 255) }, + { "5.1.", new Color32(0, 0, 0, 255) }, + { "5.2.", new Color32(0, 0, 0, 255) }, + { "5.3.", new Color32(0, 0, 0, 255) }, + { "5.4.", new Color32(255, 255, 255, 255) }, + { "5.5.", new Color32(255, 255, 255, 255) }, + { "5.6.", new Color32(255, 255, 255, 255) }, + { "2017.1.", new Color32(255, 255, 255, 255) }, + { "2017.2.", new Color32(255, 255, 255, 255) }, + { "2017.3.", new Color32(255, 255, 255, 255) } + }; + + [MenuItem("Help/Links/Statistics")] + static void OpenStatistics() + { + Application.OpenURL(statsUrl); + } + + [MenuItem("Help/Links/Experimental")] + static void OpenExperimental() + { + Application.OpenURL(experimenalUrl); + } + + [MenuItem("Help/Links/Roadmap")] + static void OpenRoadmap() + { + Application.OpenURL(roadmapUrl); + } + + [MenuItem("Help/Links/Release Archive")] + static void OpenArchive() + { + Application.OpenURL(archiveUrl); + } + + [MenuItem("Help/Links/Patch Archive")] + static void OpenPatchArchive() + { + Application.OpenURL(patchRN); + } + + [MenuItem("Help/Links/Beta Archive")] + static void OpenBetaArchive() + { + Application.OpenURL(betaArchiveUrl); + } + + [MenuItem("Help/Links/Last Releases")] + static void Init() + { + window = GetWindow(wndTitle); + } + + void OnGUI() + { + if (fullList != null) + { + ListGUI(); + } + else + WaitGUI(); + } + + public void ListGUI() + { + style = new GUIStyle(EditorStyles.miniButton); + style.alignment = TextAnchor.MiddleLeft; + //GUILayout.BeginVertical(); + DoToolbar(); + scroll = EditorGUILayout.BeginScrollView(scroll, false, false); + if (currentList == null) + currentList = fullList; + + for (int i = currentList.Count - 1; i >= 0; i--) + DoItemGUI(i, currentList.Keys[i], currentList.Values[i]); + + EditorGUILayout.EndScrollView(); + GUILayout.FlexibleSpace(); + DoDownloadProgressBar(wwwAssistant, "Downloading Assistant"); + DoDownloadProgressBar(wwwHistory, "Downloading History"); + DoDownloadProgressBar(wwwList, "Downloading List"); + DoDownloadProgressBar(wwwMerger, "Downloading Merger"); + //GUILayout.EndVertical(); + } + + private void Update() + { + Repaint(); + } + + void DoDownloadProgressBar(WWW www, string text) + { + if (www != null && !www.isDone && string.IsNullOrEmpty(www.error)) + { + text = string.Format("{0} ({1})", text, EditorUtility.FormatBytes(www.bytesDownloaded)); + EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), www.progress, string.IsNullOrEmpty(www.error) ? text : www.error); + } + } + + void DoItemGUI(int index, string key, string value) + { + var rect = EditorGUILayout.BeginHorizontal((index & 1) == 1 ? "ObjectPickerResultsOdd" : "ObjectPickerResultsEven"); + var color = GetGUIColor(index); + var colorText = GetGUITextColor(index); + var s = new GUIStyle(); + s.normal.textColor = colorText; + + EditorGUI.DrawRect(rect, color); + GUILayout.Label("Unity " + value, s); + GUILayout.FlexibleSpace(); + + var notesURL = GetReleaseNotesURL(index); + if (GUILayout.Button("Open", "minibuttonleft")) + { + DownloadList(index); + } + GUI.enabled = !string.IsNullOrEmpty(notesURL); + if (GUILayout.Button("Release Notes", "minibuttonmid")) + { + OpenReleaseNotes(index); + } + GUI.enabled = true; + if (GUILayout.Button("Download Assistant", "minibuttonright")) + { + DownloadList(index, true); + } + EditorGUILayout.EndHorizontal(); + } + + static Color32 GetGUIColor(int i) + { + foreach (var k in colors.Keys) + { + if (currentList.Values[i].Contains(k)) + { + return colors[k]; + } + } + return new Color32(255, 255, 255, 255); + } + + static Color32 GetGUITextColor(int i) + { + foreach (var k in textColors.Keys) + { + if (currentList.Values[i].Contains(k)) + { + return textColors[k]; + } + } + return new Color32(0, 0, 0, 255); + } + + void OnEnable() + { + tempDir = Application.dataPath + "/../Temp/LastRelease"; + DownloadHistory(); + } + + static void CheckNewVersion() + { + int count = EditorPrefs.GetInt(prefsCount, 0); + if (count > 0 && fullList.Count > count) + { + EditorApplication.Beep(); + Debug.LogFormat("New version: {0}", fullList.Values[fullList.Count - 1]); + } + EditorPrefs.SetInt(prefsCount, fullList.Count); + } + + static string GetReleaseNotesURL(int num) + { + string url = "", version = ""; + if (currentList.Values[num].Contains("a")) + return string.Empty; + if (currentList.Values[num].Contains("p")) + { + version = currentList.Values[num].Split(' ')[0]; + url = patchRN + version; + } + if (currentList.Values[num].Contains("f")) + { + version = currentList.Values[num].Split('f')[0]; + url = finalRN + version; + } + if (currentList.Values[num].Contains("b")) + { + version = currentList.Values[num].Split(' ')[0]; + url = betaRN + version; + } + + return url; + } + + static void OpenReleaseNotes(int num) + { + var url = GetReleaseNotesURL(num); + + if (!string.IsNullOrEmpty(url)) + Application.OpenURL(url); + } + + static void FillMenu(WWW history) + { + fullList = new SortedList(); + string build; + string[] parts, releases = history.text.Split('\n'); + for (int i = 0; i < releases.Length; i++) + { + parts = releases[i].Split(','); + DateTime dt; + if (DateTime.TryParse(string.Format("{0} {1}", parts[3], parts[4]), out dt)) + { + build = string.Format("{0} ({1})", parts[6].Trim('\"'), dt.ToString("dd-MM-yyyy")); + fullList.Add(parts[0], build); + } + //Debug.LogWarningFormat("releases[{0}]={1}\nparts={2}", i, releases[i], parts.ToStringRecursive()); + } + if (window == null) + { + HelpLastRelease[] w = Resources.FindObjectsOfTypeAll(); + if (w != null && w.Length > 0) + window = w[0]; + } + if (window != null) + window.Repaint(); + } + + static void SearchVersion() + { + string path = Path.Combine(tempDir, extractedName); + if (File.Exists(path)) + { + string[] lines; + lines = File.ReadAllLines(path, Encoding.Unicode); + FileUtil.DeleteFileOrDirectory(Path.GetDirectoryName(path)); + string version = currentList.Values[selected].Split(' ')[0] + "_"; + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].Contains(version)) + { + int pos = lines[i].IndexOf(version); + string revision = lines[i].Substring(pos + version.Length, 12); + if (!assistant) + { + Application.OpenURL(string.Format(releaseUrl, revision)); + } + else + { + DownloadAssistant(revision); + } + break; + } + } + } + } + + static void DownloadAssistant(string revision) + { + string version = currentList.Values[selected].Split(' ')[0]; + string ext = Application.platform == RuntimePlatform.WindowsEditor ? "exe" : "dmg"; + string url = string.Format(assistantUrl, revision, version, ext); + wwwAssistant = new WWW(url); + EditorApplication.update += WaitAssistant; + } + + static void DownloadHistory() + { + wwwHistory = new WWW(historyUrl); + EditorApplication.update += WaitHistory; + } + + static void DownloadList(int historyNum, bool assist = false) + { + selected = historyNum; + assistant = assist; + string listUrl = string.Format("{0}000Admin/{1}", serverUrl, currentList.Keys[historyNum]); + wwwList = new WWW(listUrl); + EditorApplication.update += WaitList; + } + + static void WaitList() + { + Wait(wwwList, WaitList, ParseList); + } + + static void WaitHistory() + { + Wait(wwwHistory, WaitHistory, FillMenu, CheckNewVersion); + } + + static void WaitAssistant() + { + Wait(wwwAssistant, WaitAssistant, SaveAssistant); + } + + static void SaveAssistant(WWW assistant) + { + if (!Directory.Exists(tempDir)) + { + Directory.CreateDirectory(tempDir); + } + string name = Path.GetFileName(assistant.url); + string path = Path.Combine(tempDir, name); + File.WriteAllBytes(path, assistant.bytes); + if (Application.platform == RuntimePlatform.WindowsEditor) + { + Application.OpenURL(path); + } + else + { + StartAssistant(path); + } + } + + static void StartAssistant(string path) + { + string cmd = "hdiutil"; + string arg = string.Format("mount '{0}'", path); + try + { + using (Process assist = new Process()) + { + assist.StartInfo.FileName = cmd; + assist.StartInfo.Arguments = arg; + assist.StartInfo.WorkingDirectory = Path.GetDirectoryName(path); + assist.StartInfo.CreateNoWindow = true; + assist.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + assist.Start(); + } + } + catch (Exception e) + { + Debug.LogErrorFormat("{0} {1}\n{2}", cmd, arg, e.Message); + } + } + + static void Wait(WWW www, EditorApplication.CallbackFunction caller, Action action, Action done = null) + { + if (www != null && www.isDone) + { + EditorApplication.update -= caller; + if (string.IsNullOrEmpty(www.error) && www.bytesDownloaded > 0) + { + //Debug.LogFormat("{0} kB: {1}", www.size/1024, www.url); + if (action != null) + action(www); + if (done != null) + done(); + } + else + Debug.LogWarningFormat("{0} {1}", www.url, www.error); + www = null; + } + else + { + if (www == null) + EditorApplication.update -= caller; + } + } + + static void ParseList(WWW list) + { + string[] files = list.text.Split('\n'); + string[] parts; + for (int i = 0; i < files.Length; i++) + { + parts = files[i].Split(','); + if (parts[0].Contains(extractedName)) + { + string mergerUrl = string.Format("{0}{1}/{2}", serverUrl, parts[0].Trim('\"').Replace('\\', '/'), compressedName); + DownloadMerger(mergerUrl); + break; + } + } + } + + static void DownloadMerger(string mergerUrl) + { + wwwMerger = new WWW(mergerUrl); + EditorApplication.update += WaitMerger; + } + + static void WaitMerger() + { + Wait(wwwMerger, WaitMerger, SaveMerger); + } + + static void SaveMerger(WWW merger) + { + if (!Directory.Exists(tempDir)) + { + Directory.CreateDirectory(tempDir); + } + string path = Path.Combine(tempDir, compressedName); + //Debug.LogFormat("path: {0}", path); + File.WriteAllBytes(path, merger.bytes); + ExtractMerger(path); + } + + static void ExtractMerger(string path) + { + string zipPath = string.Format("{0}/Tools/{1}", EditorApplication.applicationContentsPath, zipName); + string arg = string.Format("e -y \"{0}\"", path); + try + { + using (Process unzip = new Process()) + { + unzip.StartInfo.FileName = zipPath; + unzip.StartInfo.Arguments = arg; + unzip.StartInfo.WorkingDirectory = Path.GetDirectoryName(path); + unzip.StartInfo.CreateNoWindow = true; + unzip.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + unzip.Start(); + unzip.WaitForExit(); + SearchVersion(); + } + } + catch (Exception e) + { + Debug.LogErrorFormat("{0} {1}\n{2}", zipPath, arg, e.Message); + } + } + + void DoToolbar() + { + EditorGUILayout.BeginHorizontal("toolbar"); + GUILayout.FlexibleSpace(); + SearchGUI(); + EditorGUILayout.EndHorizontal(); + } + + void SearchGUI() + { + string s = string.Empty; + + try + { + var methods = typeof(EditorGUILayout).GetMethods(BindingFlags.NonPublic | BindingFlags.Static); + + for (var i = 0; i < methods.Length; i++) + if (methods[i].Name == "ToolbarSearchField" && methods[i].GetParameters().Length <= 2) + { + s = (string)methods[i].Invoke(null, new object[] { search, null }); + break; + } + } + catch (Exception e) + { + Debug.LogException(e); + s = EditorGUILayout.TextField(search, GUILayout.MaxWidth(minWidth + 56f)); + } + + if (s != search) + { + search = s; + if (!string.IsNullOrEmpty(search)) + { + sortedList = new SortedList(); + for (int i = fullList.Count - 1; i >= 0; i--) + { + if (fullList.Values[i].Contains(search)) + { + sortedList.Add(fullList.Keys[i], fullList.Values[i]); + } + } + currentList = sortedList; + } + else + currentList = fullList; + } + } + + void WaitGUI() + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUILayout.Label("Wait..."); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/HelpLastRelease.cs.meta b/Assets/Scripts/Editor/HelpLastRelease.cs.meta new file mode 100644 index 0000000..64b1d97 --- /dev/null +++ b/Assets/Scripts/Editor/HelpLastRelease.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e709b023ac010b643ad268fc30d93568 +timeCreated: 1511611021 +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 b/Assets/Scripts/Editor/Hierarchy/UnparentMe.cs new file mode 100644 index 0000000..18e75b1 --- /dev/null +++ b/Assets/Scripts/Editor/Hierarchy/UnparentMe.cs @@ -0,0 +1,21 @@ +// unparents selected gameobject in hierarchy (by moving to grandparents if available) + +using UnityEditor; + +namespace UnityLibrary +{ + public class UnparentMe + { + // https://docs.unity3d.com/ScriptReference/MenuItem.html + // shift U shortcut key + [MenuItem("GameObject/Unparent #u")] + static void UnParent() + { + // TODO: add undo + if (Selection.activeGameObject != null && Selection.activeGameObject.transform.parent != null) + { + Selection.activeGameObject.transform.parent = Selection.activeGameObject.transform.parent.parent; + } + } + } +} 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/ImageEffects.meta b/Assets/Scripts/Editor/ImageEffects.meta new file mode 100644 index 0000000..4130726 --- /dev/null +++ b/Assets/Scripts/Editor/ImageEffects.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8a3e1002f6a65554fb21b5baea37a33b +folderAsset: yes +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers b/Assets/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers similarity index 100% rename from Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers rename to Assets/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers diff --git a/Assets/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers.meta b/Assets/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers.meta new file mode 100644 index 0000000..07b343c --- /dev/null +++ b/Assets/Scripts/Editor/ImageEffects/ColorCorrectionCurvesEditorLayers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 71cb5aca4636e344db9f91f7236a532e +timeCreated: 1500793398 +licenseType: Free +DefaultImporter: + 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 clips = new List(); + 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("Mesh Combine Wizard"); + } + + void OnWizardCreate() + { + if (parentOfObjectsToCombine == null) return; + + Vector3 originalPosition = parentOfObjectsToCombine.transform.position; + parentOfObjectsToCombine.transform.position = Vector3.zero; + + MeshFilter[] meshFilters = parentOfObjectsToCombine.GetComponentsInChildren(); + Dictionary> materialToMeshFilterList = new Dictionary>(); + List combinedObjects = new List(); + + for (int i = 0; i < meshFilters.Length; i++) + { + var materials = meshFilters[i].GetComponent().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() { 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 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 meshBin = new List(); + 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(); + if (meshBin.Count > 1) + { + filter.sharedMesh = combinedMesh; + } + else + { + filter.sharedMesh = meshBin[0].sharedMesh; // the original mesh + } + var renderer = combinedObject.AddComponent(); + 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/README.md b/Assets/Scripts/Editor/README.md new file mode 100644 index 0000000..bbcec7e --- /dev/null +++ b/Assets/Scripts/Editor/README.md @@ -0,0 +1,9 @@ +# Editor Scripts +Extend the Unity Editor with the power of Community. + +Experiencing errors and problems, no worry, [File them, and let us fix them](https://github.com/UnityCommunity/UnityLibrary/issues) + +## License +[MIT](https://github.com/UnityCommunity/UnityLibrary/blob/master/LICENSE.md) @ [Unity Community](https://github.com/UnityCommunity/) + +Made with :heart: by [Unity Community](https://github.com/UnityCommunity/) diff --git a/Assets/Scripts/Editor/README.md.meta b/Assets/Scripts/Editor/README.md.meta new file mode 100644 index 0000000..1bd5cc5 --- /dev/null +++ b/Assets/Scripts/Editor/README.md.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d99cb649a69348c42b9a6e8d62766538 +timeCreated: 1500793397 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/SetPivot.cs b/Assets/Scripts/Editor/SetPivot.cs new file mode 100644 index 0000000..33663ed --- /dev/null +++ b/Assets/Scripts/Editor/SetPivot.cs @@ -0,0 +1,152 @@ +/* + * Version: 1.0 + * Author: Yilmaz Kiymaz (@VoxelBoy) + * Purpose: To be able to change the pivot of Game Objects + * without needing to use a separate 3D application. + * License: Free to use and distribute, in both free and commercial projects. + * Do not try to sell as your own work. Simply put, play nice :) + * Contact: VoxelBoy on Unity Forums + */ + +/* + * TODO: + * - Doesn't work properly with rotated objects. + * - Can't compensate for the positioning of Mesh Colliders. + * - Need to figure out if the "Instantiating mesh" error in Editor is a big issue, if not, how to supress it. + * - Allowing the pivot to move outside the bounds of the mesh, ideally using the movement gizmo but only affecting the pivot. + */ + + +using UnityEngine; +using UnityEditor; +namespace UnityLibrary +{ + public class SetPivot : EditorWindow + { + + Vector3 p; //Pivot value -1..1, calculated from Mesh bounds + Vector3 last_p; //Last used pivot + + GameObject obj; //Selected object in the Hierarchy + MeshFilter meshFilter; //Mesh Filter of the selected object + Mesh mesh; //Mesh of the selected object + Collider col; //Collider of the selected object + + bool pivotUnchanged; //Flag to decide when to instantiate a copy of the mesh + + [MenuItem("GameObject/Set Pivot")] //Place the Set Pivot menu item in the GameObject menu + static void Init() + { + SetPivot window = (SetPivot)EditorWindow.GetWindow(typeof(SetPivot)); + window.RecognizeSelectedObject(); //Initialize the variables by calling RecognizeSelectedObject on the class instance + window.Show(); + } + + void OnGUI() + { + if (obj) + { + if (mesh) + { + p.x = EditorGUILayout.Slider("X", p.x, -1.0f, 1.0f); + p.y = EditorGUILayout.Slider("Y", p.y, -1.0f, 1.0f); + p.z = EditorGUILayout.Slider("Z", p.z, -1.0f, 1.0f); + if (p != last_p) + { //Detects user input on any of the three sliders + //Only create instance of mesh when user changes pivot + if (pivotUnchanged) mesh = meshFilter.mesh; pivotUnchanged = false; + UpdatePivot(); + last_p = p; + } + if (GUILayout.Button("Center")) + { //Set pivot to the center of the mesh bounds + //Only create instance of mesh when user changes pivot + if (pivotUnchanged) mesh = meshFilter.mesh; pivotUnchanged = false; + p = Vector3.zero; + UpdatePivot(); + last_p = p; + } + GUILayout.Label("Bounds " + mesh.bounds.ToString()); + } + else + { + GUILayout.Label("Selected object does not have a Mesh specified."); + } + } + else + { + GUILayout.Label("No object selected in Hierarchy."); + } + } + + //Achieve the movement of the pivot by moving the transform position in the specified direction + //and then moving all vertices of the mesh in the opposite direction back to where they were in world-space + void UpdatePivot() + { + Vector3 diff = Vector3.Scale(mesh.bounds.extents, last_p - p); //Calculate difference in 3d position + obj.transform.position -= Vector3.Scale(diff, obj.transform.localScale); //Move object position by taking localScale into account + //Iterate over all vertices and move them in the opposite direction of the object position movement + Vector3[] verts = mesh.vertices; + for (int i = 0; i < verts.Length; i++) + { + verts[i] += diff; + } + mesh.vertices = verts; //Assign the vertex array back to the mesh + mesh.RecalculateBounds(); //Recalculate bounds of the mesh, for the renderer's sake + //The 'center' parameter of certain colliders needs to be adjusted + //when the transform position is modified + if (col) + { + if (col is BoxCollider) + { + ((BoxCollider)col).center += diff; + } + else if (col is CapsuleCollider) + { + ((CapsuleCollider)col).center += diff; + } + else if (col is SphereCollider) + { + ((SphereCollider)col).center += diff; + } + } + } + + //Look at the object's transform position in comparison to the center of its mesh bounds + //and calculate the pivot values for xyz + void UpdatePivotVector() + { + Bounds b = mesh.bounds; + Vector3 offset = -1 * b.center; + p = last_p = new Vector3(offset.x / b.extents.x, offset.y / b.extents.y, offset.z / b.extents.z); + } + + //When a selection change notification is received + //recalculate the variables and references for the new object + void OnSelectionChange() + { + RecognizeSelectedObject(); + } + + //Gather references for the selected object and its components + //and update the pivot vector if the object has a Mesh specified + void RecognizeSelectedObject() + { + Transform t = Selection.activeTransform; + obj = t ? t.gameObject : null; + if (obj) + { + meshFilter = obj.GetComponent(typeof(MeshFilter)) as MeshFilter; + mesh = meshFilter ? meshFilter.sharedMesh : null; + if (mesh) + UpdatePivotVector(); + col = obj.GetComponent(typeof(Collider)) as Collider; + pivotUnchanged = true; + } + else + { + mesh = null; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/SetPivot.cs.meta b/Assets/Scripts/Editor/SetPivot.cs.meta new file mode 100644 index 0000000..f2c0f24 --- /dev/null +++ b/Assets/Scripts/Editor/SetPivot.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a41d285eb1e4e5148a8eb9faf1d929ec +timeCreated: 1500793403 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/SpriteBackgroundRemover.cs b/Assets/Scripts/Editor/SpriteBackgroundRemover.cs new file mode 100644 index 0000000..295324c --- /dev/null +++ b/Assets/Scripts/Editor/SpriteBackgroundRemover.cs @@ -0,0 +1,161 @@ +// original script : http://answers.unity3d.com/answers/252528/view.html + +// Usage: Place this script in Editor/ folder +// Start the tool from menu, Window/Tools/Alpha-fy Images + +using UnityEngine; +using UnityEditor; +using System.IO; +namespace UnityLibrary +{ + public class SpriteBackgroundRemover : EditorWindow + { + Texture2D img; + Texture2D newImg; + Color colorToRemove = Color.magenta; + public static SpriteBackgroundRemover win; + + [MenuItem("Window/Tools/Alpha-fy Images")] + static void Init() + { + win = ScriptableObject.CreateInstance(typeof(SpriteBackgroundRemover)) as SpriteBackgroundRemover; + win.minSize = new Vector2(300, 350); + win.ShowUtility(); + } + + void OnGUI() + { + GUILayout.BeginHorizontal(); + + /** Toolbar **/ + GUILayout.BeginVertical(); + img = (Texture2D)EditorGUILayout.ObjectField(img, typeof(Texture2D), false, GUILayout.MinWidth(128), GUILayout.MinHeight(128), GUILayout.MaxWidth(128), GUILayout.MaxHeight(128)); + + colorToRemove = EditorGUILayout.ColorField(colorToRemove, GUILayout.MaxWidth(128)); + + if (GUILayout.Button("Preview", GUILayout.MinWidth(128), GUILayout.MinHeight(32), GUILayout.MaxWidth(128), GUILayout.MaxHeight(128))) + newImg = RemoveColor(colorToRemove, img); + + if (GUILayout.Button("Alpha-fy All", GUILayout.MinWidth(128), GUILayout.MinHeight(32), GUILayout.MaxWidth(128), GUILayout.MaxHeight(128))) + RemoveColor(colorToRemove, (UnityEngine.Object[])Selection.GetFiltered(typeof(Texture2D), SelectionMode.Assets)); + + GUILayout.EndVertical(); + + GUILayout.BeginVertical(); + GUILayout.Label("Selected Files", EditorStyles.boldLabel); + foreach (Texture2D selected in Selection.GetFiltered(typeof(Texture2D), SelectionMode.Assets)) + { + GUILayout.Label(selected.name); + } + GUILayout.EndVertical(); + + /** Image Display **/ + GUILayout.BeginVertical(); + GUILayout.Label("Preview", EditorStyles.boldLabel); + if (newImg) + { + GUILayout.Label(newImg); + } + GUILayout.EndVertical(); + + GUILayout.EndHorizontal(); + + } + + // for multiple images + void RemoveColor(Color c, UnityEngine.Object[] imgs) + { + if (!Directory.Exists("Assets/AlphaImages/")) + { + Directory.CreateDirectory("Assets/AlphaImages/"); + } + + float inc = 0f; + foreach (Texture2D i in imgs) + { + inc++; + if (inc % 512 == 0 && EditorUtility.DisplayCancelableProgressBar("Playin' With Pixels", "Seaching for Color Matches", ((float)inc / (float)imgs.Length))) + { + Debug.LogError("Cancelled.."); + break; + } + + CheckTextureSettings(i); + + Color[] pixels = i.GetPixels(0, 0, i.width, i.height, 0); + var clear = new Color(0, 0, 0, 0); + + for (int p = 0; p < pixels.Length; p++) + { + if (pixels[p] == c) + { + pixels[p] = clear; + } + } + + Texture2D n = new Texture2D(i.width, i.height); + n.SetPixels(0, 0, i.width, i.height, pixels, 0); + n.Apply(); + + byte[] bytes = n.EncodeToPNG(); + File.WriteAllBytes("Assets/AlphaImages/" + i.name + "_alpha.png", bytes); + } + + EditorUtility.ClearProgressBar(); + + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + + // for single image + Texture2D RemoveColor(Color c, Texture2D i) + { + CheckTextureSettings(i); + + Color[] pixels = i.GetPixels(0, 0, i.width, i.height, 0); + + var clear = new Color(0, 0, 0, 0); + + for (int p = 0; p < pixels.Length; p++) + { + if (p % 512 == 0 && EditorUtility.DisplayCancelableProgressBar("Playin' With Pixels", "Seaching for Color Matches", ((float)p / pixels.Length))) + { + Debug.LogError("Cancelled.."); + break; + } + + if (pixels[p] == c) + { + pixels[p] = clear; + } + + } + + Texture2D n = new Texture2D(i.width, i.height); + n.SetPixels(0, 0, i.width, i.height, pixels, 0); + n.Apply(); + EditorUtility.ClearProgressBar(); + return (n); + } + + public void CheckTextureSettings(Texture2D texture) + { + if (texture == null) { Debug.LogError("CheckTextureSettings Failed - Texture is null"); return; } + + string path = AssetDatabase.GetAssetPath(texture); + if (string.IsNullOrEmpty(path)) { Debug.LogError("CheckTextureSettings Failed - Texture path is null"); return; } + + TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; + + if (!textureImporter.isReadable) + { + Debug.Log("Enabling read/write for image " + path); + // textureImporter.mipmapEnabled = false; + textureImporter.isReadable = true; + AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); + } + + } + + } +} diff --git a/Assets/Scripts/Editor/SpriteBackgroundRemover.cs.meta b/Assets/Scripts/Editor/SpriteBackgroundRemover.cs.meta new file mode 100644 index 0000000..8945f25 --- /dev/null +++ b/Assets/Scripts/Editor/SpriteBackgroundRemover.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2737bc699c1d92f4ca840a5dc0992efa +timeCreated: 1500793401 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/Tools.meta b/Assets/Scripts/Editor/Tools.meta new file mode 100644 index 0000000..ff5a06e --- /dev/null +++ b/Assets/Scripts/Editor/Tools.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2a517a11ecc7f514381fcf9318d8fbfa +folderAsset: yes +timeCreated: 1500793396 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs b/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs new file mode 100644 index 0000000..3290be2 --- /dev/null +++ b/Assets/Scripts/Editor/Tools/ColorPickerWindow.cs @@ -0,0 +1,60 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +public class ColorPickerWindow : EditorWindow +{ + + protected Color color = Color.white; + protected Color32 color32 = new Color32 ( 255, 255, 255, 255 ); + protected string hexCode = "FFFFFF"; + + [MenuItem ( "Tools/Color Picker" )] + public static void Init () + { + var window = EditorWindow.GetWindow ( "Color Picker" ); + window.Show (); + } + + protected virtual void OnGUI () + { + this.color = EditorGUILayout.ColorField ( "Color", this.color ); + if ( GUI.changed ) + { + this.color32 = this.color; + this.hexCode = ColorUtility.ToHtmlStringRGB ( this.color ); + } + this.hexCode = EditorGUILayout.TextField ( "Hex Code", this.hexCode ); + if ( GUI.changed ) + { + ColorUtility.TryParseHtmlString ( this.hexCode, out this.color ); + } + this.color32.r = ( byte )EditorGUILayout.IntSlider ( "Red", this.color32.r, 0, 255 ); + this.color32.g = ( byte )EditorGUILayout.IntSlider ( "Green", this.color32.g, 0, 255 ); + this.color32.b = ( byte )EditorGUILayout.IntSlider ( "Blue", this.color32.b, 0, 255 ); + this.color32.a = ( byte )EditorGUILayout.IntSlider ( "Alpha", this.color32.a, 0, 255 ); + if ( GUI.changed ) + { + this.color = this.color32; + this.hexCode = ColorUtility.ToHtmlStringRGB ( this.color ); + } + EditorGUILayout.TextField ( + "Color Code", + string.Format ( + "new Color ( {0}f, {1}f, {2}f, {3}f )", + this.color.r, + this.color.g, + this.color.b, + this.color.a ) ); + EditorGUILayout.TextField ( + "Color32 Code", + string.Format ( + "new Color32 ( {0}, {1}, {2}, {3} )", + this.color32.r, + this.color32.g, + this.color32.b, + this.color32.a ) ); + } + +} 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 startTimes = new Dictionary(); + List 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(); + 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/CopyPasteHelper.cs b/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs new file mode 100644 index 0000000..aca2a8b --- /dev/null +++ b/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs @@ -0,0 +1,200 @@ +using UnityEditor; +using UnityEngine; +using System.IO; +using System; +using Object = UnityEngine.Object; + +// Editor tool to easily paste scripts from web (automagically creates new file) +// original source: https://unitycoder.com/blog/2017/07/12/editor-plugin-paste-script-to-file/ +// additional browser helper (add copy button to unity docs) https://unitycoder.com/blog/2017/07/13/browser-plugin-add-copy-button-to-unity-scripting-docs/ + +namespace UnityLibrary +{ + public class CopyPasteHelper : EditorWindow + { + // settings: output folder is set as Assets/Scripts/Paste/ + // TODO: need to support shaders folder too + static string baseFolder = "Scripts"; + static string subFolder = "Paste"; + + + [MenuItem("Window/UnityLibrary/CopyPasteHelper")] + public static void ShowWindow() + { + //Show existing window instance. If one doesn't exist, make one. + var window = EditorWindow.GetWindow(typeof(CopyPasteHelper)); + window.titleContent = new GUIContent("CopyPasteHelper"); + window.minSize = new Vector2(64, 24); + } + + // mainloop + void OnGUI() + { + if (GUILayout.Button("Paste", GUILayout.Width(44))) + { + PasteToFile(); + } + } + + static void PasteToFile() + { + // combine paths, TODO: cleanup + var mainFolder = Application.dataPath + Path.DirectorySeparatorChar + baseFolder + Path.DirectorySeparatorChar; + var childFolder = subFolder + Path.DirectorySeparatorChar; + + // check folders and create them if missing + if (Directory.Exists(mainFolder) == false) + { + Debug.Log("Creating missing folder: " + mainFolder); + AssetDatabase.CreateFolder("Assets", baseFolder); + } + if (Directory.Exists(mainFolder + childFolder) == false) + { + Debug.Log("Creating missing folder: " + mainFolder + childFolder); + AssetDatabase.CreateFolder("Assets" + Path.DirectorySeparatorChar + baseFolder, subFolder); + } + + // get clipboard text + var clipboardString = ReadClipboard(); + if (string.IsNullOrEmpty(clipboardString.Trim())) + { + Debug.LogError("Nothing to paste.."); + return; + } + + // TODO: check if its editor script, then place to editor/ folder + + var fileName = GetFileName(clipboardString); + var fullPath = mainFolder + childFolder + fileName; + + // TODO: fix line endings (so that there wont be visual studio popup) + + // confirm overwrite dialog + if (File.Exists(fullPath) == true) + { + // TODO: add option to autorename file (and class name) + if (EditorUtility.DisplayDialog("Copy Paste Helper", "Replace existing file: " + fullPath, "Replace", "Cancel") == false) + { + return; + } + } + + // save to file + File.WriteAllText(fullPath, clipboardString, System.Text.Encoding.Default); + Debug.Log("CopyPasteHelper Script saved at: " + fullPath); + + AssetDatabase.Refresh(); + + // FIXME: script compilation can fail here if it was bad script, then the lines below wont run? + + // show-select created asset + Object newScript = AssetDatabase.LoadAssetAtPath("Assets" + Path.DirectorySeparatorChar + baseFolder + Path.DirectorySeparatorChar + subFolder + Path.DirectorySeparatorChar + fileName, typeof(Object)); + EditorGUIUtility.PingObject(newScript); + + // FIXME: this doesnt work, file is still there but becomes zombie (have to delete through explorer..) + // Undo.RegisterCreatedObjectUndo(newScript, "CopyPaste Helper object creation"); + } + + + // paste text to temporary texteditor and then get text + static string ReadClipboard() + { + TextEditor textEditor = new TextEditor(); + textEditor.multiline = true; + textEditor.Paste(); + return textEditor.text; + } + + + // returns class name (or shader name) and file extension .cs or .shader + static string GetFileName(string str) + { + var fileName = "NewScript"; + var fileExtension = ".cs"; + + // check if this looks like c# or shader + if (str.IndexOf("using ") > -1 || str.IndexOf("class ") > -1 || str.IndexOf("namespace ") > -1) + { + // should be c#, try to get class name + // NOTE: this would fail if comment lines have same "class " string + var classSplit = str.Split(new string[] { "class " }, StringSplitOptions.None); + + var index = 0; + var looping = true; + while (looping == true) + { + var c = classSplit[1].Substring(index++, 1); + // check characters until hit end of class name + switch (c) + { + case " ": + case ":": + case "{": + case "\t": + case ",": + case "\r": + case "\n": + looping = false; + break; + default: + break; + } + + if (index >= classSplit[1].Length) + { + fileName = "NewScript"; // default.. + Debug.LogError("Failed parsing class name.."); + looping = false; + index = -1; + } + } + + // we founded end of class name + if (index > 0) + { + fileName = classSplit[1].Substring(0, --index); + } else + { + Debug.LogError("Failed parsing class name.."); + } + + } else if (str.IndexOf("Shader ") > -1 || str.IndexOf("SubShader") > -1 || str.IndexOf("CGPROGRAM") > -1) + { + fileName = "NewShader"; + + // probably its shader then, get name + // TODO: this would fail if name starts without space: 'Shader"myshader..' + var classSplit = str.Split(new string[] { "Shader " }, StringSplitOptions.None); + + if (classSplit.Length > 0) + { + var shaderNameSplit = classSplit[1].Split('"'); + + if (shaderNameSplit.Length > 1) + { + // TODO: this takes the whole shader name string, custom/some/more/here.shader, could take name without path + fileName = shaderNameSplit[1]; + } else + { + Debug.LogError("Failed parsing shader name.."); + } + } else + { + Debug.LogError("Failed parsing shader name.."); + } + + fileExtension = ".shader"; + } else + { + // unknown format + Debug.LogError("Unknown format..saving as default c#"); + } + + // just to be sure, cleanup illegal characters from filename, https://stackoverflow.com/a/13617375/5452781 + var invalidChars = Path.GetInvalidFileNameChars(); + fileName = string.Join("_", fileName.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.'); + + return fileName + fileExtension; + } + } +} diff --git a/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs.meta b/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs.meta new file mode 100644 index 0000000..f4742ce --- /dev/null +++ b/Assets/Scripts/Editor/Tools/CopyPasteHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a02af6a99d72383438d6fdca2684b2cf +timeCreated: 1500793403 +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"); + } + + 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