diff options
author | chai <chaifix@163.com> | 2021-05-08 23:15:13 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-05-08 23:15:13 +0800 |
commit | d07e14add74e017b52ab2371efeea1aa4ea10ced (patch) | |
tree | efd07869326e4c428f5bfe43fad0c2583d32a401 |
+init
345 files changed, 28687 insertions, 0 deletions
diff --git a/Assets/Demo.meta b/Assets/Demo.meta new file mode 100644 index 0000000..df4f948 --- /dev/null +++ b/Assets/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5796070fed2320e47a4656f7832342ae +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Demo/1_Grid.unity b/Assets/Demo/1_Grid.unity new file mode 100644 index 0000000..3911d7e --- /dev/null +++ b/Assets/Demo/1_Grid.unity @@ -0,0 +1,622 @@ +%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.44657898, g: 0.4964133, b: 0.5748178, 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_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 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 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &121656535 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 121656537} + - component: {fileID: 121656536} + 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 &121656536 +Light: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 121656535} + 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_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &121656537 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 121656535} + 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 &324092059 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 324092063} + - component: {fileID: 324092062} + - component: {fileID: 324092061} + - component: {fileID: 324092060} + 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 &324092060 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 324092059} + m_Enabled: 1 +--- !u!124 &324092061 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 324092059} + m_Enabled: 1 +--- !u!20 &324092062 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 324092059} + 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_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &324092063 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 324092059} + 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 &951347849 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 951347850} + - component: {fileID: 951347851} + m_Layer: 5 + m_Name: GridLayoutGroupExt + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &951347850 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 951347849} + 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: 1170892077} + - {fileID: 1261718386} + m_Father: {fileID: 1657630762} + 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: 92.4, y: 18} + m_SizeDelta: {x: 184.8, y: 171.4} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &951347851 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 951347849} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f8873f5959132ce46a5ee4027a88b867, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Scrollrect: {fileID: 1170892078} + m_Content: {fileID: 1358538557} + m_ItemTemplate: {fileID: 1261718387} + m_RowCount: 0 + m_ColumCount: 0 + m_Padding: + m_Left: 2 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_CellSize: {x: 0, y: 0} + m_Spacing: {x: 0, y: 0} + m_ScrollMode: 1 + m_MovementType: 1 +--- !u!1 &1162086327 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1162086330} + - component: {fileID: 1162086329} + - component: {fileID: 1162086328} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1162086328 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1162086327} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e2665fa6a1fb2474d8a5c19f72f8d0c6, 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 &1162086329 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1162086327} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 153642a2f08376d4daebdf63af9e161a, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 5 +--- !u!4 &1162086330 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1162086327} + 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: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1170892076 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1170892077} + - component: {fileID: 1170892078} + m_Layer: 5 + m_Name: ScrollRect + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1170892077 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1170892076} + 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: 1358538557} + m_Father: {fileID: 951347850} + 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: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1170892078 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1170892076} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 209674c43848ab24e8778e3f7bcd0f11, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1358538557} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 0} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 0} + m_HorizontalScrollbarVisibility: 0 + m_VerticalScrollbarVisibility: 0 + m_HorizontalScrollbarSpacing: 0 + m_VerticalScrollbarSpacing: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.ScrollRect+ScrollRectEvent, Assembly-CSharp, Version=0.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!1 &1261718385 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1261718386} + - component: {fileID: 1261718387} + m_Layer: 5 + m_Name: GridItemTemplate + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1261718386 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1261718385} + 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: 951347850} + 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: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1261718387 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1261718385} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6d999d80aa990cf458ba4b8679fb12de, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1358538556 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1358538557} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1358538557 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1358538556} + 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: 1170892077} + 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: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1657630758 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1657630762} + - component: {fileID: 1657630761} + - component: {fileID: 1657630760} + - component: {fileID: 1657630759} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1657630759 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1657630758} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0dc7198a94080b64e9e51e6f934b3e35, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1657630760 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1657630758} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: debcf26b89013e446a6de5574715c5af, 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 &1657630761 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1657630758} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 324092062} + 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 &1657630762 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1657630758} + 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: 951347850} + m_Father: {fileID: 0} + m_RootOrder: 3 + 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} diff --git a/Assets/Demo/1_Grid.unity.meta b/Assets/Demo/1_Grid.unity.meta new file mode 100644 index 0000000..c06e079 --- /dev/null +++ b/Assets/Demo/1_Grid.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f5d944fcf2252c14086c8f03d864ebe0 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Other.meta b/Assets/Other.meta new file mode 100644 index 0000000..d12f421 --- /dev/null +++ b/Assets/Other.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4d29614c8f05a2442bf0d75758b592bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Other/LogHelper.cs b/Assets/Other/LogHelper.cs new file mode 100644 index 0000000..f95bf18 --- /dev/null +++ b/Assets/Other/LogHelper.cs @@ -0,0 +1,16 @@ +#define UGUI_DEBUG +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class LogHelper +{ + + public static void Log(string content) + { +#if UGUI_DEBUG + Debug.Log(content); +#endif + } + +} diff --git a/Assets/Other/LogHelper.cs.meta b/Assets/Other/LogHelper.cs.meta new file mode 100644 index 0000000..f6d6dd1 --- /dev/null +++ b/Assets/Other/LogHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00a660da41438ca4b9cbdd92e673dffe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty.meta b/Assets/ThirdParty.meta new file mode 100644 index 0000000..79b3e31 --- /dev/null +++ b/Assets/ThirdParty.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f55d7a4efad74844ea7193a48fede388 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/Gallery.meta b/Assets/ThirdParty/Gallery.meta new file mode 100644 index 0000000..3d50384 --- /dev/null +++ b/Assets/ThirdParty/Gallery.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d0c0d89ff8dc5642acdb7345128825b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/Gallery/GalleryManager.cs b/Assets/ThirdParty/Gallery/GalleryManager.cs new file mode 100644 index 0000000..641c989 --- /dev/null +++ b/Assets/ThirdParty/Gallery/GalleryManager.cs @@ -0,0 +1,146 @@ +using UnityEngine; +using System.Collections; +using UnityEngine.UI; + +/* http://bobardo.com */ + +public class GalleryManager : MonoBehaviour { + + public GameObject itemsContainer; + public GameObject[] items; + + public ScrollRect scrollRect; + + private float totalWidth; + private float mapSize; + private float scrollStep; + + private float lastTimeScrollChanged; + + private RuntimePlatform platform = Application.platform; + private bool isTouchOnScroll = false; + + void Start() + { + mapSize = itemsContainer.GetComponent<RectTransform>().rect.height; + float width = Screen.width; + float pos = width / 2; + + totalWidth = ((items.Length - 1) * mapSize) + width; + Utils.setSize(itemsContainer.GetComponent<RectTransform>(), totalWidth, mapSize); + + for(int i = 0; i < items.Length; i++) + { + Utils.setSize(items[i].GetComponent<RectTransform>(), mapSize, mapSize); + items[i].transform.position = new Vector3(pos, items[i].transform.position.y, 0); + + pos += mapSize; + } + + scrollStep = (float) 1 / (items.Length - 1); + scrollRect.GetComponent<BoxCollider2D>().size = new Vector2(scrollRect.GetComponent<RectTransform>().rect.width, scrollRect.GetComponent<RectTransform>().rect.height); + + showItem(0); + } + + public void showItem(int number) + { + scrollRect.horizontalNormalizedPosition = (number * scrollStep) + 0.01f; + } + + void Update() + { + + if (platform == RuntimePlatform.Android || platform == RuntimePlatform.IPhonePlayer) + { + if (Input.touchCount > 0) + { + if (Input.GetTouch(0).phase == TouchPhase.Began) + { + clickedDown(Input.GetTouch(0).position); + } + else if (Input.GetTouch(0).phase == TouchPhase.Ended || Input.GetTouch(0).phase == TouchPhase.Canceled) + { + if (isTouchOnScroll) + { + isTouchOnScroll = false; + setScrollIndex(); + } + } + } + } + else if (platform == RuntimePlatform.WindowsEditor) + { + if (Input.GetMouseButtonDown(0)) + { + clickedDown(Input.mousePosition); + } + else if (Input.GetMouseButtonUp(0)) + { + if (isTouchOnScroll) + { + isTouchOnScroll = false; + setScrollIndex(); + } + } + } + + } + + private void clickedDown(Vector3 wp) + { + Vector2 touchPos = new Vector2(wp.x, wp.y); + Collider2D[] hit = Physics2D.OverlapPointAll(touchPos); + + foreach (Collider2D h in hit) + { + if (h.GetComponent<ScrollRect>()) + { + isTouchOnScroll = true; + return; + } + } + } + + private void setScrollIndex() + { + if (scrollRect.horizontalNormalizedPosition < 0 || scrollRect.horizontalNormalizedPosition > 1) return; + + int index = (int)(scrollRect.horizontalNormalizedPosition / scrollStep); + + if (Mathf.Abs(scrollRect.horizontalNormalizedPosition) - (index * scrollStep) < ((index + 1) * scrollStep) - scrollRect.horizontalNormalizedPosition) + { + StartCoroutine(animateScroll(index * scrollStep)); + } + else + { + StartCoroutine(animateScroll((index + 1) * scrollStep)); + } + } + + private IEnumerator animateScroll(float pos) + { + float dist = pos - scrollRect.horizontalNormalizedPosition; + float step = dist/10; + + for(int i = 0; i < 10 && !isTouchOnScroll; i++) + { + scrollRect.horizontalNormalizedPosition += step; + yield return null; + } + + } + + public void onSliderValueChange(Vector2 pos) + { + + for (int i = 0; i < items.Length; i++) + { + float scale = 1 - Mathf.Abs(Mathf.Abs(scrollRect.horizontalNormalizedPosition) - (i * scrollStep)) * 1.1f; + if (scale < 0.2f) scale = 0.2f; + items[i].transform.localScale = new Vector3(scale, scale, 1); + } + } + + +} diff --git a/Assets/ThirdParty/Gallery/GalleryManager.cs.meta b/Assets/ThirdParty/Gallery/GalleryManager.cs.meta new file mode 100644 index 0000000..3249cc7 --- /dev/null +++ b/Assets/ThirdParty/Gallery/GalleryManager.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4e5faedbc3453c1468bd0b3eb4697fa6 +timeCreated: 1477657116 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/Gallery/Sample Gallery.unity b/Assets/ThirdParty/Gallery/Sample Gallery.unity new file mode 100644 index 0000000..234be4c --- /dev/null +++ b/Assets/ThirdParty/Gallery/Sample Gallery.unity @@ -0,0 +1,1765 @@ +%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: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 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: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 9 + m_Resolution: 2 + m_BakeResolution: 40 + m_TextureWidth: 1024 + m_TextureHeight: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 0 +--- !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 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &8858839 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 8858840} + - component: {fileID: 8858842} + - component: {fileID: 8858841} + m_Layer: 5 + m_Name: website + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8858840 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 8858839} + 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: 1699074361} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.30400002, y: 0.05} + m_AnchorMax: {x: 0.69600004, y: 0.132} + m_AnchoredPosition: {x: 0, y: -0.1000061} + m_SizeDelta: {x: -0.5, y: -0.7000122} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8858841 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 8858839} + 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: 25 + m_FontStyle: 0 + m_BestFit: 1 + 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: bobardo.com +--- !u!222 &8858842 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 8858839} +--- !u!1 &111389637 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 111389638} + - component: {fileID: 111389640} + - component: {fileID: 111389639} + m_Layer: 5 + m_Name: logo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &111389638 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 111389637} + 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: 1941620115} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18400002, y: 0.4} + m_AnchorMax: {x: 0.81600004, y: 0.6} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &111389639 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 111389637} + 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: 21300000, guid: 4963afefd3a5fed4e9428e7d2c8a73a4, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &111389640 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 111389637} +--- !u!1 &137331802 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 137331803} + - component: {fileID: 137331805} + - component: {fileID: 137331804} + m_Layer: 5 + m_Name: logo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &137331803 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 137331802} + 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: 2141497354} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18400002, y: 0.4} + m_AnchorMax: {x: 0.81600004, y: 0.6} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &137331804 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 137331802} + 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: 21300000, guid: 4963afefd3a5fed4e9428e7d2c8a73a4, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &137331805 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 137331802} +--- !u!1 &225733507 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 225733511} + - component: {fileID: 225733510} + - component: {fileID: 225733509} + - component: {fileID: 225733508} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &225733508 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 225733507} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1997211142, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ForceModuleActive: 0 +--- !u!114 &225733509 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 225733507} + 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 &225733510 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 225733507} + 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 &225733511 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 225733507} + 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: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &297568769 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 297568770} + - component: {fileID: 297568772} + - component: {fileID: 297568771} + m_Layer: 5 + m_Name: logo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &297568770 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 297568769} + 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: 1699074361} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18400002, y: 0.4} + m_AnchorMax: {x: 0.81600004, y: 0.6} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &297568771 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 297568769} + 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: 21300000, guid: 4963afefd3a5fed4e9428e7d2c8a73a4, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &297568772 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 297568769} +--- !u!1 &718861367 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 718861368} + - component: {fileID: 718861370} + - component: {fileID: 718861369} + m_Layer: 5 + m_Name: Item 01 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &718861368 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 718861367} + 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: 1864392631} + - {fileID: 1423024064} + m_Father: {fileID: 1313463563} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 250, y: 0} + m_SizeDelta: {x: 500, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &718861369 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 718861367} + 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: 0.7588235 + g: 1 + b: 0.6985294 + 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: 0} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &718861370 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 718861367} +--- !u!1 &767917163 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 767917164} + - component: {fileID: 767917165} + - component: {fileID: 767917166} + m_Layer: 5 + m_Name: Gallery Container + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &767917164 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 767917163} + 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: 1313463563} + m_Father: {fileID: 1020449996} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.11148149} + m_AnchorMax: {x: 1, y: 0.84900004} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &767917165 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 767917163} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1367256648, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1313463563} + m_Horizontal: 1 + m_Vertical: 0 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 0 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 0} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 0} + m_HorizontalScrollbarVisibility: 0 + m_VerticalScrollbarVisibility: 0 + m_HorizontalScrollbarSpacing: 0 + m_VerticalScrollbarSpacing: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1347875360} + m_MethodName: onSliderValueChange + m_Mode: 0 + 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.ScrollRect+ScrollRectEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!61 &767917166 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 767917163} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0, y: 0} + oldSize: {x: 0, y: 0} + newSize: {x: 0, y: 0} + adaptiveTilingThreshold: 0 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 1200, y: 500} + m_EdgeRadius: 0 +--- !u!1 &889803443 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 889803444} + - component: {fileID: 889803446} + - component: {fileID: 889803445} + m_Layer: 5 + m_Name: website + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &889803444 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 889803443} + 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: 1109901182} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.30400002, y: 0.05} + m_AnchorMax: {x: 0.69600004, y: 0.132} + m_AnchoredPosition: {x: 0, y: -0.1000061} + m_SizeDelta: {x: -0.5, y: -0.7000122} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &889803445 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 889803443} + 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: 25 + m_FontStyle: 0 + m_BestFit: 1 + 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: bobardo.com +--- !u!222 &889803446 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 889803443} +--- !u!1 &1020449992 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1020449996} + - component: {fileID: 1020449995} + - component: {fileID: 1020449994} + - component: {fileID: 1020449993} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1020449993 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1020449992} + 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: + m_Bits: 4294967295 +--- !u!114 &1020449994 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1020449992} + 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 &1020449995 +Canvas: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1020449992} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 1347875358} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 25 + m_SortingLayerID: 0 + m_SortingOrder: 1 + m_TargetDisplay: 0 +--- !u!224 &1020449996 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1020449992} + 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: 2136989807} + - {fileID: 767917164} + m_Father: {fileID: 0} + m_RootOrder: 1 + 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 &1073465721 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1073465722} + - component: {fileID: 1073465724} + - component: {fileID: 1073465723} + m_Layer: 5 + m_Name: website + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1073465722 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1073465721} + 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: 1941620115} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.30400002, y: 0.05} + m_AnchorMax: {x: 0.69600004, y: 0.132} + m_AnchoredPosition: {x: 0, y: -0.1000061} + m_SizeDelta: {x: -0.5, y: -0.7000122} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1073465723 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1073465721} + 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: 25 + m_FontStyle: 0 + m_BestFit: 1 + 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: bobardo.com +--- !u!222 &1073465724 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1073465721} +--- !u!1 &1109901181 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1109901182} + - component: {fileID: 1109901184} + - component: {fileID: 1109901183} + m_Layer: 5 + m_Name: Item 05 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1109901182 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1109901181} + 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: 1354037528} + - {fileID: 889803444} + m_Father: {fileID: 1313463563} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 2480, y: 0} + m_SizeDelta: {x: 500, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1109901183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1109901181} + 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: 0.8161765 + g: 0.83265716 + 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: 0} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1109901184 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1109901181} +--- !u!1 &1313463562 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1313463563} + - component: {fileID: 1313463565} + - component: {fileID: 1313463564} + m_Layer: 5 + m_Name: items + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1313463563 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1313463562} + 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: 718861368} + - {fileID: 1941620115} + - {fileID: 1699074361} + - {fileID: 2141497354} + - {fileID: 1109901182} + m_Father: {fileID: 767917164} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 2700, y: 0} + m_Pivot: {x: 0, y: 0.5} +--- !u!114 &1313463564 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1313463562} + 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: 0 + 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: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1313463565 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1313463562} +--- !u!1 &1347875354 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1347875359} + - component: {fileID: 1347875358} + - component: {fileID: 1347875357} + - component: {fileID: 1347875356} + - component: {fileID: 1347875355} + - component: {fileID: 1347875360} + 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 &1347875355 +AudioListener: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_Enabled: 1 +--- !u!124 &1347875356 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_Enabled: 1 +--- !u!92 &1347875357 +Behaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_Enabled: 1 +--- !u!20 &1347875358 +Camera: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + 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: 337.27 + 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: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1347875359 +Transform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, 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!114 &1347875360 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1347875354} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e5faedbc3453c1468bd0b3eb4697fa6, type: 3} + m_Name: + m_EditorClassIdentifier: + itemsContainer: {fileID: 1313463562} + items: + - {fileID: 718861367} + - {fileID: 1941620114} + - {fileID: 1699074360} + - {fileID: 2141497353} + - {fileID: 1109901181} + scrollRect: {fileID: 767917165} +--- !u!1 &1354037527 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1354037528} + - component: {fileID: 1354037530} + - component: {fileID: 1354037529} + m_Layer: 5 + m_Name: logo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1354037528 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1354037527} + 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: 1109901182} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18400002, y: 0.4} + m_AnchorMax: {x: 0.81600004, y: 0.6} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1354037529 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1354037527} + 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: 21300000, guid: 4963afefd3a5fed4e9428e7d2c8a73a4, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1354037530 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1354037527} +--- !u!1 &1423024063 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1423024064} + - component: {fileID: 1423024066} + - component: {fileID: 1423024065} + m_Layer: 5 + m_Name: website + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1423024064 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1423024063} + 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: 718861368} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.30400002, y: 0.05} + m_AnchorMax: {x: 0.69600004, y: 0.132} + m_AnchoredPosition: {x: 0, y: -0.1000061} + m_SizeDelta: {x: -0.5, y: -0.7000122} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1423024065 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1423024063} + 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: 25 + m_FontStyle: 0 + m_BestFit: 1 + 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: bobardo.com +--- !u!222 &1423024066 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1423024063} +--- !u!1 &1699074360 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1699074361} + - component: {fileID: 1699074363} + - component: {fileID: 1699074362} + m_Layer: 5 + m_Name: Item 03 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1699074361 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1699074360} + 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: 297568770} + - {fileID: 8858840} + m_Father: {fileID: 1313463563} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 1362, y: 0} + m_SizeDelta: {x: 500, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1699074362 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1699074360} + 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: 0.77205884 + g: 1 + b: 0.8868154 + 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: 0} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1699074363 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1699074360} +--- !u!1 &1864392630 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1864392631} + - component: {fileID: 1864392633} + - component: {fileID: 1864392632} + m_Layer: 5 + m_Name: logo + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1864392631 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1864392630} + 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: 718861368} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.18400002, y: 0.4} + m_AnchorMax: {x: 0.81600004, y: 0.6} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1864392632 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1864392630} + 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: 21300000, guid: 4963afefd3a5fed4e9428e7d2c8a73a4, type: 3} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1864392633 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1864392630} +--- !u!1 &1941620114 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 1941620115} + - component: {fileID: 1941620117} + - component: {fileID: 1941620116} + m_Layer: 5 + m_Name: Item 02 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1941620115 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1941620114} + 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: 111389638} + - {fileID: 1073465722} + m_Father: {fileID: 1313463563} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 803, y: 0} + m_SizeDelta: {x: 500, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1941620116 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1941620114} + 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: 0.83823526 + b: 0.83823526 + 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: 0} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &1941620117 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1941620114} +--- !u!1 &2009910490 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2009910491} + - component: {fileID: 2009910493} + - component: {fileID: 2009910492} + m_Layer: 5 + m_Name: website + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2009910491 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2009910490} + 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: 2141497354} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.30400002, y: 0.05} + m_AnchorMax: {x: 0.69600004, y: 0.132} + m_AnchoredPosition: {x: 0, y: -0.1000061} + m_SizeDelta: {x: -0.5, y: -0.7000122} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2009910492 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2009910490} + 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: 25 + m_FontStyle: 0 + m_BestFit: 1 + 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: bobardo.com +--- !u!222 &2009910493 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2009910490} +--- !u!1 &2136989806 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2136989807} + - component: {fileID: 2136989809} + - component: {fileID: 2136989808} + m_Layer: 5 + m_Name: background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2136989807 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2136989806} + 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: 1020449996} + 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 &2136989808 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2136989806} + 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: 0.18382353 + g: 0.18382353 + b: 0.18382353 + 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: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2136989809 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2136989806} +--- !u!1 &2141497353 +GameObject: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 5 + m_Component: + - component: {fileID: 2141497354} + - component: {fileID: 2141497356} + - component: {fileID: 2141497355} + m_Layer: 5 + m_Name: Item 04 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2141497354 +RectTransform: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2141497353} + 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: 137331803} + - {fileID: 2009910491} + m_Father: {fileID: 1313463563} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 1921, y: 0} + m_SizeDelta: {x: 500, y: 500} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2141497355 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2141497353} + 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: 0.99371195 + b: 0.77205884 + 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: 0} + m_Type: 0 + m_PreserveAspect: 1 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2141497356 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2141497353} diff --git a/Assets/ThirdParty/Gallery/Sample Gallery.unity.meta b/Assets/ThirdParty/Gallery/Sample Gallery.unity.meta new file mode 100644 index 0000000..badaba2 --- /dev/null +++ b/Assets/ThirdParty/Gallery/Sample Gallery.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5e2594b1267f2c04698f4edc8e6102ab +timeCreated: 1477656980 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/Gallery/Utils.cs b/Assets/ThirdParty/Gallery/Utils.cs new file mode 100644 index 0000000..29c9962 --- /dev/null +++ b/Assets/ThirdParty/Gallery/Utils.cs @@ -0,0 +1,14 @@ +using UnityEngine; +using System.Collections; + +public static class Utils{ + + public static void setSize(RectTransform rect, float width, float height) + { + Vector2 newSize = new Vector2(width, height); + Vector2 oldSize = rect.rect.size; + Vector2 deltaSize = newSize - oldSize; + rect.offsetMin = rect.offsetMin - new Vector2(deltaSize.x * rect.pivot.x, deltaSize.y * rect.pivot.y); + rect.offsetMax = rect.offsetMax + new Vector2(deltaSize.x * (1f - rect.pivot.x), deltaSize.y * (1f - rect.pivot.y)); + } +} diff --git a/Assets/ThirdParty/Gallery/Utils.cs.meta b/Assets/ThirdParty/Gallery/Utils.cs.meta new file mode 100644 index 0000000..7b30ec6 --- /dev/null +++ b/Assets/ThirdParty/Gallery/Utils.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cdd0753daafa5c746ba9664468c5a2df +timeCreated: 1477657206 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/Gallery/logo.png b/Assets/ThirdParty/Gallery/logo.png Binary files differnew file mode 100644 index 0000000..aac5633 --- /dev/null +++ b/Assets/ThirdParty/Gallery/logo.png diff --git a/Assets/ThirdParty/Gallery/logo.png.meta b/Assets/ThirdParty/Gallery/logo.png.meta new file mode 100644 index 0000000..321596a --- /dev/null +++ b/Assets/ThirdParty/Gallery/logo.png.meta @@ -0,0 +1,59 @@ +fileFormatVersion: 2 +guid: 4963afefd3a5fed4e9428e7d2c8a73a4 +timeCreated: 1482620369 +licenseType: Pro +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + buildTargetSettings: [] + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension.meta b/Assets/UI_Extension.meta new file mode 100644 index 0000000..94e27cb --- /dev/null +++ b/Assets/UI_Extension.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f7772b4178e65c94fa2e129f107783c5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Editor.meta b/Assets/UI_Extension/Editor.meta new file mode 100644 index 0000000..3db3f54 --- /dev/null +++ b/Assets/UI_Extension/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cf1e7fd329939a2419dcf71b8a71861a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Editor/GUIUtils.cs b/Assets/UI_Extension/Editor/GUIUtils.cs new file mode 100644 index 0000000..5b881c6 --- /dev/null +++ b/Assets/UI_Extension/Editor/GUIUtils.cs @@ -0,0 +1,37 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+namespace UIExt
+{
+ internal static class GUIUtils
+ {
+
+ public static void DrawLine()
+ {
+
+ }
+
+ public static void DrawHorizontalline(Color color, Vector2 left, float length, int thickness = 1, int padding = 0)
+ {
+ Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
+ r.x = left.x;
+ r.y = left.y;
+ r.width = length;
+ EditorGUI.DrawRect(r, color);
+ GUILayout.Space(-10f);
+ }
+
+ public static void DrawVerticleline(Color color, Vector2 top, float height, int thickness = 1, int padding = 0)
+ {
+ Rect r = EditorGUILayout.GetControlRect(GUILayout.Width(padding + thickness));
+ r.x = top.x;
+ r.y = top.y;
+ r.height = height;
+ EditorGUI.DrawRect(r, color);
+ GUILayout.Space(-10f);
+ }
+
+ }
+}
diff --git a/Assets/UI_Extension/Editor/GUIUtils.cs.meta b/Assets/UI_Extension/Editor/GUIUtils.cs.meta new file mode 100644 index 0000000..17c2a95 --- /dev/null +++ b/Assets/UI_Extension/Editor/GUIUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 55d8d3929dc3359478987801df05899a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs b/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs new file mode 100644 index 0000000..5feb223 --- /dev/null +++ b/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs @@ -0,0 +1,92 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using UnityEngine.UI;
+
+namespace UIExt
+{
+
+ [CustomEditor(typeof(GridLayoutGroupExt), false)]
+ public class GridLayoutGroupExtEdtor : Editor
+ {
+ GridLayoutGroupExt layout;
+
+ SerializedProperty m_Padding; + SerializedProperty m_ScrollMode; + SerializedProperty m_MovementType; + + static Color s_LightGray = new Color(0.7f, 0.7f, 0.7f, 1); +
+ int m_ItemCount; // 测试
+ float m_HorizontalScrollAmount;
+ float m_VerticalScrollAmount;
+
+ protected virtual void OnEnable() + { + m_ItemCount = 0; + m_Padding = serializedObject.FindProperty("m_Padding"); + m_ScrollMode = serializedObject.FindProperty("m_ScrollMode"); + m_MovementType = serializedObject.FindProperty("m_MovementType"); + } + + public override void OnInspectorGUI()
+ {
+ GUI.changed = false;
+ layout = this.target as GridLayoutGroupExt;
+ if (layout == null)
+ return;
+ GUILayout.Space(10f);
+ EditorGUILayout.BeginVertical();
+
+ layout.scrollRect = EditorGUILayout.ObjectField("Scroll Rect", layout.scrollRect, typeof(ScrollRect), true) as ScrollRect;
+ layout.content = EditorGUILayout.ObjectField("Content", layout.content, typeof(RectTransform), true) as RectTransform;
+ layout.itemTemplate = EditorGUILayout.ObjectField("Item Template", layout.itemTemplate, typeof(LayoutItem), true) as LayoutItem;
+
+ layout.cellSize = EditorGUILayout.Vector2IntField("Cell Size", layout.cellSize);
+ layout.spacing = EditorGUILayout.Vector2IntField("Spacing", layout.spacing);
+ EditorGUILayout.PropertyField(m_Padding, true); + + layout.rowCount = EditorGUILayout.IntField("Row Count", layout.rowCount); + layout.columCount = EditorGUILayout.IntField("Colum Count", layout.columCount);
+
+ EditorGUILayout.PropertyField(m_ScrollMode, true); + EditorGUILayout.PropertyField(m_MovementType, true); +
+ GUILayout.Space(5f);
+
+ float y = EditorGUILayout.GetControlRect().y;
+ float x = EditorGUILayout.GetControlRect().x;
+ float w = EditorGUILayout.GetControlRect().width;
+ EditorGUI.DrawRect(new Rect(x, y, w, 95), s_LightGray);
+ GUILayout.Space(-50);
+
+ var centeredStyle = GUI.skin.GetStyle("Label");
+ centeredStyle.alignment = TextAnchor.UpperCenter;
+ GUILayout.Label("测试", centeredStyle);
+ Rect rect = EditorGUILayout.GetControlRect();
+ GUIUtils.DrawHorizontalline(Color.gray, new Vector2(rect.x, rect.y), rect.width);
+ EditorGUILayout.BeginHorizontal();
+ m_ItemCount = EditorGUILayout.IntSlider("测试生æˆItemæ•°é‡", m_ItemCount, 0, 50);
+ if(GUILayout.Button("生æˆ", GUILayout.Width(40)))
+ {
+
+ }
+ EditorGUILayout.EndHorizontal();
+
+ m_HorizontalScrollAmount = EditorGUILayout.Slider("水平滑动值", m_HorizontalScrollAmount, 0, 1000);
+ m_VerticalScrollAmount = EditorGUILayout.Slider("垂直滑动值", m_VerticalScrollAmount, 0, 1000);
+
+ GUILayout.Space(20f);
+ EditorGUILayout.EndVertical();
+ if(GUI.changed)
+ {
+ EditorUtility.SetDirty(layout);
+ }
+ }
+
+
+
+ }
+
+}
diff --git a/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs.meta b/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs.meta new file mode 100644 index 0000000..81fb941 --- /dev/null +++ b/Assets/UI_Extension/Editor/GridLayoutGroupExtEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52a853591b77ef04198d0a2b5afa64e7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Editor/MenuOptions.cs b/Assets/UI_Extension/Editor/MenuOptions.cs new file mode 100644 index 0000000..2eef47e --- /dev/null +++ b/Assets/UI_Extension/Editor/MenuOptions.cs @@ -0,0 +1,123 @@ +using UnityEditor; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace UIExt +{ + static internal class MenuOptions + {
+
+ [MenuItem("GameObject/UI Extensions/GridLayoutGroupExt", false,2000)] + static public void AddGridLayoutGroupExt(MenuCommand menuCommand) + {
+ Debug.Log("AddGridLayoutGroupExt"); + } +
+ //[MenuItem("GameObject/UI/Button", false, 2030)] + //static public void AddButton(MenuCommand menuCommand) + //{ + // //GameObject go = DefaultControls.CreateButton(GetStandardResources()); + // //PlaceUIElementRoot(go, menuCommand); + //}
+
+ //private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand) + //{ + // GameObject parent = menuCommand.context as GameObject; + // if (parent == null || parent.GetComponentInParent<Canvas>() == null) + // { + // parent = GetOrCreateCanvasGameObject(); + // } + + // string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name); + // element.name = uniqueName; + // Undo.RegisterCreatedObjectUndo(element, "Create " + element.name); + // Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name); + // GameObjectUtility.SetParentAndAlign(element, parent); + // if (parent != menuCommand.context) // not a context click, so center in sceneview + // SetPositionVisibleinSceneView(parent.GetComponent<RectTransform>(), element.GetComponent<RectTransform>()); + + // Selection.activeGameObject = element; + //}
+
+ //private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform) + //{ + // // Find the best scene view + // SceneView sceneView = SceneView.lastActiveSceneView; + // if (sceneView == null && SceneView.sceneViews.Count > 0) + // sceneView = SceneView.sceneViews[0] as SceneView; + + // // Couldn't find a SceneView. Don't set position. + // if (sceneView == null || sceneView.camera == null) + // return; + + // // Create world space Plane from canvas position. + // Vector2 localPlanePosition; + // Camera camera = sceneView.camera; + // Vector3 position = Vector3.zero; + // if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out localPlanePosition)) + // { + // // Adjust for canvas pivot + // localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x; + // localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y; + + // localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x); + // localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y); + + // // Adjust for anchoring + // position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x; + // position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y; + + // Vector3 minLocalPosition; + // minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x; + // minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y; + + // Vector3 maxLocalPosition; + // maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x; + // maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y; + + // position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x); + // position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y); + // } + + // itemTransform.anchoredPosition = position; + // itemTransform.localRotation = Quaternion.identity; + // itemTransform.localScale = Vector3.one; + //} +
+ //// Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas.
+ //static public GameObject GetOrCreateCanvasGameObject() + //{ + // GameObject selectedGo = Selection.activeGameObject; + + // // Try to find a gameobject that is the selected GO or one if its parents. + // Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null; + // if (canvas != null && canvas.gameObject.activeInHierarchy) + // return canvas.gameObject; + + // // No canvas in selection or its parents? Then use just any canvas.. + // canvas = Object.FindObjectOfType(typeof(Canvas)) as Canvas; + // if (canvas != null && canvas.gameObject.activeInHierarchy) + // return canvas.gameObject; + + // // No canvas in the scene at all? Then create a new one. + // return MenuOptions.CreateNewUI(); + //}
+ //static public GameObject CreateNewUI() + //{ + // // Root for the UI + // var root = new GameObject("Canvas"); + // root.layer = LayerMask.NameToLayer(kUILayerName); + // Canvas canvas = root.AddComponent<Canvas>(); + // canvas.renderMode = RenderMode.ScreenSpaceOverlay; + // root.AddComponent<CanvasScaler>(); + // root.AddComponent<GraphicRaycaster>(); + // Undo.RegisterCreatedObjectUndo(root, "Create " + root.name); + + // // if there is no event system add one... + // CreateEventSystem(false); + // return root; + //}
+ }
+
+}
\ No newline at end of file diff --git a/Assets/UI_Extension/Editor/MenuOptions.cs.meta b/Assets/UI_Extension/Editor/MenuOptions.cs.meta new file mode 100644 index 0000000..f829f14 --- /dev/null +++ b/Assets/UI_Extension/Editor/MenuOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71e1e3c5ea5985c4ea6fda0c03331bd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Resources.meta b/Assets/UI_Extension/Resources.meta new file mode 100644 index 0000000..a3953d8 --- /dev/null +++ b/Assets/UI_Extension/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4e28666e1b2b97342980145f237420b3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts.meta b/Assets/UI_Extension/Scripts.meta new file mode 100644 index 0000000..7b44aa8 --- /dev/null +++ b/Assets/UI_Extension/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e6bff0f6c4ee4934bb61403a634bea8b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Animation.meta b/Assets/UI_Extension/Scripts/Animation.meta new file mode 100644 index 0000000..d108950 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Animation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f33d78ae280cb724f99154d977d556dc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Animation/Tween.meta b/Assets/UI_Extension/Scripts/Animation/Tween.meta new file mode 100644 index 0000000..85f2fd1 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Animation/Tween.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6c9d4f729e1ee6344be85d61910dcd7e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs b/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs new file mode 100644 index 0000000..b55f0ce --- /dev/null +++ b/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class UIFreeFall : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs.meta b/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs.meta new file mode 100644 index 0000000..3ac37b2 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Animation/UIFreeFall.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62bb377fe7cf46249b16cdd50dd8961a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Controls.meta b/Assets/UI_Extension/Scripts/Controls.meta new file mode 100644 index 0000000..d76cc1a --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 194c26f2019ca7a458c7d29b48fa0990 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs b/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs new file mode 100644 index 0000000..036a55f --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ButtonExt : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs.meta b/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs.meta new file mode 100644 index 0000000..42b526b --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/ButtonExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ba3eab0aeb6419d49a20e4f317f2d9db +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs b/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs new file mode 100644 index 0000000..75b71f7 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class LoopTabBar : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs.meta b/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs.meta new file mode 100644 index 0000000..fb2a347 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/LoopTabBar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d43ae712f12d32409496dbd5a5758df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs b/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs new file mode 100644 index 0000000..b4a2b09 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ProgressBar : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs.meta b/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs.meta new file mode 100644 index 0000000..d8527b1 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/ProgressBar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71e0f9cfbb7afd4469a569d3101497cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs b/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs new file mode 100644 index 0000000..0668737 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RadialSlider : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs.meta b/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs.meta new file mode 100644 index 0000000..928c694 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Controls/RadialSlider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f20b62258fabcc44e89e2da07b4f12c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/DefaultControls.cs b/Assets/UI_Extension/Scripts/DefaultControls.cs new file mode 100644 index 0000000..adb63a9 --- /dev/null +++ b/Assets/UI_Extension/Scripts/DefaultControls.cs @@ -0,0 +1,11 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace UIExt
+{
+ public class DefaultControls
+ {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/DefaultControls.cs.meta b/Assets/UI_Extension/Scripts/DefaultControls.cs.meta new file mode 100644 index 0000000..b860bb9 --- /dev/null +++ b/Assets/UI_Extension/Scripts/DefaultControls.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0b24d249a55b8f41b875096ffbd5318 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Effects.meta b/Assets/UI_Extension/Scripts/Effects.meta new file mode 100644 index 0000000..cb9ccb2 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4fdd7a495ccb6514e98215767e69a227 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs b/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs new file mode 100644 index 0000000..3fefbd3 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.EventSystems; +using UnityEditor; + +[ExecuteInEditMode] +[RequireComponent(typeof(Graphic))] +public abstract class BaseUIEffect + : UIBehaviour + , IMeshModifier + , IMaterialModifier +{
+ [NonSerialized]
+ private Graphic m_Graphic;
+
+ protected Graphic graphic
+ {
+ get
+ {
+ if (m_Graphic == null)
+ m_Graphic = GetComponent<Graphic>();
+
+ return m_Graphic;
+ }
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ if (graphic != null)
+ graphic.SetVerticesDirty();
+ }
+
+ protected override void OnDisable()
+ {
+ if (graphic != null)
+ graphic.SetVerticesDirty();
+ base.OnDisable();
+ }
+
+ protected override void OnDidApplyAnimationProperties()
+ {
+ if (graphic != null)
+ graphic.SetVerticesDirty();
+ base.OnDidApplyAnimationProperties();
+ }
+
+#if UNITY_EDITOR + protected override void OnValidate()
+ {
+ base.OnValidate();
+ if (graphic != null)
+ graphic.SetVerticesDirty();
+ }
+
+#endif +
+ public void ModifyMesh(Mesh mesh)
+ {
+ using (var vh = new VertexHelper(mesh))
+ {
+ ModifyMesh(vh);
+ vh.FillMesh(mesh);
+ }
+ }
+
+ public virtual void ModifyMesh(VertexHelper vh)
+ {
+ }
+
+ public virtual Material GetModifiedMaterial(Material baseMaterial)
+ {
+ return baseMaterial;
+ } + +} diff --git a/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs.meta b/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs.meta new file mode 100644 index 0000000..eb709fa --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/BaseUIEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 741aae2b712d7ce4e9c23c79391c28a6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs b/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs new file mode 100644 index 0000000..11c48eb --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class BlurEffect : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs.meta b/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs.meta new file mode 100644 index 0000000..58a879f --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/BlurEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 42214df8920bf054092e70ef6e58281d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs b/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs new file mode 100644 index 0000000..e56ac2b --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ColorTintEffect : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs.meta b/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs.meta new file mode 100644 index 0000000..4750b94 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/ColorTintEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ddef7e92917bc44ca5dfb3a7a7fa026 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs b/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs new file mode 100644 index 0000000..352645f --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ExpandEffect : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs.meta b/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs.meta new file mode 100644 index 0000000..c565207 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Effects/ExpandEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 783b26d58e6c73d4397de9efb3a4774e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup.meta b/Assets/UI_Extension/Scripts/LayoutGroup.meta new file mode 100644 index 0000000..fff0d42 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 25f2cafc34be4d9418a6a5923eb2395d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs b/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs new file mode 100644 index 0000000..1c2ad1b --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class GalleryLayoutGroup : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs.meta new file mode 100644 index 0000000..e18f836 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/GalleryLayoutGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4691293df58d55b43bbe3bd962488c4d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs b/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs new file mode 100644 index 0000000..9d202b9 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs @@ -0,0 +1,153 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.EventSystems;
+using UnityEditor;
+
+namespace UIExt
+{
+ [AddComponentMenu("UI Extensions/LayoutGroup/GridLayoutGroupExt")]
+ [DisallowMultipleComponent]
+ [CanEditMultipleObjects]
+ public class GridLayoutGroupExt
+ : UIBehaviour
+ , ILayoutElement
+ , ILayoutGroup
+ {
+ public enum ScrollMode
+ {
+ Vertical = 1,
+ Horizontal = 2,
+ Auto = 3 // both horizontal and vertical
+ }
+
+ public enum MovementType + { + Unrestricted, // Unrestricted movement -- can scroll forever + Elastic, // Restricted but flexible -- can go past the edges, but springs back in place + Clamped, // Restricted movement where it's not possible to go past the edges + }
+
+ [System.NonSerialized] private RectTransform m_Rect; + protected RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + [SerializeField] private ScrollRect m_Scrollrect;
+ public ScrollRect scrollRect { get { return m_Scrollrect; } set { m_Scrollrect = value; } }
+
+ [SerializeField] private RectTransform m_Content;
+ public RectTransform content { get { return m_Content; } set { m_Content = value; } }
+
+ [SerializeField] private LayoutItem m_ItemTemplate;
+ public LayoutItem itemTemplate { get { return m_ItemTemplate; } set { m_ItemTemplate = value; } }
+
+ [SerializeField] private int m_RowCount;
+ public int rowCount { get { return m_RowCount; } set { m_RowCount = value; } }
+ [SerializeField] private int m_ColumCount;
+ public int columCount { get { return m_ColumCount; } set { m_ColumCount = value; } }
+
+ [SerializeField] protected RectOffset m_Padding = new RectOffset(); + public RectOffset padding { get { return m_Padding; } set { SetProperty(ref m_Padding, value); } } +
+ [SerializeField] private Vector2Int m_CellSize;
+ public Vector2Int cellSize { get { return m_CellSize; } set { m_CellSize = value; } }
+
+ [SerializeField] private Vector2Int m_Spacing;
+ public Vector2Int spacing { get { return m_Spacing; } set { m_Spacing = value; } }
+
+ [SerializeField] private ScrollMode m_ScrollMode = ScrollMode.Vertical;
+
+ [SerializeField] private MovementType m_MovementType = MovementType.Elastic;
+
+ private List<object> m_DataList;
+ public List<object> dataList { get { return m_DataList; } }
+
+ public float minWidth
+ {
+ get
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+
+ public float preferredWidth { get { return 0; } }
+
+ public float flexibleWidth { get { return 0; } }
+
+ public float minHeight { get { return 0; } }
+
+ public float preferredHeight { get { return 0; } }
+
+ public float flexibleHeight { get { return 0; } }
+
+ public int layoutPriority { get { return 0; } }
+
+ public void SetList(List<object> datalist)
+ {
+ m_DataList = datalist;
+ }
+
+ public void MoveTo(int indexOfData)
+ {
+
+ }
+
+ public void MoveTo(object data)
+ {
+
+ }
+
+ public void CalculateLayoutInputHorizontal()
+ {
+
+ }
+
+ public void CalculateLayoutInputVertical()
+ {
+
+ }
+
+ public void SetLayoutHorizontal()
+ {
+ }
+
+ public void SetLayoutVertical()
+ {
+ }
+
+ protected void SetProperty<T>(ref T currentValue, T newValue)
+ {
+ if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
+ return;
+ currentValue = newValue;
+ SetDirty();
+ }
+
+ protected void SetDirty() + { + if (!IsActive()) + return; + + if (!CanvasUpdateRegistry.IsRebuildingLayout()) + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + else + StartCoroutine(DelayedSetDirty(rectTransform)); + }
+
+ IEnumerator DelayedSetDirty(RectTransform rectTransform) + { + yield return null; + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } +
+ }
+
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs.meta new file mode 100644 index 0000000..14a6d7f --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/GridLayoutGroupExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f8873f5959132ce46a5ee4027a88b867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs b/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs new file mode 100644 index 0000000..2eb12d4 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs @@ -0,0 +1,18 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HorizontalLayoutGroupExt
+ : MonoBehaviour
+{
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs.meta new file mode 100644 index 0000000..d6872c4 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/HorizontalLayoutGroupExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 894dad6ac2c9eb3498d38fb489456748 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs b/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs new file mode 100644 index 0000000..da9cbf6 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs @@ -0,0 +1,10 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.EventSystems;
+using UnityEngine.UI;
+
+public class LayoutItem : UIBehaviour
+{
+
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs.meta new file mode 100644 index 0000000..c84bb8d --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/LayoutItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d999d80aa990cf458ba4b8679fb12de +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs b/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs new file mode 100644 index 0000000..b8e9b98 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs @@ -0,0 +1,554 @@ +//https://github.com/kiepng/Unity-PagingView
+using System;
+using UnityEngine.Events;
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI.Extensions
+{
+ [SelectionBase]
+ [ExecuteInEditMode]
+ [DisallowMultipleComponent]
+ [RequireComponent(typeof(RectTransform))]
+ [AddComponentMenu("UI/Extensions/PagingView")]
+ public class PagingView
+ : UIBehaviour
+ , IInitializePotentialDragHandler
+ , IBeginDragHandler, IEndDragHandler, IDragHandler
+ , IScrollHandler
+ , ICanvasElement
+ , ILayoutElement
+ , ILayoutGroup
+ {
+ [Serializable] public class PagingEvent : UnityEvent<int> {}
+
+ [SerializeField] private RectTransform m_Content;
+ public RectTransform Content
+ {
+ get { return m_Content; }
+ set { m_Content = value; }
+ }
+
+ [SerializeField] private RectTransform[] m_Contents;
+ public RectTransform[] Contents
+ {
+ get { return m_Contents; }
+ set { m_Contents = value; }
+ }
+
+ [SerializeField] private bool m_Horizontal = true;
+ public bool Horizontal
+ {
+ get { return m_Horizontal; }
+ set { m_Horizontal = value; }
+ }
+
+ [SerializeField] private bool m_Vertical = true;
+ public bool Vertical
+ {
+ get { return m_Vertical; }
+ set { m_Vertical = value; }
+ }
+
+ [SerializeField] private float m_Elasticity = 0.1f;
+ public float Elasticity
+ {
+ get { return m_Elasticity; }
+ set { m_Elasticity = value; }
+ }
+
+ [SerializeField] private bool m_Inertia = true;
+ public bool Inertia
+ {
+ get { return m_Inertia; }
+ set { m_Inertia = value; }
+ }
+
+ [SerializeField] private float m_DecelerationRate = 0.135f;
+ public float DecelerationRate
+ {
+ get { return m_DecelerationRate; }
+ set { m_DecelerationRate = value; }
+ }
+
+ [SerializeField] private float m_ScrollSensitivity = 1.0f;
+ public float ScrollSensitivity
+ {
+ get { return m_ScrollSensitivity; }
+ set { m_ScrollSensitivity = value; }
+ }
+
+ [SerializeField] private RectTransform m_Viewport;
+ public RectTransform viewport
+ {
+ get {return m_Viewport; }
+ set { m_Viewport = value; SetDirtyCaching(); }
+ }
+
+ [SerializeField] private PagingEvent m_OnValueChanged = new PagingEvent();
+ public PagingEvent OnValueChanged
+ {
+ get { return m_OnValueChanged; }
+ set { m_OnValueChanged = value; }
+ }
+
+ private Vector2 m_PointerStartLocalCursor = Vector2.zero;
+ private Vector2 m_ContentStartPosition = Vector2.zero;
+
+ private RectTransform m_ViewRect;
+ public RectTransform ViewRect
+ {
+ get
+ {
+ if (m_ViewRect == null)
+ m_ViewRect = m_Viewport;
+ if (m_ViewRect == null)
+ m_ViewRect = (RectTransform) transform;
+ return m_ViewRect;
+ }
+ }
+
+ [NonSerialized] private RectTransform m_Rect;
+ private RectTransform RectTransform
+ {
+ get
+ {
+ if (m_Rect == null)
+ m_Rect = GetComponent<RectTransform>();
+ return m_Rect;
+ }
+ }
+
+ private Vector2 m_Velocity;
+ public Vector2 Velocity
+ {
+ get { return m_Velocity; }
+ set { m_Velocity = value; }
+ }
+
+ private bool m_Dragging;
+
+ private Bounds m_ViewBounds;
+ private Bounds m_ContentBounds;
+ private Bounds m_CurrentContentBounds;
+ private Bounds m_PrevViewBounds;
+ private Bounds m_PrevContentBounds;
+ private Bounds m_PrevCurrentContentBounds;
+ private Vector2 m_PrevPosition = Vector2.zero;
+
+ private DrivenRectTransformTracker m_Tracker;
+
+ [NonSerialized] private bool m_HasRebuiltLayout;
+
+ private const float EPSILON = float.Epsilon;
+
+ protected PagingView()
+ {
+ flexibleWidth = -1;
+ }
+
+ public void Rebuild(CanvasUpdate executing)
+ {
+ if (executing == CanvasUpdate.PostLayout)
+ {
+ UpdateBounds();
+ UpdatePrevData();
+
+ m_HasRebuiltLayout = true;
+ }
+ }
+
+ protected override void OnRectTransformDimensionsChange()
+ {
+ SetDirty();
+ }
+
+ public virtual void LayoutComplete() {}
+
+ public virtual void GraphicUpdateComplete() {}
+
+ public virtual void CalculateLayoutInputHorizontal() {}
+
+ public virtual void CalculateLayoutInputVertical() {}
+
+ public virtual float minWidth { get { return -1; } }
+
+ public virtual float preferredWidth { get { return -1; } }
+
+ public virtual float flexibleWidth { get; private set; }
+
+ public virtual float minHeight { get { return -1; } }
+
+ public virtual float preferredHeight { get { return -1; } }
+
+ public virtual float flexibleHeight { get { return -1; } }
+
+ public virtual int layoutPriority { get { return -1; } }
+
+ public virtual void SetLayoutHorizontal() { m_Tracker.Clear(); }
+
+ public virtual void SetLayoutVertical()
+ {
+ m_ViewBounds = new Bounds(ViewRect.rect.center, ViewRect.rect.size);
+ m_ContentBounds = GetBounds(m_Content);
+ m_CurrentContentBounds = GetBounds(m_Contents[m_ContentIndex]);
+ }
+
+ public virtual void OnScroll(PointerEventData eventData)
+ {
+ if (!IsActive())
+ return;
+
+ EnsureLayoutHasRebuilt();
+ UpdateBounds();
+
+ Vector2 delta = eventData.scrollDelta;
+ delta.y *= -1;
+ if (Vertical && !Horizontal)
+ {
+ if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y))
+ delta.y = delta.x;
+ delta.x = 0;
+ }
+
+ if (Horizontal && !Vertical)
+ {
+ if (Mathf.Abs(delta.y) > Mathf.Abs(delta.x))
+ delta.x = delta.y;
+ delta.y = 0;
+ }
+
+ Vector2 position = m_Content.anchoredPosition;
+ position += delta * m_ScrollSensitivity;
+
+ SetContentAnchoredPosition(position);
+ UpdateBounds();
+ }
+
+ public void OnInitializePotentialDrag(PointerEventData eventData)
+ {
+ if (eventData.button != PointerEventData.InputButton.Left)
+ return;
+
+ m_Velocity = Vector2.zero;
+ }
+
+ public void OnBeginDrag(PointerEventData eventData)
+ {
+ if (eventData.button != PointerEventData.InputButton.Left)
+ return;
+
+ if (!IsActive())
+ return;
+
+ UpdateBounds();
+
+ m_PointerStartLocalCursor = Vector2.zero;
+ RectTransformUtility.ScreenPointToLocalPointInRectangle(ViewRect, eventData.position,
+ eventData.pressEventCamera, out m_PointerStartLocalCursor);
+ m_ContentStartPosition = m_Content.anchoredPosition;
+ m_Dragging = true;
+ }
+
+ public void OnEndDrag(PointerEventData eventData)
+ {
+ if (eventData.button != PointerEventData.InputButton.Left)
+ return;
+
+ m_Dragging = false;
+
+ JudgementIndex();
+ }
+
+ public void OnDrag(PointerEventData eventData)
+ {
+ if (eventData.button != PointerEventData.InputButton.Left)
+ return;
+
+ if (!IsActive())
+ return;
+
+ Vector2 localCursor;
+ if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(ViewRect, eventData.position,
+ eventData.pressEventCamera, out localCursor))
+ return;
+
+ UpdateBounds();
+
+ var pointerDelta = localCursor - m_PointerStartLocalCursor;
+ Vector2 position = m_ContentStartPosition + pointerDelta;
+ Vector2 offset = CalculateOffset(m_ContentBounds, position - m_Content.anchoredPosition);
+ position += offset;
+ if (Math.Abs(offset.x) > EPSILON)
+ position.x = position.x - RubberDelta(offset.x, m_ViewBounds.size.x);
+ if (Math.Abs(offset.y) > EPSILON)
+ position.y = position.y - RubberDelta(offset.y, m_ViewBounds.size.y);
+
+ SetContentAnchoredPosition(position);
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+
+ CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
+ }
+
+ protected override void OnDisable()
+ {
+ CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild(this);
+
+ m_Tracker.Clear();
+ m_Velocity = Vector2.zero;
+ LayoutRebuilder.MarkLayoutForRebuild(RectTransform);
+
+ base.OnDisable();
+ }
+
+ public override bool IsActive()
+ {
+ return base.IsActive() && m_Content != null;
+ }
+
+ private int m_PrevContentIndex;
+ private int m_ContentIndex;
+ private void LateUpdate()
+ {
+ if (!m_Content)
+ return;
+
+ EnsureLayoutHasRebuilt();
+ UpdateBounds();
+ float deltaTime = Time.unscaledDeltaTime;
+ Vector2 offset = CalculateOffset(m_CurrentContentBounds, Vector2.zero);
+ if (!m_Dragging && (offset != Vector2.zero || m_Velocity != Vector2.zero))
+ {
+ Vector2 position = m_Content.anchoredPosition;
+ for (int axis = 0; axis < 2; ++axis)
+ {
+ if (Math.Abs(offset[axis]) > EPSILON)
+ {
+ float speed = m_Velocity[axis];
+ position[axis] = Mathf.SmoothDamp(m_Content.anchoredPosition[axis], m_Content.anchoredPosition[axis] + offset[axis], ref speed, m_Elasticity, Mathf.Infinity, deltaTime);
+ m_Velocity[axis] = speed;
+ }
+ else if (m_Inertia)
+ {
+ m_Velocity[axis] *= Mathf.Pow(m_DecelerationRate, deltaTime);
+ if (Mathf.Abs(m_Velocity[axis]) < 1)
+ m_Velocity[axis] = 0;
+ position[axis] += m_Velocity[axis] * deltaTime;
+ }
+ else
+ {
+ m_Velocity[axis] = 0;
+ }
+ }
+
+ if (m_Velocity != Vector2.zero)
+ SetContentAnchoredPosition(position);
+ }
+
+ if (m_Dragging && m_Inertia)
+ {
+ Vector3 newVelocity = (m_Content.anchoredPosition - m_PrevPosition) / deltaTime;
+ m_Velocity = Vector3.Lerp(m_Velocity, newVelocity, deltaTime * 10);
+ }
+
+ if (m_Dragging && m_Velocity != Vector2.zero)
+ JudgementIndex(offset);
+
+ if (!m_Dragging && m_PrevContentIndex != m_ContentIndex)
+ {
+ m_OnValueChanged.Invoke(m_ContentIndex);
+ m_PrevContentIndex = m_ContentIndex;
+ }
+
+ if (m_ViewBounds != m_PrevViewBounds || m_ContentBounds != m_PrevContentBounds
+ || m_ContentBounds != m_PrevCurrentContentBounds || m_Content.anchoredPosition != m_PrevPosition)
+ UpdatePrevData();
+ }
+
+ public virtual void StopMovement()
+ {
+ m_Velocity = Vector2.zero;
+ }
+
+ protected virtual void SetContentAnchoredPosition(Vector2 position)
+ {
+ if (!m_Horizontal)
+ position.x = m_Content.anchoredPosition.x;
+ if (!m_Vertical)
+ position.y = m_Content.anchoredPosition.y;
+
+ if (position != m_Content.anchoredPosition)
+ {
+ m_Content.anchoredPosition = position;
+ UpdateBounds();
+ }
+ }
+
+ private void EnsureLayoutHasRebuilt()
+ {
+ if (m_HasRebuiltLayout && !CanvasUpdateRegistry.IsRebuildingLayout())
+ Canvas.ForceUpdateCanvases();
+ }
+
+ private void UpdatePrevData()
+ {
+ if (m_Content == null)
+ m_PrevPosition = Vector2.zero;
+ else
+ m_PrevPosition = m_Content.anchoredPosition;
+ m_PrevViewBounds = m_ViewBounds;
+ m_PrevContentBounds = m_ContentBounds;
+ m_PrevCurrentContentBounds = m_ContentBounds;
+ }
+
+ private static float RubberDelta(float overStretching, float viewSize)
+ {
+ return (1 - (1 / ((Mathf.Abs(overStretching) * 0.55f / viewSize) + 1)))
+ * viewSize * Mathf.Sign(overStretching);
+ }
+
+ private void UpdateBounds()
+ {
+ m_ViewBounds = new Bounds(ViewRect.rect.center, ViewRect.rect.size);
+ m_ContentBounds = GetBounds(m_Content);
+ m_CurrentContentBounds = GetBounds(m_Contents[m_ContentIndex]);
+
+ if (m_Content == null)
+ return;
+
+ Vector3 contentSize = m_ContentBounds.size;
+ Vector3 contentPos = m_ContentBounds.center;
+ Vector3 excess = m_ViewBounds.size - contentSize;
+ if (excess.x > 0)
+ {
+ contentPos.x -= excess.x * (m_Content.pivot.x - 0.5f);
+ contentSize.x = m_ViewBounds.size.x;
+ }
+ if (excess.y > 0)
+ {
+ contentPos.y -= excess.y * (m_Content.pivot.y - 0.5f);
+ contentSize.y = m_ViewBounds.size.y;
+ }
+
+ m_ContentBounds.size = contentSize;
+ m_ContentBounds.center = contentPos;
+ }
+
+ private readonly Vector3[] m_Corners = new Vector3[4];
+ private Bounds GetBounds(RectTransform content)
+ {
+ if (m_Content == null)
+ return new Bounds();
+
+ var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
+ var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
+
+ var toLocal = ViewRect.worldToLocalMatrix;
+ content.GetWorldCorners(m_Corners);
+ for (int j = 0; j < 4; j++)
+ {
+ Vector3 v = toLocal.MultiplyPoint3x4(m_Corners[j]);
+ vMin = Vector3.Min(v, vMin);
+ vMax = Vector3.Max(v, vMax);
+ }
+
+ var bounds = new Bounds(vMin, Vector3.zero);
+ bounds.Encapsulate(vMax);
+ return bounds;
+ }
+
+ private Vector2 CalculateOffset(Bounds bounds, Vector2 delta)
+ {
+ Vector2 offset = Vector2.zero;
+
+ Vector2 min = bounds.min;
+ Vector2 max = bounds.max;
+
+ if (m_Horizontal)
+ {
+ min.x += delta.x;
+ max.x += delta.x;
+ if (min.x > m_ViewBounds.min.x)
+ offset.x = m_ViewBounds.min.x - min.x;
+ else if (max.x < m_ViewBounds.max.x)
+ offset.x = m_ViewBounds.max.x - max.x;
+ }
+
+ if (m_Vertical)
+ {
+ min.y += delta.y;
+ max.y += delta.y;
+ if (max.y < m_ViewBounds.max.y)
+ offset.y = m_ViewBounds.max.y - max.y;
+ else if (min.y > m_ViewBounds.min.y)
+ offset.y = m_ViewBounds.min.y - min.y;
+ }
+
+ return offset;
+ }
+
+ private void JudgementIndex()
+ {
+ if (Horizontal)
+ {
+ if (-m_Velocity.x > m_ViewBounds.size.x)
+ m_ContentIndex = Mathf.Clamp(m_PrevContentIndex + 1, 0, m_Contents.Length - 1);
+ else if (m_Velocity.x > m_ViewBounds.size.x)
+ m_ContentIndex = Mathf.Clamp(m_PrevContentIndex - 1, 0, m_Contents.Length - 1);
+ }
+
+ if (Vertical)
+ {
+ if (m_Velocity.y > m_ViewBounds.size.y)
+ m_ContentIndex = Mathf.Clamp(m_PrevContentIndex + 1, 0, m_Contents.Length - 1);
+ else if (-m_Velocity.y > m_ViewBounds.size.y)
+ m_ContentIndex = Mathf.Clamp(m_PrevContentIndex - 1, 0, m_Contents.Length - 1);
+ }
+ }
+
+ private void JudgementIndex(Vector2 offset)
+ {
+ if (Horizontal)
+ {
+ if (offset.x > m_ViewBounds.extents.x)
+ m_ContentIndex = Mathf.Clamp(m_ContentIndex + 1, 0, m_Contents.Length - 1);
+ else if (-offset.x > m_ViewBounds.extents.x)
+ m_ContentIndex = Mathf.Clamp(m_ContentIndex - 1, 0, m_Contents.Length - 1);
+ }
+
+ if (Vertical)
+ {
+ if (-offset.y > m_ViewBounds.extents.y)
+ m_ContentIndex = Mathf.Clamp(m_ContentIndex + 1, 0, m_Contents.Length - 1);
+ else if (offset.y > m_ViewBounds.extents.y)
+ m_ContentIndex = Mathf.Clamp(m_ContentIndex - 1, 0, m_Contents.Length - 1);
+ }
+ }
+
+ protected void SetDirty()
+ {
+ if (!IsActive())
+ return;
+ LayoutRebuilder.MarkLayoutForRebuild(RectTransform);
+ }
+
+ protected void SetDirtyCaching()
+ {
+ if (!IsActive())
+ return;
+
+ CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
+ LayoutRebuilder.MarkLayoutForRebuild(RectTransform);
+ }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetDirtyCaching();
+ }
+#endif
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs.meta new file mode 100644 index 0000000..3935af3 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/PagingView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d3fb2d406ecb624986076b829c961ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs b/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs new file mode 100644 index 0000000..1608f4a --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs @@ -0,0 +1,16 @@ +using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RoundLayoutGroup : MonoBehaviour {
+
+ // Use this for initialization
+ void Start () {
+
+ }
+
+ // Update is called once per frame
+ void Update () {
+
+ }
+}
diff --git a/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs.meta b/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs.meta new file mode 100644 index 0000000..f3802f6 --- /dev/null +++ b/Assets/UI_Extension/Scripts/LayoutGroup/RoundLayoutGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 541b1949d4980f749ae3d0ca8b26189a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Utilities.meta b/Assets/UI_Extension/Scripts/Utilities.meta new file mode 100644 index 0000000..2ca0069 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Utilities.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e9106d463951b4d4cac6baed153876eb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Utilities/ListPool.cs b/Assets/UI_Extension/Scripts/Utilities/ListPool.cs new file mode 100644 index 0000000..774d55c --- /dev/null +++ b/Assets/UI_Extension/Scripts/Utilities/ListPool.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UIExt +{ + + internal static class ListPool<T> + { + // Object pool to avoid allocations. + private static readonly ObjectPool<List<T>> s_ListPool = new ObjectPool<List<T>>(null, l => l.Clear()); + + public static List<T> Get() + { + return s_ListPool.Get(); + } + + public static void Release(List<T> toRelease) + { + s_ListPool.Release(toRelease); + } + } +} diff --git a/Assets/UI_Extension/Scripts/Utilities/ListPool.cs.meta b/Assets/UI_Extension/Scripts/Utilities/ListPool.cs.meta new file mode 100644 index 0000000..9f8bf39 --- /dev/null +++ b/Assets/UI_Extension/Scripts/Utilities/ListPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0ddf6384711d3e4489db520510ac43a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs b/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs new file mode 100644 index 0000000..f1db3ec --- /dev/null +++ b/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using UnityEngine.Events;
+using UnityEngine; + +namespace UIExt +{ + + internal class ObjectPool<T> where T : new() + { + private readonly Stack<T> m_Stack = new Stack<T>(); + private readonly UnityAction<T> m_ActionOnGet; + private readonly UnityAction<T> m_ActionOnRelease; + + public int countAll { get; private set; } + public int countActive { get { return countAll - countInactive; } } + public int countInactive { get { return m_Stack.Count; } } + + public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) + { + m_ActionOnGet = actionOnGet; + m_ActionOnRelease = actionOnRelease; + } + + public T Get() + { + T element; + if (m_Stack.Count == 0) + { + element = new T(); + countAll++; + } + else + { + element = m_Stack.Pop(); + } + if (m_ActionOnGet != null) + m_ActionOnGet(element); + return element; + } + + public void Release(T element) + { + if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) + Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); + if (m_ActionOnRelease != null) + m_ActionOnRelease(element); + m_Stack.Push(element); + } + } +} diff --git a/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs.meta b/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs.meta new file mode 100644 index 0000000..5fe9f8d --- /dev/null +++ b/Assets/UI_Extension/Scripts/Utilities/ObjectPool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75cc36573df9c1a4fa34a095a99d7eeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1.meta b/Assets/uGUI-2017.1.meta new file mode 100644 index 0000000..b1fea62 --- /dev/null +++ b/Assets/uGUI-2017.1.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 407f9e044f509d04ea0f59932d4b8671 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor.meta b/Assets/uGUI-2017.1/Editor.meta new file mode 100644 index 0000000..9bf6899 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f2ad34301c84c4e44b5376c99a3b956f +folderAsset: yes +timeCreated: 1602119560 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/EventSystem.meta b/Assets/uGUI-2017.1/Editor/EventSystem.meta new file mode 100644 index 0000000..5ffb514 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/EventSystem.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 01fe218d8ac061941a01b34673d19eaa +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs b/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs new file mode 100644 index 0000000..729b584 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs @@ -0,0 +1,66 @@ +using UnityEngine; +using UnityEngine.EventSystems; + +namespace UnityEditor.EventSystems +{ + [CustomEditor(typeof(EventSystem), true)] + public class EventSystemEditor : Editor + { + public override void OnInspectorGUI() + { + DrawDefaultInspector(); + + var eventSystem = target as EventSystem; + if (eventSystem == null) + return; + + if (eventSystem.GetComponent<BaseInputModule>() != null) + return; + + // no input modules :( + if (GUILayout.Button("Add Default Input Modules")) + { + Undo.AddComponent<StandaloneInputModule>(eventSystem.gameObject); + } + } + + public override bool HasPreviewGUI() + { + return Application.isPlaying; + } + + private GUIStyle m_PreviewLabelStyle; + + protected GUIStyle previewLabelStyle + { + get + { + if (m_PreviewLabelStyle == null) + { + m_PreviewLabelStyle = new GUIStyle("PreOverlayLabel") + { + richText = true, + alignment = TextAnchor.UpperLeft, + fontStyle = FontStyle.Normal + }; + } + + return m_PreviewLabelStyle; + } + } + + public override bool RequiresConstantRepaint() + { + return Application.isPlaying; + } + + public override void OnPreviewGUI(Rect rect, GUIStyle background) + { + var system = target as EventSystem; + if (system == null) + return; + + GUI.Label(rect, system.ToString(), previewLabelStyle); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs.meta b/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs.meta new file mode 100644 index 0000000..adf1b92 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/EventSystem/EventSystemEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 3b529ab7403fbf24cb6439ab7da2ce2b +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs b/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs new file mode 100644 index 0000000..37811df --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs @@ -0,0 +1,122 @@ +using System; +using UnityEngine; +using UnityEngine.EventSystems; + +namespace UnityEditor.EventSystems +{ + [CustomEditor(typeof(EventTrigger), true)] + public class EventTriggerEditor : Editor + { + SerializedProperty m_DelegatesProperty; + + GUIContent m_IconToolbarMinus; + GUIContent m_EventIDName; + GUIContent[] m_EventTypes; + GUIContent m_AddButonContent; + + protected virtual void OnEnable() + { + m_DelegatesProperty = serializedObject.FindProperty("m_Delegates"); + m_AddButonContent = new GUIContent("Add New Event Type"); + m_EventIDName = new GUIContent(""); + // Have to create a copy since otherwise the tooltip will be overwritten. + m_IconToolbarMinus = new GUIContent(EditorGUIUtility.IconContent("Toolbar Minus")); + m_IconToolbarMinus.tooltip = "Remove all events in this list."; + + string[] eventNames = Enum.GetNames(typeof(EventTriggerType)); + m_EventTypes = new GUIContent[eventNames.Length]; + for (int i = 0; i < eventNames.Length; ++i) + { + m_EventTypes[i] = new GUIContent(eventNames[i]); + } + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + int toBeRemovedEntry = -1; + + EditorGUILayout.Space(); + + Vector2 removeButtonSize = GUIStyle.none.CalcSize(m_IconToolbarMinus); + + for (int i = 0; i < m_DelegatesProperty.arraySize; ++i) + { + SerializedProperty delegateProperty = m_DelegatesProperty.GetArrayElementAtIndex(i); + SerializedProperty eventProperty = delegateProperty.FindPropertyRelative("eventID"); + SerializedProperty callbacksProperty = delegateProperty.FindPropertyRelative("callback"); + m_EventIDName.text = eventProperty.enumDisplayNames[eventProperty.enumValueIndex]; + + EditorGUILayout.PropertyField(callbacksProperty, m_EventIDName); + Rect callbackRect = GUILayoutUtility.GetLastRect(); + + Rect removeButtonPos = new Rect(callbackRect.xMax - removeButtonSize.x - 8, callbackRect.y + 1, removeButtonSize.x, removeButtonSize.y); + if (GUI.Button(removeButtonPos, m_IconToolbarMinus, GUIStyle.none)) + { + toBeRemovedEntry = i; + } + + EditorGUILayout.Space(); + } + + if (toBeRemovedEntry > -1) + { + RemoveEntry(toBeRemovedEntry); + } + + Rect btPosition = GUILayoutUtility.GetRect(m_AddButonContent, GUI.skin.button); + const float addButonWidth = 200f; + btPosition.x = btPosition.x + (btPosition.width - addButonWidth) / 2; + btPosition.width = addButonWidth; + if (GUI.Button(btPosition, m_AddButonContent)) + { + ShowAddTriggermenu(); + } + + serializedObject.ApplyModifiedProperties(); + } + + private void RemoveEntry(int toBeRemovedEntry) + { + m_DelegatesProperty.DeleteArrayElementAtIndex(toBeRemovedEntry); + } + + void ShowAddTriggermenu() + { + // Now create the menu, add items and show it + GenericMenu menu = new GenericMenu(); + for (int i = 0; i < m_EventTypes.Length; ++i) + { + bool active = true; + + // Check if we already have a Entry for the current eventType, if so, disable it + for (int p = 0; p < m_DelegatesProperty.arraySize; ++p) + { + SerializedProperty delegateEntry = m_DelegatesProperty.GetArrayElementAtIndex(p); + SerializedProperty eventProperty = delegateEntry.FindPropertyRelative("eventID"); + if (eventProperty.enumValueIndex == i) + { + active = false; + } + } + if (active) + menu.AddItem(m_EventTypes[i], false, OnAddNewSelected, i); + else + menu.AddDisabledItem(m_EventTypes[i]); + } + menu.ShowAsContext(); + Event.current.Use(); + } + + private void OnAddNewSelected(object index) + { + int selected = (int)index; + + m_DelegatesProperty.arraySize += 1; + SerializedProperty delegateEntry = m_DelegatesProperty.GetArrayElementAtIndex(m_DelegatesProperty.arraySize - 1); + SerializedProperty eventProperty = delegateEntry.FindPropertyRelative("eventID"); + eventProperty.enumValueIndex = selected; + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs.meta b/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs.meta new file mode 100644 index 0000000..7271bfc --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/EventSystem/EventTriggerEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1316b73e356230a498f95e64a50672d6 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI.meta b/Assets/uGUI-2017.1/Editor/UI.meta new file mode 100644 index 0000000..82bc206 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 427ac1252da1fe044956726ab7c0e899 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs b/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs new file mode 100644 index 0000000..2901460 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(AspectRatioFitter), true)] + [CanEditMultipleObjects] + public class AspectRatioFitterEditor : SelfControllerEditor + { + SerializedProperty m_AspectMode; + SerializedProperty m_AspectRatio; + + protected virtual void OnEnable() + { + m_AspectMode = serializedObject.FindProperty("m_AspectMode"); + m_AspectRatio = serializedObject.FindProperty("m_AspectRatio"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(m_AspectMode); + EditorGUILayout.PropertyField(m_AspectRatio); + serializedObject.ApplyModifiedProperties(); + + base.OnInspectorGUI(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs.meta new file mode 100644 index 0000000..0e02140 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/AspectRatioFitterEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 47edf64b98c2574419b1a0c2b1cb4a78 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs b/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs new file mode 100644 index 0000000..9aa72dc --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs @@ -0,0 +1,38 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using UnityEngine; + + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("UnityEditor.UI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Unity Technologies")] +[assembly: AssemblyProduct("guisystemeditor")] +[assembly: AssemblyCopyright("Copyright © Unity Technologies 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyIsEditorAssembly] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ad7418c3-5d25-4670-b468-8e7196596d42")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs.meta b/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs.meta new file mode 100644 index 0000000..9d5566f --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/AssemblyInfo.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 17fd9454424a6004e9982ef22617b070 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs new file mode 100644 index 0000000..9676934 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs @@ -0,0 +1,29 @@ +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Button), true)] + [CanEditMultipleObjects] + public class ButtonEditor : SelectableEditor + { + SerializedProperty m_OnClickProperty; + + protected override void OnEnable() + { + base.OnEnable(); + m_OnClickProperty = serializedObject.FindProperty("m_OnClick"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_OnClickProperty); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs.meta new file mode 100644 index 0000000..3d63fb0 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ButtonEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 87698847489a1eb49a05be64fb084cc3 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs b/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs new file mode 100644 index 0000000..883d300 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs @@ -0,0 +1,160 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(CanvasScaler), true)] + [CanEditMultipleObjects] + public class CanvasScalerEditor : Editor + { + SerializedProperty m_UiScaleMode; + SerializedProperty m_ScaleFactor; + SerializedProperty m_ReferenceResolution; + SerializedProperty m_ScreenMatchMode; + SerializedProperty m_MatchWidthOrHeight; + SerializedProperty m_PhysicalUnit; + SerializedProperty m_FallbackScreenDPI; + SerializedProperty m_DefaultSpriteDPI; + SerializedProperty m_DynamicPixelsPerUnit; + SerializedProperty m_ReferencePixelsPerUnit; + + const int kSliderEndpointLabelsHeight = 12; + + private class Styles + { + public GUIContent matchContent; + public GUIContent widthContent; + public GUIContent heightContent; + public GUIContent uiScaleModeContent; + public GUIStyle leftAlignedLabel; + public GUIStyle rightAlignedLabel; + + public Styles() + { + matchContent = new GUIContent("Match"); + widthContent = new GUIContent("Width"); + heightContent = new GUIContent("Height"); + uiScaleModeContent = new GUIContent("UI Scale Mode"); + + leftAlignedLabel = new GUIStyle(EditorStyles.label); + rightAlignedLabel = new GUIStyle(EditorStyles.label); + rightAlignedLabel.alignment = TextAnchor.MiddleRight; + } + } + private static Styles s_Styles; + + protected virtual void OnEnable() + { + m_UiScaleMode = serializedObject.FindProperty("m_UiScaleMode"); + m_ScaleFactor = serializedObject.FindProperty("m_ScaleFactor"); + m_ReferenceResolution = serializedObject.FindProperty("m_ReferenceResolution"); + m_ScreenMatchMode = serializedObject.FindProperty("m_ScreenMatchMode"); + m_MatchWidthOrHeight = serializedObject.FindProperty("m_MatchWidthOrHeight"); + m_PhysicalUnit = serializedObject.FindProperty("m_PhysicalUnit"); + m_FallbackScreenDPI = serializedObject.FindProperty("m_FallbackScreenDPI"); + m_DefaultSpriteDPI = serializedObject.FindProperty("m_DefaultSpriteDPI"); + m_DynamicPixelsPerUnit = serializedObject.FindProperty("m_DynamicPixelsPerUnit"); + m_ReferencePixelsPerUnit = serializedObject.FindProperty("m_ReferencePixelsPerUnit"); + } + + public override void OnInspectorGUI() + { + if (s_Styles == null) + s_Styles = new Styles(); + + bool allAreRoot = true; + bool showWorldDiffers = false; + bool showWorld = ((target as CanvasScaler).GetComponent<Canvas>().renderMode == RenderMode.WorldSpace); + for (int i = 0; i < targets.Length; i++) + { + CanvasScaler scaler = targets[i] as CanvasScaler; + Canvas canvas = scaler.GetComponent<Canvas>(); + if (!canvas.isRootCanvas) + { + allAreRoot = false; + break; + } + if (showWorld && canvas.renderMode != RenderMode.WorldSpace || !showWorld && canvas.renderMode == RenderMode.WorldSpace) + { + showWorldDiffers = true; + break; + } + } + + if (!allAreRoot) + { + EditorGUILayout.HelpBox("Non-root Canvases will not be scaled.", MessageType.Warning); + return; + } + + serializedObject.Update(); + + EditorGUI.showMixedValue = showWorldDiffers; + using (new EditorGUI.DisabledScope(showWorld || showWorldDiffers)) + { + if (showWorld || showWorldDiffers) + { + EditorGUILayout.Popup(s_Styles.uiScaleModeContent.text, 0, new[] { "World" }); + } + else + { + EditorGUILayout.PropertyField(m_UiScaleMode, s_Styles.uiScaleModeContent); + } + } + EditorGUI.showMixedValue = false; + + if (!showWorldDiffers && !(!showWorld && m_UiScaleMode.hasMultipleDifferentValues)) + { + EditorGUILayout.Space(); + + // World Canvas + if (showWorld) + { + EditorGUILayout.PropertyField(m_DynamicPixelsPerUnit); + } + // Constant pixel size + else if (m_UiScaleMode.enumValueIndex == (int)CanvasScaler.ScaleMode.ConstantPixelSize) + { + EditorGUILayout.PropertyField(m_ScaleFactor); + } + // Scale with screen size + else if (m_UiScaleMode.enumValueIndex == (int)CanvasScaler.ScaleMode.ScaleWithScreenSize) + { + EditorGUILayout.PropertyField(m_ReferenceResolution); + EditorGUILayout.PropertyField(m_ScreenMatchMode); + if (m_ScreenMatchMode.enumValueIndex == (int)CanvasScaler.ScreenMatchMode.MatchWidthOrHeight && !m_ScreenMatchMode.hasMultipleDifferentValues) + { + Rect r = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight + kSliderEndpointLabelsHeight); + DualLabeledSlider(r, m_MatchWidthOrHeight, s_Styles.matchContent, s_Styles.widthContent, s_Styles.heightContent); + } + } + // Constant physical size + else if (m_UiScaleMode.enumValueIndex == (int)CanvasScaler.ScaleMode.ConstantPhysicalSize) + { + EditorGUILayout.PropertyField(m_PhysicalUnit); + EditorGUILayout.PropertyField(m_FallbackScreenDPI); + EditorGUILayout.PropertyField(m_DefaultSpriteDPI); + } + + EditorGUILayout.PropertyField(m_ReferencePixelsPerUnit); + } + + serializedObject.ApplyModifiedProperties(); + } + + private static void DualLabeledSlider(Rect position, SerializedProperty property, GUIContent mainLabel, GUIContent labelLeft, GUIContent labelRight) + { + position.height = EditorGUIUtility.singleLineHeight; + Rect pos = position; + + position.y += 12; + position.xMin += EditorGUIUtility.labelWidth; + position.xMax -= EditorGUIUtility.fieldWidth; + + GUI.Label(position, labelLeft, s_Styles.leftAlignedLabel); + GUI.Label(position, labelRight, s_Styles.rightAlignedLabel); + + EditorGUI.PropertyField(pos, property, mainLabel); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs.meta new file mode 100644 index 0000000..e92d213 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/CanvasScalerEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 03c5d085f2f1a3d468f8073e18105b77 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs new file mode 100644 index 0000000..87fdbef --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs @@ -0,0 +1,29 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(ContentSizeFitter), true)] + [CanEditMultipleObjects] + public class ContentSizeFitterEditor : SelfControllerEditor + { + SerializedProperty m_HorizontalFit; + SerializedProperty m_VerticalFit; + + protected virtual void OnEnable() + { + m_HorizontalFit = serializedObject.FindProperty("m_HorizontalFit"); + m_VerticalFit = serializedObject.FindProperty("m_VerticalFit"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(m_HorizontalFit, true); + EditorGUILayout.PropertyField(m_VerticalFit, true); + serializedObject.ApplyModifiedProperties(); + + base.OnInspectorGUI(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs.meta new file mode 100644 index 0000000..9f09d06 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ContentSizeFitterEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 906585751f53cee439d265a08589edcf +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs b/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs new file mode 100644 index 0000000..1dd16e4 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs @@ -0,0 +1,48 @@ +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Dropdown), true)] + [CanEditMultipleObjects] + public class DropdownEditor : SelectableEditor + { + SerializedProperty m_Template; + SerializedProperty m_CaptionText; + SerializedProperty m_CaptionImage; + SerializedProperty m_ItemText; + SerializedProperty m_ItemImage; + SerializedProperty m_OnSelectionChanged; + SerializedProperty m_Value; + SerializedProperty m_Options; + + protected override void OnEnable() + { + base.OnEnable(); + m_Template = serializedObject.FindProperty("m_Template"); + m_CaptionText = serializedObject.FindProperty("m_CaptionText"); + m_CaptionImage = serializedObject.FindProperty("m_CaptionImage"); + m_ItemText = serializedObject.FindProperty("m_ItemText"); + m_ItemImage = serializedObject.FindProperty("m_ItemImage"); + m_OnSelectionChanged = serializedObject.FindProperty("m_OnValueChanged"); + m_Value = serializedObject.FindProperty("m_Value"); + m_Options = serializedObject.FindProperty("m_Options"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + EditorGUILayout.PropertyField(m_Template); + EditorGUILayout.PropertyField(m_CaptionText); + EditorGUILayout.PropertyField(m_CaptionImage); + EditorGUILayout.PropertyField(m_ItemText); + EditorGUILayout.PropertyField(m_ItemImage); + EditorGUILayout.PropertyField(m_Value); + EditorGUILayout.PropertyField(m_Options); + EditorGUILayout.PropertyField(m_OnSelectionChanged); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs.meta new file mode 100644 index 0000000..1f51b0a --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/DropdownEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 7b05a7b6f5fe0744a850680d5f282a6a +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs b/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs new file mode 100644 index 0000000..3fc16ee --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs @@ -0,0 +1,93 @@ +using System.Linq; +using UnityEditor.AnimatedValues; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + /// <summary> + /// Editor class used to edit UI Graphics. + /// </summary> + + [CustomEditor(typeof(MaskableGraphic), false)] + [CanEditMultipleObjects] + public class GraphicEditor : Editor + { + protected SerializedProperty m_Script; + protected SerializedProperty m_Color; + protected SerializedProperty m_Material; + protected SerializedProperty m_RaycastTarget; + + private GUIContent m_CorrectButtonContent; + protected AnimBool m_ShowNativeSize; + + protected virtual void OnDisable() + { + Tools.hidden = false; + m_ShowNativeSize.valueChanged.RemoveListener(Repaint); + } + + protected virtual void OnEnable() + { + m_CorrectButtonContent = new GUIContent("Set Native Size", "Sets the size to match the content."); + + m_Script = serializedObject.FindProperty("m_Script"); + m_Color = serializedObject.FindProperty("m_Color"); + m_Material = serializedObject.FindProperty("m_Material"); + m_RaycastTarget = serializedObject.FindProperty("m_RaycastTarget"); + + m_ShowNativeSize = new AnimBool(false); + m_ShowNativeSize.valueChanged.AddListener(Repaint); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(m_Script); + AppearanceControlsGUI(); + RaycastControlsGUI(); + serializedObject.ApplyModifiedProperties(); + } + + protected void SetShowNativeSize(bool show, bool instant) + { + if (instant) + m_ShowNativeSize.value = show; + else + m_ShowNativeSize.target = show; + } + + protected void NativeSizeButtonGUI() + { + if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded)) + { + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Space(EditorGUIUtility.labelWidth); + if (GUILayout.Button(m_CorrectButtonContent, EditorStyles.miniButton)) + { + foreach (Graphic graphic in targets.Select(obj => obj as Graphic)) + { + Undo.RecordObject(graphic.rectTransform, "Set Native Size"); + graphic.SetNativeSize(); + EditorUtility.SetDirty(graphic); + } + } + } + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndFadeGroup(); + } + + protected void AppearanceControlsGUI() + { + EditorGUILayout.PropertyField(m_Color); + EditorGUILayout.PropertyField(m_Material); + } + + protected void RaycastControlsGUI() + { + EditorGUILayout.PropertyField(m_RaycastTarget); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs.meta new file mode 100644 index 0000000..d6a4459 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/GraphicEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 46f6948c5f4af7747b8bd84eaff48829 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs b/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs new file mode 100644 index 0000000..462e99a --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs @@ -0,0 +1,52 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEditorInternal; +using UnityEditor.AnimatedValues; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(GridLayoutGroup), true)] + [CanEditMultipleObjects] + public class GridLayoutGroupEditor : Editor + { + SerializedProperty m_Padding; + SerializedProperty m_CellSize; + SerializedProperty m_Spacing; + SerializedProperty m_StartCorner; + SerializedProperty m_StartAxis; + SerializedProperty m_ChildAlignment; + SerializedProperty m_Constraint; + SerializedProperty m_ConstraintCount; + + protected virtual void OnEnable() + { + m_Padding = serializedObject.FindProperty("m_Padding"); + m_CellSize = serializedObject.FindProperty("m_CellSize"); + m_Spacing = serializedObject.FindProperty("m_Spacing"); + m_StartCorner = serializedObject.FindProperty("m_StartCorner"); + m_StartAxis = serializedObject.FindProperty("m_StartAxis"); + m_ChildAlignment = serializedObject.FindProperty("m_ChildAlignment"); + m_Constraint = serializedObject.FindProperty("m_Constraint"); + m_ConstraintCount = serializedObject.FindProperty("m_ConstraintCount"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(m_Padding, true); + EditorGUILayout.PropertyField(m_CellSize, true); + EditorGUILayout.PropertyField(m_Spacing, true); + EditorGUILayout.PropertyField(m_StartCorner, true); + EditorGUILayout.PropertyField(m_StartAxis, true); + EditorGUILayout.PropertyField(m_ChildAlignment, true); + EditorGUILayout.PropertyField(m_Constraint, true); + if (m_Constraint.enumValueIndex > 0) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_ConstraintCount, true); + EditorGUI.indentLevel--; + } + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs.meta new file mode 100644 index 0000000..b0931bf --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/GridLayoutGroupEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 41b243187f9b6264e8f982c805ac671d +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs b/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs new file mode 100644 index 0000000..01b17b8 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs @@ -0,0 +1,75 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEditorInternal; +using UnityEditor.AnimatedValues; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(HorizontalOrVerticalLayoutGroup), true)] + [CanEditMultipleObjects] + public class HorizontalOrVerticalLayoutGroupEditor : Editor + { + SerializedProperty m_Padding; + SerializedProperty m_Spacing; + SerializedProperty m_ChildAlignment; + SerializedProperty m_ChildControlWidth; + SerializedProperty m_ChildControlHeight; + SerializedProperty m_ChildForceExpandWidth; + SerializedProperty m_ChildForceExpandHeight; + + protected virtual void OnEnable() + { + m_Padding = serializedObject.FindProperty("m_Padding"); + m_Spacing = serializedObject.FindProperty("m_Spacing"); + m_ChildAlignment = serializedObject.FindProperty("m_ChildAlignment"); + m_ChildControlWidth = serializedObject.FindProperty("m_ChildControlWidth"); + m_ChildControlHeight = serializedObject.FindProperty("m_ChildControlHeight"); + m_ChildForceExpandWidth = serializedObject.FindProperty("m_ChildForceExpandWidth"); + m_ChildForceExpandHeight = serializedObject.FindProperty("m_ChildForceExpandHeight"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + EditorGUILayout.PropertyField(m_Padding, true); + EditorGUILayout.PropertyField(m_Spacing, true); + EditorGUILayout.PropertyField(m_ChildAlignment, true); + + Rect rect = EditorGUILayout.GetControlRect(); + rect = EditorGUI.PrefixLabel(rect, -1, new GUIContent("Child Controls Size")); + rect.width = Mathf.Max(50, (rect.width - 4) / 3); + EditorGUIUtility.labelWidth = 50; + ToggleLeft(rect, m_ChildControlWidth, new GUIContent("Width")); + rect.x += rect.width + 2; + ToggleLeft(rect, m_ChildControlHeight, new GUIContent("Height")); + EditorGUIUtility.labelWidth = 0; + + rect = EditorGUILayout.GetControlRect(); + rect = EditorGUI.PrefixLabel(rect, -1, new GUIContent("Child Force Expand")); + rect.width = Mathf.Max(50, (rect.width - 4) / 3); + EditorGUIUtility.labelWidth = 50; + ToggleLeft(rect, m_ChildForceExpandWidth, new GUIContent("Width")); + rect.x += rect.width + 2; + ToggleLeft(rect, m_ChildForceExpandHeight, new GUIContent("Height")); + EditorGUIUtility.labelWidth = 0; + + serializedObject.ApplyModifiedProperties(); + } + + void ToggleLeft(Rect position, SerializedProperty property, GUIContent label) + { + bool toggle = property.boolValue; + EditorGUI.showMixedValue = property.hasMultipleDifferentValues; + EditorGUI.BeginChangeCheck(); + int oldIndent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + toggle = EditorGUI.ToggleLeft(position, label, toggle); + EditorGUI.indentLevel = oldIndent; + if (EditorGUI.EndChangeCheck()) + { + property.boolValue = property.hasMultipleDifferentValues ? true : !property.boolValue; + } + EditorGUI.showMixedValue = false; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs.meta new file mode 100644 index 0000000..f91a76b --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/HorizontalOrVerticalLayoutGroupEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: be8e8f57c18c7b64a8db44d2f8b15598 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs new file mode 100644 index 0000000..85da33f --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs @@ -0,0 +1,251 @@ +using System.Linq; +using UnityEngine; +using UnityEditor.AnimatedValues; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + /// <summary> + /// Editor class used to edit UI Sprites. + /// </summary> + + [CustomEditor(typeof(Image), true)] + [CanEditMultipleObjects] + public class ImageEditor : GraphicEditor + { + SerializedProperty m_FillMethod; + SerializedProperty m_FillOrigin; + SerializedProperty m_FillAmount; + SerializedProperty m_FillClockwise; + SerializedProperty m_Type; + SerializedProperty m_FillCenter; + SerializedProperty m_Sprite; + SerializedProperty m_PreserveAspect; + GUIContent m_SpriteContent; + GUIContent m_SpriteTypeContent; + GUIContent m_ClockwiseContent; + AnimBool m_ShowSlicedOrTiled; + AnimBool m_ShowSliced; + AnimBool m_ShowTiled; + AnimBool m_ShowFilled; + AnimBool m_ShowType; + + protected override void OnEnable() + { + base.OnEnable(); + + m_SpriteContent = new GUIContent("Source Image"); + m_SpriteTypeContent = new GUIContent("Image Type"); + m_ClockwiseContent = new GUIContent("Clockwise"); + + m_Sprite = serializedObject.FindProperty("m_Sprite"); + m_Type = serializedObject.FindProperty("m_Type"); + m_FillCenter = serializedObject.FindProperty("m_FillCenter"); + m_FillMethod = serializedObject.FindProperty("m_FillMethod"); + m_FillOrigin = serializedObject.FindProperty("m_FillOrigin"); + m_FillClockwise = serializedObject.FindProperty("m_FillClockwise"); + m_FillAmount = serializedObject.FindProperty("m_FillAmount"); + m_PreserveAspect = serializedObject.FindProperty("m_PreserveAspect"); + + m_ShowType = new AnimBool(m_Sprite.objectReferenceValue != null); + m_ShowType.valueChanged.AddListener(Repaint); + + var typeEnum = (Image.Type)m_Type.enumValueIndex; + + m_ShowSlicedOrTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); + m_ShowSliced = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); + m_ShowTiled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Tiled); + m_ShowFilled = new AnimBool(!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled); + m_ShowSlicedOrTiled.valueChanged.AddListener(Repaint); + m_ShowSliced.valueChanged.AddListener(Repaint); + m_ShowTiled.valueChanged.AddListener(Repaint); + m_ShowFilled.valueChanged.AddListener(Repaint); + + SetShowNativeSize(true); + } + + protected override void OnDisable() + { + m_ShowType.valueChanged.RemoveListener(Repaint); + m_ShowSlicedOrTiled.valueChanged.RemoveListener(Repaint); + m_ShowSliced.valueChanged.RemoveListener(Repaint); + m_ShowTiled.valueChanged.RemoveListener(Repaint); + m_ShowFilled.valueChanged.RemoveListener(Repaint); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + SpriteGUI(); + AppearanceControlsGUI(); + RaycastControlsGUI(); + + m_ShowType.target = m_Sprite.objectReferenceValue != null; + if (EditorGUILayout.BeginFadeGroup(m_ShowType.faded)) + TypeGUI(); + EditorGUILayout.EndFadeGroup(); + + SetShowNativeSize(false); + if (EditorGUILayout.BeginFadeGroup(m_ShowNativeSize.faded)) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_PreserveAspect); + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFadeGroup(); + NativeSizeButtonGUI(); + + serializedObject.ApplyModifiedProperties(); + } + + void SetShowNativeSize(bool instant) + { + Image.Type type = (Image.Type)m_Type.enumValueIndex; + bool showNativeSize = (type == Image.Type.Simple || type == Image.Type.Filled) && m_Sprite.objectReferenceValue != null; + base.SetShowNativeSize(showNativeSize, instant); + } + + /// <summary> + /// Draw the atlas and Image selection fields. + /// </summary> + + protected void SpriteGUI() + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_Sprite, m_SpriteContent); + if (EditorGUI.EndChangeCheck()) + { + var newSprite = m_Sprite.objectReferenceValue as Sprite; + if (newSprite) + { + Image.Type oldType = (Image.Type)m_Type.enumValueIndex; + if (newSprite.border.SqrMagnitude() > 0) + { + m_Type.enumValueIndex = (int)Image.Type.Sliced; + } + else if (oldType == Image.Type.Sliced) + { + m_Type.enumValueIndex = (int)Image.Type.Simple; + } + } + } + } + + /// <summary> + /// Sprites's custom properties based on the type. + /// </summary> + + protected void TypeGUI() + { + EditorGUILayout.PropertyField(m_Type, m_SpriteTypeContent); + + ++EditorGUI.indentLevel; + { + Image.Type typeEnum = (Image.Type)m_Type.enumValueIndex; + + bool showSlicedOrTiled = (!m_Type.hasMultipleDifferentValues && (typeEnum == Image.Type.Sliced || typeEnum == Image.Type.Tiled)); + if (showSlicedOrTiled && targets.Length > 1) + showSlicedOrTiled = targets.Select(obj => obj as Image).All(img => img.hasBorder); + + m_ShowSlicedOrTiled.target = showSlicedOrTiled; + m_ShowSliced.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Sliced); + m_ShowTiled.target = (showSlicedOrTiled && !m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Tiled); + m_ShowFilled.target = (!m_Type.hasMultipleDifferentValues && typeEnum == Image.Type.Filled); + + Image image = target as Image; + if (EditorGUILayout.BeginFadeGroup(m_ShowSlicedOrTiled.faded)) + { + if (image.hasBorder) + EditorGUILayout.PropertyField(m_FillCenter); + } + EditorGUILayout.EndFadeGroup(); + + if (EditorGUILayout.BeginFadeGroup(m_ShowSliced.faded)) + { + if (image.sprite != null && !image.hasBorder) + EditorGUILayout.HelpBox("This Image doesn't have a border.", MessageType.Warning); + } + EditorGUILayout.EndFadeGroup(); + + if (EditorGUILayout.BeginFadeGroup(m_ShowTiled.faded)) + { + if (image.sprite != null && !image.hasBorder && (image.sprite.texture.wrapMode != TextureWrapMode.Repeat || image.sprite.packed)) + EditorGUILayout.HelpBox("It looks like you want to tile a sprite with no border. It would be more efficient to convert the Sprite to an Advanced texture, clear the Packing tag and set the Wrap mode to Repeat.", MessageType.Warning); + } + EditorGUILayout.EndFadeGroup(); + + if (EditorGUILayout.BeginFadeGroup(m_ShowFilled.faded)) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_FillMethod); + if (EditorGUI.EndChangeCheck()) + { + m_FillOrigin.intValue = 0; + } + switch ((Image.FillMethod)m_FillMethod.enumValueIndex) + { + case Image.FillMethod.Horizontal: + m_FillOrigin.intValue = (int)(Image.OriginHorizontal)EditorGUILayout.EnumPopup("Fill Origin", (Image.OriginHorizontal)m_FillOrigin.intValue); + break; + case Image.FillMethod.Vertical: + m_FillOrigin.intValue = (int)(Image.OriginVertical)EditorGUILayout.EnumPopup("Fill Origin", (Image.OriginVertical)m_FillOrigin.intValue); + break; + case Image.FillMethod.Radial90: + m_FillOrigin.intValue = (int)(Image.Origin90)EditorGUILayout.EnumPopup("Fill Origin", (Image.Origin90)m_FillOrigin.intValue); + break; + case Image.FillMethod.Radial180: + m_FillOrigin.intValue = (int)(Image.Origin180)EditorGUILayout.EnumPopup("Fill Origin", (Image.Origin180)m_FillOrigin.intValue); + break; + case Image.FillMethod.Radial360: + m_FillOrigin.intValue = (int)(Image.Origin360)EditorGUILayout.EnumPopup("Fill Origin", (Image.Origin360)m_FillOrigin.intValue); + break; + } + EditorGUILayout.PropertyField(m_FillAmount); + if ((Image.FillMethod)m_FillMethod.enumValueIndex > Image.FillMethod.Vertical) + { + EditorGUILayout.PropertyField(m_FillClockwise, m_ClockwiseContent); + } + } + EditorGUILayout.EndFadeGroup(); + } + --EditorGUI.indentLevel; + } + + /// <summary> + /// All graphics have a preview. + /// </summary> + + public override bool HasPreviewGUI() { return true; } + + /// <summary> + /// Draw the Image preview. + /// </summary> + + public override void OnPreviewGUI(Rect rect, GUIStyle background) + { + Image image = target as Image; + if (image == null) return; + + Sprite sf = image.sprite; + if (sf == null) return; + + SpriteDrawUtility.DrawSprite(sf, rect, image.canvasRenderer.GetColor()); + } + + /// <summary> + /// Info String drawn at the bottom of the Preview + /// </summary> + + public override string GetInfoString() + { + Image image = target as Image; + Sprite sprite = image.sprite; + + int x = (sprite != null) ? Mathf.RoundToInt(sprite.rect.width) : 0; + int y = (sprite != null) ? Mathf.RoundToInt(sprite.rect.height) : 0; + + return string.Format("Image Size: {0}x{1}", x, y); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs.meta new file mode 100644 index 0000000..db137d4 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ImageEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 8c5c2197b06fed749be6adac4f6a0c1c +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs b/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs new file mode 100644 index 0000000..f100f07 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs @@ -0,0 +1,139 @@ +using UnityEditor.AnimatedValues; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(InputField), true)] + public class InputFieldEditor : SelectableEditor + { + SerializedProperty m_TextComponent; + SerializedProperty m_Text; + SerializedProperty m_ContentType; + SerializedProperty m_LineType; + SerializedProperty m_InputType; + SerializedProperty m_CharacterValidation; + SerializedProperty m_KeyboardType; + SerializedProperty m_CharacterLimit; + SerializedProperty m_CaretBlinkRate; + SerializedProperty m_CaretWidth; + SerializedProperty m_CaretColor; + SerializedProperty m_CustomCaretColor; + SerializedProperty m_SelectionColor; + SerializedProperty m_HideMobileInput; + SerializedProperty m_Placeholder; + SerializedProperty m_OnValueChanged; + SerializedProperty m_OnEndEdit; + SerializedProperty m_ReadOnly; + + AnimBool m_CustomColor; + + protected override void OnEnable() + { + base.OnEnable(); + m_TextComponent = serializedObject.FindProperty("m_TextComponent"); + m_Text = serializedObject.FindProperty("m_Text"); + m_ContentType = serializedObject.FindProperty("m_ContentType"); + m_LineType = serializedObject.FindProperty("m_LineType"); + m_InputType = serializedObject.FindProperty("m_InputType"); + m_CharacterValidation = serializedObject.FindProperty("m_CharacterValidation"); + m_KeyboardType = serializedObject.FindProperty("m_KeyboardType"); + m_CharacterLimit = serializedObject.FindProperty("m_CharacterLimit"); + m_CaretBlinkRate = serializedObject.FindProperty("m_CaretBlinkRate"); + m_CaretWidth = serializedObject.FindProperty("m_CaretWidth"); + m_CaretColor = serializedObject.FindProperty("m_CaretColor"); + m_CustomCaretColor = serializedObject.FindProperty("m_CustomCaretColor"); + m_SelectionColor = serializedObject.FindProperty("m_SelectionColor"); + m_HideMobileInput = serializedObject.FindProperty("m_HideMobileInput"); + m_Placeholder = serializedObject.FindProperty("m_Placeholder"); + m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); + m_OnEndEdit = serializedObject.FindProperty("m_OnEndEdit"); + m_ReadOnly = serializedObject.FindProperty("m_ReadOnly"); + + m_CustomColor = new AnimBool(m_CustomCaretColor.boolValue); + m_CustomColor.valueChanged.AddListener(Repaint); + } + + protected override void OnDisable() + { + base.OnDisable(); + m_CustomColor.valueChanged.RemoveListener(Repaint); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + base.OnInspectorGUI(); + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_TextComponent); + + if (m_TextComponent != null && m_TextComponent.objectReferenceValue != null) + { + Text text = m_TextComponent.objectReferenceValue as Text; + if (text.supportRichText) + { + EditorGUILayout.HelpBox("Using Rich Text with input is unsupported.", MessageType.Warning); + } + } + + using (new EditorGUI.DisabledScope(m_TextComponent == null || m_TextComponent.objectReferenceValue == null)) + { + EditorGUILayout.PropertyField(m_Text); + EditorGUILayout.PropertyField(m_CharacterLimit); + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_ContentType); + if (!m_ContentType.hasMultipleDifferentValues) + { + EditorGUI.indentLevel++; + + if (m_ContentType.enumValueIndex == (int)InputField.ContentType.Standard || + m_ContentType.enumValueIndex == (int)InputField.ContentType.Autocorrected || + m_ContentType.enumValueIndex == (int)InputField.ContentType.Custom) + EditorGUILayout.PropertyField(m_LineType); + + if (m_ContentType.enumValueIndex == (int)InputField.ContentType.Custom) + { + EditorGUILayout.PropertyField(m_InputType); + EditorGUILayout.PropertyField(m_KeyboardType); + EditorGUILayout.PropertyField(m_CharacterValidation); + } + + EditorGUI.indentLevel--; + } + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_Placeholder); + EditorGUILayout.PropertyField(m_CaretBlinkRate); + EditorGUILayout.PropertyField(m_CaretWidth); + + EditorGUILayout.PropertyField(m_CustomCaretColor); + + m_CustomColor.target = m_CustomCaretColor.boolValue; + + if (EditorGUILayout.BeginFadeGroup(m_CustomColor.faded)) + { + EditorGUILayout.PropertyField(m_CaretColor); + } + EditorGUILayout.EndFadeGroup(); + + EditorGUILayout.PropertyField(m_SelectionColor); + EditorGUILayout.PropertyField(m_HideMobileInput); + EditorGUILayout.PropertyField(m_ReadOnly); + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_OnValueChanged); + EditorGUILayout.PropertyField(m_OnEndEdit); + } + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs.meta new file mode 100644 index 0000000..961284b --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/InputFieldEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2c23aeb09974d4c41b3e2157285f204c +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs b/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs new file mode 100644 index 0000000..b02e37e --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.Profiling; +using UnityEngine.EventSystems; + +namespace UnityEditor.Events +{ + [CustomPreview(typeof(GameObject))] + class InterceptedEventsPreview : ObjectPreview + { + protected class ComponentInterceptedEvents + { + public GUIContent componentName; + public int[] interceptedEvents; + } + + class Styles + { + public GUIStyle labelStyle = new GUIStyle(EditorStyles.label); + public GUIStyle componentName = new GUIStyle(EditorStyles.boldLabel); + + public Styles() + { + Color fontColor = new Color(0.7f, 0.7f, 0.7f); + labelStyle.padding.right += 20; + labelStyle.normal.textColor = fontColor; + labelStyle.active.textColor = fontColor; + labelStyle.focused.textColor = fontColor; + labelStyle.hover.textColor = fontColor; + labelStyle.onNormal.textColor = fontColor; + labelStyle.onActive.textColor = fontColor; + labelStyle.onFocused.textColor = fontColor; + labelStyle.onHover.textColor = fontColor; + + componentName.normal.textColor = fontColor; + componentName.active.textColor = fontColor; + componentName.focused.textColor = fontColor; + componentName.hover.textColor = fontColor; + componentName.onNormal.textColor = fontColor; + componentName.onActive.textColor = fontColor; + componentName.onFocused.textColor = fontColor; + componentName.onHover.textColor = fontColor; + } + } + + private Dictionary<GameObject, List<ComponentInterceptedEvents>> m_TargetEvents; + private bool m_InterceptsAnyEvent = false; + private GUIContent m_Title; + private Styles m_Styles = new Styles(); + + public override void Initialize(UnityEngine.Object[] targets) + { + Profiler.BeginSample("ComponentInterceptedEvents.Initialize"); + + base.Initialize(targets); + m_TargetEvents = new Dictionary<GameObject, List<ComponentInterceptedEvents>>(targets.Count()); + m_InterceptsAnyEvent = false; + for (int i = 0; i < targets.Length; ++i) + { + GameObject go = targets[i] as GameObject; + List<ComponentInterceptedEvents> interceptedEvents = GetEventsInfo(go); + m_TargetEvents.Add(go, interceptedEvents); + if (interceptedEvents.Any()) + m_InterceptsAnyEvent = true; + } + Profiler.EndSample(); + } + + public override GUIContent GetPreviewTitle() + { + if (m_Title == null) + { + m_Title = new GUIContent("Intercepted Events"); + } + return m_Title; + } + + public override bool HasPreviewGUI() + { + return m_TargetEvents != null && m_InterceptsAnyEvent; + } + + public override void OnPreviewGUI(Rect r, GUIStyle background) + { + if (Event.current.type != EventType.Repaint) + return; + Profiler.BeginSample("InterceptedEventsPreview.OnPreviewGUI"); + + + if (m_Styles == null) + m_Styles = new Styles(); + + Vector2 maxEventLabelSize = Vector2.zero; + int totalInterceptedEvents = 0; + + List<ComponentInterceptedEvents> componentIncerceptedEvents = m_TargetEvents[target as GameObject]; + + // Find out the maximum size needed for any given label. + foreach (ComponentInterceptedEvents componentInterceptedEvents in componentIncerceptedEvents) + { + foreach (int eventIndex in componentInterceptedEvents.interceptedEvents) + { + GUIContent eventContent = s_PossibleEvents[eventIndex]; + ++totalInterceptedEvents; + Vector2 labelSize = m_Styles.labelStyle.CalcSize(eventContent); + if (maxEventLabelSize.x < labelSize.x) + { + maxEventLabelSize.x = labelSize.x; + } + if (maxEventLabelSize.y < labelSize.y) + { + maxEventLabelSize.y = labelSize.y; + } + } + } + + // Apply padding + RectOffset previewPadding = new RectOffset(-5, -5, -5, -5); + r = previewPadding.Add(r); + + // Figure out how many rows and columns we can/should have + int columns = Mathf.Max(Mathf.FloorToInt(r.width / maxEventLabelSize.x), 1); + int rows = Mathf.Max(totalInterceptedEvents / columns, 1) + componentIncerceptedEvents.Count; + + // Centering + float initialX = r.x + Mathf.Max(0, (r.width - (maxEventLabelSize.x * columns)) / 2); + float initialY = r.y + Mathf.Max(0, (r.height - (maxEventLabelSize.y * rows)) / 2); + + Rect labelRect = new Rect(initialX, initialY, maxEventLabelSize.x, maxEventLabelSize.y); + int currentColumn = 0; + foreach (ComponentInterceptedEvents componentInterceptedEvents in componentIncerceptedEvents) + { + GUI.Label(labelRect, componentInterceptedEvents.componentName, m_Styles.componentName); + labelRect.y += labelRect.height; + labelRect.x = initialX; + foreach (int eventIndex in componentInterceptedEvents.interceptedEvents) + { + GUIContent eventContent = s_PossibleEvents[eventIndex]; + GUI.Label(labelRect, eventContent, m_Styles.labelStyle); + if (currentColumn < columns - 1) + { + labelRect.x += labelRect.width; + } + else + { + labelRect.y += labelRect.height; + labelRect.x = initialX; + } + + currentColumn = (currentColumn + 1) % columns; + } + + if (labelRect.x != initialX) + { + labelRect.y += labelRect.height; + labelRect.x = initialX; + } + } + Profiler.EndSample(); + } + + //Lookup cache to avoid recalculating which types uses which events: + //Caches all interfaces that inherit from IEventSystemHandler + static List<Type> s_EventSystemInterfaces = null; + //Caches all GUIContents in a single list to avoid creating too much GUIContent and strings. + private static List<GUIContent> s_PossibleEvents = null; + //Caches all events used by each interface + static Dictionary<Type, List<int>> s_InterfaceEventSystemEvents = null; + //Caches each concrete type and it's events + static readonly Dictionary<Type, ComponentInterceptedEvents> s_ComponentEvents2 = new Dictionary<Type, ComponentInterceptedEvents>(); + + + protected static List<ComponentInterceptedEvents> GetEventsInfo(GameObject gameObject) + { + InitializeEvetnsInterfaceCacheIfNeeded(); + + List<ComponentInterceptedEvents> componentEvents = new List<ComponentInterceptedEvents>(); + + MonoBehaviour[] mbs = gameObject.GetComponents<MonoBehaviour>(); + + for (int i = 0, imax = mbs.Length; i < imax; ++i) + { + ComponentInterceptedEvents componentEvent = null; + + MonoBehaviour mb = mbs[i]; + if (mb == null) + continue; + + Type type = mb.GetType(); + + if (!s_ComponentEvents2.ContainsKey(type)) + { + List<int> events = null; + Profiler.BeginSample("ComponentInterceptedEvents.GetEventsInfo.NewType"); + if (typeof(IEventSystemHandler).IsAssignableFrom(type)) + { + for (int index = 0; index < s_EventSystemInterfaces.Count; index++) + { + var eventInterface = s_EventSystemInterfaces[index]; + if (!eventInterface.IsAssignableFrom(type)) + continue; + + if (events == null) + events = new List<int>(); + + events.AddRange(s_InterfaceEventSystemEvents[eventInterface]); + } + } + + if (events != null) + { + componentEvent = new ComponentInterceptedEvents(); + componentEvent.componentName = new GUIContent(type.Name); + componentEvent.interceptedEvents = events.OrderBy(index => s_PossibleEvents[index].text).ToArray(); + } + s_ComponentEvents2.Add(type, componentEvent); + + Profiler.EndSample(); + } + else + { + componentEvent = s_ComponentEvents2[type]; + } + + + if (componentEvent != null) + { + componentEvents.Add(componentEvent); + } + } + + return componentEvents; + } + + private static void InitializeEvetnsInterfaceCacheIfNeeded() + { + if (s_EventSystemInterfaces != null) + return; + + s_EventSystemInterfaces = new List<Type>(); + s_PossibleEvents = new List<GUIContent>(); + s_InterfaceEventSystemEvents = new Dictionary<Type, List<int>>(); + + foreach (var type in GetAccessibleTypesInLoadedAssemblies()) + { + if (!type.IsInterface) + continue; + + if (!typeof(IEventSystemHandler).IsAssignableFrom(type)) + continue; + + s_EventSystemInterfaces.Add(type); + List<int> eventIndexList = new List<int>(); + + MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + for (int mi = 0; mi < methodInfos.Length; mi++) + { + MethodInfo methodInfo = methodInfos[mi]; + eventIndexList.Add(s_PossibleEvents.Count); + s_PossibleEvents.Add(new GUIContent(methodInfo.Name)); + } + s_InterfaceEventSystemEvents.Add(type, eventIndexList); + } + } + + private static IEnumerable<Type> GetAccessibleTypesInLoadedAssemblies() + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + for (var i = 0; i < assemblies.Length; ++i) + { + Type[] types; + var assembly = assemblies[i]; + + if (assembly == null) + continue; + + try + { + types = assembly.GetTypes(); + } + catch (ReflectionTypeLoadException e) + { + // assembly.GetTypes() might fail in case the Assembly cannot resolve all its references, + // or in case it was built targetting a newer version of .NET. + // In case the resolution fails for some types, we can still access the ones that have been + // properly loaded. + types = e.Types; + } + + for (var j = 0; j < types.Length; ++j) + { + var type = types[j]; + if (type == null) + continue; + + yield return type; + } + } + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs.meta b/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs.meta new file mode 100644 index 0000000..6b1ac00 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/InterceptedEventsPreview.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d8a1fb8949afd2b4a89786a167d4efbe +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs b/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs new file mode 100644 index 0000000..ac80f5a --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs @@ -0,0 +1,102 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEditorInternal; +using UnityEditor.AnimatedValues; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(LayoutElement), true)] + [CanEditMultipleObjects] + public class LayoutElementEditor : Editor + { + SerializedProperty m_IgnoreLayout; + SerializedProperty m_MinWidth; + SerializedProperty m_MinHeight; + SerializedProperty m_PreferredWidth; + SerializedProperty m_PreferredHeight; + SerializedProperty m_FlexibleWidth; + SerializedProperty m_FlexibleHeight; + SerializedProperty m_LayoutPriority; + + protected virtual void OnEnable() + { + m_IgnoreLayout = serializedObject.FindProperty("m_IgnoreLayout"); + m_MinWidth = serializedObject.FindProperty("m_MinWidth"); + m_MinHeight = serializedObject.FindProperty("m_MinHeight"); + m_PreferredWidth = serializedObject.FindProperty("m_PreferredWidth"); + m_PreferredHeight = serializedObject.FindProperty("m_PreferredHeight"); + m_FlexibleWidth = serializedObject.FindProperty("m_FlexibleWidth"); + m_FlexibleHeight = serializedObject.FindProperty("m_FlexibleHeight"); + m_LayoutPriority = serializedObject.FindProperty("m_LayoutPriority"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_IgnoreLayout); + + if (!m_IgnoreLayout.boolValue) + { + EditorGUILayout.Space(); + + LayoutElementField(m_MinWidth, 0); + LayoutElementField(m_MinHeight, 0); + LayoutElementField(m_PreferredWidth, t => t.rect.width); + LayoutElementField(m_PreferredHeight, t => t.rect.height); + LayoutElementField(m_FlexibleWidth, 1); + LayoutElementField(m_FlexibleHeight, 1); + } + + EditorGUILayout.PropertyField(m_LayoutPriority); + + serializedObject.ApplyModifiedProperties(); + } + + void LayoutElementField(SerializedProperty property, float defaultValue) + { + LayoutElementField(property, _ => defaultValue); + } + + void LayoutElementField(SerializedProperty property, System.Func<RectTransform, float> defaultValue) + { + Rect position = EditorGUILayout.GetControlRect(); + + // Label + GUIContent label = EditorGUI.BeginProperty(position, null, property); + + // Rects + Rect fieldPosition = EditorGUI.PrefixLabel(position, label); + + Rect toggleRect = fieldPosition; + toggleRect.width = 16; + + Rect floatFieldRect = fieldPosition; + floatFieldRect.xMin += 16; + + // Checkbox + EditorGUI.BeginChangeCheck(); + bool enabled = EditorGUI.ToggleLeft(toggleRect, GUIContent.none, property.floatValue >= 0); + if (EditorGUI.EndChangeCheck()) + { + // This could be made better to set all of the targets to their initial width, but mimizing code change for now + property.floatValue = (enabled ? defaultValue((target as LayoutElement).transform as RectTransform) : -1); + } + + if (!property.hasMultipleDifferentValues && property.floatValue >= 0) + { + // Float field + EditorGUIUtility.labelWidth = 4; // Small invisible label area for drag zone functionality + EditorGUI.BeginChangeCheck(); + float newValue = EditorGUI.FloatField(floatFieldRect, new GUIContent(" "), property.floatValue); + if (EditorGUI.EndChangeCheck()) + { + property.floatValue = Mathf.Max(0, newValue); + } + EditorGUIUtility.labelWidth = 0; + } + + EditorGUI.EndProperty(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs.meta new file mode 100644 index 0000000..8744d62 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/LayoutElementEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: ffcef66c44c6c174eb838804dcaab7f0 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs b/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs new file mode 100644 index 0000000..6f93c98 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs @@ -0,0 +1,123 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.Events +{ + [CustomPreview(typeof(GameObject))] + class LayoutPropertiesPreview : ObjectPreview + { + private const float kLabelWidth = 110; + private const float kValueWidth = 100; + + class Styles + { + public GUIStyle labelStyle = new GUIStyle(EditorStyles.label); + public GUIStyle headerStyle = new GUIStyle(EditorStyles.boldLabel); + + public Styles() + { + Color fontColor = new Color(0.7f, 0.7f, 0.7f); + labelStyle.padding.right += 4; + labelStyle.normal.textColor = fontColor; + headerStyle.padding.right += 4; + headerStyle.normal.textColor = fontColor; + } + } + + private GUIContent m_Title; + private Styles m_Styles = new Styles(); + + public override void Initialize(UnityEngine.Object[] targets) + { + base.Initialize(targets); + } + + public override GUIContent GetPreviewTitle() + { + if (m_Title == null) + { + m_Title = new GUIContent("Layout Properties"); + } + return m_Title; + } + + public override bool HasPreviewGUI() + { + GameObject go = target as GameObject; + if (!go) + return false; + return go.GetComponent(typeof(ILayoutElement)) != null; + } + + public override void OnPreviewGUI(Rect r, GUIStyle background) + { + if (Event.current.type != EventType.Repaint) + return; + + if (m_Styles == null) + m_Styles = new Styles(); + + GameObject go = target as GameObject; + RectTransform rect = go.transform as RectTransform; + if (rect == null) + return; + + // Apply padding + RectOffset previewPadding = new RectOffset(-5, -5, -5, -5); + r = previewPadding.Add(r); + + // Prepare rects for columns + r.height = EditorGUIUtility.singleLineHeight; + Rect labelRect = r; + Rect valueRect = r; + Rect sourceRect = r; + labelRect.width = kLabelWidth; + valueRect.xMin += kLabelWidth; + valueRect.width = kValueWidth; + sourceRect.xMin += kLabelWidth + kValueWidth; + + // Headers + GUI.Label(labelRect, "Property", m_Styles.headerStyle); + GUI.Label(valueRect, "Value", m_Styles.headerStyle); + GUI.Label(sourceRect, "Source", m_Styles.headerStyle); + labelRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + valueRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + sourceRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + // Prepare reusable variable for out argument + ILayoutElement source = null; + + // Show properties + + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Min Width", LayoutUtility.GetLayoutProperty(rect, e => e.minWidth, 0, out source).ToString(), source); + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Min Height", LayoutUtility.GetLayoutProperty(rect, e => e.minHeight, 0, out source).ToString(), source); + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Preferred Width", LayoutUtility.GetLayoutProperty(rect, e => e.preferredWidth, 0, out source).ToString(), source); + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Preferred Height", LayoutUtility.GetLayoutProperty(rect, e => e.preferredHeight, 0, out source).ToString(), source); + + float flexible = 0; + + flexible = LayoutUtility.GetLayoutProperty(rect, e => e.flexibleWidth, 0, out source); + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Flexible Width", flexible > 0 ? ("enabled (" + flexible.ToString() + ")") : "disabled", source); + flexible = LayoutUtility.GetLayoutProperty(rect, e => e.flexibleHeight, 0, out source); + ShowProp(ref labelRect, ref valueRect, ref sourceRect, "Flexible Height", flexible > 0 ? ("enabled (" + flexible.ToString() + ")") : "disabled", source); + + if (!rect.GetComponent<LayoutElement>()) + { + Rect noteRect = new Rect(labelRect.x, labelRect.y + 10, r.width, EditorGUIUtility.singleLineHeight); + GUI.Label(noteRect, "Add a LayoutElement to override values.", m_Styles.labelStyle); + } + } + + private void ShowProp(ref Rect labelRect, ref Rect valueRect, ref Rect sourceRect, string label, string value, ILayoutElement source) + { + GUI.Label(labelRect, label, m_Styles.labelStyle); + GUI.Label(valueRect, value, m_Styles.labelStyle); + GUI.Label(sourceRect, source == null ? "none" : source.GetType().Name, m_Styles.labelStyle); + labelRect.y += EditorGUIUtility.singleLineHeight; + valueRect.y += EditorGUIUtility.singleLineHeight; + sourceRect.y += EditorGUIUtility.singleLineHeight; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs.meta b/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs.meta new file mode 100644 index 0000000..20eb908 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/LayoutPropertiesPreview.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f103303bf9c7f654492f77f00631a1be +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs b/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs new file mode 100644 index 0000000..8a1a486 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs @@ -0,0 +1,28 @@ +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Mask), true)] + [CanEditMultipleObjects] + public class MaskEditor : Editor + { + SerializedProperty m_ShowMaskGraphic; + + protected virtual void OnEnable() + { + m_ShowMaskGraphic = serializedObject.FindProperty("m_ShowMaskGraphic"); + } + + public override void OnInspectorGUI() + { + var graphic = (target as Mask).GetComponent<Graphic>(); + + if (graphic && !graphic.IsActive()) + EditorGUILayout.HelpBox("Masking disabled due to Graphic component being disabled.", MessageType.Warning); + + serializedObject.Update(); + EditorGUILayout.PropertyField(m_ShowMaskGraphic); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs.meta new file mode 100644 index 0000000..925cbdf --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/MaskEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 764bee73159c4d443a00c1c3788a3be9 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs b/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs new file mode 100644 index 0000000..94d0016 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs @@ -0,0 +1,282 @@ +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + /// <summary> + /// This script adds the UI menu options to the Unity Editor. + /// </summary> + + static internal class MenuOptions + { + private const string kUILayerName = "UI"; + + private const string kStandardSpritePath = "UI/Skin/UISprite.psd"; + private const string kBackgroundSpritePath = "UI/Skin/Background.psd"; + private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd"; + private const string kKnobPath = "UI/Skin/Knob.psd"; + private const string kCheckmarkPath = "UI/Skin/Checkmark.psd"; + private const string kDropdownArrowPath = "UI/Skin/DropdownArrow.psd"; + private const string kMaskPath = "UI/Skin/UIMask.psd"; + + static private DefaultControls.Resources s_StandardResources; + + static private DefaultControls.Resources GetStandardResources() + { + if (s_StandardResources.standard == null) + { + s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath); + s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpritePath); + s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>(kInputFieldBackgroundPath); + s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource<Sprite>(kKnobPath); + s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>(kCheckmarkPath); + s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>(kDropdownArrowPath); + s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource<Sprite>(kMaskPath); + } + return s_StandardResources; + } + + private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform) + { + // Find the best scene view + SceneView sceneView = SceneView.lastActiveSceneView; + if (sceneView == null && SceneView.sceneViews.Count > 0) + sceneView = SceneView.sceneViews[0] as SceneView; + + // Couldn't find a SceneView. Don't set position. + if (sceneView == null || sceneView.camera == null) + return; + + // Create world space Plane from canvas position. + Vector2 localPlanePosition; + Camera camera = sceneView.camera; + Vector3 position = Vector3.zero; + if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out localPlanePosition)) + { + // Adjust for canvas pivot + localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x; + localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y; + + localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x); + localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y); + + // Adjust for anchoring + position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x; + position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y; + + Vector3 minLocalPosition; + minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x; + minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y; + + Vector3 maxLocalPosition; + maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x; + maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y; + + position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x); + position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y); + } + + itemTransform.anchoredPosition = position; + itemTransform.localRotation = Quaternion.identity; + itemTransform.localScale = Vector3.one; + } + + private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand) + { + GameObject parent = menuCommand.context as GameObject; + if (parent == null || parent.GetComponentInParent<Canvas>() == null) + { + parent = GetOrCreateCanvasGameObject(); + } + + string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent.transform, element.name); + element.name = uniqueName; + Undo.RegisterCreatedObjectUndo(element, "Create " + element.name); + Undo.SetTransformParent(element.transform, parent.transform, "Parent " + element.name); + GameObjectUtility.SetParentAndAlign(element, parent); + if (parent != menuCommand.context) // not a context click, so center in sceneview + SetPositionVisibleinSceneView(parent.GetComponent<RectTransform>(), element.GetComponent<RectTransform>()); + + Selection.activeGameObject = element; + } + + // Graphic elements + + [MenuItem("GameObject/UI/Text", false, 2000)] + static public void AddText(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateText(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + [MenuItem("GameObject/UI/Image", false, 2001)] + static public void AddImage(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateImage(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + [MenuItem("GameObject/UI/Raw Image", false, 2002)] + static public void AddRawImage(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateRawImage(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + // Controls + + // Button and toggle are controls you just click on. + + [MenuItem("GameObject/UI/Button", false, 2030)] + static public void AddButton(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateButton(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + [MenuItem("GameObject/UI/Toggle", false, 2031)] + static public void AddToggle(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateToggle(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + // Slider and Scrollbar modify a number + + [MenuItem("GameObject/UI/Slider", false, 2033)] + static public void AddSlider(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateSlider(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + [MenuItem("GameObject/UI/Scrollbar", false, 2034)] + static public void AddScrollbar(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateScrollbar(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + // More advanced controls below + + [MenuItem("GameObject/UI/Dropdown", false, 2035)] + static public void AddDropdown(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateDropdown(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + [MenuItem("GameObject/UI/Input Field", false, 2036)] + public static void AddInputField(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateInputField(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + // Containers + + [MenuItem("GameObject/UI/Canvas", false, 2060)] + static public void AddCanvas(MenuCommand menuCommand) + { + var go = CreateNewUI(); + GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject); + if (go.transform.parent as RectTransform) + { + RectTransform rect = go.transform as RectTransform; + rect.anchorMin = Vector2.zero; + rect.anchorMax = Vector2.one; + rect.anchoredPosition = Vector2.zero; + rect.sizeDelta = Vector2.zero; + } + Selection.activeGameObject = go; + } + + [MenuItem("GameObject/UI/Panel", false, 2061)] + static public void AddPanel(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreatePanel(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + + // Panel is special, we need to ensure there's no padding after repositioning. + RectTransform rect = go.GetComponent<RectTransform>(); + rect.anchoredPosition = Vector2.zero; + rect.sizeDelta = Vector2.zero; + } + + [MenuItem("GameObject/UI/Scroll View", false, 2062)] + static public void AddScrollView(MenuCommand menuCommand) + { + GameObject go = DefaultControls.CreateScrollView(GetStandardResources()); + PlaceUIElementRoot(go, menuCommand); + } + + // Helper methods + + static public GameObject CreateNewUI() + { + // Root for the UI + var root = new GameObject("Canvas"); + root.layer = LayerMask.NameToLayer(kUILayerName); + Canvas canvas = root.AddComponent<Canvas>(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + root.AddComponent<CanvasScaler>(); + root.AddComponent<GraphicRaycaster>(); + Undo.RegisterCreatedObjectUndo(root, "Create " + root.name); + + // if there is no event system add one... + CreateEventSystem(false); + return root; + } + + [MenuItem("GameObject/UI/Event System", false, 2100)] + public static void CreateEventSystem(MenuCommand menuCommand) + { + GameObject parent = menuCommand.context as GameObject; + CreateEventSystem(true, parent); + } + + private static void CreateEventSystem(bool select) + { + CreateEventSystem(select, null); + } + + private static void CreateEventSystem(bool select, GameObject parent) + { + var esys = Object.FindObjectOfType<EventSystem>(); + if (esys == null) + { + var eventSystem = new GameObject("EventSystem"); + GameObjectUtility.SetParentAndAlign(eventSystem, parent); + esys = eventSystem.AddComponent<EventSystem>(); + eventSystem.AddComponent<StandaloneInputModule>(); + + Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name); + } + + if (select && esys != null) + { + Selection.activeGameObject = esys.gameObject; + } + } + + // Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas. + static public GameObject GetOrCreateCanvasGameObject() + { + GameObject selectedGo = Selection.activeGameObject; + + // Try to find a gameobject that is the selected GO or one if its parents. + Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null; + if (canvas != null && canvas.gameObject.activeInHierarchy) + return canvas.gameObject; + + // No canvas in selection or its parents? Then use just any canvas.. + canvas = Object.FindObjectOfType(typeof(Canvas)) as Canvas; + if (canvas != null && canvas.gameObject.activeInHierarchy) + return canvas.gameObject; + + // No canvas in the scene at all? Then create a new one. + return MenuOptions.CreateNewUI(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs.meta b/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs.meta new file mode 100644 index 0000000..17aac1f --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/MenuOptions.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a30d9ac75138f9e45811070c267b929d +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs b/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs new file mode 100644 index 0000000..0f933da --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs @@ -0,0 +1,24 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [InitializeOnLoad] + internal class PrefabLayoutRebuilder + { + static PrefabLayoutRebuilder() + { + PrefabUtility.prefabInstanceUpdated += OnPrefabInstanceUpdates; + } + + static void OnPrefabInstanceUpdates(GameObject instance) + { + if (instance) + { + RectTransform rect = instance.transform as RectTransform; + if (rect) + LayoutRebuilder.MarkLayoutForRebuild(rect); + } + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs.meta new file mode 100644 index 0000000..435b8d5 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PrefabLayoutRebuilder.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 258eff23cc7cc4a4888c4570caabda7c +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers.meta new file mode 100644 index 0000000..5514f30 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f6033d0a1e14b0f4f81e73060756cf38 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs new file mode 100644 index 0000000..67cab2e --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs @@ -0,0 +1,33 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(AnimationTriggers), true)] + public class AnimationTriggersDrawer : PropertyDrawer + { + public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label) + { + Rect drawRect = rect; + drawRect.height = EditorGUIUtility.singleLineHeight; + + SerializedProperty normalTrigger = prop.FindPropertyRelative("m_NormalTrigger"); + SerializedProperty higlightedTrigger = prop.FindPropertyRelative("m_HighlightedTrigger"); + SerializedProperty pressedTrigger = prop.FindPropertyRelative("m_PressedTrigger"); + SerializedProperty disabledTrigger = prop.FindPropertyRelative("m_DisabledTrigger"); + + EditorGUI.PropertyField(drawRect, normalTrigger); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, higlightedTrigger); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, pressedTrigger); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, disabledTrigger); + } + + public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) + { + return 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs.meta new file mode 100644 index 0000000..f9df6cc --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/AnimationTriggersDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c7e8a036dae779446aa880079e2fcd93 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs new file mode 100644 index 0000000..a471eeb --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs @@ -0,0 +1,39 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(ColorBlock), true)] + public class ColorBlockDrawer : PropertyDrawer + { + public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label) + { + Rect drawRect = rect; + drawRect.height = EditorGUIUtility.singleLineHeight; + + SerializedProperty normalColor = prop.FindPropertyRelative("m_NormalColor"); + SerializedProperty highlighted = prop.FindPropertyRelative("m_HighlightedColor"); + SerializedProperty pressedColor = prop.FindPropertyRelative("m_PressedColor"); + SerializedProperty disabledColor = prop.FindPropertyRelative("m_DisabledColor"); + SerializedProperty colorMultiplier = prop.FindPropertyRelative("m_ColorMultiplier"); + SerializedProperty fadeDuration = prop.FindPropertyRelative("m_FadeDuration"); + + EditorGUI.PropertyField(drawRect, normalColor); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, highlighted); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, pressedColor); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, disabledColor); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, colorMultiplier); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, fadeDuration); + } + + public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) + { + return 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs.meta new file mode 100644 index 0000000..a7ac278 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/ColorBlockDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 94cd9d005e865c94faaef6f8213faecd +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs new file mode 100644 index 0000000..662016c --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs @@ -0,0 +1,59 @@ +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(Dropdown.OptionDataList), true)] + class DropdownOptionListDrawer : PropertyDrawer + { + private ReorderableList m_ReorderableList; + + private void Init(SerializedProperty property) + { + if (m_ReorderableList != null) + return; + + SerializedProperty array = property.FindPropertyRelative("m_Options"); + + m_ReorderableList = new ReorderableList(property.serializedObject, array); + m_ReorderableList.drawElementCallback = DrawOptionData; + m_ReorderableList.drawHeaderCallback = DrawHeader; + m_ReorderableList.elementHeight += 16; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + Init(property); + + m_ReorderableList.DoList(position); + } + + private void DrawHeader(Rect rect) + { + GUI.Label(rect, "Options"); + } + + private void DrawOptionData(Rect rect, int index, bool isActive, bool isFocused) + { + SerializedProperty itemData = m_ReorderableList.serializedProperty.GetArrayElementAtIndex(index); + SerializedProperty itemText = itemData.FindPropertyRelative("m_Text"); + SerializedProperty itemImage = itemData.FindPropertyRelative("m_Image"); + + RectOffset offset = new RectOffset(0, 0, -1, -3); + rect = offset.Add(rect); + rect.height = EditorGUIUtility.singleLineHeight; + + EditorGUI.PropertyField(rect, itemText, GUIContent.none); + rect.y += EditorGUIUtility.singleLineHeight; + EditorGUI.PropertyField(rect, itemImage, GUIContent.none); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + Init(property); + + return m_ReorderableList.GetHeight(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs.meta new file mode 100644 index 0000000..21f09c2 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/DropdownOptionListDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 0b0e171e6b1b1d943b7da016b41a7f88 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs new file mode 100644 index 0000000..5db2387 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs @@ -0,0 +1,512 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(FontData), true)] + public class FontDataDrawer : PropertyDrawer + { + static private class Styles + { + public static GUIStyle alignmentButtonLeft = new GUIStyle(EditorStyles.miniButtonLeft); + public static GUIStyle alignmentButtonMid = new GUIStyle(EditorStyles.miniButtonMid); + public static GUIStyle alignmentButtonRight = new GUIStyle(EditorStyles.miniButtonRight); + + public static GUIContent m_EncodingContent; + + public static GUIContent m_LeftAlignText; + public static GUIContent m_CenterAlignText; + public static GUIContent m_RightAlignText; + public static GUIContent m_TopAlignText; + public static GUIContent m_MiddleAlignText; + public static GUIContent m_BottomAlignText; + + public static GUIContent m_LeftAlignTextActive; + public static GUIContent m_CenterAlignTextActive; + public static GUIContent m_RightAlignTextActive; + public static GUIContent m_TopAlignTextActive; + public static GUIContent m_MiddleAlignTextActive; + public static GUIContent m_BottomAlignTextActive; + + static Styles() + { + m_EncodingContent = new GUIContent("Rich Text", "Use emoticons and colors"); + + // Horizontal Alignment Icons + m_LeftAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_left", "Left Align"); + m_CenterAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_center", "Center Align"); + m_RightAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_right", "Right Align"); + m_LeftAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_left_active", "Left Align"); + m_CenterAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_center_active", "Center Align"); + m_RightAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_horizontally_right_active", "Right Align"); + + // Vertical Alignment Icons + m_TopAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_top", "Top Align"); + m_MiddleAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_center", "Middle Align"); + m_BottomAlignText = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_bottom", "Bottom Align"); + m_TopAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_top_active", "Top Align"); + m_MiddleAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_center_active", "Middle Align"); + m_BottomAlignTextActive = EditorGUIUtility.IconContent(@"GUISystem/align_vertically_bottom_active", "Bottom Align"); + + FixAlignmentButtonStyles(alignmentButtonLeft, alignmentButtonMid, alignmentButtonRight); + } + + static void FixAlignmentButtonStyles(params GUIStyle[] styles) + { + foreach (GUIStyle style in styles) + { + style.padding.left = 2; + style.padding.right = 2; + } + } + } + + private enum VerticalTextAligment + { + Top, + Middle, + Bottom + } + + private enum HorizontalTextAligment + { + Left, + Center, + Right + } + + private const int kAlignmentButtonWidth = 20; + + static int s_TextAlignmentHash = "DoTextAligmentControl".GetHashCode(); + + private SerializedProperty m_SupportEncoding; + private SerializedProperty m_Font; + private SerializedProperty m_FontSize; + private SerializedProperty m_LineSpacing; + private SerializedProperty m_FontStyle; + private SerializedProperty m_ResizeTextForBestFit; + private SerializedProperty m_ResizeTextMinSize; + private SerializedProperty m_ResizeTextMaxSize; + private SerializedProperty m_HorizontalOverflow; + private SerializedProperty m_VerticalOverflow; + private SerializedProperty m_Alignment; + private SerializedProperty m_AlignByGeometry; + + private float m_FontFieldfHeight = 0f; + private float m_FontStyleHeight = 0f; + private float m_FontSizeHeight = 0f; + private float m_LineSpacingHeight = 0f; + private float m_EncodingHeight = 0f; + private float m_ResizeTextForBestFitHeight = 0f; + private float m_ResizeTextMinSizeHeight = 0f; + private float m_ResizeTextMaxSizeHeight = 0f; + private float m_HorizontalOverflowHeight = 0f; + private float m_VerticalOverflowHeight = 0f; + private float m_AlignByGeometryHeight = 0f; + + protected void Init(SerializedProperty property) + { + m_SupportEncoding = property.FindPropertyRelative("m_RichText"); + m_Font = property.FindPropertyRelative("m_Font"); + m_FontSize = property.FindPropertyRelative("m_FontSize"); + m_LineSpacing = property.FindPropertyRelative("m_LineSpacing"); + m_FontStyle = property.FindPropertyRelative("m_FontStyle"); + m_ResizeTextForBestFit = property.FindPropertyRelative("m_BestFit"); + m_ResizeTextMinSize = property.FindPropertyRelative("m_MinSize"); + m_ResizeTextMaxSize = property.FindPropertyRelative("m_MaxSize"); + m_HorizontalOverflow = property.FindPropertyRelative("m_HorizontalOverflow"); + m_VerticalOverflow = property.FindPropertyRelative("m_VerticalOverflow"); + m_Alignment = property.FindPropertyRelative("m_Alignment"); + m_AlignByGeometry = property.FindPropertyRelative("m_AlignByGeometry"); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + Init(property); + m_FontFieldfHeight = EditorGUI.GetPropertyHeight(m_Font); + m_FontStyleHeight = EditorGUI.GetPropertyHeight(m_FontStyle); + m_FontSizeHeight = EditorGUI.GetPropertyHeight(m_FontSize); + m_LineSpacingHeight = EditorGUI.GetPropertyHeight(m_LineSpacing); + m_EncodingHeight = EditorGUI.GetPropertyHeight(m_SupportEncoding); + m_ResizeTextForBestFitHeight = EditorGUI.GetPropertyHeight(m_ResizeTextForBestFit); + m_ResizeTextMinSizeHeight = EditorGUI.GetPropertyHeight(m_ResizeTextMinSize); + m_ResizeTextMaxSizeHeight = EditorGUI.GetPropertyHeight(m_ResizeTextMaxSize); + m_HorizontalOverflowHeight = EditorGUI.GetPropertyHeight(m_HorizontalOverflow); + m_VerticalOverflowHeight = EditorGUI.GetPropertyHeight(m_VerticalOverflow); + m_AlignByGeometryHeight = EditorGUI.GetPropertyHeight(m_AlignByGeometry); + + var height = m_FontFieldfHeight + + m_FontStyleHeight + + m_FontSizeHeight + + m_LineSpacingHeight + + m_EncodingHeight + + m_ResizeTextForBestFitHeight + + m_HorizontalOverflowHeight + + m_VerticalOverflowHeight + + EditorGUIUtility.singleLineHeight * 3 + + EditorGUIUtility.standardVerticalSpacing * 10 + + m_AlignByGeometryHeight; + + if (m_ResizeTextForBestFit.boolValue) + { + height += m_ResizeTextMinSizeHeight + + m_ResizeTextMaxSizeHeight + + EditorGUIUtility.standardVerticalSpacing * 2; + } + return height; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + Init(property); + + Rect rect = position; + rect.height = EditorGUIUtility.singleLineHeight; + + EditorGUI.LabelField(rect, "Character", EditorStyles.boldLabel); + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + ++EditorGUI.indentLevel; + { + Font font = m_Font.objectReferenceValue as Font; + rect.height = m_FontFieldfHeight; + EditorGUI.BeginChangeCheck(); + EditorGUI.PropertyField(rect, m_Font); + if (EditorGUI.EndChangeCheck()) + { + font = m_Font.objectReferenceValue as Font; + if (font != null && !font.dynamic) + m_FontSize.intValue = font.fontSize; + } + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_FontStyleHeight; + using (new EditorGUI.DisabledScope(!m_Font.hasMultipleDifferentValues && font != null && !font.dynamic)) + { + EditorGUI.PropertyField(rect, m_FontStyle); + } + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_FontSizeHeight; + EditorGUI.PropertyField(rect, m_FontSize); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_LineSpacingHeight; + EditorGUI.PropertyField(rect, m_LineSpacing); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_EncodingHeight; + EditorGUI.PropertyField(rect, m_SupportEncoding, Styles.m_EncodingContent); + } + --EditorGUI.indentLevel; + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = EditorGUIUtility.singleLineHeight; + EditorGUI.LabelField(rect, "Paragraph", EditorStyles.boldLabel); + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + ++EditorGUI.indentLevel; + { + rect.height = EditorGUIUtility.singleLineHeight; + DoTextAligmentControl(rect, m_Alignment); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_HorizontalOverflowHeight; + EditorGUI.PropertyField(rect, m_AlignByGeometry); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_HorizontalOverflowHeight; + EditorGUI.PropertyField(rect, m_HorizontalOverflow); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_VerticalOverflowHeight; + EditorGUI.PropertyField(rect, m_VerticalOverflow); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_ResizeTextMaxSizeHeight; + EditorGUI.PropertyField(rect, m_ResizeTextForBestFit); + + if (m_ResizeTextForBestFit.boolValue) + { + EditorGUILayout.EndFadeGroup(); + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_ResizeTextMinSizeHeight; + EditorGUI.PropertyField(rect, m_ResizeTextMinSize); + + rect.y += rect.height + EditorGUIUtility.standardVerticalSpacing; + rect.height = m_ResizeTextMaxSizeHeight; + EditorGUI.PropertyField(rect, m_ResizeTextMaxSize); + } + } + --EditorGUI.indentLevel; + } + + private void DoTextAligmentControl(Rect position, SerializedProperty alignment) + { + GUIContent alingmentContent = new GUIContent("Alignment"); + + int id = EditorGUIUtility.GetControlID(s_TextAlignmentHash, FocusType.Keyboard, position); + + EditorGUIUtility.SetIconSize(new Vector2(15, 15)); + EditorGUI.BeginProperty(position, alingmentContent, alignment); + { + Rect controlArea = EditorGUI.PrefixLabel(position, id, alingmentContent); + + float width = kAlignmentButtonWidth * 3; + float spacing = Mathf.Clamp(controlArea.width - width * 2, 2, 10); + + Rect horizontalAligment = new Rect(controlArea.x, controlArea.y, width, controlArea.height); + Rect verticalAligment = new Rect(horizontalAligment.xMax + spacing, controlArea.y, width, controlArea.height); + + DoHorizontalAligmentControl(horizontalAligment, alignment); + DoVerticalAligmentControl(verticalAligment, alignment); + } + EditorGUI.EndProperty(); + EditorGUIUtility.SetIconSize(Vector2.zero); + } + + private static void DoHorizontalAligmentControl(Rect position, SerializedProperty alignment) + { + TextAnchor ta = (TextAnchor)alignment.intValue; + HorizontalTextAligment horizontalAlignment = GetHorizontalAlignment(ta); + + bool leftAlign = (horizontalAlignment == HorizontalTextAligment.Left); + bool centerAlign = (horizontalAlignment == HorizontalTextAligment.Center); + bool rightAlign = (horizontalAlignment == HorizontalTextAligment.Right); + + if (alignment.hasMultipleDifferentValues) + { + foreach (var obj in alignment.serializedObject.targetObjects) + { + Text text = obj as Text; + horizontalAlignment = GetHorizontalAlignment(text.alignment); + leftAlign = leftAlign || (horizontalAlignment == HorizontalTextAligment.Left); + centerAlign = centerAlign || (horizontalAlignment == HorizontalTextAligment.Center); + rightAlign = rightAlign || (horizontalAlignment == HorizontalTextAligment.Right); + } + } + + position.width = kAlignmentButtonWidth; + + EditorGUI.BeginChangeCheck(); + EditorToggle(position, leftAlign, leftAlign ? Styles.m_LeftAlignTextActive : Styles.m_LeftAlignText, Styles.alignmentButtonLeft); + if (EditorGUI.EndChangeCheck()) + { + SetHorizontalAlignment(alignment, HorizontalTextAligment.Left); + } + + position.x += position.width; + EditorGUI.BeginChangeCheck(); + EditorToggle(position, centerAlign, centerAlign ? Styles.m_CenterAlignTextActive : Styles.m_CenterAlignText, Styles.alignmentButtonMid); + if (EditorGUI.EndChangeCheck()) + { + SetHorizontalAlignment(alignment, HorizontalTextAligment.Center); + } + + position.x += position.width; + EditorGUI.BeginChangeCheck(); + EditorToggle(position, rightAlign, rightAlign ? Styles.m_RightAlignTextActive : Styles.m_RightAlignText, Styles.alignmentButtonRight); + if (EditorGUI.EndChangeCheck()) + { + SetHorizontalAlignment(alignment, HorizontalTextAligment.Right); + } + } + + private static void DoVerticalAligmentControl(Rect position, SerializedProperty alignment) + { + TextAnchor ta = (TextAnchor)alignment.intValue; + VerticalTextAligment verticalTextAligment = GetVerticalAlignment(ta); + + bool topAlign = (verticalTextAligment == VerticalTextAligment.Top); + bool middleAlign = (verticalTextAligment == VerticalTextAligment.Middle); + bool bottomAlign = (verticalTextAligment == VerticalTextAligment.Bottom); + + if (alignment.hasMultipleDifferentValues) + { + foreach (var obj in alignment.serializedObject.targetObjects) + { + Text text = obj as Text; + TextAnchor textAlignment = text.alignment; + verticalTextAligment = GetVerticalAlignment(textAlignment); + topAlign = topAlign || (verticalTextAligment == VerticalTextAligment.Top); + middleAlign = middleAlign || (verticalTextAligment == VerticalTextAligment.Middle); + bottomAlign = bottomAlign || (verticalTextAligment == VerticalTextAligment.Bottom); + } + } + + + position.width = kAlignmentButtonWidth; + + // position.x += position.width; + EditorGUI.BeginChangeCheck(); + EditorToggle(position, topAlign, topAlign ? Styles.m_TopAlignTextActive : Styles.m_TopAlignText, Styles.alignmentButtonLeft); + if (EditorGUI.EndChangeCheck()) + { + SetVerticalAlignment(alignment, VerticalTextAligment.Top); + } + + position.x += position.width; + EditorGUI.BeginChangeCheck(); + EditorToggle(position, middleAlign, middleAlign ? Styles.m_MiddleAlignTextActive : Styles.m_MiddleAlignText, Styles.alignmentButtonMid); + if (EditorGUI.EndChangeCheck()) + { + SetVerticalAlignment(alignment, VerticalTextAligment.Middle); + } + + position.x += position.width; + EditorGUI.BeginChangeCheck(); + EditorToggle(position, bottomAlign, bottomAlign ? Styles.m_BottomAlignTextActive : Styles.m_BottomAlignText, Styles.alignmentButtonRight); + if (EditorGUI.EndChangeCheck()) + { + SetVerticalAlignment(alignment, VerticalTextAligment.Bottom); + } + } + + private static bool EditorToggle(Rect position, bool value, GUIContent content, GUIStyle style) + { + int hashCode = "AlignToggle".GetHashCode(); + int id = EditorGUIUtility.GetControlID(hashCode, FocusType.Keyboard, position); + Event evt = Event.current; + + // Toggle selected toggle on space or return key + if (EditorGUIUtility.keyboardControl == id && evt.type == EventType.KeyDown && (evt.keyCode == KeyCode.Space || evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)) + { + value = !value; + evt.Use(); + GUI.changed = true; + } + + if (evt.type == EventType.KeyDown && Event.current.button == 0 && position.Contains(Event.current.mousePosition)) + { + GUIUtility.keyboardControl = id; + EditorGUIUtility.editingTextField = false; + HandleUtility.Repaint(); + } + + bool returnValue = GUI.Toggle(position, id, value, content, style); + + return returnValue; + } + + private static HorizontalTextAligment GetHorizontalAlignment(TextAnchor ta) + { + switch (ta) + { + case TextAnchor.MiddleCenter: + case TextAnchor.UpperCenter: + case TextAnchor.LowerCenter: + return HorizontalTextAligment.Center; + + case TextAnchor.UpperRight: + case TextAnchor.MiddleRight: + case TextAnchor.LowerRight: + return HorizontalTextAligment.Right; + + case TextAnchor.UpperLeft: + case TextAnchor.MiddleLeft: + case TextAnchor.LowerLeft: + return HorizontalTextAligment.Left; + } + + return HorizontalTextAligment.Left; + } + + private static VerticalTextAligment GetVerticalAlignment(TextAnchor ta) + { + switch (ta) + { + case TextAnchor.UpperLeft: + case TextAnchor.UpperCenter: + case TextAnchor.UpperRight: + return VerticalTextAligment.Top; + + case TextAnchor.MiddleLeft: + case TextAnchor.MiddleCenter: + case TextAnchor.MiddleRight: + return VerticalTextAligment.Middle; + + case TextAnchor.LowerLeft: + case TextAnchor.LowerCenter: + case TextAnchor.LowerRight: + return VerticalTextAligment.Bottom; + } + + return VerticalTextAligment.Top; + } + + // We can't go through serialized properties here since we're showing two controls for a single SerializzedProperty. + private static void SetHorizontalAlignment(SerializedProperty alignment, HorizontalTextAligment horizontalAlignment) + { + foreach (var obj in alignment.serializedObject.targetObjects) + { + Text text = obj as Text; + VerticalTextAligment currentVerticalAligment = GetVerticalAlignment(text.alignment); + Undo.RecordObject(text, "Horizontal Alignment"); + text.alignment = GetAnchor(currentVerticalAligment, horizontalAlignment); + EditorUtility.SetDirty(obj); + } + } + + private static void SetVerticalAlignment(SerializedProperty alignment, VerticalTextAligment verticalAlignment) + { + foreach (var obj in alignment.serializedObject.targetObjects) + { + Text text = obj as Text; + HorizontalTextAligment currentHorizontalAligment = GetHorizontalAlignment(text.alignment); + Undo.RecordObject(text, "Vertical Alignment"); + text.alignment = GetAnchor(verticalAlignment, currentHorizontalAligment); + EditorUtility.SetDirty(obj); + } + } + + private static TextAnchor GetAnchor(VerticalTextAligment verticalTextAligment, HorizontalTextAligment horizontalTextAligment) + { + TextAnchor ac = TextAnchor.UpperLeft; + + switch (horizontalTextAligment) + { + case HorizontalTextAligment.Left: + switch (verticalTextAligment) + { + case VerticalTextAligment.Bottom: + ac = TextAnchor.LowerLeft; + break; + case VerticalTextAligment.Middle: + ac = TextAnchor.MiddleLeft; + break; + default: + ac = TextAnchor.UpperLeft; + break; + } + break; + case HorizontalTextAligment.Center: + switch (verticalTextAligment) + { + case VerticalTextAligment.Bottom: + ac = TextAnchor.LowerCenter; + break; + case VerticalTextAligment.Middle: + ac = TextAnchor.MiddleCenter; + break; + default: + ac = TextAnchor.UpperCenter; + break; + } + break; + default: + switch (verticalTextAligment) + { + case VerticalTextAligment.Bottom: + ac = TextAnchor.LowerRight; + break; + case VerticalTextAligment.Middle: + ac = TextAnchor.MiddleRight; + break; + default: + ac = TextAnchor.UpperRight; + break; + } + break; + } + return ac; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs.meta new file mode 100644 index 0000000..01a9f7b --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/FontDataDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9a502f8fd08923f4a804fcbbc63bab90 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs new file mode 100644 index 0000000..2cfc4d3 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs @@ -0,0 +1,83 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(Navigation), true)] + public class NavigationDrawer : PropertyDrawer + { + private class Styles + { + readonly public GUIContent navigationContent; + + public Styles() + { + navigationContent = new GUIContent("Navigation"); + } + } + + private static Styles s_Styles = null; + + public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) + { + if (s_Styles == null) + s_Styles = new Styles(); + + Rect drawRect = pos; + drawRect.height = EditorGUIUtility.singleLineHeight; + + SerializedProperty navigation = prop.FindPropertyRelative("m_Mode"); + Navigation.Mode navMode = GetNavigationMode(navigation); + + EditorGUI.PropertyField(drawRect, navigation, s_Styles.navigationContent); + + ++EditorGUI.indentLevel; + + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + switch (navMode) + { + case Navigation.Mode.Explicit: + { + SerializedProperty selectOnUp = prop.FindPropertyRelative("m_SelectOnUp"); + SerializedProperty selectOnDown = prop.FindPropertyRelative("m_SelectOnDown"); + SerializedProperty selectOnLeft = prop.FindPropertyRelative("m_SelectOnLeft"); + SerializedProperty selectOnRight = prop.FindPropertyRelative("m_SelectOnRight"); + + EditorGUI.PropertyField(drawRect, selectOnUp); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, selectOnDown); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, selectOnLeft); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, selectOnRight); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + } + break; + } + + --EditorGUI.indentLevel; + } + + static Navigation.Mode GetNavigationMode(SerializedProperty navigation) + { + return (Navigation.Mode)navigation.enumValueIndex; + } + + public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) + { + SerializedProperty navigation = prop.FindPropertyRelative("m_Mode"); + if (navigation == null) + return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + + Navigation.Mode navMode = GetNavigationMode(navigation); + + switch (navMode) + { + case Navigation.Mode.None: return EditorGUIUtility.singleLineHeight; + case Navigation.Mode.Explicit: return 5 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing; + default: return EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing; + } + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs.meta new file mode 100644 index 0000000..6eb8468 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/NavigationDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9fc1ecf033776204b9a224661a28dcfd +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs new file mode 100644 index 0000000..510db1a --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomPropertyDrawer(typeof(SpriteState), true)] + public class SpriteStateDrawer : PropertyDrawer + { + public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label) + { + Rect drawRect = rect; + drawRect.height = EditorGUIUtility.singleLineHeight; + SerializedProperty highlightedSprite = prop.FindPropertyRelative("m_HighlightedSprite"); + SerializedProperty pressedSprite = prop.FindPropertyRelative("m_PressedSprite"); + SerializedProperty disabledSprite = prop.FindPropertyRelative("m_DisabledSprite"); + + EditorGUI.PropertyField(drawRect, highlightedSprite); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, pressedSprite); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + EditorGUI.PropertyField(drawRect, disabledSprite); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + } + + public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) + { + return 3 * EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs.meta b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs.meta new file mode 100644 index 0000000..cbcad61 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/PropertyDrawers/SpriteStateDrawer.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: cc8f8e0433b0dff4289da30bc91c831d +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs b/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs new file mode 100644 index 0000000..36e43b1 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs @@ -0,0 +1,107 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + /// <summary> + /// Editor class used to edit UI Images. + /// </summary> + [CustomEditor(typeof(RawImage), true)] + [CanEditMultipleObjects] + public class RawImageEditor : GraphicEditor + { + SerializedProperty m_Texture; + SerializedProperty m_UVRect; + GUIContent m_UVRectContent; + + protected override void OnEnable() + { + base.OnEnable(); + + // Note we have precedence for calling rectangle for just rect, even in the Inspector. + // For example in the Camera component's Viewport Rect. + // Hence sticking with Rect here to be consistent with corresponding property in the API. + m_UVRectContent = new GUIContent("UV Rect"); + + m_Texture = serializedObject.FindProperty("m_Texture"); + m_UVRect = serializedObject.FindProperty("m_UVRect"); + + SetShowNativeSize(true); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_Texture); + AppearanceControlsGUI(); + RaycastControlsGUI(); + EditorGUILayout.PropertyField(m_UVRect, m_UVRectContent); + SetShowNativeSize(false); + NativeSizeButtonGUI(); + + serializedObject.ApplyModifiedProperties(); + } + + void SetShowNativeSize(bool instant) + { + base.SetShowNativeSize(m_Texture.objectReferenceValue != null, instant); + } + + private static Rect Outer(RawImage rawImage) + { + Rect outer = rawImage.uvRect; + outer.xMin *= rawImage.rectTransform.rect.width; + outer.xMax *= rawImage.rectTransform.rect.width; + outer.yMin *= rawImage.rectTransform.rect.height; + outer.yMax *= rawImage.rectTransform.rect.height; + return outer; + } + + /// <summary> + /// Allow the texture to be previewed. + /// </summary> + + public override bool HasPreviewGUI() + { + RawImage rawImage = target as RawImage; + if (rawImage == null) + return false; + + var outer = Outer(rawImage); + return outer.width > 0 && outer.height > 0; + } + + /// <summary> + /// Draw the Image preview. + /// </summary> + + public override void OnPreviewGUI(Rect rect, GUIStyle background) + { + RawImage rawImage = target as RawImage; + Texture tex = rawImage.mainTexture; + + if (tex == null) + return; + + var outer = Outer(rawImage); + SpriteDrawUtility.DrawSprite(tex, rect, outer, rawImage.uvRect, rawImage.canvasRenderer.GetColor()); + } + + /// <summary> + /// Info String drawn at the bottom of the Preview + /// </summary> + + public override string GetInfoString() + { + RawImage rawImage = target as RawImage; + + // Image size Text + string text = string.Format("RawImage Size: {0}x{1}", + Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.width)), + Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.height))); + + return text; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs.meta new file mode 100644 index 0000000..c5b427a --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/RawImageEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 735e178f724133c42b4eeb469dd13867 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs b/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs new file mode 100644 index 0000000..cad5773 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs @@ -0,0 +1,13 @@ +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(RectMask2D), true)] + [CanEditMultipleObjects] + public class RectMask2DEditor : Editor + { + public override void OnInspectorGUI() + { + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs.meta new file mode 100644 index 0000000..02621a3 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/RectMask2DEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a2e0aadc108e8f342a529c3ff8e70470 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs new file mode 100644 index 0000000..56e7d64 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs @@ -0,0 +1,172 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEditor.AnimatedValues; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(ScrollRect), true)] + [CanEditMultipleObjects] + public class ScrollRectEditor : Editor + { + SerializedProperty m_Content; + SerializedProperty m_Horizontal; + SerializedProperty m_Vertical; + SerializedProperty m_MovementType; + SerializedProperty m_Elasticity; + SerializedProperty m_Inertia; + SerializedProperty m_DecelerationRate; + SerializedProperty m_ScrollSensitivity; + SerializedProperty m_Viewport; + SerializedProperty m_HorizontalScrollbar; + SerializedProperty m_VerticalScrollbar; + SerializedProperty m_HorizontalScrollbarVisibility; + SerializedProperty m_VerticalScrollbarVisibility; + SerializedProperty m_HorizontalScrollbarSpacing; + SerializedProperty m_VerticalScrollbarSpacing; + SerializedProperty m_OnValueChanged; + AnimBool m_ShowElasticity; + AnimBool m_ShowDecelerationRate; + bool m_ViewportIsNotChild, m_HScrollbarIsNotChild, m_VScrollbarIsNotChild; + static string s_HError = "For this visibility mode, the Viewport property and the Horizontal Scrollbar property both needs to be set to a Rect Transform that is a child to the Scroll Rect."; + static string s_VError = "For this visibility mode, the Viewport property and the Vertical Scrollbar property both needs to be set to a Rect Transform that is a child to the Scroll Rect."; + + protected virtual void OnEnable() + { + m_Content = serializedObject.FindProperty("m_Content"); + m_Horizontal = serializedObject.FindProperty("m_Horizontal"); + m_Vertical = serializedObject.FindProperty("m_Vertical"); + m_MovementType = serializedObject.FindProperty("m_MovementType"); + m_Elasticity = serializedObject.FindProperty("m_Elasticity"); + m_Inertia = serializedObject.FindProperty("m_Inertia"); + m_DecelerationRate = serializedObject.FindProperty("m_DecelerationRate"); + m_ScrollSensitivity = serializedObject.FindProperty("m_ScrollSensitivity"); + m_Viewport = serializedObject.FindProperty("m_Viewport"); + m_HorizontalScrollbar = serializedObject.FindProperty("m_HorizontalScrollbar"); + m_VerticalScrollbar = serializedObject.FindProperty("m_VerticalScrollbar"); + m_HorizontalScrollbarVisibility = serializedObject.FindProperty("m_HorizontalScrollbarVisibility"); + m_VerticalScrollbarVisibility = serializedObject.FindProperty("m_VerticalScrollbarVisibility"); + m_HorizontalScrollbarSpacing = serializedObject.FindProperty("m_HorizontalScrollbarSpacing"); + m_VerticalScrollbarSpacing = serializedObject.FindProperty("m_VerticalScrollbarSpacing"); + m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); + + m_ShowElasticity = new AnimBool(Repaint); + m_ShowDecelerationRate = new AnimBool(Repaint); + SetAnimBools(true); + } + + protected virtual void OnDisable() + { + m_ShowElasticity.valueChanged.RemoveListener(Repaint); + m_ShowDecelerationRate.valueChanged.RemoveListener(Repaint); + } + + void SetAnimBools(bool instant) + { + SetAnimBool(m_ShowElasticity, !m_MovementType.hasMultipleDifferentValues && m_MovementType.enumValueIndex == (int)ScrollRect.MovementType.Elastic, instant); + SetAnimBool(m_ShowDecelerationRate, !m_Inertia.hasMultipleDifferentValues && m_Inertia.boolValue == true, instant); + } + + void SetAnimBool(AnimBool a, bool value, bool instant) + { + if (instant) + a.value = value; + else + a.target = value; + } + + void CalculateCachedValues() + { + m_ViewportIsNotChild = false; + m_HScrollbarIsNotChild = false; + m_VScrollbarIsNotChild = false; + if (targets.Length == 1) + { + Transform transform = ((ScrollRect)target).transform; + if (m_Viewport.objectReferenceValue == null || ((RectTransform)m_Viewport.objectReferenceValue).transform.parent != transform) + m_ViewportIsNotChild = true; + if (m_HorizontalScrollbar.objectReferenceValue == null || ((Scrollbar)m_HorizontalScrollbar.objectReferenceValue).transform.parent != transform) + m_HScrollbarIsNotChild = true; + if (m_VerticalScrollbar.objectReferenceValue == null || ((Scrollbar)m_VerticalScrollbar.objectReferenceValue).transform.parent != transform) + m_VScrollbarIsNotChild = true; + } + } + + public override void OnInspectorGUI() + { + SetAnimBools(false); + + serializedObject.Update(); + // Once we have a reliable way to know if the object changed, only re-cache in that case. + CalculateCachedValues(); + + EditorGUILayout.PropertyField(m_Content); + + EditorGUILayout.PropertyField(m_Horizontal); + EditorGUILayout.PropertyField(m_Vertical); + + EditorGUILayout.PropertyField(m_MovementType); + if (EditorGUILayout.BeginFadeGroup(m_ShowElasticity.faded)) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_Elasticity); + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFadeGroup(); + + EditorGUILayout.PropertyField(m_Inertia); + if (EditorGUILayout.BeginFadeGroup(m_ShowDecelerationRate.faded)) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_DecelerationRate); + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFadeGroup(); + + EditorGUILayout.PropertyField(m_ScrollSensitivity); + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_Viewport); + + EditorGUILayout.PropertyField(m_HorizontalScrollbar); + if (m_HorizontalScrollbar.objectReferenceValue && !m_HorizontalScrollbar.hasMultipleDifferentValues) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_HorizontalScrollbarVisibility, new GUIContent("Visibility")); + + if ((ScrollRect.ScrollbarVisibility)m_HorizontalScrollbarVisibility.enumValueIndex == ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport + && !m_HorizontalScrollbarVisibility.hasMultipleDifferentValues) + { + if (m_ViewportIsNotChild || m_HScrollbarIsNotChild) + EditorGUILayout.HelpBox(s_HError, MessageType.Error); + EditorGUILayout.PropertyField(m_HorizontalScrollbarSpacing, new GUIContent("Spacing")); + } + + EditorGUI.indentLevel--; + } + + EditorGUILayout.PropertyField(m_VerticalScrollbar); + if (m_VerticalScrollbar.objectReferenceValue && !m_VerticalScrollbar.hasMultipleDifferentValues) + { + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(m_VerticalScrollbarVisibility, new GUIContent("Visibility")); + + if ((ScrollRect.ScrollbarVisibility)m_VerticalScrollbarVisibility.enumValueIndex == ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport + && !m_VerticalScrollbarVisibility.hasMultipleDifferentValues) + { + if (m_ViewportIsNotChild || m_VScrollbarIsNotChild) + EditorGUILayout.HelpBox(s_VError, MessageType.Error); + EditorGUILayout.PropertyField(m_VerticalScrollbarSpacing, new GUIContent("Spacing")); + } + + EditorGUI.indentLevel--; + } + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_OnValueChanged); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs.meta new file mode 100644 index 0000000..4311b0b --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ScrollRectEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: ff377b0e7561593448ad1c54668efe83 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs new file mode 100644 index 0000000..73b97d6 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Scrollbar), true)] + [CanEditMultipleObjects] + public class ScrollbarEditor : SelectableEditor + { + SerializedProperty m_HandleRect; + SerializedProperty m_Direction; + SerializedProperty m_Value; + SerializedProperty m_Size; + SerializedProperty m_NumberOfSteps; + SerializedProperty m_OnValueChanged; + + protected override void OnEnable() + { + base.OnEnable(); + + m_HandleRect = serializedObject.FindProperty("m_HandleRect"); + m_Direction = serializedObject.FindProperty("m_Direction"); + m_Value = serializedObject.FindProperty("m_Value"); + m_Size = serializedObject.FindProperty("m_Size"); + m_NumberOfSteps = serializedObject.FindProperty("m_NumberOfSteps"); + m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + + // EditorGUILayout.PropertyField(m_HandleRect); + EditorGUI.BeginChangeCheck(); + RectTransform newRectTransform = EditorGUILayout.ObjectField("Handle Rect", m_HandleRect.objectReferenceValue, typeof(RectTransform), true) as RectTransform; + if (EditorGUI.EndChangeCheck()) + { + // Handle Rect will modify its GameObject RectTransform drivenBy, so we need to Record the old and new RectTransform. + List<Object> modifiedObjects = new List<Object>(); + modifiedObjects.Add(newRectTransform); + foreach (var target in m_HandleRect.serializedObject.targetObjects) + { + MonoBehaviour mb = target as MonoBehaviour; + if (mb == null) + continue; + + modifiedObjects.Add(mb); + modifiedObjects.Add(mb.GetComponent<RectTransform>()); + } + Undo.RecordObjects(modifiedObjects.ToArray(), "Change Handle Rect"); + m_HandleRect.objectReferenceValue = newRectTransform; + } + + if (m_HandleRect.objectReferenceValue != null) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_Direction); + if (EditorGUI.EndChangeCheck()) + { + Scrollbar.Direction direction = (Scrollbar.Direction)m_Direction.enumValueIndex; + foreach (var obj in serializedObject.targetObjects) + { + Scrollbar scrollbar = obj as Scrollbar; + scrollbar.SetDirection(direction, true); + } + } + + EditorGUILayout.PropertyField(m_Value); + EditorGUILayout.PropertyField(m_Size); + EditorGUILayout.PropertyField(m_NumberOfSteps); + + bool warning = false; + foreach (var obj in serializedObject.targetObjects) + { + Scrollbar scrollbar = obj as Scrollbar; + Scrollbar.Direction dir = scrollbar.direction; + if (dir == Scrollbar.Direction.LeftToRight || dir == Scrollbar.Direction.RightToLeft) + warning = (scrollbar.navigation.mode != Navigation.Mode.Automatic && (scrollbar.FindSelectableOnLeft() != null || scrollbar.FindSelectableOnRight() != null)); + else + warning = (scrollbar.navigation.mode != Navigation.Mode.Automatic && (scrollbar.FindSelectableOnDown() != null || scrollbar.FindSelectableOnUp() != null)); + } + + if (warning) + EditorGUILayout.HelpBox("The selected scrollbar direction conflicts with navigation. Not all navigation options may work.", MessageType.Warning); + + EditorGUILayout.Space(); + // Draw the event notification options + EditorGUILayout.PropertyField(m_OnValueChanged); + } + else + { + EditorGUILayout.HelpBox("Specify a RectTransform for the scrollbar handle. It must have a parent RectTransform that the handle can slide within.", MessageType.Info); + } + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs.meta new file mode 100644 index 0000000..80bbf88 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ScrollbarEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 607de83ab7663e74dac5e5d063fb2954 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs b/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs new file mode 100644 index 0000000..d3329cc --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs @@ -0,0 +1,370 @@ +using System.Collections.Generic; +using System.Text; +using System.Linq; +using UnityEngine; +using UnityEngine.UI; +using UnityEditor.AnimatedValues; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Selectable), true)] + public class SelectableEditor : Editor + { + SerializedProperty m_Script; + SerializedProperty m_InteractableProperty; + SerializedProperty m_TargetGraphicProperty; + SerializedProperty m_TransitionProperty; + SerializedProperty m_ColorBlockProperty; + SerializedProperty m_SpriteStateProperty; + SerializedProperty m_AnimTriggerProperty; + SerializedProperty m_NavigationProperty; + + GUIContent m_VisualizeNavigation = new GUIContent("Visualize", "Show navigation flows between selectable UI elements."); + + AnimBool m_ShowColorTint = new AnimBool(); + AnimBool m_ShowSpriteTrasition = new AnimBool(); + AnimBool m_ShowAnimTransition = new AnimBool(); + + private static List<SelectableEditor> s_Editors = new List<SelectableEditor>(); + private static bool s_ShowNavigation = false; + private static string s_ShowNavigationKey = "SelectableEditor.ShowNavigation"; + + // Whenever adding new SerializedProperties to the Selectable and SelectableEditor + // Also update this guy in OnEnable. This makes the inherited classes from Selectable not require a CustomEditor. + private string[] m_PropertyPathToExcludeForChildClasses; + + protected virtual void OnEnable() + { + m_Script = serializedObject.FindProperty("m_Script"); + m_InteractableProperty = serializedObject.FindProperty("m_Interactable"); + m_TargetGraphicProperty = serializedObject.FindProperty("m_TargetGraphic"); + m_TransitionProperty = serializedObject.FindProperty("m_Transition"); + m_ColorBlockProperty = serializedObject.FindProperty("m_Colors"); + m_SpriteStateProperty = serializedObject.FindProperty("m_SpriteState"); + m_AnimTriggerProperty = serializedObject.FindProperty("m_AnimationTriggers"); + m_NavigationProperty = serializedObject.FindProperty("m_Navigation"); + + m_PropertyPathToExcludeForChildClasses = new[] + { + m_Script.propertyPath, + m_NavigationProperty.propertyPath, + m_TransitionProperty.propertyPath, + m_ColorBlockProperty.propertyPath, + m_SpriteStateProperty.propertyPath, + m_AnimTriggerProperty.propertyPath, + m_InteractableProperty.propertyPath, + m_TargetGraphicProperty.propertyPath, + }; + + var trans = GetTransition(m_TransitionProperty); + m_ShowColorTint.value = (trans == Selectable.Transition.ColorTint); + m_ShowSpriteTrasition.value = (trans == Selectable.Transition.SpriteSwap); + m_ShowAnimTransition.value = (trans == Selectable.Transition.Animation); + + m_ShowColorTint.valueChanged.AddListener(Repaint); + m_ShowSpriteTrasition.valueChanged.AddListener(Repaint); + + s_Editors.Add(this); + RegisterStaticOnSceneGUI(); + + s_ShowNavigation = EditorPrefs.GetBool(s_ShowNavigationKey); + } + + protected virtual void OnDisable() + { + m_ShowColorTint.valueChanged.RemoveListener(Repaint); + m_ShowSpriteTrasition.valueChanged.RemoveListener(Repaint); + + s_Editors.Remove(this); + RegisterStaticOnSceneGUI(); + } + + private void RegisterStaticOnSceneGUI() + { + SceneView.onSceneGUIDelegate -= StaticOnSceneGUI; + if (s_Editors.Count > 0) + SceneView.onSceneGUIDelegate += StaticOnSceneGUI; + } + + static Selectable.Transition GetTransition(SerializedProperty transition) + { + return (Selectable.Transition)transition.enumValueIndex; + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_InteractableProperty); + + var trans = GetTransition(m_TransitionProperty); + + var graphic = m_TargetGraphicProperty.objectReferenceValue as Graphic; + if (graphic == null) + graphic = (target as Selectable).GetComponent<Graphic>(); + + var animator = (target as Selectable).GetComponent<Animator>(); + m_ShowColorTint.target = (!m_TransitionProperty.hasMultipleDifferentValues && trans == Button.Transition.ColorTint); + m_ShowSpriteTrasition.target = (!m_TransitionProperty.hasMultipleDifferentValues && trans == Button.Transition.SpriteSwap); + m_ShowAnimTransition.target = (!m_TransitionProperty.hasMultipleDifferentValues && trans == Button.Transition.Animation); + + EditorGUILayout.PropertyField(m_TransitionProperty); + + ++EditorGUI.indentLevel; + { + if (trans == Selectable.Transition.ColorTint || trans == Selectable.Transition.SpriteSwap) + { + EditorGUILayout.PropertyField(m_TargetGraphicProperty); + } + + switch (trans) + { + case Selectable.Transition.ColorTint: + if (graphic == null) + EditorGUILayout.HelpBox("You must have a Graphic target in order to use a color transition.", MessageType.Warning); + break; + + case Selectable.Transition.SpriteSwap: + if (graphic as Image == null) + EditorGUILayout.HelpBox("You must have a Image target in order to use a sprite swap transition.", MessageType.Warning); + break; + } + + if (EditorGUILayout.BeginFadeGroup(m_ShowColorTint.faded)) + { + EditorGUILayout.PropertyField(m_ColorBlockProperty); + } + EditorGUILayout.EndFadeGroup(); + + if (EditorGUILayout.BeginFadeGroup(m_ShowSpriteTrasition.faded)) + { + EditorGUILayout.PropertyField(m_SpriteStateProperty); + } + EditorGUILayout.EndFadeGroup(); + + if (EditorGUILayout.BeginFadeGroup(m_ShowAnimTransition.faded)) + { + EditorGUILayout.PropertyField(m_AnimTriggerProperty); + + if (animator == null || animator.runtimeAnimatorController == null) + { + Rect buttonRect = EditorGUILayout.GetControlRect(); + buttonRect.xMin += EditorGUIUtility.labelWidth; + if (GUI.Button(buttonRect, "Auto Generate Animation", EditorStyles.miniButton)) + { + var controller = GenerateSelectableAnimatorContoller((target as Selectable).animationTriggers, target as Selectable); + if (controller != null) + { + if (animator == null) + animator = (target as Selectable).gameObject.AddComponent<Animator>(); + + Animations.AnimatorController.SetAnimatorController(animator, controller); + } + } + } + } + EditorGUILayout.EndFadeGroup(); + } + --EditorGUI.indentLevel; + + EditorGUILayout.Space(); + + EditorGUILayout.PropertyField(m_NavigationProperty); + + EditorGUI.BeginChangeCheck(); + Rect toggleRect = EditorGUILayout.GetControlRect(); + toggleRect.xMin += EditorGUIUtility.labelWidth; + s_ShowNavigation = GUI.Toggle(toggleRect, s_ShowNavigation, m_VisualizeNavigation, EditorStyles.miniButton); + if (EditorGUI.EndChangeCheck()) + { + EditorPrefs.SetBool(s_ShowNavigationKey, s_ShowNavigation); + SceneView.RepaintAll(); + } + + // We do this here to avoid requiring the user to also write a Editor for their Selectable-derived classes. + // This way if we are on a derived class we dont draw anything else, otherwise draw the remaining properties. + ChildClassPropertiesGUI(); + + serializedObject.ApplyModifiedProperties(); + } + + // Draw the extra SerializedProperties of the child class. + // We need to make sure that m_PropertyPathToExcludeForChildClasses has all the Selectable properties and in the correct order. + // TODO: find a nicer way of doing this. (creating a InheritedEditor class that automagically does this) + private void ChildClassPropertiesGUI() + { + if (IsDerivedSelectableEditor()) + return; + + DrawPropertiesExcluding(serializedObject, m_PropertyPathToExcludeForChildClasses); + } + + private bool IsDerivedSelectableEditor() + { + return GetType() != typeof(SelectableEditor); + } + + private static Animations.AnimatorController GenerateSelectableAnimatorContoller(AnimationTriggers animationTriggers, Selectable target) + { + if (target == null) + return null; + + // Where should we create the controller? + var path = GetSaveControllerPath(target); + if (string.IsNullOrEmpty(path)) + return null; + + // figure out clip names + var normalName = string.IsNullOrEmpty(animationTriggers.normalTrigger) ? "Normal" : animationTriggers.normalTrigger; + var highlightedName = string.IsNullOrEmpty(animationTriggers.highlightedTrigger) ? "Highlighted" : animationTriggers.highlightedTrigger; + var pressedName = string.IsNullOrEmpty(animationTriggers.pressedTrigger) ? "Pressed" : animationTriggers.pressedTrigger; + var disabledName = string.IsNullOrEmpty(animationTriggers.disabledTrigger) ? "Disabled" : animationTriggers.disabledTrigger; + + // Create controller and hook up transitions. + var controller = Animations.AnimatorController.CreateAnimatorControllerAtPath(path); + GenerateTriggerableTransition(normalName, controller); + GenerateTriggerableTransition(highlightedName, controller); + GenerateTriggerableTransition(pressedName, controller); + GenerateTriggerableTransition(disabledName, controller); + + AssetDatabase.ImportAsset(path); + + return controller; + } + + private static string GetSaveControllerPath(Selectable target) + { + var defaultName = target.gameObject.name; + var message = string.Format("Create a new animator for the game object '{0}':", defaultName); + return EditorUtility.SaveFilePanelInProject("New Animation Contoller", defaultName, "controller", message); + } + + private static void SetUpCurves(AnimationClip highlightedClip, AnimationClip pressedClip, string animationPath) + { + string[] channels = { "m_LocalScale.x", "m_LocalScale.y", "m_LocalScale.z" }; + + var highlightedKeys = new[] { new Keyframe(0f, 1f), new Keyframe(0.5f, 1.1f), new Keyframe(1f, 1f) }; + var highlightedCurve = new AnimationCurve(highlightedKeys); + foreach (var channel in channels) + AnimationUtility.SetEditorCurve(highlightedClip, EditorCurveBinding.FloatCurve(animationPath, typeof(Transform), channel), highlightedCurve); + + var pressedKeys = new[] { new Keyframe(0f, 1.15f) }; + var pressedCurve = new AnimationCurve(pressedKeys); + foreach (var channel in channels) + AnimationUtility.SetEditorCurve(pressedClip, EditorCurveBinding.FloatCurve(animationPath, typeof(Transform), channel), pressedCurve); + } + + private static string BuildAnimationPath(Selectable target) + { + // if no target don't hook up any curves. + var highlight = target.targetGraphic; + if (highlight == null) + return string.Empty; + + var startGo = highlight.gameObject; + var toFindGo = target.gameObject; + + var pathComponents = new Stack<string>(); + while (toFindGo != startGo) + { + pathComponents.Push(startGo.name); + + // didn't exist in hierarchy! + if (startGo.transform.parent == null) + return string.Empty; + + startGo = startGo.transform.parent.gameObject; + } + + // calculate path + var animPath = new StringBuilder(); + if (pathComponents.Count > 0) + animPath.Append(pathComponents.Pop()); + + while (pathComponents.Count > 0) + animPath.Append("/").Append(pathComponents.Pop()); + + return animPath.ToString(); + } + + private static AnimationClip GenerateTriggerableTransition(string name, Animations.AnimatorController controller) + { + // Create the clip + var clip = Animations.AnimatorController.AllocateAnimatorClip(name); + AssetDatabase.AddObjectToAsset(clip, controller); + + // Create a state in the animatior controller for this clip + var state = controller.AddMotion(clip); + + // Add a transition property + controller.AddParameter(name, AnimatorControllerParameterType.Trigger); + + // Add an any state transition + var stateMachine = controller.layers[0].stateMachine; + var transition = stateMachine.AddAnyStateTransition(state); + transition.AddCondition(Animations.AnimatorConditionMode.If, 0, name); + return clip; + } + + private static void StaticOnSceneGUI(SceneView view) + { + if (!s_ShowNavigation) + return; + + for (int i = 0; i < Selectable.allSelectables.Count; i++) + { + DrawNavigationForSelectable(Selectable.allSelectables[i]); + } + } + + private static void DrawNavigationForSelectable(Selectable sel) + { + if (sel == null) + return; + + Transform transform = sel.transform; + bool active = Selection.transforms.Any(e => e == transform); + Handles.color = new Color(1.0f, 0.9f, 0.1f, active ? 1.0f : 0.4f); + DrawNavigationArrow(-Vector2.right, sel, sel.FindSelectableOnLeft()); + DrawNavigationArrow(Vector2.right, sel, sel.FindSelectableOnRight()); + DrawNavigationArrow(Vector2.up, sel, sel.FindSelectableOnUp()); + DrawNavigationArrow(-Vector2.up, sel, sel.FindSelectableOnDown()); + } + + const float kArrowThickness = 2.5f; + const float kArrowHeadSize = 1.2f; + + private static void DrawNavigationArrow(Vector2 direction, Selectable fromObj, Selectable toObj) + { + if (fromObj == null || toObj == null) + return; + Transform fromTransform = fromObj.transform; + Transform toTransform = toObj.transform; + + Vector2 sideDir = new Vector2(direction.y, -direction.x); + Vector3 fromPoint = fromTransform.TransformPoint(GetPointOnRectEdge(fromTransform as RectTransform, direction)); + Vector3 toPoint = toTransform.TransformPoint(GetPointOnRectEdge(toTransform as RectTransform, -direction)); + float fromSize = HandleUtility.GetHandleSize(fromPoint) * 0.05f; + float toSize = HandleUtility.GetHandleSize(toPoint) * 0.05f; + fromPoint += fromTransform.TransformDirection(sideDir) * fromSize; + toPoint += toTransform.TransformDirection(sideDir) * toSize; + float length = Vector3.Distance(fromPoint, toPoint); + Vector3 fromTangent = fromTransform.rotation * direction * length * 0.3f; + Vector3 toTangent = toTransform.rotation * -direction * length * 0.3f; + + Handles.DrawBezier(fromPoint, toPoint, fromPoint + fromTangent, toPoint + toTangent, Handles.color, null, kArrowThickness); + Handles.DrawAAPolyLine(kArrowThickness, toPoint, toPoint + toTransform.rotation * (-direction - sideDir) * toSize * kArrowHeadSize); + Handles.DrawAAPolyLine(kArrowThickness, toPoint, toPoint + toTransform.rotation * (-direction + sideDir) * toSize * kArrowHeadSize); + } + + private static Vector3 GetPointOnRectEdge(RectTransform rect, Vector2 dir) + { + if (rect == null) + return Vector3.zero; + if (dir != Vector2.zero) + dir /= Mathf.Max(Mathf.Abs(dir.x), Mathf.Abs(dir.y)); + dir = rect.rect.center + Vector2.Scale(rect.rect.size, dir * 0.5f); + return dir; + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs.meta new file mode 100644 index 0000000..0384e82 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SelectableEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1d4d444b0a1bacb46a743e88cc4da1d0 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs b/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs new file mode 100644 index 0000000..4510d44 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs @@ -0,0 +1,35 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + public class SelfControllerEditor : Editor + { + static string s_Warning = "Parent has a type of layout group component. A child of a layout group should not have a {0} component, since it should be driven by the layout group."; + + public override void OnInspectorGUI() + { + bool anyHaveLayoutParent = false; + for (int i = 0; i < targets.Length; i++) + { + Component comp = (targets[i] as Component); + ILayoutIgnorer ignorer = comp.GetComponent(typeof(ILayoutIgnorer)) as ILayoutIgnorer; + if (ignorer != null && ignorer.ignoreLayout) + continue; + + RectTransform parent = comp.transform.parent as RectTransform; + if (parent != null) + { + Behaviour layoutGroup = parent.GetComponent(typeof(ILayoutGroup)) as Behaviour; + if (layoutGroup != null && layoutGroup.enabled) + { + anyHaveLayoutParent = true; + break; + } + } + } + if (anyHaveLayoutParent) + EditorGUILayout.HelpBox(string.Format(s_Warning, ObjectNames.NicifyVariableName(target.GetType().Name)), MessageType.Warning); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs.meta new file mode 100644 index 0000000..a088542 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SelfControllerEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1c525819dc6fd8d43b99b1eaed430ddd +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs b/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs new file mode 100644 index 0000000..f284648 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Slider), true)] + [CanEditMultipleObjects] + public class SliderEditor : SelectableEditor + { + SerializedProperty m_Direction; + SerializedProperty m_FillRect; + SerializedProperty m_HandleRect; + SerializedProperty m_MinValue; + SerializedProperty m_MaxValue; + SerializedProperty m_WholeNumbers; + SerializedProperty m_Value; + SerializedProperty m_OnValueChanged; + + protected override void OnEnable() + { + base.OnEnable(); + m_FillRect = serializedObject.FindProperty("m_FillRect"); + m_HandleRect = serializedObject.FindProperty("m_HandleRect"); + m_Direction = serializedObject.FindProperty("m_Direction"); + m_MinValue = serializedObject.FindProperty("m_MinValue"); + m_MaxValue = serializedObject.FindProperty("m_MaxValue"); + m_WholeNumbers = serializedObject.FindProperty("m_WholeNumbers"); + m_Value = serializedObject.FindProperty("m_Value"); + m_OnValueChanged = serializedObject.FindProperty("m_OnValueChanged"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_FillRect); + EditorGUILayout.PropertyField(m_HandleRect); + + if (m_FillRect.objectReferenceValue != null || m_HandleRect.objectReferenceValue != null) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(m_Direction); + if (EditorGUI.EndChangeCheck()) + { + Slider.Direction direction = (Slider.Direction)m_Direction.enumValueIndex; + foreach (var obj in serializedObject.targetObjects) + { + Slider slider = obj as Slider; + slider.SetDirection(direction, true); + } + } + + EditorGUILayout.PropertyField(m_MinValue); + EditorGUILayout.PropertyField(m_MaxValue); + EditorGUILayout.PropertyField(m_WholeNumbers); + EditorGUILayout.Slider(m_Value, m_MinValue.floatValue, m_MaxValue.floatValue); + + bool warning = false; + foreach (var obj in serializedObject.targetObjects) + { + Slider slider = obj as Slider; + Slider.Direction dir = slider.direction; + if (dir == Slider.Direction.LeftToRight || dir == Slider.Direction.RightToLeft) + warning = (slider.navigation.mode != Navigation.Mode.Automatic && (slider.FindSelectableOnLeft() != null || slider.FindSelectableOnRight() != null)); + else + warning = (slider.navigation.mode != Navigation.Mode.Automatic && (slider.FindSelectableOnDown() != null || slider.FindSelectableOnUp() != null)); + } + + if (warning) + EditorGUILayout.HelpBox("The selected slider direction conflicts with navigation. Not all navigation options may work.", MessageType.Warning); + + // Draw the event notification options + EditorGUILayout.Space(); + EditorGUILayout.PropertyField(m_OnValueChanged); + } + else + { + EditorGUILayout.HelpBox("Specify a RectTransform for the slider fill or the slider handle or both. Each must have a parent RectTransform that it can slide within.", MessageType.Info); + } + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs.meta new file mode 100644 index 0000000..b313067 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SliderEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 778a137b5ae337b4db4a47f1d34442b1 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs b/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs new file mode 100644 index 0000000..32b9498 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs @@ -0,0 +1,200 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.UI +{ + // Tools for the editor + internal class SpriteDrawUtility + { + static Texture2D s_ContrastTex; + + // Returns a usable texture that looks like a high-contrast checker board. + static Texture2D contrastTexture + { + get + { + if (s_ContrastTex == null) + s_ContrastTex = CreateCheckerTex( + new Color(0f, 0.0f, 0f, 0.5f), + new Color(1f, 1f, 1f, 0.5f)); + return s_ContrastTex; + } + } + + // Create a checker-background texture. + static Texture2D CreateCheckerTex(Color c0, Color c1) + { + Texture2D tex = new Texture2D(16, 16); + tex.name = "[Generated] Checker Texture"; + tex.hideFlags = HideFlags.DontSave; + + for (int y = 0; y < 8; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c1); + for (int y = 8; y < 16; ++y) for (int x = 0; x < 8; ++x) tex.SetPixel(x, y, c0); + for (int y = 0; y < 8; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c0); + for (int y = 8; y < 16; ++y) for (int x = 8; x < 16; ++x) tex.SetPixel(x, y, c1); + + tex.Apply(); + tex.filterMode = FilterMode.Point; + return tex; + } + + // Create a gradient texture. + static Texture2D CreateGradientTex() + { + Texture2D tex = new Texture2D(1, 16); + tex.name = "[Generated] Gradient Texture"; + tex.hideFlags = HideFlags.DontSave; + + Color c0 = new Color(1f, 1f, 1f, 0f); + Color c1 = new Color(1f, 1f, 1f, 0.4f); + + for (int i = 0; i < 16; ++i) + { + float f = Mathf.Abs((i / 15f) * 2f - 1f); + f *= f; + tex.SetPixel(0, i, Color.Lerp(c0, c1, f)); + } + + tex.Apply(); + tex.filterMode = FilterMode.Bilinear; + return tex; + } + + // Draws the tiled texture. Like GUI.DrawTexture() but tiled instead of stretched. + static void DrawTiledTexture(Rect rect, Texture tex) + { + float u = rect.width / tex.width; + float v = rect.height / tex.height; + + Rect texCoords = new Rect(0, 0, u, v); + TextureWrapMode originalMode = tex.wrapMode; + tex.wrapMode = TextureWrapMode.Repeat; + GUI.DrawTextureWithTexCoords(rect, tex, texCoords); + tex.wrapMode = originalMode; + } + + // Draw the specified Image. + public static void DrawSprite(Sprite sprite, Rect drawArea, Color color) + { + if (sprite == null) + return; + + Texture2D tex = sprite.texture; + if (tex == null) + return; + + Rect outer = sprite.rect; + Rect inner = outer; + inner.xMin += sprite.border.x; + inner.yMin += sprite.border.y; + inner.xMax -= sprite.border.z; + inner.yMax -= sprite.border.w; + + Vector4 uv4 = UnityEngine.Sprites.DataUtility.GetOuterUV(sprite); + Rect uv = new Rect(uv4.x, uv4.y, uv4.z - uv4.x, uv4.w - uv4.y); + Vector4 padding = UnityEngine.Sprites.DataUtility.GetPadding(sprite); + padding.x /= outer.width; + padding.y /= outer.height; + padding.z /= outer.width; + padding.w /= outer.height; + + DrawSprite(tex, drawArea, padding, outer, inner, uv, color, null); + } + + // Draw the specified Image. + public static void DrawSprite(Texture tex, Rect drawArea, Rect outer, Rect uv, Color color) + { + DrawSprite(tex, drawArea, Vector4.zero, outer, outer, uv, color, null); + } + + // Draw the specified Image. + private static void DrawSprite(Texture tex, Rect drawArea, Vector4 padding, Rect outer, Rect inner, Rect uv, Color color, Material mat) + { + // Create the texture rectangle that is centered inside rect. + Rect outerRect = drawArea; + outerRect.width = Mathf.Abs(outer.width); + outerRect.height = Mathf.Abs(outer.height); + + if (outerRect.width > 0f) + { + float f = drawArea.width / outerRect.width; + outerRect.width *= f; + outerRect.height *= f; + } + + if (drawArea.height > outerRect.height) + { + outerRect.y += (drawArea.height - outerRect.height) * 0.5f; + } + else if (outerRect.height > drawArea.height) + { + float f = drawArea.height / outerRect.height; + outerRect.width *= f; + outerRect.height *= f; + } + + if (drawArea.width > outerRect.width) + outerRect.x += (drawArea.width - outerRect.width) * 0.5f; + + // Draw the background + EditorGUI.DrawTextureTransparent(outerRect, null, ScaleMode.ScaleToFit, outer.width / outer.height); + + // Draw the Image + GUI.color = color; + + Rect paddedTexArea = new Rect( + outerRect.x + outerRect.width * padding.x, + outerRect.y + outerRect.height * padding.w, + outerRect.width - (outerRect.width * (padding.z + padding.x)), + outerRect.height - (outerRect.height * (padding.w + padding.y)) + ); + + if (mat == null) + { + GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear; + GUI.DrawTextureWithTexCoords(paddedTexArea, tex, uv, true); + GL.sRGBWrite = false; + } + else + { + // NOTE: There is an issue in Unity that prevents it from clipping the drawn preview + // using BeginGroup/EndGroup, and there is no way to specify a UV rect... + EditorGUI.DrawPreviewTexture(paddedTexArea, tex, mat); + } + + // Draw the border indicator lines + GUI.BeginGroup(outerRect); + { + tex = contrastTexture; + GUI.color = Color.white; + + if (inner.xMin != outer.xMin) + { + float x = (inner.xMin - outer.xMin) / outer.width * outerRect.width - 1; + DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex); + } + + if (inner.xMax != outer.xMax) + { + float x = (inner.xMax - outer.xMin) / outer.width * outerRect.width - 1; + DrawTiledTexture(new Rect(x, 0f, 1f, outerRect.height), tex); + } + + if (inner.yMin != outer.yMin) + { + // GUI.DrawTexture is top-left based rather than bottom-left + float y = (inner.yMin - outer.yMin) / outer.height * outerRect.height - 1; + DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex); + } + + if (inner.yMax != outer.yMax) + { + float y = (inner.yMax - outer.yMin) / outer.height * outerRect.height - 1; + DrawTiledTexture(new Rect(0f, outerRect.height - y, outerRect.width, 1f), tex); + } + } + + GUI.EndGroup(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs.meta b/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs.meta new file mode 100644 index 0000000..eafacaa --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/SpriteDrawUtility.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: fb3e0854e2906b14289d932ddbf67d55 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs b/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs new file mode 100644 index 0000000..b818f21 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + // TODO REVIEW + // Have material live under text + // move stencil mask into effects *make an efects top level element like there is + // paragraph and character + + /// <summary> + /// Editor class used to edit UI Labels. + /// </summary> + + [CustomEditor(typeof(Text), true)] + [CanEditMultipleObjects] + public class TextEditor : GraphicEditor + { + SerializedProperty m_Text; + SerializedProperty m_FontData; + + protected override void OnEnable() + { + base.OnEnable(); + m_Text = serializedObject.FindProperty("m_Text"); + m_FontData = serializedObject.FindProperty("m_FontData"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.PropertyField(m_Text); + EditorGUILayout.PropertyField(m_FontData); + AppearanceControlsGUI(); + RaycastControlsGUI(); + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs.meta new file mode 100644 index 0000000..04e20ed --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/TextEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c6bec5fe73b6cdc4486c22e79e6ef095 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs b/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs new file mode 100644 index 0000000..632e4d0 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs @@ -0,0 +1,46 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace UnityEditor.UI +{ + [CustomEditor(typeof(Toggle), true)] + [CanEditMultipleObjects] + public class ToggleEditor : SelectableEditor + { + SerializedProperty m_OnValueChangedProperty; + SerializedProperty m_TransitionProperty; + SerializedProperty m_GraphicProperty; + SerializedProperty m_GroupProperty; + SerializedProperty m_IsOnProperty; + + protected override void OnEnable() + { + base.OnEnable(); + + m_TransitionProperty = serializedObject.FindProperty("toggleTransition"); + m_GraphicProperty = serializedObject.FindProperty("graphic"); + m_GroupProperty = serializedObject.FindProperty("m_Group"); + m_IsOnProperty = serializedObject.FindProperty("m_IsOn"); + m_OnValueChangedProperty = serializedObject.FindProperty("onValueChanged"); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + EditorGUILayout.Space(); + + serializedObject.Update(); + EditorGUILayout.PropertyField(m_IsOnProperty); + EditorGUILayout.PropertyField(m_TransitionProperty); + EditorGUILayout.PropertyField(m_GraphicProperty); + EditorGUILayout.PropertyField(m_GroupProperty); + + EditorGUILayout.Space(); + + // Draw the event notification options + EditorGUILayout.PropertyField(m_OnValueChangedProperty); + + serializedObject.ApplyModifiedProperties(); + } + } +} diff --git a/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs.meta b/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs.meta new file mode 100644 index 0000000..18f05c3 --- /dev/null +++ b/Assets/uGUI-2017.1/Editor/UI/ToggleEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 5c004313ae1b2fb40986d6453e88b8bf +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI.meta b/Assets/uGUI-2017.1/UnityEngine.UI.meta new file mode 100644 index 0000000..974250f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e90c2c81193e4314ab3be0cc92d903b5 +folderAsset: yes +timeCreated: 1602119377 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem.meta new file mode 100644 index 0000000..608a0d2 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6d4a24f03e32ddb46aa2d88b59098524 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData.meta new file mode 100644 index 0000000..6a26991 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2a7965b878e0c3c4abdb68deac365981 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs new file mode 100644 index 0000000..3278d6d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs @@ -0,0 +1,15 @@ +namespace UnityEngine.EventSystems +{ + public class AxisEventData : BaseEventData + { + public Vector2 moveVector { get; set; } + public MoveDirection moveDir { get; set; } + + public AxisEventData(EventSystem eventSystem) + : base(eventSystem) + { + moveVector = Vector2.zero; + moveDir = MoveDirection.None; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs.meta new file mode 100644 index 0000000..d770a40 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/AxisEventData.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 068c7c2e61fdac34ebd23b76779526fd +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs new file mode 100644 index 0000000..f353314 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs @@ -0,0 +1,42 @@ +namespace UnityEngine.EventSystems +{ + public abstract class AbstractEventData + { + protected bool m_Used; // µ±Ç°Ê¼þÊÇ·ñ±»´¦Àí£¨±»ÍÌ£© + + public virtual void Reset() + { + m_Used = false; + } + + public virtual void Use() + { + m_Used = true; + } + + public virtual bool used + { + get { return m_Used; } + } + } + + public class BaseEventData : AbstractEventData + { + private readonly EventSystem m_EventSystem; + public BaseEventData(EventSystem eventSystem) + { + m_EventSystem = eventSystem; + } + + public BaseInputModule currentInputModule + { + get { return m_EventSystem.currentInputModule; } + } + + public GameObject selectedObject + { + get { return m_EventSystem.currentSelectedGameObject; } + set { m_EventSystem.SetSelectedGameObject(value, this); } // »á·¢ËÍÒ»¸öselecthandlerʼþ + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs.meta new file mode 100644 index 0000000..5265b51 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/BaseEventData.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 8249b81d25be82b4388cb41d127fe369 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs new file mode 100644 index 0000000..9b94e00 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs @@ -0,0 +1,138 @@ +using System; +using System.Text; +using System.Collections.Generic; + +namespace UnityEngine.EventSystems +{ + /// <summary> + /// Each touch event creates one of these containing all the relevant information. + /// </summary> + public class PointerEventData : BaseEventData + { + public enum InputButton + { + Left = 0, + Right = 1, + Middle = 2 + } + + public enum FramePressState + { + Pressed, + Released, + PressedAndReleased, + NotChanged + } + + public GameObject pointerEnter { get; set; } + + // The object that received OnPointerDown + private GameObject m_PointerPress; + // The object last received OnPointerDown + public GameObject lastPress { get; private set; } + // The object that the press happened on even if it can not handle the press event + public GameObject rawPointerPress { get; set; } + // The object that received OnDrag + public GameObject pointerDrag { get; set; } + + public RaycastResult pointerCurrentRaycast { get; set; } + public RaycastResult pointerPressRaycast { get; set; } + + public List<GameObject> hovered = new List<GameObject>(); + + public bool eligibleForClick { get; set; } + + public int pointerId { get; set; } + + // Current position of the mouse or touch event + public Vector2 position { get; set; } + // Delta since last update + public Vector2 delta { get; set; } + // Position of the press event + public Vector2 pressPosition { get; set; } + // World-space position where a ray cast into the screen hits something + [Obsolete("Use either pointerCurrentRaycast.worldPosition or pointerPressRaycast.worldPosition")] + public Vector3 worldPosition { get; set; } + // World-space normal where a ray cast into the screen hits something + [Obsolete("Use either pointerCurrentRaycast.worldNormal or pointerPressRaycast.worldNormal")] + public Vector3 worldNormal { get; set; } + // The last time a click event was sent out (used for double-clicks) + public float clickTime { get; set; } + // Number of clicks in a row. 2 for a double-click for example. + public int clickCount { get; set; } + + public Vector2 scrollDelta { get; set; } + public bool useDragThreshold { get; set; } + public bool dragging { get; set; } + + public InputButton button { get; set; } + + public PointerEventData(EventSystem eventSystem) : base(eventSystem) + { + eligibleForClick = false; + + pointerId = -1; + position = Vector2.zero; // Current position of the mouse or touch event + delta = Vector2.zero; // Delta since last update + pressPosition = Vector2.zero; // Delta since the event started being tracked + clickTime = 0.0f; // The last time a click event was sent out (used for double-clicks) + clickCount = 0; // Number of clicks in a row. 2 for a double-click for example. + + scrollDelta = Vector2.zero; + useDragThreshold = true; + dragging = false; + button = InputButton.Left; + } + + public bool IsPointerMoving() + { + return delta.sqrMagnitude > 0.0f; + } + + public bool IsScrolling() + { + return scrollDelta.sqrMagnitude > 0.0f; + } + + public Camera enterEventCamera + { + get { return pointerCurrentRaycast.module == null ? null : pointerCurrentRaycast.module.eventCamera; } + } + + public Camera pressEventCamera + { + get { return pointerPressRaycast.module == null ? null : pointerPressRaycast.module.eventCamera; } + } + + public GameObject pointerPress + { + get { return m_PointerPress; } + set + { + if (m_PointerPress == value) + return; + + lastPress = m_PointerPress; + m_PointerPress = value; + } + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.AppendLine("<b>Position</b>: " + position); + sb.AppendLine("<b>delta</b>: " + delta); + sb.AppendLine("<b>eligibleForClick</b>: " + eligibleForClick); + sb.AppendLine("<b>pointerEnter</b>: " + pointerEnter); + sb.AppendLine("<b>pointerPress</b>: " + pointerPress); + sb.AppendLine("<b>lastPointerPress</b>: " + lastPress); + sb.AppendLine("<b>pointerDrag</b>: " + pointerDrag); + sb.AppendLine("<b>Use Drag Threshold</b>: " + useDragThreshold); + sb.AppendLine("<b>Current Rayast:</b>"); + sb.AppendLine(pointerCurrentRaycast.ToString()); + sb.AppendLine("<b>Press Rayast:</b>"); + sb.AppendLine(pointerPressRaycast.ToString()); + return sb.ToString(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs.meta new file mode 100644 index 0000000..866eab8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventData/PointerEventData.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 721b5956a0219d74b9aa58b2fd44ffe3 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler.meta new file mode 100644 index 0000000..732637d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 146a9b1a2f14b51468a9381c1562257e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs new file mode 100644 index 0000000..977514f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs @@ -0,0 +1,11 @@ +using System; + +namespace UnityEngine.EventSystems +{ + [Flags] + public enum EventHandle + { + Unused = 0, + Used = 1 + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs.meta new file mode 100644 index 0000000..1e2c52f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventHandle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0c5751e0f52a2d9459e76555a888ad06 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs new file mode 100644 index 0000000..b808e6c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs @@ -0,0 +1,91 @@ +namespace UnityEngine.EventSystems +{ + public interface IEventSystemHandler + { + } + + public interface IPointerEnterHandler : IEventSystemHandler + { + void OnPointerEnter(PointerEventData eventData); + } + + public interface IPointerExitHandler : IEventSystemHandler + { + void OnPointerExit(PointerEventData eventData); + } + + public interface IPointerDownHandler : IEventSystemHandler + { + void OnPointerDown(PointerEventData eventData); + } + + public interface IPointerUpHandler : IEventSystemHandler + { + void OnPointerUp(PointerEventData eventData); + } + + public interface IPointerClickHandler : IEventSystemHandler + { + void OnPointerClick(PointerEventData eventData); + } + + public interface IBeginDragHandler : IEventSystemHandler + { + void OnBeginDrag(PointerEventData eventData); + } + + public interface IInitializePotentialDragHandler : IEventSystemHandler + { + void OnInitializePotentialDrag(PointerEventData eventData); + } + + public interface IDragHandler : IEventSystemHandler + { + void OnDrag(PointerEventData eventData); + } + + public interface IEndDragHandler : IEventSystemHandler + { + void OnEndDrag(PointerEventData eventData); + } + + public interface IDropHandler : IEventSystemHandler + { + void OnDrop(PointerEventData eventData); + } + + public interface IScrollHandler : IEventSystemHandler + { + void OnScroll(PointerEventData eventData); + } + + public interface IUpdateSelectedHandler : IEventSystemHandler + { + void OnUpdateSelected(BaseEventData eventData); + } + + public interface ISelectHandler : IEventSystemHandler + { + void OnSelect(BaseEventData eventData); + } + + public interface IDeselectHandler : IEventSystemHandler + { + void OnDeselect(BaseEventData eventData); + } + + public interface IMoveHandler : IEventSystemHandler + { + void OnMove(AxisEventData eventData); + } + + public interface ISubmitHandler : IEventSystemHandler + { + void OnSubmit(BaseEventData eventData); + } + + public interface ICancelHandler : IEventSystemHandler + { + void OnCancel(BaseEventData eventData); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs.meta new file mode 100644 index 0000000..2a369ae --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventInterfaces.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7bb73ff56f2f85b4ca62f8cb5ea59840 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs new file mode 100644 index 0000000..1440547 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using UnityEngine.Serialization; + +namespace UnityEngine.EventSystems +{ + [AddComponentMenu("Event/Event System")] + public class EventSystem : UIBehaviour + { + // »ñµÃµ±Ç°EventSystem¹Ò×ŵÄBaseInputModuleµÄÅÉÉúÀ࣬һ°ãÀ´ËµÖ»»á¹ÒÒ»¸öStandableInputModule + private List<BaseInputModule> m_SystemInputModules = new List<BaseInputModule>(); + + private BaseInputModule m_CurrentInputModule; + + public static EventSystem current { get; set; } + + [SerializeField] + [FormerlySerializedAs("m_Selected")] + private GameObject m_FirstSelected; + + [SerializeField] + private bool m_sendNavigationEvents = true; // Should the EventSystem allow navigation events (move / submit / cancel). + + public bool sendNavigationEvents + { + get { return m_sendNavigationEvents; } + set { m_sendNavigationEvents = value; } + } + + [SerializeField] + private int m_DragThreshold = 5; + public int pixelDragThreshold + { + get { return m_DragThreshold; } + set { m_DragThreshold = value; } + } + + private GameObject m_CurrentSelected; + + public BaseInputModule currentInputModule + { + get { return m_CurrentInputModule; } + } + + /// <summary> + /// Only one object can be selected at a time. Think: controller-selected button. + /// </summary> + public GameObject firstSelectedGameObject + { + get { return m_FirstSelected; } + set { m_FirstSelected = value; } + } + + public GameObject currentSelectedGameObject + { + get { return m_CurrentSelected; } + } + + [Obsolete("lastSelectedGameObject is no longer supported")] + public GameObject lastSelectedGameObject + { + get { return null; } + } + + private bool m_HasFocus = true; + + public bool isFocused + { + get { return m_HasFocus; } + } + + protected EventSystem() + {} + + //c °Ñ¹Ò×ŵÄinput modules¼ÓÈëm_SystemInputModules + public void UpdateModules() + { + // Äõ½µ±Ç°EventSystemÏÂÃæ¹Ò×ŵÄinputmodule,ͨ³£À´ËµÖ»»á¹ÒÒ»¸östandaloneInputModule + GetComponents(m_SystemInputModules); + for (int i = m_SystemInputModules.Count - 1; i >= 0; i--) + { + if (m_SystemInputModules[i] && m_SystemInputModules[i].IsActive()) + continue; + m_SystemInputModules.RemoveAt(i); + } + } + + private bool m_SelectionGuard; + public bool alreadySelecting + { + get { return m_SelectionGuard; } + } + + public void SetSelectedGameObject(GameObject selected, BaseEventData pointer) + { + if (m_SelectionGuard) + { + Debug.LogError("Attempting to select " + selected + "while already selecting an object."); + return; + } + + m_SelectionGuard = true; + if (selected == m_CurrentSelected) + { + m_SelectionGuard = false; + return; + } + + // Debug.Log("Selection: new (" + selected + ") old (" + m_CurrentSelected + ")"); + ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.deselectHandler); + m_CurrentSelected = selected; + ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler); + m_SelectionGuard = false; + } + + private BaseEventData m_DummyData; + private BaseEventData baseEventDataCache + { + get + { + if (m_DummyData == null) + m_DummyData = new BaseEventData(this); + + return m_DummyData; + } + } + + public void SetSelectedGameObject(GameObject selected) + { + SetSelectedGameObject(selected, baseEventDataCache); + } + + private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs) + { + if (lhs.module != rhs.module) + { + var lhsEventCamera = lhs.module.eventCamera; + var rhsEventCamera = rhs.module.eventCamera; + if (lhsEventCamera != null && rhsEventCamera != null && lhsEventCamera.depth != rhsEventCamera.depth) + { + // need to reverse the standard compareTo + if (lhsEventCamera.depth < rhsEventCamera.depth) + return 1; + if (lhsEventCamera.depth == rhsEventCamera.depth) + return 0; + + return -1; + } + + if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority) + return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority); + + if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority) + return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority); + } + + if (lhs.sortingLayer != rhs.sortingLayer) + { + // Uses the layer value to properly compare the relative order of the layers. + var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer); + var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer); + return rid.CompareTo(lid); + } + + + if (lhs.sortingOrder != rhs.sortingOrder) + return rhs.sortingOrder.CompareTo(lhs.sortingOrder); + + if (lhs.depth != rhs.depth) + return rhs.depth.CompareTo(lhs.depth); + + if (lhs.distance != rhs.distance) + return lhs.distance.CompareTo(rhs.distance); + + return lhs.index.CompareTo(rhs.index); + }
+
+ #region ÉäÏß¼ì²â +
+ private static readonly Comparison<RaycastResult> s_RaycastComparer = RaycastComparer; + + // ´ÓPointerInputModule.GetTouchPointerEventData()À´µÄ´¥ÃþÊý¾Ý + public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults) + { + raycastResults.Clear(); + //°üÀ¨³¡¾°ÖÐËùÓеÄraycaster + var modules = RaycasterManager.GetRaycasters(); + for (int i = 0; i < modules.Count; ++i) + { + var module = modules[i]; + if (module == null || !module.IsActive()) + continue; + + module.Raycast(eventData, raycastResults); + } + + raycastResults.Sort(s_RaycastComparer); + }
+
+ #endregion +
+ //c ÊÇ·ñµã»÷µ½Ä³¸öÎïÌå
+ public bool IsPointerOverGameObject() + { + return IsPointerOverGameObject(PointerInputModule.kMouseLeftId); + } + + //c ÊÇ·ñµã»÷µ½Ä³¸öÎïÌå + public bool IsPointerOverGameObject(int pointerId) + { + if (m_CurrentInputModule == null) + return false; + + return m_CurrentInputModule.IsPointerOverGameObject(pointerId); + } + + protected override void OnEnable() + { + base.OnEnable(); + if (EventSystem.current == null) + EventSystem.current = this; +#if UNITY_EDITOR + else + { + Debug.LogWarning("Multiple EventSystems in scene... this is not supported"); + } +#endif + } + + protected override void OnDisable() + { + if (m_CurrentInputModule != null) + { + m_CurrentInputModule.DeactivateModule(); + m_CurrentInputModule = null; + } + + if (EventSystem.current == this) + EventSystem.current = null; + + base.OnDisable(); + } + + protected virtual void OnApplicationFocus(bool hasFocus) + { + m_HasFocus = hasFocus; + } + + private void TickModules() + { + // Ö»ÓÐstandaloneInputModuleÒ»¸ö + for (var i = 0; i < m_SystemInputModules.Count; i++) + { + if (m_SystemInputModules[i] != null) + m_SystemInputModules[i].UpdateModule(); + } + } + + //c ʼþ´¦ÀíÅÜÔÚÒ»¸öupdateÀÒÔÂÖѵµÄ·½Ê½¼ì²âÊäÈë + protected virtual void Update() + { + if (current != this) + return; + + // Ö»¸üÐÂÊó±êλÖà + TickModules(); + + // ½«m_CurrentInputModuleÉèÖÃΪm_SystemInputModulesµÚÒ»¸ö¿ÉÓõÄmodule + bool changedModule = false; + for (var i = 0; i < m_SystemInputModules.Count; i++) + { + var module = m_SystemInputModules[i]; + if (module.IsModuleSupported() && module.ShouldActivateModule()) + { + if (m_CurrentInputModule != module) + { + ChangeEventModule(module); + changedModule = true; + } + break; + } + } + // no event module set... set the first valid one... + if (m_CurrentInputModule == null) + { + for (var i = 0; i < m_SystemInputModules.Count; i++) + { + var module = m_SystemInputModules[i]; + if (module.IsModuleSupported()) + { + ChangeEventModule(module); + changedModule = true; + break; + } + } + } + + //c! Ö´ÐÐʼþ´¦ÀíÖ÷Èë¿Ú£¬Í¨³£Çé¿öÏ£¬Èç¹ûûÓÐ×Ô¶¨ÒåµÄinputModule£¬¾ÍÊÇ×ßStandaloneInputModuleµÄProcess + if (!changedModule && m_CurrentInputModule != null) + m_CurrentInputModule.Process(); + } + + private void ChangeEventModule(BaseInputModule module) + { + if (m_CurrentInputModule == module) + return; + + if (m_CurrentInputModule != null) + m_CurrentInputModule.DeactivateModule(); + + if (module != null) + module.ActivateModule(); + m_CurrentInputModule = module; + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.AppendLine("<b>Selected:</b>" + currentSelectedGameObject); + sb.AppendLine(); + sb.AppendLine(); + sb.AppendLine(m_CurrentInputModule != null ? m_CurrentInputModule.ToString() : "No module"); + return sb.ToString(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs.meta new file mode 100644 index 0000000..8ff114e --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 153642a2f08376d4daebdf63af9e161a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs new file mode 100644 index 0000000..11d1c1c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Events; +using UnityEngine.Serialization; + +namespace UnityEngine.EventSystems +{ + //c Ò»¸ö¸¨Öú×é¼þ£¬¸øÒ»¸öʼþÌí¼Ó×Ô¶¨ÒåµÄ»Øµ÷º¯Êý + //¼Ì³ÐÁËËùÓнӿڣ¬Ð§Âʲ»¸ß£¬É÷Óá£Ö»ÊDZȽϷ½±ã + + [AddComponentMenu("Event/Event Trigger")] + public class EventTrigger : + MonoBehaviour, + IPointerEnterHandler, + IPointerExitHandler, + IPointerDownHandler, + IPointerUpHandler, + IPointerClickHandler, + IInitializePotentialDragHandler, + IBeginDragHandler, + IDragHandler, + IEndDragHandler, + IDropHandler, + IScrollHandler, + IUpdateSelectedHandler, + ISelectHandler, + IDeselectHandler, + IMoveHandler, + ISubmitHandler, + ICancelHandler + { + [Serializable] + public class TriggerEvent : UnityEvent<BaseEventData> + {} + + [Serializable] + public class Entry + { + public EventTriggerType eventID = EventTriggerType.PointerClick; + public TriggerEvent callback = new TriggerEvent(); + } + + [FormerlySerializedAs("delegates")] + [SerializeField] + private List<Entry> m_Delegates; + + [Obsolete("Please use triggers instead (UnityUpgradable) -> triggers", true)] + public List<Entry> delegates; + + protected EventTrigger() + {} + + public List<Entry> triggers + { + get + { + if (m_Delegates == null) + m_Delegates = new List<Entry>(); + return m_Delegates; + } + set { m_Delegates = value; } + } + + private void Execute(EventTriggerType id, BaseEventData eventData) + { + for (int i = 0, imax = triggers.Count; i < imax; ++i) + { + var ent = triggers[i]; + if (ent.eventID == id && ent.callback != null) + ent.callback.Invoke(eventData); + } + } + + public virtual void OnPointerEnter(PointerEventData eventData) + { + Execute(EventTriggerType.PointerEnter, eventData); + } + + public virtual void OnPointerExit(PointerEventData eventData) + { + Execute(EventTriggerType.PointerExit, eventData); + } + + public virtual void OnDrag(PointerEventData eventData) + { + Execute(EventTriggerType.Drag, eventData); + } + + public virtual void OnDrop(PointerEventData eventData) + { + Execute(EventTriggerType.Drop, eventData); + } + + public virtual void OnPointerDown(PointerEventData eventData) + { + Execute(EventTriggerType.PointerDown, eventData); + } + + public virtual void OnPointerUp(PointerEventData eventData) + { + Execute(EventTriggerType.PointerUp, eventData); + } + + public virtual void OnPointerClick(PointerEventData eventData) + { + Execute(EventTriggerType.PointerClick, eventData); + } + + public virtual void OnSelect(BaseEventData eventData) + { + Execute(EventTriggerType.Select, eventData); + } + + public virtual void OnDeselect(BaseEventData eventData) + { + Execute(EventTriggerType.Deselect, eventData); + } + + public virtual void OnScroll(PointerEventData eventData) + { + Execute(EventTriggerType.Scroll, eventData); + } + + public virtual void OnMove(AxisEventData eventData) + { + Execute(EventTriggerType.Move, eventData); + } + + public virtual void OnUpdateSelected(BaseEventData eventData) + { + Execute(EventTriggerType.UpdateSelected, eventData); + } + + public virtual void OnInitializePotentialDrag(PointerEventData eventData) + { + Execute(EventTriggerType.InitializePotentialDrag, eventData); + } + + public virtual void OnBeginDrag(PointerEventData eventData) + { + Execute(EventTriggerType.BeginDrag, eventData); + } + + public virtual void OnEndDrag(PointerEventData eventData) + { + Execute(EventTriggerType.EndDrag, eventData); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + Execute(EventTriggerType.Submit, eventData); + } + + public virtual void OnCancel(BaseEventData eventData) + { + Execute(EventTriggerType.Cancel, eventData); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs.meta new file mode 100644 index 0000000..af5beba --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bacfe5cf756f51b4f8c77a4addae254e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs new file mode 100644 index 0000000..11c232c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs @@ -0,0 +1,29 @@ +namespace UnityEngine.EventSystems +{ + /// <summary> + /// This class is capable of triggering one or more remote functions from a specified event. + /// Usage: Attach it to an object with a collider, or to a GUI Graphic of your choice. + /// NOTE: Doing this will make this object intercept ALL events, and no event bubbling will occur from this object! + /// </summary> + + public enum EventTriggerType + { + PointerEnter = 0, + PointerExit = 1, + PointerDown = 2, + PointerUp = 3, + PointerClick = 4, + Drag = 5, + Drop = 6, + Scroll = 7, + UpdateSelected = 8, + Select = 9, + Deselect = 10, + Move = 11, + InitializePotentialDrag = 12, + BeginDrag = 13, + EndDrag = 14, + Submit = 15, + Cancel = 16 + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs.meta new file mode 100644 index 0000000..4647857 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/EventTriggerType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec8af6a988832aa46844f9df796dfc4c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs new file mode 100644 index 0000000..a749ce8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs @@ -0,0 +1,368 @@ +using System; +using System.Collections.Generic; +using UnityEngine.UI; + +namespace UnityEngine.EventSystems +{ + // ×î¹Ø¼üµÄÀ࣬µ÷ÓÃgameobject¶ÔÓ¦µÄ»Øµ÷º¯Êý + public static class ExecuteEvents + { + public delegate void EventFunction<T1>(T1 handler, BaseEventData eventData); + + public static T ValidateEventData<T>(BaseEventData data) where T : class + { + if ((data as T) == null) + throw new ArgumentException(String.Format("Invalid type: {0} passed to event expecting {1}", data.GetType(), typeof(T))); + return data as T; + } + + private static readonly EventFunction<IPointerEnterHandler> s_PointerEnterHandler = Execute; + + private static void Execute(IPointerEnterHandler handler, BaseEventData eventData) + { + handler.OnPointerEnter(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IPointerExitHandler> s_PointerExitHandler = Execute; + + private static void Execute(IPointerExitHandler handler, BaseEventData eventData) + { + handler.OnPointerExit(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IPointerDownHandler> s_PointerDownHandler = Execute; + + private static void Execute(IPointerDownHandler handler, BaseEventData eventData) + { + handler.OnPointerDown(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IPointerUpHandler> s_PointerUpHandler = Execute; + + private static void Execute(IPointerUpHandler handler, BaseEventData eventData) + { + handler.OnPointerUp(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IPointerClickHandler> s_PointerClickHandler = Execute; + + private static void Execute(IPointerClickHandler handler, BaseEventData eventData) + { + handler.OnPointerClick(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IInitializePotentialDragHandler> s_InitializePotentialDragHandler = Execute; + + private static void Execute(IInitializePotentialDragHandler handler, BaseEventData eventData) + { + handler.OnInitializePotentialDrag(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IBeginDragHandler> s_BeginDragHandler = Execute; + + private static void Execute(IBeginDragHandler handler, BaseEventData eventData) + { + handler.OnBeginDrag(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IDragHandler> s_DragHandler = Execute; + + private static void Execute(IDragHandler handler, BaseEventData eventData) + { + handler.OnDrag(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IEndDragHandler> s_EndDragHandler = Execute; + + private static void Execute(IEndDragHandler handler, BaseEventData eventData) + { + handler.OnEndDrag(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IDropHandler> s_DropHandler = Execute; + + private static void Execute(IDropHandler handler, BaseEventData eventData) + { + handler.OnDrop(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IScrollHandler> s_ScrollHandler = Execute; + + private static void Execute(IScrollHandler handler, BaseEventData eventData) + { + handler.OnScroll(ValidateEventData<PointerEventData>(eventData)); + } + + private static readonly EventFunction<IUpdateSelectedHandler> s_UpdateSelectedHandler = Execute; + + private static void Execute(IUpdateSelectedHandler handler, BaseEventData eventData) + { + handler.OnUpdateSelected(eventData); + } + + private static readonly EventFunction<ISelectHandler> s_SelectHandler = Execute; + + private static void Execute(ISelectHandler handler, BaseEventData eventData) + { + handler.OnSelect(eventData); + } + + private static readonly EventFunction<IDeselectHandler> s_DeselectHandler = Execute; + + private static void Execute(IDeselectHandler handler, BaseEventData eventData) + { + handler.OnDeselect(eventData); + } + + private static readonly EventFunction<IMoveHandler> s_MoveHandler = Execute; + + private static void Execute(IMoveHandler handler, BaseEventData eventData) + { + handler.OnMove(ValidateEventData<AxisEventData>(eventData)); + } + + private static readonly EventFunction<ISubmitHandler> s_SubmitHandler = Execute; + + private static void Execute(ISubmitHandler handler, BaseEventData eventData) + { + handler.OnSubmit(eventData); + } + + private static readonly EventFunction<ICancelHandler> s_CancelHandler = Execute; + + private static void Execute(ICancelHandler handler, BaseEventData eventData) + { + handler.OnCancel(eventData); + } + + public static EventFunction<IPointerEnterHandler> pointerEnterHandler + { + get { return s_PointerEnterHandler; } + } + + public static EventFunction<IPointerExitHandler> pointerExitHandler + { + get { return s_PointerExitHandler; } + } + + public static EventFunction<IPointerDownHandler> pointerDownHandler + { + get { return s_PointerDownHandler; } + } + + public static EventFunction<IPointerUpHandler> pointerUpHandler + { + get { return s_PointerUpHandler; } + } + + public static EventFunction<IPointerClickHandler> pointerClickHandler + { + get { return s_PointerClickHandler; } + } + + public static EventFunction<IInitializePotentialDragHandler> initializePotentialDrag + { + get { return s_InitializePotentialDragHandler; } + } + + public static EventFunction<IBeginDragHandler> beginDragHandler + { + get { return s_BeginDragHandler; } + } + + public static EventFunction<IDragHandler> dragHandler + { + get { return s_DragHandler; } + } + + public static EventFunction<IEndDragHandler> endDragHandler + { + get { return s_EndDragHandler; } + } + + public static EventFunction<IDropHandler> dropHandler + { + get { return s_DropHandler; } + } + + public static EventFunction<IScrollHandler> scrollHandler + { + get { return s_ScrollHandler; } + } + + public static EventFunction<IUpdateSelectedHandler> updateSelectedHandler + { + get { return s_UpdateSelectedHandler; } + } + + public static EventFunction<ISelectHandler> selectHandler + { + get { return s_SelectHandler; } + } + + public static EventFunction<IDeselectHandler> deselectHandler + { + get { return s_DeselectHandler; } + } + + public static EventFunction<IMoveHandler> moveHandler + { + get { return s_MoveHandler; } + } + + public static EventFunction<ISubmitHandler> submitHandler + { + get { return s_SubmitHandler; } + } + + public static EventFunction<ICancelHandler> cancelHandler + { + get { return s_CancelHandler; } + } + + private static void GetEventChain(GameObject root, IList<Transform> eventChain) + { + eventChain.Clear(); + if (root == null) + return; + + var t = root.transform; + while (t != null) + { + eventChain.Add(t); + t = t.parent; + } + } + + //IEventSystemHandlerÊÇËùÓнӿڵĻùÀà + private static readonly ObjectPool<List<IEventSystemHandler>> s_HandlerListPool = new ObjectPool<List<IEventSystemHandler>>(null, l => l.Clear()); + + // Ïòtarget gameobject·¢ËÍÒ»¸öʼþ£¬¶Ôÿ¸öʵÏÖÁËT½Ó¿ÚµÄÀàÖ´ÐÐfunctor·½·¨£¨¾ÍÊǽӿÚÖж¨ÒåµÄ»Øµ÷£© + public static bool Execute<T>(GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler + { + var internalHandlers = s_HandlerListPool.Get(); + GetEventList<T>(target, internalHandlers); + // if (s_InternalHandlers.Count > 0) + // Debug.Log("Executinng " + typeof (T) + " on " + target); + + // Äõ½ÊµÏÖÁËT½Ó¿ÚµÄ×é¼þ£¬µ÷ÓöÔÓ¦µÄ·½·¨ + + for (var i = 0; i < internalHandlers.Count; i++) + { + T arg; + try + { + arg = (T)internalHandlers[i]; + } + catch (Exception e) + { + var temp = internalHandlers[i]; + Debug.LogException(new Exception(string.Format("Type {0} expected {1} received.", typeof(T).Name, temp.GetType().Name), e)); + continue; + } + + try + { + functor(arg, eventData); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + var handlerCount = internalHandlers.Count; + s_HandlerListPool.Release(internalHandlers); + return handlerCount > 0; + } + + /// <summary> + /// Execute the specified event on the first game object underneath the current touch. + /// </summary> + private static readonly List<Transform> s_InternalTransformList = new List<Transform>(30); + + public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler + { + GetEventChain(root, s_InternalTransformList); + + for (var i = 0; i < s_InternalTransformList.Count; i++) + { + var transform = s_InternalTransformList[i]; + if (Execute(transform.gameObject, eventData, callbackFunction)) + return transform.gameObject; + } + return null; + } + + //c componentÊÇ·ñÆ¥ÅäÀàÐÍTÇÒÊÇ·ñ±»¼¤»î + private static bool ShouldSendToComponent<T>(Component component) where T : IEventSystemHandler + { + var valid = component is T; + if (!valid) + return false; + + var behaviour = component as Behaviour; + if (behaviour != null) + return behaviour.isActiveAndEnabled; + return true; + } + + /// <summary> + /// Get the specified object's event event. + /// </summary> + private static void GetEventList<T>(GameObject go, IList<IEventSystemHandler> results) where T : IEventSystemHandler + { + // Debug.LogWarning("GetEventList<" + typeof(T).Name + ">"); + if (results == null) + throw new ArgumentException("Results array is null", "results"); + + if (go == null || !go.activeInHierarchy) + return; + + var components = ListPool<Component>.Get(); + go.GetComponents(components); + // ±éÀúËùÓеÄ×é¼þ£¬ÕÒµ½Æ¥ÅäÀàÐÍTµÄ + for (var i = 0; i < components.Count; i++) + { + // Èç¹û²»Æ¥ÅäÀàÐÍT£¬Ìø¹ýÕâ¸ö + if (!ShouldSendToComponent<T>(components[i])) + continue; + + // Debug.Log(string.Format("{2} found! On {0}.{1}", go, s_GetComponentsScratch[i].GetType(), typeof(T))); + results.Add(components[i] as IEventSystemHandler); + } + ListPool<Component>.Release(components); + // Debug.LogWarning("end GetEventList<" + typeof(T).Name + ">"); + } + + /// <summary> + /// Whether the specified game object will be able to handle the specified event. + /// </summary> + public static bool CanHandleEvent<T>(GameObject go) where T : IEventSystemHandler + { + var internalHandlers = s_HandlerListPool.Get(); + GetEventList<T>(go, internalHandlers); + var handlerCount = internalHandlers.Count; + s_HandlerListPool.Release(internalHandlers); + return handlerCount != 0; + } + + /// <summary> + /// Bubble the specified event on the game object, figuring out which object will actually receive the event. + /// </summary> + public static GameObject GetEventHandler<T>(GameObject root) where T : IEventSystemHandler + { + if (root == null) + return null; + + Transform t = root.transform; + while (t != null) + { + if (CanHandleEvent<T>(t.gameObject)) + return t.gameObject; + t = t.parent; + } + return null; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs.meta new file mode 100644 index 0000000..6317afb --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/ExecuteEvents.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06bc2e6f5036fa848bb09004f4ab4e54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs new file mode 100644 index 0000000..4f4147c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs @@ -0,0 +1,11 @@ +namespace UnityEngine.EventSystems +{ + public enum MoveDirection + { + Left, + Up, + Right, + Down, + None + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs.meta new file mode 100644 index 0000000..ba67175 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/EventHandler/MoveDirection.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a1de2f5af1cc8aa4aa68afe78b9c671e +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules.meta new file mode 100644 index 0000000..377e98b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 01c44af785d19084ba79209e04e7e3b3 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs new file mode 100644 index 0000000..8d22d04 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs @@ -0,0 +1,80 @@ +namespace UnityEngine.EventSystems +{ + + //c ¶ÔUnityEngine.Input½øÐÐÒ»´Î¼òµ¥°ü×°£¬·½±ãµ÷ÊÔ + // ÁíÍâÈç¹ûÏ£Íû×Ô¶¨ÒåÊäÈ룬¼Ì³ÐÕâ¸öÀ࣬²¢ÊµÏÖÕâЩÊôÐÔ + public class BaseInput : UIBehaviour + { + public virtual string compositionString + { + get { return Input.compositionString; } + } + + public virtual IMECompositionMode imeCompositionMode + { + get { return Input.imeCompositionMode; } + set { Input.imeCompositionMode = value; } + } + + public virtual Vector2 compositionCursorPos + { + get { return Input.compositionCursorPos; } + set { Input.compositionCursorPos = value; } + } + + public virtual bool mousePresent + { + get { return Input.mousePresent; } + } + + public virtual bool GetMouseButtonDown(int button) + { + return Input.GetMouseButtonDown(button); + } + + public virtual bool GetMouseButtonUp(int button) + { + return Input.GetMouseButtonUp(button); + } + + public virtual bool GetMouseButton(int button) + { + return Input.GetMouseButton(button); + } + + public virtual Vector2 mousePosition + { + get { return Input.mousePosition; } + } + + public virtual Vector2 mouseScrollDelta + { + get { return Input.mouseScrollDelta; } + } + + public virtual bool touchSupported + { + get { return Input.touchSupported; } + } + + public virtual int touchCount + { + get { return Input.touchCount; } + } + + public virtual Touch GetTouch(int index) + { + return Input.GetTouch(index); + } + + public virtual float GetAxisRaw(string axisName) + { + return Input.GetAxisRaw(axisName); + } + + public virtual bool GetButtonDown(string buttonName) + { + return Input.GetButtonDown(buttonName); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs.meta new file mode 100644 index 0000000..57a6da5 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInput.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6b9bc579ce1ae3148add9cf327b4ff2e +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs new file mode 100644 index 0000000..afb4678 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.EventSystems +{ + [RequireComponent(typeof(EventSystem))] + public abstract class BaseInputModule : UIBehaviour + { + [NonSerialized] + protected List<RaycastResult> m_RaycastResultCache = new List<RaycastResult>(); + + private AxisEventData m_AxisEventData; + + private EventSystem m_EventSystem; + private BaseEventData m_BaseEventData; + +#region ÊäÈëϵͳ + // Èç¹ûm_InputOverride²»Îª¿Õ¾ÍÓÃËü£¬·ñÔòÓÃĬÈϵÄm_DefaultInput + // Èç¹ûÒª×Ô¼ºÊµÏÖBaseInput£¬¼Ì³Ð´ËÀಢ¸øÕâ¸ö×ֶθ³Öµ + // StandaloneInputModuleûÓÐ×Ô¶¨Ò壬ֱ½Ó²ÉÓõÄÊÇBaseInput + protected BaseInput m_InputOverride; + private BaseInput m_DefaultInput; + public BaseInput input + { + get + { + if (m_InputOverride != null) + return m_InputOverride; + + if (m_DefaultInput == null) + { + var inputs = GetComponents<BaseInput>(); + foreach (var baseInput in inputs) + { + // We dont want to use any classes that derrive from BaseInput for default. + if (baseInput != null && baseInput.GetType() == typeof(BaseInput)) + { + m_DefaultInput = baseInput; + break; + } + } + + if (m_DefaultInput == null) + m_DefaultInput = gameObject.AddComponent<BaseInput>(); + } + return m_DefaultInput; + } + } +#endregion + + protected EventSystem eventSystem + { + get { return m_EventSystem; } + } + + protected override void OnEnable() + { + base.OnEnable(); + if(input != null)
+ {
+ } + m_EventSystem = GetComponent<EventSystem>(); + m_EventSystem.UpdateModules(); // °Ñ´Ëinput module¼ÓÈëEventSystem + } + + protected override void OnDisable() + { + m_EventSystem.UpdateModules();// °Ñ´Ëinput moduleÒÆ³öEventSystem + base.OnDisable(); + } + + public abstract void Process(); + + protected static RaycastResult FindFirstRaycast(List<RaycastResult> candidates) + { + for (var i = 0; i < candidates.Count; ++i) + { + if (candidates[i].gameObject == null) + continue; + + return candidates[i]; + } + return new RaycastResult(); + } + + protected static MoveDirection DetermineMoveDirection(float x, float y) + { + return DetermineMoveDirection(x, y, 0.6f); + } + + protected static MoveDirection DetermineMoveDirection(float x, float y, float deadZone) + { + // if vector is too small... just return + if (new Vector2(x, y).sqrMagnitude < deadZone * deadZone) + return MoveDirection.None; + + if (Mathf.Abs(x) > Mathf.Abs(y)) + { + if (x > 0) + return MoveDirection.Right; + return MoveDirection.Left; + } + else + { + if (y > 0) + return MoveDirection.Up; + return MoveDirection.Down; + } + } + + protected static GameObject FindCommonRoot(GameObject g1, GameObject g2) + { + if (g1 == null || g2 == null) + return null; + + var t1 = g1.transform; + while (t1 != null) + { + var t2 = g2.transform; + while (t2 != null) + { + if (t1 == t2) + return t1.gameObject; + t2 = t2.parent; + } + t1 = t1.parent; + } + return null; + } + + // walk up the tree till a common root between the last entered and the current entered is foung + // send exit events up to (but not inluding) the common root. Then send enter events up to + // (but not including the common root). + protected void HandlePointerExitAndEnter(PointerEventData currentPointerData, GameObject newEnterTarget) + { + // if we have no target / pointerEnter has been deleted + // just send exit events to anything we are tracking + // then exit + if (newEnterTarget == null || currentPointerData.pointerEnter == null) + { + for (var i = 0; i < currentPointerData.hovered.Count; ++i) + ExecuteEvents.Execute(currentPointerData.hovered[i], currentPointerData, ExecuteEvents.pointerExitHandler); + + currentPointerData.hovered.Clear(); + + if (newEnterTarget == null) + { + currentPointerData.pointerEnter = newEnterTarget; + return; + } + } + + // if we have not changed hover target + if (currentPointerData.pointerEnter == newEnterTarget && newEnterTarget) + return; + + GameObject commonRoot = FindCommonRoot(currentPointerData.pointerEnter, newEnterTarget); + + // and we already an entered object from last time + if (currentPointerData.pointerEnter != null) + { + // send exit handler call to all elements in the chain + // until we reach the new target, or null! + Transform t = currentPointerData.pointerEnter.transform; + + while (t != null) + { + // if we reach the common root break out! + if (commonRoot != null && commonRoot.transform == t) + break; + + ExecuteEvents.Execute(t.gameObject, currentPointerData, ExecuteEvents.pointerExitHandler); + currentPointerData.hovered.Remove(t.gameObject); + t = t.parent; + } + } + + // now issue the enter call up to but not including the common root + currentPointerData.pointerEnter = newEnterTarget; + if (newEnterTarget != null) + { + Transform t = newEnterTarget.transform; + + while (t != null && t.gameObject != commonRoot) + { + ExecuteEvents.Execute(t.gameObject, currentPointerData, ExecuteEvents.pointerEnterHandler); + currentPointerData.hovered.Add(t.gameObject); + t = t.parent; + } + } + } + + protected virtual AxisEventData GetAxisEventData(float x, float y, float moveDeadZone) + { + if (m_AxisEventData == null) + m_AxisEventData = new AxisEventData(eventSystem); + + m_AxisEventData.Reset(); + m_AxisEventData.moveVector = new Vector2(x, y); + m_AxisEventData.moveDir = DetermineMoveDirection(x, y, moveDeadZone); + return m_AxisEventData; + } + + protected virtual BaseEventData GetBaseEventData() + { + if (m_BaseEventData == null) + m_BaseEventData = new BaseEventData(eventSystem); + + m_BaseEventData.Reset(); + return m_BaseEventData; + } + + public virtual bool IsPointerOverGameObject(int pointerId) + { + return false; + } + + public virtual bool ShouldActivateModule() + { + return enabled && gameObject.activeInHierarchy; + } + + public virtual void DeactivateModule() + {} + + public virtual void ActivateModule() + {} + + // Ä£¿é¸üÐÂÈë¿Ú£¬ÔÚÕâÀïÀïÃæµ÷ÓÃInput¼ì²âʼþ + public virtual void UpdateModule() + {} + + public virtual bool IsModuleSupported() + { + return true; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs.meta new file mode 100644 index 0000000..5108b8b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/BaseInputModule.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 87c800b13211f034e90e29ad88dd2d60 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs new file mode 100644 index 0000000..3aa8e09 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs @@ -0,0 +1,342 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine.UI; + +namespace UnityEngine.EventSystems +{ + + // »á´¦Àí´¥ÆÁºÍÊó±ê + public abstract class PointerInputModule : BaseInputModule + { + public const int kMouseLeftId = -1; + public const int kMouseRightId = -2; + public const int kMouseMiddleId = -3; + + public const int kFakeTouchesId = -4; + + // Ò»¸ö³Ø×Ó + protected Dictionary<int, PointerEventData> m_PointerData = new Dictionary<int, PointerEventData>(); + + protected bool GetPointerData(int id, out PointerEventData data, bool create) + { + if (!m_PointerData.TryGetValue(id, out data) && create) // Ò»¸ö³Ø×Ó + { + data = new PointerEventData(eventSystem) + { + pointerId = id, + }; + m_PointerData.Add(id, data); + return true; + } + return false; + } + + protected void RemovePointerData(PointerEventData data) + { + m_PointerData.Remove(data.pointerId); + } + + //c ¸ù¾ÝtouchÊý¾ÝµÃµ½pointEventData£¬²¢ÇÒ±£´æraycaster½á¹û + protected PointerEventData GetTouchPointerEventData(Touch input, out bool pressed, out bool released) + { + PointerEventData pointerData; + // ´Ó³Ø×ÓÀïÄõ½´æ´¢½á¹¹£¬·µ»ØÊÇ·ñÊÇн¨½á¹¹ + var created = GetPointerData(input.fingerId, out pointerData, true); + + pointerData.Reset(); + + // pressedºÍreleasedÓÃÀ´ÅжÏ̧Æð»òÕß·ÅÏ + + pressed = created || (input.phase == TouchPhase.Began); // Èç¹û½á¹¹ÊÇн¨µÄ»òinput phaseÊÇbagan£¬ËµÃ÷ÊǸհ´Ï + released = (input.phase == TouchPhase.Canceled) || (input.phase == TouchPhase.Ended); // Èç¹ûphaseÊÇÕâÁ½ÖÖ£¬ËµÃ÷ÊÇ̧ÆðÀ´ÁË + + if (created)//Èç¹ûÊÇн¨µÄ£¬¼Ç¼ÏÂÆðʼλÖ㬷ñÔò»¹±£Áô¾ÉÖµ£¬ÏÂÃæÓÃÀ´¼ÆËãdelta + pointerData.position = input.position; + + if (pressed)//Èç¹ûÊǸհ´Ï£¬deltaÖÃΪ0 + pointerData.delta = Vector2.zero; + else + pointerData.delta = input.position - pointerData.position; // ¼ÆËãdelta + + pointerData.position = input.position; // ¼ÆËãÍêdeltaºó¸²¸Ç + + pointerData.button = PointerEventData.InputButton.Left; // ÕâÀï²»ÖªµÀΪʲô + + // ÓÃÕâ¸ö´¥ÃþÊý¾Ý×öÉäÏß¼ì²â£¬¼ì²â½á¹ûÔÚm_RaycastResultCache + eventSystem.RaycastAll(pointerData, m_RaycastResultCache); + + // ֻȡµÚÒ»¸ö£¬ÉáÆúÆäËûµÄ + var raycast = FindFirstRaycast(m_RaycastResultCache); + Debug.Log("raycast: " + raycast.index); + pointerData.pointerCurrentRaycast = raycast; + m_RaycastResultCache.Clear(); + return pointerData; + } + + protected void CopyFromTo(PointerEventData @from, PointerEventData @to) + { + @to.position = @from.position; + @to.delta = @from.delta; + @to.scrollDelta = @from.scrollDelta; + @to.pointerCurrentRaycast = @from.pointerCurrentRaycast; + @to.pointerEnter = @from.pointerEnter; + } + + protected PointerEventData.FramePressState StateForMouseButton(int buttonId) + { + var pressed = input.GetMouseButtonDown(buttonId); + var released = input.GetMouseButtonUp(buttonId); + if (pressed && released) + return PointerEventData.FramePressState.PressedAndReleased; + if (pressed) + return PointerEventData.FramePressState.Pressed; + if (released) + return PointerEventData.FramePressState.Released; + return PointerEventData.FramePressState.NotChanged; + } + + protected class ButtonState + { + private PointerEventData.InputButton m_Button = PointerEventData.InputButton.Left; + + public MouseButtonEventData eventData + { + get { return m_EventData; } + set { m_EventData = value; } + } + + public PointerEventData.InputButton button + { + get { return m_Button; } + set { m_Button = value; } + } + + private MouseButtonEventData m_EventData; + } + + protected class MouseState + { + private List<ButtonState> m_TrackedButtons = new List<ButtonState>(); + + public bool AnyPressesThisFrame() + { + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].eventData.PressedThisFrame()) + return true; + } + return false; + } + + public bool AnyReleasesThisFrame() + { + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].eventData.ReleasedThisFrame()) + return true; + } + return false; + } + + public ButtonState GetButtonState(PointerEventData.InputButton button) + { + ButtonState tracked = null; + for (int i = 0; i < m_TrackedButtons.Count; i++) + { + if (m_TrackedButtons[i].button == button) + { + tracked = m_TrackedButtons[i]; + break; + } + } + + if (tracked == null) + { + tracked = new ButtonState { button = button, eventData = new MouseButtonEventData() }; + m_TrackedButtons.Add(tracked); + } + return tracked; + } + + public void SetButtonState(PointerEventData.InputButton button, PointerEventData.FramePressState stateForMouseButton, PointerEventData data) + { + var toModify = GetButtonState(button); + toModify.eventData.buttonState = stateForMouseButton; + toModify.eventData.buttonData = data; + } + } + + public class MouseButtonEventData + { + public PointerEventData.FramePressState buttonState; + public PointerEventData buttonData; + + public bool PressedThisFrame() + { + return buttonState == PointerEventData.FramePressState.Pressed || buttonState == PointerEventData.FramePressState.PressedAndReleased; + } + + public bool ReleasedThisFrame() + { + return buttonState == PointerEventData.FramePressState.Released || buttonState == PointerEventData.FramePressState.PressedAndReleased; + } + } + + private readonly MouseState m_MouseState = new MouseState(); + + protected virtual MouseState GetMousePointerEventData() + { + return GetMousePointerEventData(0); + } + + protected virtual MouseState GetMousePointerEventData(int id) + { + // Populate the left button... + PointerEventData leftData; + var created = GetPointerData(kMouseLeftId, out leftData, true); + + leftData.Reset(); + + if (created) + leftData.position = input.mousePosition; + + Vector2 pos = input.mousePosition; + if (Cursor.lockState == CursorLockMode.Locked) + { + // We don't want to do ANY cursor-based interaction when the mouse is locked + leftData.position = new Vector2(-1.0f, -1.0f); + leftData.delta = Vector2.zero; + } + else + { + leftData.delta = pos - leftData.position; + leftData.position = pos; + } + leftData.scrollDelta = input.mouseScrollDelta; + leftData.button = PointerEventData.InputButton.Left; + eventSystem.RaycastAll(leftData, m_RaycastResultCache); + + // Ö»ÒªµÚÒ»¸öraycast½á¹û + var raycast = FindFirstRaycast(m_RaycastResultCache); + leftData.pointerCurrentRaycast = raycast; + m_RaycastResultCache.Clear(); + + // copy the apropriate data into right and middle slots + PointerEventData rightData; + GetPointerData(kMouseRightId, out rightData, true); + CopyFromTo(leftData, rightData); + rightData.button = PointerEventData.InputButton.Right; + + PointerEventData middleData; + GetPointerData(kMouseMiddleId, out middleData, true); + CopyFromTo(leftData, middleData); + middleData.button = PointerEventData.InputButton.Middle; + + // ÉèÖð´¼ü״̬ + m_MouseState.SetButtonState(PointerEventData.InputButton.Left, StateForMouseButton(0), leftData); + m_MouseState.SetButtonState(PointerEventData.InputButton.Right, StateForMouseButton(1), rightData); + m_MouseState.SetButtonState(PointerEventData.InputButton.Middle, StateForMouseButton(2), middleData); + + return m_MouseState; + } + + protected PointerEventData GetLastPointerEventData(int id) + { + PointerEventData data; + GetPointerData(id, out data, false); + return data; + } + + private static bool ShouldStartDrag(Vector2 pressPos, Vector2 currentPos, float threshold, bool useDragThreshold) + { + if (!useDragThreshold) + return true; + + return (pressPos - currentPos).sqrMagnitude >= threshold * threshold; + } + + protected virtual void ProcessMove(PointerEventData pointerEvent) + { + var targetGO = (Cursor.lockState == CursorLockMode.Locked ? null : pointerEvent.pointerCurrentRaycast.gameObject); + HandlePointerExitAndEnter(pointerEvent, targetGO); + } + + // ·¢ËÍdragʼþ + protected virtual void ProcessDrag(PointerEventData pointerEvent) + { + if (!pointerEvent.IsPointerMoving() || + Cursor.lockState == CursorLockMode.Locked || + pointerEvent.pointerDrag == null) + return; + + if (!pointerEvent.dragging + && ShouldStartDrag(pointerEvent.pressPosition, pointerEvent.position, eventSystem.pixelDragThreshold, pointerEvent.useDragThreshold)) + { + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler); + pointerEvent.dragging = true; + } + + // Drag notification + if (pointerEvent.dragging) + { + // Before doing drag we should cancel any pointer down state + // And clear selection! + if (pointerEvent.pointerPress != pointerEvent.pointerDrag) + { + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + } + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler); + } + } + + public override bool IsPointerOverGameObject(int pointerId) + { + var lastPointer = GetLastPointerEventData(pointerId); + if (lastPointer != null) + return lastPointer.pointerEnter != null; + return false; + } + + protected void ClearSelection() + { + var baseEventData = GetBaseEventData(); + + foreach (var pointer in m_PointerData.Values) + { + // clear all selection + HandlePointerExitAndEnter(pointer, null); + } + + m_PointerData.Clear(); + eventSystem.SetSelectedGameObject(null, baseEventData); + } + + public override string ToString() + { + var sb = new StringBuilder("<b>Pointer Input Module of type: </b>" + GetType()); + sb.AppendLine(); + foreach (var pointer in m_PointerData) + { + if (pointer.Value == null) + continue; + sb.AppendLine("<B>Pointer:</b> " + pointer.Key); + sb.AppendLine(pointer.Value.ToString()); + } + return sb.ToString(); + } + + protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent) + { + // Selection tracking + var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo); + // if we have clicked something new, deselect the old thing + // leave 'selection handling' up to the press event though. + if (selectHandlerGO != eventSystem.currentSelectedGameObject) + eventSystem.SetSelectedGameObject(null, pointerEvent); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs.meta new file mode 100644 index 0000000..e4f85e9 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/PointerInputModule.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: ca2a80b2630ad814e85c9b5d17e69cbf +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs new file mode 100644 index 0000000..592ea4d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs @@ -0,0 +1,623 @@ +/* + * StandaloneInputModule : + * PointerInputModule : + * BaseInputModule + */ + +using System; +using UnityEngine; +using UnityEngine.Serialization; + +namespace UnityEngine.EventSystems +{ + [AddComponentMenu("Event/Standalone Input Module")] + public class StandaloneInputModule : PointerInputModule + { + private float m_PrevActionTime; + private Vector2 m_LastMoveVector; + private int m_ConsecutiveMoveCount = 0; + + // ÉÏÒ»¸öÊó±êλÖú͵±Ç°Êó±êλÖã¬Ã¿Ö¡¸üР+ private Vector2 m_LastMousePosition; + private Vector2 m_MousePosition; + + private GameObject m_CurrentFocusedGameObject; + + protected StandaloneInputModule() + { + } + + [Obsolete("Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.", false)] + public enum InputMode + { + Mouse, + Buttons + } + + [Obsolete("Mode is no longer needed on input module as it handles both mouse and keyboard simultaneously.", false)] + public InputMode inputMode + { + get { return InputMode.Mouse; } + } + + [SerializeField] + private string m_HorizontalAxis = "Horizontal"; + + /// <summary> + /// Name of the vertical axis for movement (if axis events are used). + /// </summary> + [SerializeField] + private string m_VerticalAxis = "Vertical"; + + /// <summary> + /// Name of the submit button. + /// </summary> + [SerializeField] + private string m_SubmitButton = "Submit"; + + /// <summary> + /// Name of the submit button. + /// </summary> + [SerializeField] + private string m_CancelButton = "Cancel"; + + [SerializeField] + private float m_InputActionsPerSecond = 10; + + [SerializeField] + private float m_RepeatDelay = 0.5f; + + [SerializeField] + [FormerlySerializedAs("m_AllowActivationOnMobileDevice")] + private bool m_ForceModuleActive; + + [Obsolete("allowActivationOnMobileDevice has been deprecated. Use forceModuleActive instead (UnityUpgradable) -> forceModuleActive")] + public bool allowActivationOnMobileDevice + { + get { return m_ForceModuleActive; } + set { m_ForceModuleActive = value; } + } + + public bool forceModuleActive + { + get { return m_ForceModuleActive; } + set { m_ForceModuleActive = value; } + } + + public float inputActionsPerSecond + { + get { return m_InputActionsPerSecond; } + set { m_InputActionsPerSecond = value; } + } + + public float repeatDelay + { + get { return m_RepeatDelay; } + set { m_RepeatDelay = value; } + } + + /// <summary> + /// Name of the horizontal axis for movement (if axis events are used). + /// </summary> + public string horizontalAxis + { + get { return m_HorizontalAxis; } + set { m_HorizontalAxis = value; } + } + + /// <summary> + /// Name of the vertical axis for movement (if axis events are used). + /// </summary> + public string verticalAxis + { + get { return m_VerticalAxis; } + set { m_VerticalAxis = value; } + } + + public string submitButton + { + get { return m_SubmitButton; } + set { m_SubmitButton = value; } + } + + public string cancelButton + { + get { return m_CancelButton; } + set { m_CancelButton = value; } + } + + private bool ShouldIgnoreEventsOnNoFocus() + { + switch (SystemInfo.operatingSystemFamily) + { + case OperatingSystemFamily.Windows: + case OperatingSystemFamily.Linux: + case OperatingSystemFamily.MacOSX: +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isRemoteConnected) + return false; +#endif + return true; + default: + return false; + } + }
+
+ //c! ÕâÀïÖ»¸üÐÂÊó±êλÖÃ
+ public override void UpdateModule() + { + // Èç¹ûûÓлñÈ¡½¹µã£¬ÇÒºöÂÔûÓн¹µãʱµÄʼþ£¬·µ»Ø£¨³ý·Ç¿ªÆôÔ¶³ÌÁ¬½Ó£¬·ñÔò»áÕâÑù£© + if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) + return; + + // ¸üÐÂÊó±êλÖà + m_LastMousePosition = m_MousePosition; + m_MousePosition = input.mousePosition; + } + + public override bool IsModuleSupported() + { + return m_ForceModuleActive || input.mousePresent || input.touchSupported; + } + + public override bool ShouldActivateModule() + { + if (!base.ShouldActivateModule()) + return false; + + var shouldActivate = m_ForceModuleActive; + shouldActivate |= input.GetButtonDown(m_SubmitButton); + shouldActivate |= input.GetButtonDown(m_CancelButton); + shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_HorizontalAxis), 0.0f); + shouldActivate |= !Mathf.Approximately(input.GetAxisRaw(m_VerticalAxis), 0.0f); + shouldActivate |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f; + shouldActivate |= input.GetMouseButtonDown(0); + + if (input.touchCount > 0) + shouldActivate = true; + + return shouldActivate; + } + + public override void ActivateModule() + { + if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) + return; + + base.ActivateModule(); + m_MousePosition = input.mousePosition; + m_LastMousePosition = input.mousePosition; + + var toSelect = eventSystem.currentSelectedGameObject; + if (toSelect == null) + toSelect = eventSystem.firstSelectedGameObject; + + eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData()); + } + + public override void DeactivateModule() + { + base.DeactivateModule(); + ClearSelection(); + } + + //c! input moduleʼþ´¦ÀíÖ÷Èë¿Ú£¬Ã¿Ö¡¸üР+ public override void Process() + { + // Èç¹ûûÓлñÈ¡½¹µã£¬²»ÐèÒª´¦Àí + if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) + return; + + //event ¸øÑ¡ÖеĶÔÏó·¢²¼¸üÐÂʼþ + bool usedEvent = SendUpdateEventToSelectedObject(); + + // Èç¹û¹´ÉÏÁËSend Navigation Events£¬·¢ËÍmove , submit, cancelʼþ + if (eventSystem.sendNavigationEvents) + { + if (!usedEvent) + usedEvent |= SendMoveEventToSelectedObject(); //event ¼üÅÌ·½Ïò¼üÒÆ¶¯Ê±¸øeventSystemÑ¡ÖеĶÔÏó·¢²¼IMoveHandlerʼþ + + if (!usedEvent) + SendSubmitEventToSelectedObject(); //event Èç¹û°´ÁËÏàÓ¦°´¼ü£¬·¢²¼submit»òÕßcancelʼþ + } + + // Ä£Äâ´¥Ãþ»òÊó±êÊäÈë + // touch needs to take precedence because of the mouse emulation layer + usedEvent = ProcessTouchEvents(); //event ¼ì²âÆÁÄ»´¥Ãþ£¬PCÉÏûÓÐ + + if(!usedEvent && input.mousePresent) + ProcessMouseEvent(); // ´¦ÀíÊó±êʼþ + } + + //c ´¥Ãþʼþ + private bool ProcessTouchEvents() + { + for (int i = 0; i < input.touchCount; ++i) //¶àµã´¥¿Ø + { + Debug.Log("Touch"); + + Touch touch = input.GetTouch(i); + + if (touch.type == TouchType.Indirect) + continue; + + bool released; // ÕâÊÇÒ»¸öÊÖָ̧Æð²Ù×÷ + bool pressed; // ÕâÊÇÒ»¸öÊÖÖ¸·ÅϲÙ×÷ + // + PointerEventData pointer = GetTouchPointerEventData(touch, out pressed, out released); // ÉäÏß¼ì²â²¢±£´æ¼ì²â½á¹û + + // ´¦Àí´¥Ãþ»ò̧Æð·´À¡£¬ÒѾ׼±¸ºÃÁ˱»´¥ÃþµÄÎïÌå + ProcessTouchPress(pointer, pressed, released); + + if (!released) + { + ProcessMove(pointer); + ProcessDrag(pointer); + } + else + RemovePointerData(pointer); + } + return input.touchCount > 0; + } + + //c ´¦Àí´¥Ãþ\̧Æð + protected void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released) + { + var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; + + // ´¥Ãþ·´À¡ + // PointerDown notification + if (pressed) + { + pointerEvent.eligibleForClick = true; + pointerEvent.delta = Vector2.zero; + pointerEvent.dragging = false; + pointerEvent.useDragThreshold = true; + pointerEvent.pressPosition = pointerEvent.position; + pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; + + DeselectIfSelectionChanged(currentOverGo, pointerEvent); + + if (pointerEvent.pointerEnter != currentOverGo) + { + // send a pointer enter to the touched element if it isn't the one to select... + HandlePointerExitAndEnter(pointerEvent, currentOverGo); + pointerEvent.pointerEnter = currentOverGo; + } + + //event IPointerDownHandler + // search for the control that will receive the press + // if we can't find a press handler set the press + // handler to be what would receive a click. + var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); + + // didnt find a press handler... search for a click handler + if (newPressed == null) + newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); + + // Debug.Log("Pressed: " + newPressed); + + float time = Time.unscaledTime; + + if (newPressed == pointerEvent.lastPress) + { + var diffTime = time - pointerEvent.clickTime; + if (diffTime < 0.3f) + ++pointerEvent.clickCount; + else + pointerEvent.clickCount = 1; + + pointerEvent.clickTime = time; + } + else + { + pointerEvent.clickCount = 1; + } + + pointerEvent.pointerPress = newPressed; + pointerEvent.rawPointerPress = currentOverGo; + + pointerEvent.clickTime = time; + + // Save the drag handler as well + pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo); + + if (pointerEvent.pointerDrag != null) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); + } + + // ̧Æð·´À¡ + // PointerUp notification + if (released) + { + // Debug.Log("Executing pressup on: " + pointer.pointerPress); + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + + // Debug.Log("KeyCode: " + pointer.eventData.keyCode); + + // see if we mouse up on the same element that we clicked on... + var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); // ´ÓÕâ¸ö¶ÔÏó¿ªÊ¼ÍùÉÏÕÒ£¬Ö±µ½Ò»¸ö¹ÒÁ˼̳ÐÁËIPointerClickHandlerµÄ×é¼þ + + // PointerClick and Drop events + if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick) //Ö»ÓÐÔÚpointerPress == pointerUpHandlerʱ²Å»á´¥·¢clickʼþ + { + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler); + } + else if (pointerEvent.pointerDrag != null && pointerEvent.dragging) // Èç¹ûÁ½Õß²»ÏàµÈ£¬´¥·¢dropʼþ + { + ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); + } + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + + if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); + + pointerEvent.dragging = false; + pointerEvent.pointerDrag = null; + + // send exit events as we need to simulate this on touch up on touch device + ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler); + pointerEvent.pointerEnter = null; + } + } + + /// <summary> + /// Process submit keys. + /// </summary> + protected bool SendSubmitEventToSelectedObject() + { + if (eventSystem.currentSelectedGameObject == null) + return false; + + // ·¢²¼submitʼþ»òÕßcancelʼþ + + var data = GetBaseEventData(); + if (input.GetButtonDown(m_SubmitButton)) // ÕâÀïÊÇProject>InputÀïÃæÅäÖÃµÄ + ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler); + + if (input.GetButtonDown(m_CancelButton)) + ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler); + return data.used; + } + + private Vector2 GetRawMoveVector() + { + Vector2 move = Vector2.zero; + move.x = input.GetAxisRaw(m_HorizontalAxis); + move.y = input.GetAxisRaw(m_VerticalAxis); + + if (input.GetButtonDown(m_HorizontalAxis)) + { + if (move.x < 0) + move.x = -1f; + if (move.x > 0) + move.x = 1f; + } + if (input.GetButtonDown(m_VerticalAxis)) + { + if (move.y < 0) + move.y = -1f; + if (move.y > 0) + move.y = 1f; + } + return move; + } + + /// <summary> + /// Process keyboard events. + /// </summary> + protected bool SendMoveEventToSelectedObject() + { + float time = Time.unscaledTime; + + Vector2 movement = GetRawMoveVector(); + if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f)) // Èç¹û¼üÅÌ·½Ïò¼üû¶¯£¬·µ»Ø + { + m_ConsecutiveMoveCount = 0; + return false; + } + + //allow¼´ÊÇ·ñÔÊÐí·¢²¼Ê¼þ + // If user pressed key again, always allow event + bool allow = input.GetButtonDown(m_HorizontalAxis) || input.GetButtonDown(m_VerticalAxis); + bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0); // ºÍ֮ǰµÄ·½ÏòÊÇ·ñ¼Ð½ÇÔÚ90¡ãÒÔÄÚ£¬Èç¹ûÊǵĻ°ËµÃ÷ºÜ½Ó½ü + if (!allow) + { + // Otherwise, user held down key or axis. + // If direction didn't change at least 90 degrees, wait for delay before allowing consequtive event. + if (similarDir && m_ConsecutiveMoveCount == 1) + allow = (time > m_PrevActionTime + m_RepeatDelay); + // If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate. + else + allow = (time > m_PrevActionTime + 1f / m_InputActionsPerSecond); + } + if (!allow) + return false; + + // ·¢²¼IMoveHandlerʼþ + + // Debug.Log(m_ProcessingEvent.rawType + " axis:" + m_AllowAxisEvents + " value:" + "(" + x + "," + y + ")"); + var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f); + + if (axisEventData.moveDir != MoveDirection.None) + { + ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler); // IMoveHandler.OnMove + if (!similarDir) + m_ConsecutiveMoveCount = 0; + m_ConsecutiveMoveCount++; + + m_PrevActionTime = time; + m_LastMoveVector = movement; + } + else + { + m_ConsecutiveMoveCount = 0; + } + + return axisEventData.used; + } + + protected void ProcessMouseEvent() + { + ProcessMouseEvent(0); + } + + [Obsolete("This method is no longer checked, overriding it with return true does nothing!")] + protected virtual bool ForceAutoSelect() + { + return false; + } + + /// <summary> + /// Process all mouse events. + /// </summary> + protected void ProcessMouseEvent(int id) + { + var mouseData = GetMousePointerEventData(id); + var leftButtonData = mouseData.GetButtonState(PointerEventData.InputButton.Left).eventData; + + m_CurrentFocusedGameObject = leftButtonData.buttonData.pointerCurrentRaycast.gameObject; + + // Process the first mouse button fully + ProcessMousePress(leftButtonData); + ProcessMove(leftButtonData.buttonData); + ProcessDrag(leftButtonData.buttonData); + + // Now process right / middle clicks + ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData); + ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Right).eventData.buttonData); + ProcessMousePress(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData); + ProcessDrag(mouseData.GetButtonState(PointerEventData.InputButton.Middle).eventData.buttonData); + + if (!Mathf.Approximately(leftButtonData.buttonData.scrollDelta.sqrMagnitude, 0.0f)) + { + var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(leftButtonData.buttonData.pointerCurrentRaycast.gameObject); + ExecuteEvents.ExecuteHierarchy(scrollHandler, leftButtonData.buttonData, ExecuteEvents.scrollHandler); + } + } + + // ÿ֡·¢ËÍÒ»¸öOnUpdateSelectedʼþ + protected bool SendUpdateEventToSelectedObject() + { + if (eventSystem.currentSelectedGameObject == null) + return false; + + var data = GetBaseEventData(); + //event ÏòeventSystemµ±Ç°Ñ¡ÖеÄgameobject·¢²¼Ò»¸ö¸üÐÂʼþIUpdateSelectedHandler£¬±ÈÈçinputfield + ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler); + return data.used; + } + + // ´¦ÀíÊó±ê°´ÏÂʼþ£¬·¢ËÍÏûÏ¢£¬µ÷Óûص÷ + /// <summary> + /// Process the current mouse press. + /// </summary> + protected void ProcessMousePress(MouseButtonEventData data) + { + var pointerEvent = data.buttonData; + var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; + + // PointerDown notification + if (data.PressedThisFrame()) + { + pointerEvent.eligibleForClick = true; + pointerEvent.delta = Vector2.zero; + pointerEvent.dragging = false; + pointerEvent.useDragThreshold = true; + pointerEvent.pressPosition = pointerEvent.position; + pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; + + DeselectIfSelectionChanged(currentOverGo, pointerEvent); + + // search for the control that will receive the press + // if we can't find a press handler set the press + // handler to be what would receive a click. + var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); + + // didnt find a press handler... search for a click handler + if (newPressed == null) + newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); + + // Debug.Log("Pressed: " + newPressed); + + float time = Time.unscaledTime; + + if (newPressed == pointerEvent.lastPress) + { + var diffTime = time - pointerEvent.clickTime; + if (diffTime < 0.3f) + ++pointerEvent.clickCount; + else + pointerEvent.clickCount = 1; + + pointerEvent.clickTime = time; + } + else + { + pointerEvent.clickCount = 1; + } + + pointerEvent.pointerPress = newPressed; + pointerEvent.rawPointerPress = currentOverGo; + + pointerEvent.clickTime = time; + + // Save the drag handler as well + pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo); + + if (pointerEvent.pointerDrag != null) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); + } + + // PointerUp notification + if (data.ReleasedThisFrame()) + { + // Debug.Log("Executing pressup on: " + pointer.pointerPress); + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + + // Debug.Log("KeyCode: " + pointer.eventData.keyCode); + + // see if we mouse up on the same element that we clicked on... + var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); + + // PointerClick and Drop events + if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick) + { + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler); + } + else if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + { + ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); + } + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + + if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); + + pointerEvent.dragging = false; + pointerEvent.pointerDrag = null; + + // redo pointer enter / exit to refresh state + // so that if we moused over somethign that ignored it before + // due to having pressed on something else + // it now gets it. + if (currentOverGo != pointerEvent.pointerEnter) + { + HandlePointerExitAndEnter(pointerEvent, null); + HandlePointerExitAndEnter(pointerEvent, currentOverGo); + } + } + } + + protected GameObject GetCurrentFocusedGameObject() + { + return m_CurrentFocusedGameObject; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs.meta new file mode 100644 index 0000000..dde31b7 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/StandaloneInputModule.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e2665fa6a1fb2474d8a5c19f72f8d0c6 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs new file mode 100644 index 0000000..58ac97c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs @@ -0,0 +1,263 @@ +using System; +using System.Text; +using UnityEngine.Serialization; + +namespace UnityEngine.EventSystems +{ + //c TouchInputModule±»·ÏÆúÁË£¬Í³Ò»ÔÚstandaloneInputModuleÖд¦Àí + [Obsolete("TouchInputModule is no longer required as Touch input is now handled in StandaloneInputModule.")] + [AddComponentMenu("Event/Touch Input Module")] + public class TouchInputModule : PointerInputModule + { + protected TouchInputModule() + {} + + // ´¥ÃþµãλÖà + private Vector2 m_LastMousePosition; + private Vector2 m_MousePosition; + + [SerializeField] + [FormerlySerializedAs("m_AllowActivationOnStandalone")] + private bool m_ForceModuleActive; + + [Obsolete("allowActivationOnStandalone has been deprecated. Use forceModuleActive instead (UnityUpgradable) -> forceModuleActive")] + public bool allowActivationOnStandalone + { + get { return m_ForceModuleActive; } + set { m_ForceModuleActive = value; } + } + + public bool forceModuleActive + { + get { return m_ForceModuleActive; } + set { m_ForceModuleActive = value; } + } + + //c ¸üÐÂÊó±ê£¨´¥Ãþµã£©Î»Öà + public override void UpdateModule() + { + m_LastMousePosition = m_MousePosition; + m_MousePosition = input.mousePosition; + } + + public override bool IsModuleSupported() + { + return forceModuleActive || input.touchSupported; + } + + public override bool ShouldActivateModule() + { + if (!base.ShouldActivateModule()) + return false; + + if (m_ForceModuleActive) + return true; + + if (UseFakeInput()) + { + bool wantsEnable = input.GetMouseButtonDown(0); + + wantsEnable |= (m_MousePosition - m_LastMousePosition).sqrMagnitude > 0.0f; + return wantsEnable; + } + + if (input.touchCount > 0) + return true; + + return false; + } + + private bool UseFakeInput() + { + return !input.touchSupported; + } + + public override void Process() + { + if (UseFakeInput()) + FakeTouches(); + else + ProcessTouchEvents(); + } + + /// <summary> + /// For debugging touch-based devices using the mouse. + /// </summary> + private void FakeTouches() + { + var pointerData = GetMousePointerEventData(0); + + var leftPressData = pointerData.GetButtonState(PointerEventData.InputButton.Left).eventData; + + // fake touches... on press clear delta + if (leftPressData.PressedThisFrame()) + leftPressData.buttonData.delta = Vector2.zero; + + ProcessTouchPress(leftPressData.buttonData, leftPressData.PressedThisFrame(), leftPressData.ReleasedThisFrame()); + + // only process move if we are pressed... + if (input.GetMouseButton(0)) + { + ProcessMove(leftPressData.buttonData); + ProcessDrag(leftPressData.buttonData); + } + } + + /// <summary> + /// Process all touch events. + /// </summary> + private void ProcessTouchEvents() + { + for (int i = 0; i < input.touchCount; ++i) + { + Touch touch = input.GetTouch(i); + + if (touch.type == TouchType.Indirect) + continue; + + bool released; + bool pressed; + var pointer = GetTouchPointerEventData(touch, out pressed, out released); + + ProcessTouchPress(pointer, pressed, released); + + if (!released) + { + ProcessMove(pointer); + ProcessDrag(pointer); + } + else + RemovePointerData(pointer); + } + } + + protected void ProcessTouchPress(PointerEventData pointerEvent, bool pressed, bool released) + { + var currentOverGo = pointerEvent.pointerCurrentRaycast.gameObject; + + // PointerDown notification + if (pressed) + { + pointerEvent.eligibleForClick = true; + pointerEvent.delta = Vector2.zero; + pointerEvent.dragging = false; + pointerEvent.useDragThreshold = true; + pointerEvent.pressPosition = pointerEvent.position; + pointerEvent.pointerPressRaycast = pointerEvent.pointerCurrentRaycast; + + DeselectIfSelectionChanged(currentOverGo, pointerEvent); + + if (pointerEvent.pointerEnter != currentOverGo) + { + // send a pointer enter to the touched element if it isn't the one to select... + HandlePointerExitAndEnter(pointerEvent, currentOverGo); + pointerEvent.pointerEnter = currentOverGo; + } + + // search for the control that will receive the press + // if we can't find a press handler set the press + // handler to be what would receive a click. + var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.pointerDownHandler); + + // didnt find a press handler... search for a click handler + if (newPressed == null) + newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); + + // Debug.Log("Pressed: " + newPressed); + + float time = Time.unscaledTime; + + if (newPressed == pointerEvent.lastPress) + { + var diffTime = time - pointerEvent.clickTime; + if (diffTime < 0.3f) + ++pointerEvent.clickCount; + else + pointerEvent.clickCount = 1; + + pointerEvent.clickTime = time; + } + else + { + pointerEvent.clickCount = 1; + } + + pointerEvent.pointerPress = newPressed; + pointerEvent.rawPointerPress = currentOverGo; + + pointerEvent.clickTime = time; + + // Save the drag handler as well + pointerEvent.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo); + + if (pointerEvent.pointerDrag != null) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.initializePotentialDrag); + } + + // PointerUp notification + if (released) + { + // Debug.Log("Executing pressup on: " + pointer.pointerPress); + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler); + + // Debug.Log("KeyCode: " + pointer.eventData.keyCode); + + // see if we mouse up on the same element that we clicked on... + var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo); + + // PointerClick and Drop events + if (pointerEvent.pointerPress == pointerUpHandler && pointerEvent.eligibleForClick) + { + ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerClickHandler); + } + else if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + { + ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerEvent, ExecuteEvents.dropHandler); + } + + pointerEvent.eligibleForClick = false; + pointerEvent.pointerPress = null; + pointerEvent.rawPointerPress = null; + + if (pointerEvent.pointerDrag != null && pointerEvent.dragging) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); + + pointerEvent.dragging = false; + pointerEvent.pointerDrag = null; + + if (pointerEvent.pointerDrag != null) + ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.endDragHandler); + + pointerEvent.pointerDrag = null; + + // send exit events as we need to simulate this on touch up on touch device + ExecuteEvents.ExecuteHierarchy(pointerEvent.pointerEnter, pointerEvent, ExecuteEvents.pointerExitHandler); + pointerEvent.pointerEnter = null; + } + } + + public override void DeactivateModule() + { + base.DeactivateModule(); + ClearSelection(); + } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.AppendLine(UseFakeInput() ? "Input: Faked" : "Input: Touch"); + if (UseFakeInput()) + { + var pointerData = GetLastPointerEventData(kMouseLeftId); + if (pointerData != null) + sb.AppendLine(pointerData.ToString()); + } + else + { + foreach (var pointerEventData in m_PointerData) + sb.AppendLine(pointerEventData.ToString()); + } + return sb.ToString(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs.meta new file mode 100644 index 0000000..facfc33 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/InputModules/TouchInputModule.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 27cc0457fb3bcbe4eb6038275fbdde36 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters.meta new file mode 100644 index 0000000..104ea1f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c57aabd138e5b164ebd06107a0c19483 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs new file mode 100644 index 0000000..d58c358 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.EventSystems +{ + public abstract class BaseRaycaster : UIBehaviour + { + public abstract void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList); + public abstract Camera eventCamera { get; } + + [Obsolete("Please use sortOrderPriority and renderOrderPriority", false)] + public virtual int priority + { + get { return 0; } + } + + public virtual int sortOrderPriority + { + get { return int.MinValue; } + } + + public virtual int renderOrderPriority + { + get { return int.MinValue; } + } + + public override string ToString() + { + return "Name: " + gameObject + "\n" + + "eventCamera: " + eventCamera + "\n" + + "sortOrderPriority: " + sortOrderPriority + "\n" + + "renderOrderPriority: " + renderOrderPriority; + } + + // Ö»ÒªÊǼ̳ÐÁËBaseRaycasterµÄ¶¼»á×Ô¶¯¼Óµ½raycasterµÄÁбíÀïÃæ + protected override void OnEnable() + { + base.OnEnable(); + RaycasterManager.AddRaycaster(this); + } + + protected override void OnDisable() + { + RaycasterManager.RemoveRaycasters(this); + base.OnDisable(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs.meta new file mode 100644 index 0000000..eb8b89a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/BaseRaycaster.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 89c5c6ccaa917c94a864388cc962e706 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs new file mode 100644 index 0000000..6346938 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using UnityEngine.UI; + +namespace UnityEngine.EventSystems +{ + /// <summary> + /// Simple event system using physics raycasts. + /// </summary> + [AddComponentMenu("Event/Physics 2D Raycaster")] + [RequireComponent(typeof(Camera))] + public class Physics2DRaycaster : PhysicsRaycaster + { + protected Physics2DRaycaster() + {} + + // ·¢ÉäÏß + public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList) + { + if (eventCamera == null) + return; + + Ray ray; + float distanceToClipPlane; + ComputeRayAndDistance(eventData, out ray, out distanceToClipPlane); + + if (ReflectionMethodsCache.Singleton.getRayIntersectionAll == null) + return; + + var hits = ReflectionMethodsCache.Singleton.getRayIntersectionAll(ray, distanceToClipPlane, finalEventMask); + + if (hits.Length != 0) + { + for (int b = 0, bmax = hits.Length; b < bmax; ++b) + { + var sr = hits[b].collider.gameObject.GetComponent<SpriteRenderer>(); + + var result = new RaycastResult + { + gameObject = hits[b].collider.gameObject, + module = this, + distance = Vector3.Distance(eventCamera.transform.position, hits[b].point), + worldPosition = hits[b].point, + worldNormal = hits[b].normal, + screenPosition = eventData.position, + index = resultAppendList.Count, + sortingLayer = sr != null ? sr.sortingLayerID : 0, + sortingOrder = sr != null ? sr.sortingOrder : 0 + }; + resultAppendList.Add(result); + } + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs.meta new file mode 100644 index 0000000..828be37 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/Physics2DRaycaster.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 055a0cdd9d5d3e0489f854f7bdf22ded +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs new file mode 100644 index 0000000..c7d431c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs @@ -0,0 +1,117 @@ +using System.Collections.Generic; +using UnityEngine.UI; + +namespace UnityEngine.EventSystems +{ + //c ͶÉä3DÎïÌåµÄÏà»ú¹ÒÕâ¸ö½Å±¾ + + /// <summary> + /// Simple event system using physics raycasts. + /// </summary> + [AddComponentMenu("Event/Physics Raycaster")] + [RequireComponent(typeof(Camera))] + public class PhysicsRaycaster : BaseRaycaster + { + /// <summary> + /// Const to use for clarity when no event mask is set + /// </summary> + protected const int kNoEventMaskSet = -1; + + protected Camera m_EventCamera; + + /// <summary> + /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. + /// </summary> + [SerializeField] + protected LayerMask m_EventMask = kNoEventMaskSet; + + protected PhysicsRaycaster() + {} + + public override Camera eventCamera + { + get + { + if (m_EventCamera == null) + m_EventCamera = GetComponent<Camera>(); + return m_EventCamera ?? Camera.main; + } + } + + + /// <summary> + /// Depth used to determine the order of event processing. + /// </summary> + public virtual int depth + { + get { return (eventCamera != null) ? (int)eventCamera.depth : 0xFFFFFF; } + } + + /// <summary> + /// Event mask used to determine which objects will receive events. + /// </summary> + public int finalEventMask + { + get { return (eventCamera != null) ? eventCamera.cullingMask & m_EventMask : kNoEventMaskSet; } + } + + /// <summary> + /// Layer mask used to filter events. Always combined with the camera's culling mask if a camera is used. + /// </summary> + public LayerMask eventMask + { + get { return m_EventMask; } + set { m_EventMask = value; } + } + + protected void ComputeRayAndDistance(PointerEventData eventData, out Ray ray, out float distanceToClipPlane) + { + ray = eventCamera.ScreenPointToRay(eventData.position); + // compensate far plane distance - see MouseEvents.cs + float projectionDirection = ray.direction.z; // ray.directionÊǹéÒ»»¯Á赀 + distanceToClipPlane = Mathf.Approximately(0.0f, projectionDirection) + ? Mathf.Infinity + : Mathf.Abs((eventCamera.farClipPlane - eventCamera.nearClipPlane) / projectionDirection); + } + + public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList) + { + // Cull ray casts that are outside of the view rect. (case 636595) + if (eventCamera == null || !eventCamera.pixelRect.Contains(eventData.position)) + return; + + // ¸ù¾Ý´¥ÃþÊý¾ÝÄõ½ÉäÏß + Ray ray; + float distanceToClipPlane; + ComputeRayAndDistance(eventData, out ray, out distanceToClipPlane); + + if (ReflectionMethodsCache.Singleton.raycast3DAll == null) + return; + + var hits = ReflectionMethodsCache.Singleton.raycast3DAll(ray, distanceToClipPlane, finalEventMask); + + if (hits.Length > 1) + System.Array.Sort(hits, (r1, r2) => r1.distance.CompareTo(r2.distance)); + + if (hits.Length != 0) + { + for (int b = 0, bmax = hits.Length; b < bmax; ++b) + { + var result = new RaycastResult + { + gameObject = hits[b].collider.gameObject, + module = this, + distance = hits[b].distance, + worldPosition = hits[b].point, + worldNormal = hits[b].normal, + screenPosition = eventData.position, + index = resultAppendList.Count, + sortingLayer = 0, + sortingOrder = 0 + }; + resultAppendList.Add(result); + } + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs.meta new file mode 100644 index 0000000..848c302 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/PhysicsRaycaster.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b2bb18305a46ea44686ad8cdffbb3a58 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs new file mode 100644 index 0000000..666ef8d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs @@ -0,0 +1,65 @@ +namespace UnityEngine.EventSystems +{ + // UGUIÉäÏß¼ì²â½á¹û + public struct RaycastResult + { + private GameObject m_GameObject; // Game object hit by the raycast + + public GameObject gameObject + { + get { return m_GameObject; } + set { m_GameObject = value; } + } + + public BaseRaycaster module; // Event system that hit this object + public float distance; // The distance from the origin this hit was. + public float index; // The index this element is in the raycastList (used for sorting) + public int depth; + public int sortingLayer; + public int sortingOrder; + // World-space position where a ray cast into the screen hits something + public Vector3 worldPosition; + // World-space normal where a ray cast into the screen hits something + public Vector3 worldNormal; + + public Vector2 screenPosition; + + public bool isValid + { + get { return module != null && gameObject != null; } + } + + public void Clear() + { + gameObject = null; + module = null; + distance = 0; + index = 0; + depth = 0; + sortingLayer = 0; + sortingOrder = 0; + worldNormal = Vector3.up; + worldPosition = Vector3.zero; + screenPosition = Vector2.zero; + } + + public override string ToString() + { + if (!isValid) + return ""; + + return "Name: " + gameObject + "\n" + + "module: " + module + "\n" + + "distance: " + distance + "\n" + + "index: " + index + "\n" + + "depth: " + depth + "\n" + + "worldNormal: " + worldNormal + "\n" + + "worldPosition: " + worldPosition + "\n" + + "screenPosition: " + screenPosition + "\n" + + "module.sortOrderPriority: " + module.sortOrderPriority + "\n" + + "module.renderOrderPriority: " + module.renderOrderPriority + "\n" + + "sortingLayer: " + sortingLayer + "\n" + + "sortingOrder: " + sortingOrder; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs.meta new file mode 100644 index 0000000..c2d01ba --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycastResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f5a2c96e65809c43ad8a958f062ef1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs new file mode 100644 index 0000000..c3480b4 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace UnityEngine.EventSystems +{ + internal static class RaycasterManager + { + private static readonly List<BaseRaycaster> s_Raycasters = new List<BaseRaycaster>(); + + public static void AddRaycaster(BaseRaycaster baseRaycaster) + { + if (s_Raycasters.Contains(baseRaycaster)) + return; + + s_Raycasters.Add(baseRaycaster); + } + + public static List<BaseRaycaster> GetRaycasters() + { + return s_Raycasters; + } + + public static void RemoveRaycasters(BaseRaycaster baseRaycaster) + { + if (!s_Raycasters.Contains(baseRaycaster)) + return; + s_Raycasters.Remove(baseRaycaster); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs.meta new file mode 100644 index 0000000..594b8d2 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/Raycasters/RaycasterManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5c12b7bf7a4800945ba532802a36b165 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs new file mode 100644 index 0000000..fa24cff --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs @@ -0,0 +1,77 @@ +namespace UnityEngine.EventSystems +{ + public abstract class UIBehaviour : MonoBehaviour + {
+#region MonoBehaviour¹²ÓÐÉúÃüÖÜÆÚ +
+ protected virtual void Awake() + {} + + protected virtual void OnEnable() + {} + + protected virtual void Start() + {} + + protected virtual void OnDisable() + {} + + protected virtual void OnDestroy() + {}
+
+ // ¸¸½Úµã£¨°üÀ¨·ÇÖ±½Ó¸¸½ÚµãµÄ׿ÏȽڵ㣩ÔÚhierachyÖеĸ¸×Ӳ㼶¸Ä±äǰµ÷ÓÃ
+ protected virtual void OnBeforeTransformParentChanged() + { } + + // ¸¸½Úµã£¨°üÀ¨·ÇÖ±½Ó¸¸½ÚµãµÄ׿ÏȽڵ㣩ÔÚhierachyÖеĸ¸×Ӳ㼶¸Ä±äÍêµ÷Óà + protected virtual void OnTransformParentChanged() + { }
+
+#endregion +
+ public virtual bool IsActive() + { + return isActiveAndEnabled; + } + +#if UNITY_EDITOR + // ×é¼þÖµÔÚinspectorÖб»ÐÞ¸Äʱµ÷Óà + protected virtual void OnValidate() + {} + + // inspectorÖÐÓÒ¼üresetµ÷Óà + protected virtual void Reset() + {}
+#endif +
+#region UGUIÌØÓлص÷º¯Êý +
+ // µ±gRectTransform´óС¸Ä±ä£¨²»°üÀ¨Î»Ö㩵Äʱºò»Øµ÷¡£ÇÒÈç¹û×ÓÎïÌåÓÉÓÚêµãµÄÉèÖÃÒ²»áµ¼ÖÂ
+ // ´óС¸Ä±äʱҲ»áµ÷ÓÃ×ÓÎïÌåµÄÕâ¸ö»Øµ÷¡£Èç¹û×ÓÎïÌå´óС²»»áÒò´Ë¸Ä±ä£¬ÄÇô²»»á´¥·¢Õâ¸ö»Øµ÷
+ protected virtual void OnRectTransformDimensionsChange() + {} + + // ÓÃanimation clipÐ޴˽ű¾ÊôÐÔÖµµÄʱºò´¥·¢¡£¿ÉÒÔÓÃÓÚÐÞÕý¶¯»½á¹û + protected virtual void OnDidApplyAnimationProperties() + {} + + // ׿ÏȽڵãCanvasGroup²ÎÊý±ä»¯»òenable\disable»òcanvasGroupÏÂÃæµÄcanvasµÄ²ã¼¶±ä»¯ + protected virtual void OnCanvasGroupChanged() + {} + + // ׿ÏȽڵãCanvas enable\disable»òOverrideSorting״̬¸Ä±ä + protected virtual void OnCanvasHierarchyChanged() + {}
+
+#endregion +
+ public bool IsDestroyed() + { + // Workaround for Unity native side of the object + // having been destroyed but accessing via interface + // won't call the overloaded == + return this == null; + }
+
+ } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs.meta new file mode 100644 index 0000000..8a8845a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/EventSystem/UIBehaviour.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: c17b5e621296cc74ca0fdc04a3cb30d0 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI.meta new file mode 100644 index 0000000..4764843 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d5f4eaf4348fe954f9122f4bcf79bb50 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation.meta new file mode 100644 index 0000000..5b44e55 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e00b01f6bce849742b17da47682197e4 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs new file mode 100644 index 0000000..8b15b3c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs @@ -0,0 +1,244 @@ +using System.Collections; +using UnityEngine.Events; + +namespace UnityEngine.UI.CoroutineTween +{ + // Base interface for tweeners, + // using an interface instead of + // an abstract class as we want the + // tweens to be structs. + internal interface ITweenValue + { + void TweenValue(float floatPercentage); + bool ignoreTimeScale { get; } + float duration { get; } + bool ValidTarget(); + } + + // Color tween class, receives the + // TweenValue callback and then sets + // the value on the target. + internal struct ColorTween : ITweenValue + { + public enum ColorTweenMode + { + All, + RGB, + Alpha + } + + public class ColorTweenCallback : UnityEvent<Color> {} + + private ColorTweenCallback m_Target; + private Color m_StartColor; + private Color m_TargetColor; + private ColorTweenMode m_TweenMode; + + private float m_Duration; + private bool m_IgnoreTimeScale; + + public Color startColor + { + get { return m_StartColor; } + set { m_StartColor = value; } + } + + public Color targetColor + { + get { return m_TargetColor; } + set { m_TargetColor = value; } + } + + public ColorTweenMode tweenMode + { + get { return m_TweenMode; } + set { m_TweenMode = value; } + } + + public float duration + { + get { return m_Duration; } + set { m_Duration = value; } + } + + public bool ignoreTimeScale + { + get { return m_IgnoreTimeScale; } + set { m_IgnoreTimeScale = value; } + } + + public void TweenValue(float floatPercentage) + { + if (!ValidTarget()) + return; + + var newColor = Color.Lerp(m_StartColor, m_TargetColor, floatPercentage); + + if (m_TweenMode == ColorTweenMode.Alpha) + { + newColor.r = m_StartColor.r; + newColor.g = m_StartColor.g; + newColor.b = m_StartColor.b; + } + else if (m_TweenMode == ColorTweenMode.RGB) + { + newColor.a = m_StartColor.a; + } + m_Target.Invoke(newColor); + } + + public void AddOnChangedCallback(UnityAction<Color> callback) + { + if (m_Target == null) + m_Target = new ColorTweenCallback(); + + m_Target.AddListener(callback); + } + + public bool GetIgnoreTimescale() + { + return m_IgnoreTimeScale; + } + + public float GetDuration() + { + return m_Duration; + } + + public bool ValidTarget() + { + return m_Target != null; + } + } + + // Float tween class, receives the + // TweenValue callback and then sets + // the value on the target. + internal struct FloatTween : ITweenValue + { + public class FloatTweenCallback : UnityEvent<float> {} + + private FloatTweenCallback m_Target; + private float m_StartValue; + private float m_TargetValue; + + private float m_Duration; + private bool m_IgnoreTimeScale; + + public float startValue + { + get { return m_StartValue; } + set { m_StartValue = value; } + } + + public float targetValue + { + get { return m_TargetValue; } + set { m_TargetValue = value; } + } + + public float duration + { + get { return m_Duration; } + set { m_Duration = value; } + } + + public bool ignoreTimeScale + { + get { return m_IgnoreTimeScale; } + set { m_IgnoreTimeScale = value; } + } + + public void TweenValue(float floatPercentage) + { + if (!ValidTarget()) + return; + + var newValue = Mathf.Lerp(m_StartValue, m_TargetValue, floatPercentage); + m_Target.Invoke(newValue); + } + + public void AddOnChangedCallback(UnityAction<float> callback) + { + if (m_Target == null) + m_Target = new FloatTweenCallback(); + + m_Target.AddListener(callback); + } + + public bool GetIgnoreTimescale() + { + return m_IgnoreTimeScale; + } + + public float GetDuration() + { + return m_Duration; + } + + public bool ValidTarget() + { + return m_Target != null; + } + } + + // Tween runner, executes the given tween. + // The coroutine will live within the given + // behaviour container. + internal class TweenRunner<T> where T : struct, ITweenValue + { + protected MonoBehaviour m_CoroutineContainer; + protected IEnumerator m_Tween; + + // utility function for starting the tween + private static IEnumerator Start(T tweenInfo) + { + if (!tweenInfo.ValidTarget()) + yield break; + + var elapsedTime = 0.0f; + while (elapsedTime < tweenInfo.duration) + { + elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime; + var percentage = Mathf.Clamp01(elapsedTime / tweenInfo.duration); + tweenInfo.TweenValue(percentage); + yield return null; + } + tweenInfo.TweenValue(1.0f); + } + + public void Init(MonoBehaviour coroutineContainer) + { + m_CoroutineContainer = coroutineContainer; + } + + public void StartTween(T info) + { + if (m_CoroutineContainer == null) + { + Debug.LogWarning("Coroutine container not configured... did you forget to call Init?"); + return; + } + + StopTween(); + + if (!m_CoroutineContainer.gameObject.activeInHierarchy) + { + info.TweenValue(1.0f); + return; + } + + m_Tween = Start(info); + m_CoroutineContainer.StartCoroutine(m_Tween); + } + + public void StopTween() + { + if (m_Tween != null) + { + m_CoroutineContainer.StopCoroutine(m_Tween); + m_Tween = null; + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs.meta new file mode 100644 index 0000000..9983570 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Animation/CoroutineTween.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: efe72eb8cde345840879f501ccbaede1 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core.meta new file mode 100644 index 0000000..5c6fab8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a003943df2ce88d4fb12b21661fe21ab +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs new file mode 100644 index 0000000..200b4e5 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs @@ -0,0 +1,307 @@ +using System; +using System.Collections.Generic; +using UnityEngine.UI.Collections; + +namespace UnityEngine.UI +{ + // canvasµÄ²»Í¬½×¶Î£¬ÓÃÀ´ÉèÖÃlayout¡¢graphic×ö²»Í¬µÄÊÂÇ飬¾ßÌå¿´CanvasUpdateRegistry + // prelayout -> layout -> postlayout -> prerender -> laterender =>=>=> render + public enum CanvasUpdate + { + Prelayout = 0, + Layout = 1, + PostLayout = 2, + PreRender = 3, + LatePreRender = 4, + + MaxUpdateValue = 5 + } + + public interface ICanvasElement + { + Transform transform { get; } + void Rebuild(CanvasUpdate executing); + void LayoutComplete(); + void GraphicUpdateComplete(); + // due to unity overriding null check + // we need this as something may not be null + // but may be destroyed + bool IsDestroyed(); + } + + // ÐèҪעÒâÕû¸öÓÎÏ·Ö»ÓÐÒ»¸öµ¥Àý + public class CanvasUpdateRegistry + { + private static CanvasUpdateRegistry s_Instance; + + private bool m_PerformingLayoutUpdate; + private bool m_PerformingGraphicUpdate; + + private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>(); + private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>(); + + protected CanvasUpdateRegistry() + { + // willRenderCanvasesÔÚäÖȾcanvas֮ǰµ÷Óã¬Ö´ÐÐPerformUpdateÀ´Rebuild´¦Àím_LayoutRebuildQueueºÍm_GraphicRebuildQueue + Canvas.willRenderCanvases += PerformUpdate; + } + + // ¼òµ¥µ¥Àý + public static CanvasUpdateRegistry instance + { + get + { + if (s_Instance == null) + s_Instance = new CanvasUpdateRegistry(); + return s_Instance; + } + } + + // ¼ì²éÒ»ÏÂʵÏÖÁËICanvasElementµÄ¶ÔÏóºÏ·¨ÐÔ£¬ÊµÏÖÁËICanvasElement½Ó¿ÚµÄ¶ÔÏó±ØÐëÊÇUnity Object£¬ + private bool ObjectValidForUpdate(ICanvasElement element) + { + var valid = element != null; + + var isUnityObject = element is Object; + if (isUnityObject) + valid = (element as Object) != null; //Here we make use of the overloaded UnityEngine.Object == null, that checks if the native object is alive. + + return valid; + } + + private void CleanInvalidItems() + { + // So MB's override the == operator for null equality, which checks + // if they are destroyed. This is fine if you are looking at a concrete + // mb, but in this case we are looking at a list of ICanvasElement + // this won't forward the == operator to the MB, but just check if the + // interface is null. IsDestroyed will return if the backend is destroyed. + + for (int i = m_LayoutRebuildQueue.Count - 1; i >= 0; --i) + { + var item = m_LayoutRebuildQueue[i]; + if (item == null) + { + m_LayoutRebuildQueue.RemoveAt(i); + continue; + } + + if (item.IsDestroyed()) + { + m_LayoutRebuildQueue.RemoveAt(i); + item.LayoutComplete(); + } + } + + for (int i = m_GraphicRebuildQueue.Count - 1; i >= 0; --i) + { + var item = m_GraphicRebuildQueue[i]; + if (item == null) + { + m_GraphicRebuildQueue.RemoveAt(i); + continue; + } + + if (item.IsDestroyed()) + { + m_GraphicRebuildQueue.RemoveAt(i); + item.GraphicUpdateComplete(); + } + } + } + + private static readonly Comparison<ICanvasElement> s_SortLayoutFunction = SortLayoutList; + // ÔÚäÖȾcanvas֮ǰ¶ÔcanvasϵÄÔªËØ½øÐÐrebuild + // ½øÐÐ prelayout -> layout -> postlayout -> prerender -> LatePreRender Á÷³Ì + private void PerformUpdate() + { + UISystemProfilerApi.BeginSample(UISystemProfilerApi.SampleType.Layout); + CleanInvalidItems(); + + m_PerformingLayoutUpdate = true; + + // ÖØ½¨layout + + // ¸ù¾Ý¸¸½Úµã´ÓÉÙµ½¶àÅÅÐò£¬ÏȲ¼¾Ö¸¸½ÚµãÉٵģ¬ÓÉÉÙµ½¶à£¬ÓÉÄÚµ½Íâ + m_LayoutRebuildQueue.Sort(s_SortLayoutFunction); + // prelayout -> layout -> postlayout + for (int i = 0; i <= (int)CanvasUpdate.PostLayout; i++) // ²»Í¬µÄ½×¶Î + { + for (int j = 0; j < m_LayoutRebuildQueue.Count; j++) + { + var rebuild = instance.m_LayoutRebuildQueue[j]; + try + { + if (ObjectValidForUpdate(rebuild)) + rebuild.Rebuild((CanvasUpdate)i); + } + catch (Exception e) + { + Debug.LogException(e, rebuild.transform); + } + } + } + + // ²¼¾ÖÍê³É + for (int i = 0; i < m_LayoutRebuildQueue.Count; ++i) + m_LayoutRebuildQueue[i].LayoutComplete(); + + // Çå¿Õ¶ÓÁУ¬ÖØÖÃ״̬ + instance.m_LayoutRebuildQueue.Clear(); + m_PerformingLayoutUpdate = false; + + // ×öÌÞ³ý+²Ã¼ô + // now layout is complete do culling... + ClipperRegistry.instance.Cull(); + + // ÖØ½¨graphic + + m_PerformingGraphicUpdate = true; + // prerender -> lateprerender + for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; i++) + { + for (var k = 0; k < instance.m_GraphicRebuildQueue.Count; k++) + { + try + { + var element = instance.m_GraphicRebuildQueue[k]; + if (ObjectValidForUpdate(element)) + element.Rebuild((CanvasUpdate)i); + } + catch (Exception e) + { + Debug.LogException(e, instance.m_GraphicRebuildQueue[k].transform); + } + } + } + + // graphicÉèÖÃmeshºÍ²ÄÖÊÍê³É + for (int i = 0; i < m_GraphicRebuildQueue.Count; ++i) + m_GraphicRebuildQueue[i].GraphicUpdateComplete(); + + // Çå¿Õ¶ÓÁУ¬ÖØÖÃ״̬ + instance.m_GraphicRebuildQueue.Clear(); + m_PerformingGraphicUpdate = false; + + // µ½ÁËÕâÀï²¼¾ÖºÍÍø¸ñ¡¢²ÄÖʶ¼ÉèÖÃÍê±Ï£¬ºóÃæcanvas»áäÖȾ + + // profiler²»ÓÃ¹Ü + UISystemProfilerApi.EndSample(UISystemProfilerApi.SampleType.Layout); + } + + // ͳ¼Æ¸¸½Úµã¸öÊý + private static int ParentCount(Transform child) + { + if (child == null) + return 0; + + var parent = child.parent; + int count = 0; + while (parent != null) + { + count++; + parent = parent.parent; + } + return count; + } + + // ¸ù¾Ý¸¸½ÚµãÓÉÉÙµ½¶àÅÅÐò + private static int SortLayoutList(ICanvasElement x, ICanvasElement y) + { + Transform t1 = x.transform; + Transform t2 = y.transform; + + return ParentCount(t1) - ParentCount(t2); + }
+
+ public static bool IsRebuildingLayout() + { + return instance.m_PerformingLayoutUpdate; + } + + public static bool IsRebuildingGraphics() + { + return instance.m_PerformingGraphicUpdate; + }
+
+#region ½«canvas elements×¢²áµ½¶ÓÁÐÀïµÄ·½·¨ +
+ public static void RegisterCanvasElementForLayoutRebuild(ICanvasElement element) + { + instance.InternalRegisterCanvasElementForLayoutRebuild(element); + } + + public static bool TryRegisterCanvasElementForLayoutRebuild(ICanvasElement element) + { + return instance.InternalRegisterCanvasElementForLayoutRebuild(element); + } + + private bool InternalRegisterCanvasElementForLayoutRebuild(ICanvasElement element) + { + if (m_LayoutRebuildQueue.Contains(element)) + return false; + + /* TODO: this likely should be here but causes the error to show just resizing the game view (case 739376) + if (m_PerformingLayoutUpdate) + { + Debug.LogError(string.Format("Trying to add {0} for layout rebuild while we are already inside a layout rebuild loop. This is not supported.", element)); + return false; + }*/ + + return m_LayoutRebuildQueue.AddUnique(element); + } + + public static void RegisterCanvasElementForGraphicRebuild(ICanvasElement element) + { + instance.InternalRegisterCanvasElementForGraphicRebuild(element); + } + + public static bool TryRegisterCanvasElementForGraphicRebuild(ICanvasElement element) + { + return instance.InternalRegisterCanvasElementForGraphicRebuild(element); + } + + private bool InternalRegisterCanvasElementForGraphicRebuild(ICanvasElement element) + { + if (m_PerformingGraphicUpdate) + { + Debug.LogError(string.Format("Trying to add {0} for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported.", element)); + return false; + } + + return m_GraphicRebuildQueue.AddUnique(element); + } + + public static void UnRegisterCanvasElementForRebuild(ICanvasElement element) + { + instance.InternalUnRegisterCanvasElementForLayoutRebuild(element); + instance.InternalUnRegisterCanvasElementForGraphicRebuild(element); + } + + private void InternalUnRegisterCanvasElementForLayoutRebuild(ICanvasElement element) + { + if (m_PerformingLayoutUpdate) + { + Debug.LogError(string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", element)); + return; + } + + element.LayoutComplete(); + instance.m_LayoutRebuildQueue.Remove(element); + } + + private void InternalUnRegisterCanvasElementForGraphicRebuild(ICanvasElement element) + { + if (m_PerformingGraphicUpdate) + { + Debug.LogError(string.Format("Trying to remove {0} from rebuild list while we are already inside a rebuild loop. This is not supported.", element)); + return; + } + element.GraphicUpdateComplete(); + instance.m_GraphicRebuildQueue.Remove(element); + }
+
+#endregion + + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs.meta new file mode 100644 index 0000000..be77e1d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b607eb8b4c72f944c9fda5d106491067 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling.meta new file mode 100644 index 0000000..2b86263 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2f77b3d02da9eb145be1dfc4c8684a80 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs new file mode 100644 index 0000000..ea7f527 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using UnityEngine.UI.Collections; + +namespace UnityEngine.UI +{ + public class ClipperRegistry + { + static ClipperRegistry s_Instance; + + readonly IndexedSet<IClipper> m_Clippers = new IndexedSet<IClipper>(); + + protected ClipperRegistry() + { + // This is needed for AOT platforms. Without it the compile doesn't get the definition of the Dictionarys +#pragma warning disable 168 + Dictionary<IClipper, int> emptyIClipperDic; +#pragma warning restore 168 + } + + public static ClipperRegistry instance + { + get + { + if (s_Instance == null) + s_Instance = new ClipperRegistry(); + return s_Instance; + } + } + + public void Cull() + { + for (var i = 0; i < m_Clippers.Count; ++i) + { + m_Clippers[i].PerformClipping(); + } + } + + public static void Register(IClipper c) + { + if (c == null) + return; + instance.m_Clippers.AddUnique(c); + } + + public static void Unregister(IClipper c) + { + instance.m_Clippers.Remove(c); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs.meta new file mode 100644 index 0000000..32995ae --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/ClipperRegistry.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: b494fa40405522d49af6bca6e68e4ba6 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs new file mode 100644 index 0000000..7dd39bf --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + public static class Clipping + { + public static Rect FindCullAndClipWorldRect(List<RectMask2D> rectMaskParents, out bool validRect) + { + if (rectMaskParents.Count == 0) + { + validRect = false; + return new Rect(); + } + + var compoundRect = rectMaskParents[0].canvasRect; + for (var i = 0; i < rectMaskParents.Count; ++i) + compoundRect = RectIntersect(compoundRect, rectMaskParents[i].canvasRect); + + var cull = compoundRect.width <= 0 || compoundRect.height <= 0; + if (cull) + { + validRect = false; + return new Rect(); + } + + Vector3 point1 = new Vector3(compoundRect.x, compoundRect.y, 0.0f); + Vector3 point2 = new Vector3(compoundRect.x + compoundRect.width, compoundRect.y + compoundRect.height, 0.0f); + validRect = true; + return new Rect(point1.x, point1.y, point2.x - point1.x, point2.y - point1.y); + } + + // ¼ÆËã¾ØÐν»¼¯ + private static Rect RectIntersect(Rect a, Rect b) + { + float xMin = Mathf.Max(a.x, b.x); + float xMax = Mathf.Min(a.x + a.width, b.x + b.width); + float yMin = Mathf.Max(a.y, b.y); + float yMax = Mathf.Min(a.y + a.height, b.y + b.height); + if (xMax >= xMin && yMax >= yMin) + return new Rect(xMin, yMin, xMax - xMin, yMax - yMin); + return new Rect(0f, 0f, 0f, 0f); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs.meta new file mode 100644 index 0000000..698e06f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/Clipping.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 88fc11e9a11bf1941abc08b9ed323b6f +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs new file mode 100644 index 0000000..4593f17 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs @@ -0,0 +1,16 @@ +namespace UnityEngine.UI +{ + public interface IClipper + { + void PerformClipping(); + } + + public interface IClippable + { + GameObject gameObject { get; } + void RecalculateClipping(); + RectTransform rectTransform { get; } + void Cull(Rect clipRect, bool validRect); + void SetClipRect(Rect value, bool validRect); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs.meta new file mode 100644 index 0000000..1852869 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/IClipRegion.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d395da6bc4c1e6f4b9521bb99b22f3b4 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs new file mode 100644 index 0000000..6d12322 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs @@ -0,0 +1,21 @@ +namespace UnityEngine.UI +{ + internal class RectangularVertexClipper + { + readonly Vector3[] m_WorldCorners = new Vector3[4]; + readonly Vector3[] m_CanvasCorners = new Vector3[4]; + + public Rect GetCanvasRect(RectTransform t, Canvas c) + { + if (c == null) + return new Rect(); + + t.GetWorldCorners(m_WorldCorners); + var canvasTransform = c.GetComponent<Transform>(); + for (int i = 0; i < 4; ++i) + m_CanvasCorners[i] = canvasTransform.InverseTransformPoint(m_WorldCorners[i]); + + return new Rect(m_CanvasCorners[0].x, m_CanvasCorners[0].y, m_CanvasCorners[2].x - m_CanvasCorners[0].x, m_CanvasCorners[2].y - m_CanvasCorners[0].y); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs.meta new file mode 100644 index 0000000..f33cd90 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Culling/RectangularVertexClipper.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 545014a8997364a47b344095371a7332 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font.meta new file mode 100644 index 0000000..28b5ef6 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 680fe3dddba51f54ca833b46dc6b5a82 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs new file mode 100644 index 0000000..3a85af1 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs @@ -0,0 +1,158 @@ +using System; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + /// <summary> + /// Labels reference specific font data used to draw them. This class contains that data. + /// </summary> + + [Serializable] + public class FontData : ISerializationCallbackReceiver + { + [SerializeField] + [FormerlySerializedAs("font")] + private Font m_Font; + + [SerializeField] + [FormerlySerializedAs("fontSize")] + private int m_FontSize; + + [SerializeField] + [FormerlySerializedAs("fontStyle")] + private FontStyle m_FontStyle; + + [SerializeField] + private bool m_BestFit; + + [SerializeField] + private int m_MinSize; + + [SerializeField] + private int m_MaxSize; + + [SerializeField] + [FormerlySerializedAs("alignment")] + private TextAnchor m_Alignment; + + [SerializeField] + private bool m_AlignByGeometry; + + [SerializeField] + [FormerlySerializedAs("richText")] + private bool m_RichText; + + [SerializeField] + private HorizontalWrapMode m_HorizontalOverflow; + + [SerializeField] + private VerticalWrapMode m_VerticalOverflow; + + [SerializeField] + private float m_LineSpacing; + + public static FontData defaultFontData + { + get + { + var fontData = new FontData + { + m_FontSize = 14, + m_LineSpacing = 1f, + m_FontStyle = FontStyle.Normal, + m_BestFit = false, + m_MinSize = 10, + m_MaxSize = 40, + m_Alignment = TextAnchor.UpperLeft, + m_HorizontalOverflow = HorizontalWrapMode.Wrap, + m_VerticalOverflow = VerticalWrapMode.Truncate, + m_RichText = true, + m_AlignByGeometry = false + }; + return fontData; + } + } + + public Font font + { + get { return m_Font; } + set { m_Font = value; } + } + + public int fontSize + { + get { return m_FontSize; } + set { Debug.Log("FontData.fontSize"); m_FontSize = value; } + } + + public FontStyle fontStyle + { + get { return m_FontStyle; } + set { m_FontStyle = value; } + } + + public bool bestFit + { + get { return m_BestFit; } + set { m_BestFit = value; } + } + + public int minSize + { + get { return m_MinSize; } + set { m_MinSize = value; } + } + + public int maxSize + { + get { return m_MaxSize; } + set { m_MaxSize = value; } + } + + public TextAnchor alignment + { + get { return m_Alignment; } + set { m_Alignment = value; } + } + + public bool alignByGeometry + { + get { return m_AlignByGeometry; } + set { m_AlignByGeometry = value; } + } + + public bool richText + { + get { return m_RichText; } + set { m_RichText = value; } + } + + public HorizontalWrapMode horizontalOverflow + { + get { return m_HorizontalOverflow; } + set { m_HorizontalOverflow = value; } + } + + public VerticalWrapMode verticalOverflow + { + get { return m_VerticalOverflow; } + set { m_VerticalOverflow = value; } + } + + public float lineSpacing + { + get { return m_LineSpacing; } + set { m_LineSpacing = value; } + } + + void ISerializationCallbackReceiver.OnBeforeSerialize() + {} + + void ISerializationCallbackReceiver.OnAfterDeserialize() + { + m_FontSize = Mathf.Clamp(m_FontSize, 0, 300); + m_MinSize = Mathf.Clamp(m_MinSize, 0, m_FontSize); + m_MaxSize = Mathf.Clamp(m_MaxSize, m_FontSize, 300); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs.meta new file mode 100644 index 0000000..f4bb2a1 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontData.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 7c47b221885e53f479140fc48712f249 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs new file mode 100644 index 0000000..a63d62b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEngine.UI +{ + // È«¾Ö¼Ç¼ʹÓÃÁËij¸öFont×ÖÌåµÄËùÓÐText£¬µ±Õâ¸öFontµÄGlyphAtlas´óС¸Ä±äµÄʱºò֪ͨÕâЩTextÖØ½¨mesh(¸üÐÂUV£© + // ÒòΪGlyphAtlas´óС¸Ä±äÁË£¬ÔÏȵÄUVÒѾ²»¶ÔÁË + public static class FontUpdateTracker + { + static Dictionary<Font, HashSet<Text>> m_Tracked = new Dictionary<Font, HashSet<Text>>(); + + public static void TrackText(Text t) + { + if (t.font == null) + return; + + HashSet<Text> exists; + m_Tracked.TryGetValue(t.font, out exists); + if (exists == null) + {
+ // font textureÖØÐÂÉú³ÉµÄʱºò»áµ÷Õâ¸ö»Øµ÷£¬È»ºóÐèÒªText×é¼þÖØ½¨meshµÄUVÊý¾Ý£¬ÒòΪÔÏȵÄfontGlyphÀïµÄUVÒѾ²»×¼ÁË
+ // https://docs.unity3d.com/ScriptReference/Font-textureRebuilt.html
+ // The textureRebuilt event is global for all fonts, so we add our delegate the first time we register *any* Text
+ if (m_Tracked.Count == 0) + Font.textureRebuilt += RebuildForFont; + + exists = new HashSet<Text>(); + m_Tracked.Add(t.font, exists); + } + + if (!exists.Contains(t)) + exists.Add(t); + } + + private static void RebuildForFont(Font f) + { + HashSet<Text> texts; + m_Tracked.TryGetValue(f, out texts); + + if (texts == null) + return; + + foreach (var text in texts) + text.FontTextureChanged(); + } + + public static void UntrackText(Text t) + { + if (t.font == null) + return; + + HashSet<Text> texts; + m_Tracked.TryGetValue(t.font, out texts); + + if (texts == null) + return; + + texts.Remove(t); + + if (texts.Count == 0) + { + m_Tracked.Remove(t.font); + + // There is a global textureRebuilt event for all fonts, so once the last Text reference goes away, remove our delegate + if (m_Tracked.Count == 0) + Font.textureRebuilt -= RebuildForFont; + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs.meta new file mode 100644 index 0000000..8e6ddeb --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/FontUpdateTracker.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: fba9c6c6325db2d49bdf2b608066f0e0 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs new file mode 100644 index 0000000..3d3d17b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs @@ -0,0 +1,576 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + /// <summary> + /// Labels are graphics that display text. + /// </summary> + + [AddComponentMenu("UI/Text", 10)] + public class Text : MaskableGraphic, ILayoutElement + { + [SerializeField] private FontData m_FontData = FontData.defaultFontData; + +#if UNITY_EDITOR + // needed to track font changes from the inspector + private Font m_LastTrackedFont; +#endif + + [TextArea(3, 10)][SerializeField] protected string m_Text = String.Empty; + + private TextGenerator m_TextCache; + private TextGenerator m_TextCacheForLayout; + + static protected Material s_DefaultText = null; + + // We use this flag instead of Unregistering/Registering the callback to avoid allocation. + [NonSerialized] protected bool m_DisableFontTextureRebuiltCallback = false; + + protected Text() + { + useLegacyMeshGeneration = false; + } + + // text generator£¬µÃµ½×Ö·û´®ÔÚglyph atlasÖеÄUV£¬¹¹½¨mesh + /// <summary> + /// Get or set the material used by this Text. + /// </summary> + + public TextGenerator cachedTextGenerator + { + get { return m_TextCache ?? (m_TextCache = (m_Text.Length != 0 ? new TextGenerator(m_Text.Length) : new TextGenerator())); } + } + + public TextGenerator cachedTextGeneratorForLayout + { + get { return m_TextCacheForLayout ?? (m_TextCacheForLayout = new TextGenerator()); } + } + + /// <summary> + /// Text's texture comes from the font. + /// </summary> + public override Texture mainTexture + { + get + { + if (font != null && font.material != null && font.material.mainTexture != null) + return font.material.mainTexture; + + if (m_Material != null) + return m_Material.mainTexture; + + return base.mainTexture; + } + } + + public void FontTextureChanged() + { + // Only invoke if we are not destroyed. + if (!this) + return; + + if (m_DisableFontTextureRebuiltCallback) + return; + + cachedTextGenerator.Invalidate(); + + if (!IsActive()) + return; + + // this is a bit hacky, but it is currently the + // cleanest solution.... + // if we detect the font texture has changed and are in a rebuild loop + // we just regenerate the verts for the new UV's + if (CanvasUpdateRegistry.IsRebuildingGraphics() || CanvasUpdateRegistry.IsRebuildingLayout()) + UpdateGeometry(); + else + SetAllDirty(); + } + + public Font font + { + get + { + return m_FontData.font; + } + set + { + if (m_FontData.font == value) + return; + + FontUpdateTracker.UntrackText(this); + + m_FontData.font = value; + + FontUpdateTracker.TrackText(this); + +#if UNITY_EDITOR + // needed to track font changes from the inspector + m_LastTrackedFont = value; +#endif + + SetAllDirty(); + } + } + + /// <summary> + /// Text that's being displayed by the Text. + /// </summary> + + public virtual string text + { + get + { + return m_Text; + } + set + { + if (String.IsNullOrEmpty(value)) + { + if (String.IsNullOrEmpty(m_Text)) + return; + m_Text = ""; + SetVerticesDirty(); + } + else if (m_Text != value) + { + m_Text = value; + SetVerticesDirty(); + SetLayoutDirty(); + } + } + } + + /// <summary> + /// Whether this Text will support rich text. + /// </summary> + + public bool supportRichText + { + get + { + return m_FontData.richText; + } + set + { + if (m_FontData.richText == value) + return; + m_FontData.richText = value; + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + /// <summary> + /// Wrap mode used by the text. + /// </summary> + + public bool resizeTextForBestFit + { + get + { + return m_FontData.bestFit; + } + set + { + if (m_FontData.bestFit == value) + return; + m_FontData.bestFit = value; + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public int resizeTextMinSize + { + get + { + return m_FontData.minSize; + } + set + { + if (m_FontData.minSize == value) + return; + m_FontData.minSize = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public int resizeTextMaxSize + { + get + { + return m_FontData.maxSize; + } + set + { + if (m_FontData.maxSize == value) + return; + m_FontData.maxSize = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + /// <summary> + /// Alignment anchor used by the text. + /// </summary> + + public TextAnchor alignment + { + get + { + return m_FontData.alignment; + } + set + { + if (m_FontData.alignment == value) + return; + m_FontData.alignment = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public bool alignByGeometry + { + get + { + return m_FontData.alignByGeometry; + } + set + { + if (m_FontData.alignByGeometry == value) + return; + m_FontData.alignByGeometry = value; + + SetVerticesDirty(); + } + } + + public int fontSize + { + get + { + return m_FontData.fontSize; + } + set + { + // font size¸Ä±äµÄʱºòÖØ½¨mesh + if (m_FontData.fontSize == value) + return; + m_FontData.fontSize = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public HorizontalWrapMode horizontalOverflow + { + get + { + return m_FontData.horizontalOverflow; + } + set + { + if (m_FontData.horizontalOverflow == value) + return; + m_FontData.horizontalOverflow = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public VerticalWrapMode verticalOverflow + { + get + { + return m_FontData.verticalOverflow; + } + set + { + if (m_FontData.verticalOverflow == value) + return; + m_FontData.verticalOverflow = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public float lineSpacing + { + get + { + return m_FontData.lineSpacing; + } + set + { + if (m_FontData.lineSpacing == value) + return; + m_FontData.lineSpacing = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + /// <summary> + /// Font style used by the Text's text. + /// </summary> + + public FontStyle fontStyle + { + get + { + return m_FontData.fontStyle; + } + set + { + if (m_FontData.fontStyle == value) + return; + m_FontData.fontStyle = value; + + SetVerticesDirty(); + SetLayoutDirty(); + } + } + + public float pixelsPerUnit + { + get + { + var localCanvas = canvas; + if (!localCanvas) + return 1; + // For dynamic fonts, ensure we use one pixel per pixel on the screen. + if (!font || font.dynamic) + return localCanvas.scaleFactor; + // For non-dynamic fonts, calculate pixels per unit based on specified font size relative to font object's own font size. + if (m_FontData.fontSize <= 0 || font.fontSize <= 0) + return 1; + return font.fontSize / (float)m_FontData.fontSize; + } + } + + protected override void OnEnable() + { + base.OnEnable(); + cachedTextGenerator.Invalidate(); + FontUpdateTracker.TrackText(this); + } + + protected override void OnDisable() + { + FontUpdateTracker.UntrackText(this); + base.OnDisable(); + } + + protected override void UpdateGeometry() + { + if (font != null) + { + base.UpdateGeometry(); + } + } + +#if UNITY_EDITOR + protected override void Reset() + { + AssignDefaultFont(); + } + +#endif + internal void AssignDefaultFont() + { + font = Resources.GetBuiltinResource<Font>("Arial.ttf"); + } + + // ¸ù¾ÝFontDataÉèÖÃTextGenerationSettings + public TextGenerationSettings GetGenerationSettings(Vector2 extents) + { + var settings = new TextGenerationSettings(); + + settings.generationExtents = extents; + if (font != null && font.dynamic) + { + settings.fontSize = m_FontData.fontSize; + settings.resizeTextMinSize = m_FontData.minSize; + settings.resizeTextMaxSize = m_FontData.maxSize; + } + + // Other settings + settings.textAnchor = m_FontData.alignment; + settings.alignByGeometry = m_FontData.alignByGeometry; + settings.scaleFactor = pixelsPerUnit; + settings.color = color; // ÕâÀïÊǶ¥µãÑÕÉ« + settings.font = font; + settings.pivot = rectTransform.pivot; + settings.richText = m_FontData.richText; + settings.lineSpacing = m_FontData.lineSpacing; + settings.fontStyle = m_FontData.fontStyle; + settings.resizeTextForBestFit = m_FontData.bestFit; + settings.updateBounds = false; + settings.horizontalOverflow = m_FontData.horizontalOverflow; + settings.verticalOverflow = m_FontData.verticalOverflow; + + return settings; + } + + static public Vector2 GetTextAnchorPivot(TextAnchor anchor) + { + switch (anchor) + { + case TextAnchor.LowerLeft: return new Vector2(0, 0); + case TextAnchor.LowerCenter: return new Vector2(0.5f, 0); + case TextAnchor.LowerRight: return new Vector2(1, 0); + case TextAnchor.MiddleLeft: return new Vector2(0, 0.5f); + case TextAnchor.MiddleCenter: return new Vector2(0.5f, 0.5f); + case TextAnchor.MiddleRight: return new Vector2(1, 0.5f); + case TextAnchor.UpperLeft: return new Vector2(0, 1); + case TextAnchor.UpperCenter: return new Vector2(0.5f, 1); + case TextAnchor.UpperRight: return new Vector2(1, 1); + default: return Vector2.zero; + } + } + + readonly UIVertex[] m_TempVerts = new UIVertex[4]; + protected override void OnPopulateMesh(VertexHelper toFill) + { + if (font == null) + return; + + // We don't care if we the font Texture changes while we are doing our Update. + // The end result of cachedTextGenerator will be valid for this instance. + // Otherwise we can get issues like Case 619238. + m_DisableFontTextureRebuiltCallback = true; + + Vector2 extents = rectTransform.rect.size; + + // Éú³É¶ÔÓ¦µÄÍø¸ñÊý¾Ý£¨¶¥µã¡¢UV£© + var settings = GetGenerationSettings(extents); + cachedTextGenerator.PopulateWithErrors(text, settings, gameObject); + + // Apply the offset to the vertices + IList<UIVertex> verts = cachedTextGenerator.verts; + float unitsPerPixel = 1 / pixelsPerUnit; + //Last 4 verts are always a new line... (\n) + int vertCount = verts.Count - 4; + + Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel; + roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset; + toFill.Clear(); + if (roundingOffset != Vector2.zero) + { + for (int i = 0; i < vertCount; ++i) + { + int tempVertsIndex = i & 3; + m_TempVerts[tempVertsIndex] = verts[i]; + m_TempVerts[tempVertsIndex].position *= unitsPerPixel; + m_TempVerts[tempVertsIndex].position.x += roundingOffset.x; + m_TempVerts[tempVertsIndex].position.y += roundingOffset.y; + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); + } + } + else + { + for (int i = 0; i < vertCount; ++i) + { + int tempVertsIndex = i & 3; + m_TempVerts[tempVertsIndex] = verts[i]; + m_TempVerts[tempVertsIndex].position *= unitsPerPixel; + if (tempVertsIndex == 3) + toFill.AddUIVertexQuad(m_TempVerts); + } + } + + m_DisableFontTextureRebuiltCallback = false; + } + + public virtual void CalculateLayoutInputHorizontal() {} + public virtual void CalculateLayoutInputVertical() {} + + public virtual float minWidth + { + get { return 0; } + } + + public virtual float preferredWidth + { + get + { + var settings = GetGenerationSettings(Vector2.zero); + return cachedTextGeneratorForLayout.GetPreferredWidth(m_Text, settings) / pixelsPerUnit; + } + } + + public virtual float flexibleWidth { get { return -1; } } + + public virtual float minHeight + { + get { return 0; } + } + + public virtual float preferredHeight + { + get + { + var settings = GetGenerationSettings(new Vector2(GetPixelAdjustedRect().size.x, 0.0f)); + return cachedTextGeneratorForLayout.GetPreferredHeight(m_Text, settings) / pixelsPerUnit; + } + } + + public virtual float flexibleHeight { get { return -1; } } + + public virtual int layoutPriority { get { return 0; } } + +#if UNITY_EDITOR + public override void OnRebuildRequested() + { + // After a Font asset gets re-imported the managed side gets deleted and recreated, + // that means the delegates are not persisted. + // so we need to properly enforce a consistent state here. + FontUpdateTracker.UntrackText(this); + FontUpdateTracker.TrackText(this); + + // Also the textgenerator is no longer valid. + cachedTextGenerator.Invalidate(); + + base.OnRebuildRequested(); + } + + // µ±±à¼Æ÷ÀïÐÞ¸ÄÁ˲ÎÊýÖµµÄʱºòµ÷Õâ¸ö»Øµ÷£¬setDirty£¬ºóÐøÖØ½¨mesh + // The Text inspector editor can change the font, and we need a way to track changes so that we get the appropriate rebuild callbacks + // We can intercept changes in OnValidate, and keep track of the previous font reference + protected override void OnValidate() + { + if (!IsActive()) + { + base.OnValidate(); + return; + } + + if (m_FontData.font != m_LastTrackedFont) + { + Font newFont = m_FontData.font; + m_FontData.font = m_LastTrackedFont; + FontUpdateTracker.UntrackText(this); + m_FontData.font = newFont; + FontUpdateTracker.TrackText(this); + + m_LastTrackedFont = newFont; + } + base.OnValidate(); + } + +#endif // if UNITY_EDITOR + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs.meta new file mode 100644 index 0000000..ea6d1d8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Font/Text.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 48696ad002dcb2146ab8d6ad72d455d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics.meta new file mode 100644 index 0000000..f28155d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 68d41682b219698458518d531a2805cc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs new file mode 100644 index 0000000..21acfb4 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs @@ -0,0 +1,669 @@ +using System; +#if UNITY_EDITOR +using System.Reflection; +#endif +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; +using UnityEngine.UI.CoroutineTween; + +namespace UnityEngine.UI +{ + /// <summary> + /// Base class for all UI components that should be derived from when creating new Graphic types. + /// </summary> + [DisallowMultipleComponent] + [RequireComponent(typeof(CanvasRenderer))] + [RequireComponent(typeof(RectTransform))] + [ExecuteInEditMode] + public abstract class Graphic + : UIBehaviour, + ICanvasElement + { + static protected Material s_DefaultUI = null; + static protected Texture2D s_WhiteTexture = null; + + /// <summary> + /// Default material used to draw everything if no explicit material was specified. + /// </summary> + + static public Material defaultGraphicMaterial + { + get + { + if (s_DefaultUI == null) + s_DefaultUI = Canvas.GetDefaultCanvasMaterial(); + return s_DefaultUI; + } + } + + // Cached and saved values + [FormerlySerializedAs("m_Mat")] + [SerializeField] protected Material m_Material; + + [SerializeField] private Color m_Color = Color.white; + public virtual Color color { get { return m_Color; } set { if (SetPropertyUtility.SetColor(ref m_Color, value)) SetVerticesDirty(); } } + + [SerializeField] private bool m_RaycastTarget = true; + public virtual bool raycastTarget { get { return m_RaycastTarget; } set { m_RaycastTarget = value; } } + + [NonSerialized] private RectTransform m_RectTransform; + [NonSerialized] private CanvasRenderer m_CanvasRender; + [NonSerialized] private Canvas m_Canvas; + + [NonSerialized] private bool m_VertsDirty; + [NonSerialized] private bool m_MaterialDirty; + + [NonSerialized] protected UnityAction m_OnDirtyLayoutCallback; + [NonSerialized] protected UnityAction m_OnDirtyVertsCallback; + [NonSerialized] protected UnityAction m_OnDirtyMaterialCallback; + + [NonSerialized] protected static Mesh s_Mesh; + [NonSerialized] private static readonly VertexHelper s_VertexHelper = new VertexHelper(); + + // Tween controls for the Graphic + [NonSerialized] + private readonly TweenRunner<ColorTween> m_ColorTweenRunner; + + protected bool useLegacyMeshGeneration { get; set; } + + // Called by Unity prior to deserialization, + // should not be called by users + protected Graphic() + { + if (m_ColorTweenRunner == null) + m_ColorTweenRunner = new TweenRunner<ColorTween>(); + m_ColorTweenRunner.Init(this); + useLegacyMeshGeneration = true; + } + + public virtual void SetAllDirty() + { + SetLayoutDirty(); + SetVerticesDirty(); + SetMaterialDirty(); + } + + public virtual void SetLayoutDirty() + { + if (!IsActive()) + return; + + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + + if (m_OnDirtyLayoutCallback != null) + m_OnDirtyLayoutCallback(); + } + + public virtual void SetVerticesDirty() + { + if (!IsActive()) + return; + + m_VertsDirty = true; + CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); + + if (m_OnDirtyVertsCallback != null) + m_OnDirtyVertsCallback(); + } + + public virtual void SetMaterialDirty() + { + if (!IsActive()) + return; + + m_MaterialDirty = true; + CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); + + if (m_OnDirtyMaterialCallback != null) + m_OnDirtyMaterialCallback(); + } + + protected override void OnRectTransformDimensionsChange() + { + if (gameObject.activeInHierarchy) + { + // prevent double dirtying... + if (CanvasUpdateRegistry.IsRebuildingLayout()) + SetVerticesDirty(); + else + { + SetVerticesDirty(); + SetLayoutDirty(); + } + } + } + + protected override void OnBeforeTransformParentChanged() + { + GraphicRegistry.UnregisterGraphicForCanvas(canvas, this); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + + m_Canvas = null; + + if (!IsActive()) + return; + + CacheCanvas(); + GraphicRegistry.RegisterGraphicForCanvas(canvas, this); + SetAllDirty(); + } + + // ÔÚhierachyÀïµÄÉî¶È£¬ÒÀ´ÎÔö¼Ó + /// <summary> + /// Absolute depth of the graphic, used by rendering and events -- lowest to highest. + /// </summary> + public int depth { get { return canvasRenderer.absoluteDepth; } } + + /// <summary> + /// Transform gets cached for speed. + /// </summary> + public RectTransform rectTransform + { + get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); } + } + + public Canvas canvas + { + get + { + if (m_Canvas == null) + CacheCanvas(); + return m_Canvas; + } + } + + // ÕÒµ½¸¸½ÚµãÖÐ×î½üµÄcanvas + private void CacheCanvas() + { + var list = ListPool<Canvas>.Get(); + // ÕÒµ½ËùÓи¸½ÚµãÖÐËùÓÐcanvas£¬´ÓÀïµ½Íâ + gameObject.GetComponentsInParent(false, list); + if (list.Count > 0) + { + // Find the first active and enabled canvas. + for (int i = 0; i < list.Count; ++i) + { + if (list[i].isActiveAndEnabled) + { + m_Canvas = list[i]; + break; + } + } + } + else + m_Canvas = null; + ListPool<Canvas>.Release(list); + } + + /// <summary> + /// UI Renderer component. + /// </summary> + public CanvasRenderer canvasRenderer + { + get + { + if (m_CanvasRender == null) + m_CanvasRender = GetComponent<CanvasRenderer>(); + return m_CanvasRender; + } + } + + public virtual Material defaultMaterial + { + get { return defaultGraphicMaterial; } + } + + /// <summary> + /// Returns the material used by this Graphic. + /// </summary> + public virtual Material material + { + get + { + return (m_Material != null) ? m_Material : defaultMaterial; + } + set + { + if (m_Material == value) + return; + + m_Material = value; + SetMaterialDirty(); + } + } + + /// <summary>
+ /// Ìá½»µ½CanvasRendererÓÃÕâ¸ö£¬ÒªÓ¦ÓÃIMaterialModifierµÄÐ޸Ľá¹û
+ /// </summary> + public virtual Material materialForRendering + { + get + { + // ÔÚÕâÀïµ÷ÓÃIMaterialModifierµÄÐÞ¸Ä + var components = ListPool<Component>.Get(); + GetComponents(typeof(IMaterialModifier), components); + + var currentMat = material; + for (var i = 0; i < components.Count; i++) + currentMat = (components[i] as IMaterialModifier).GetModifiedMaterial(currentMat); + ListPool<Component>.Release(components); + return currentMat; + } + } + + /// <summary> + /// Returns the texture used to draw this Graphic. + /// </summary> + public virtual Texture mainTexture + { + get + { + return s_WhiteTexture; + } + } + + /// <summary> + /// Mark the Graphic and the canvas as having been changed. + /// </summary> + protected override void OnEnable() + { + base.OnEnable(); + CacheCanvas(); + GraphicRegistry.RegisterGraphicForCanvas(canvas, this); + +#if UNITY_EDITOR + GraphicRebuildTracker.TrackGraphic(this); +#endif + if (s_WhiteTexture == null) + s_WhiteTexture = Texture2D.whiteTexture; + + SetAllDirty(); + } + + /// <summary> + /// Clear references. + /// </summary> + protected override void OnDisable() + { +#if UNITY_EDITOR + GraphicRebuildTracker.UnTrackGraphic(this); +#endif + GraphicRegistry.UnregisterGraphicForCanvas(canvas, this); + CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild(this); + + if (canvasRenderer != null) + canvasRenderer.Clear(); + + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + + base.OnDisable(); + } + + protected override void OnCanvasHierarchyChanged() + { + // Use m_Cavas so we dont auto call CacheCanvas + Canvas currentCanvas = m_Canvas; + + // Clear the cached canvas. Will be fetched below if active. + m_Canvas = null; + + if (!IsActive()) + return; + + CacheCanvas(); + + if (currentCanvas != m_Canvas) + { + GraphicRegistry.UnregisterGraphicForCanvas(currentCanvas, this); + + // Only register if we are active and enabled as OnCanvasHierarchyChanged can get called + // during object destruction and we dont want to register ourself and then become null. + if (IsActive()) + GraphicRegistry.RegisterGraphicForCanvas(canvas, this); + } + } + + // canvasÖØ½¨ + public virtual void Rebuild(CanvasUpdate update) + { + if (canvasRenderer.cull) + return; + + switch (update) + { + case CanvasUpdate.PreRender: + if (m_VertsDirty) + { + UpdateGeometry(); + m_VertsDirty = false; + } + if (m_MaterialDirty) + { + UpdateMaterial(); + m_MaterialDirty = false; + } + break; + } + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + /// <summary> + /// Update the renderer's material. + /// </summary> + protected virtual void UpdateMaterial() + { + if (!IsActive()) + return; + + canvasRenderer.materialCount = 1; + canvasRenderer.SetMaterial(materialForRendering, 0); + canvasRenderer.SetTexture(mainTexture); // ÉèÖÃ_MainTex£¬»á¸²¸Ç²ÄÖÊÉÏÉèÖõÄ_MainTex + } + + //c ¶¥µãÖØ½¨ + /// <summary> + /// Update the renderer's vertices. + /// </summary> + protected virtual void UpdateGeometry() + { + if (useLegacyMeshGeneration) + DoLegacyMeshGeneration(); + else + DoMeshGeneration(); + } + + // ¶¥µãÖØ½¨£¬Éú³Émesh + private void DoMeshGeneration() + { + if (rectTransform != null && rectTransform.rect.width >= 0 && rectTransform.rect.height >= 0) + OnPopulateMesh(s_VertexHelper); // Ìî³ävertexHelper + else + s_VertexHelper.Clear(); // clear the vertex helper so invalid graphics dont draw. + + // ¿ÉÒÔͨ¹ýʵÏÖIMeshModiferÐÞ¸Ämesh + var components = ListPool<Component>.Get(); + GetComponents(typeof(IMeshModifier), components); + + for (var i = 0; i < components.Count; i++) + ((IMeshModifier)components[i]).ModifyMesh(s_VertexHelper); + + ListPool<Component>.Release(components); + + s_VertexHelper.FillMesh(workerMesh); + + // ´«ÈëcanvasRenderer×÷Ϊmesh + canvasRenderer.SetMesh(workerMesh); + } + + private void DoLegacyMeshGeneration() + { + if (rectTransform != null && rectTransform.rect.width >= 0 && rectTransform.rect.height >= 0) + { +#pragma warning disable 618 + OnPopulateMesh(workerMesh); +#pragma warning restore 618 + } + else + { + workerMesh.Clear(); + } + + // ×Ô¶¨ÒåÁ÷³Ì + var components = ListPool<Component>.Get(); + GetComponents(typeof(IMeshModifier), components); + + for (var i = 0; i < components.Count; i++) + { +#pragma warning disable 618 + ((IMeshModifier)components[i]).ModifyMesh(workerMesh); +#pragma warning restore 618 + } + + ListPool<Component>.Release(components); + canvasRenderer.SetMesh(workerMesh); + } + + protected static Mesh workerMesh + { + get + { + if (s_Mesh == null) + { + s_Mesh = new Mesh(); + s_Mesh.name = "Shared UI Mesh"; + s_Mesh.hideFlags = HideFlags.HideAndDontSave; + } + return s_Mesh; + } + } + + [Obsolete("Use OnPopulateMesh instead.", true)] + protected virtual void OnFillVBO(System.Collections.Generic.List<UIVertex> vbo) {} + + [Obsolete("Use OnPopulateMesh(VertexHelper vh) instead.", false)] + protected virtual void OnPopulateMesh(Mesh m) + { + OnPopulateMesh(s_VertexHelper); + s_VertexHelper.FillMesh(m); + } + + /// <summary> + /// Fill the vertex buffer data. + /// </summary> + protected virtual void OnPopulateMesh(VertexHelper vh) + { + var r = GetPixelAdjustedRect(); + var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height); + + Color32 color32 = color; + vh.Clear(); + vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(0f, 0f)); + vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(0f, 1f)); + vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(1f, 1f)); + vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(1f, 0f)); + + vh.AddTriangle(0, 1, 2); + vh.AddTriangle(2, 3, 0); + } + +#if UNITY_EDITOR + public virtual void OnRebuildRequested() + { + // when rebuild is requested we need to rebuild all the graphics / + // and associated components... The correct way to do this is by + // calling OnValidate... Because MB's don't have a common base class + // we do this via reflection. It's nasty and ugly... Editor only. + var mbs = gameObject.GetComponents<MonoBehaviour>(); + foreach (var mb in mbs) + { + if (mb == null) + continue; + var methodInfo = mb.GetType().GetMethod("OnValidate", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (methodInfo != null) + methodInfo.Invoke(mb, null); + } + } + + protected override void Reset() + { + SetAllDirty(); + } + +#endif + + // Call from unity if animation properties have changed + + protected override void OnDidApplyAnimationProperties() + { + SetAllDirty(); + } + + /// <summary> + /// Make the Graphic have the native size of its content. + /// </summary> + public virtual void SetNativeSize() {} + public virtual bool Raycast(Vector2 sp, Camera eventCamera) + { + if (!isActiveAndEnabled) + return false; + + var t = transform; + var components = ListPool<Component>.Get(); + + bool ignoreParentGroups = false; + bool continueTraversal = true; + + while (t != null) + { + t.GetComponents(components); + for (var i = 0; i < components.Count; i++) + { + var canvas = components[i] as Canvas; + if (canvas != null && canvas.overrideSorting) + continueTraversal = false; + + // Èç¹ûʵÏÖÁËÕâ¸ö½Ó¿ÚÔÙ½øÒ»²½ÅжÏһϠ+ var filter = components[i] as ICanvasRaycastFilter; + + if (filter == null) + continue; + + var raycastValid = true; + + var group = components[i] as CanvasGroup; + if (group != null) + { + if (ignoreParentGroups == false && group.ignoreParentGroups) + { + ignoreParentGroups = true; + raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); + } + else if (!ignoreParentGroups) + raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); + } + else + { + raycastValid = filter.IsRaycastLocationValid(sp, eventCamera); + } + + if (!raycastValid) + { + ListPool<Component>.Release(components); + return false; + } + } + t = continueTraversal ? t.parent : null; + } + ListPool<Component>.Release(components); + return true; + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + SetAllDirty(); + } + +#endif + + public Vector2 PixelAdjustPoint(Vector2 point) + { + if (!canvas || canvas.renderMode == RenderMode.WorldSpace || canvas.scaleFactor == 0.0f || !canvas.pixelPerfect) + return point; + else + { + return RectTransformUtility.PixelAdjustPoint(point, transform, canvas); + } + } + + public Rect GetPixelAdjustedRect() + { + if (!canvas || canvas.renderMode == RenderMode.WorldSpace || canvas.scaleFactor == 0.0f || !canvas.pixelPerfect) + return rectTransform.rect; + else + return RectTransformUtility.PixelAdjustRect(rectTransform, canvas); + } + + public virtual void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha) + { + CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha, true); + } + + public virtual void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB) + { + if (canvasRenderer == null || (!useRGB && !useAlpha)) + return; + + Color currentColor = canvasRenderer.GetColor(); + if (currentColor.Equals(targetColor)) + { + m_ColorTweenRunner.StopTween(); + return; + } + + ColorTween.ColorTweenMode mode = (useRGB && useAlpha ? + ColorTween.ColorTweenMode.All : + (useRGB ? ColorTween.ColorTweenMode.RGB : ColorTween.ColorTweenMode.Alpha)); + + var colorTween = new ColorTween {duration = duration, startColor = canvasRenderer.GetColor(), targetColor = targetColor}; + colorTween.AddOnChangedCallback(canvasRenderer.SetColor); + colorTween.ignoreTimeScale = ignoreTimeScale; + colorTween.tweenMode = mode; + m_ColorTweenRunner.StartTween(colorTween); + } + + static private Color CreateColorFromAlpha(float alpha) + { + var alphaColor = Color.black; + alphaColor.a = alpha; + return alphaColor; + } + + public virtual void CrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale) + { + CrossFadeColor(CreateColorFromAlpha(alpha), duration, ignoreTimeScale, true, false); + } + + public void RegisterDirtyLayoutCallback(UnityAction action) + { + m_OnDirtyLayoutCallback += action; + } + + public void UnregisterDirtyLayoutCallback(UnityAction action) + { + m_OnDirtyLayoutCallback -= action; + } + + public void RegisterDirtyVerticesCallback(UnityAction action) + { + m_OnDirtyVertsCallback += action; + } + + public void UnregisterDirtyVerticesCallback(UnityAction action) + { + m_OnDirtyVertsCallback -= action; + } + + public void RegisterDirtyMaterialCallback(UnityAction action) + { + m_OnDirtyMaterialCallback += action; + } + + public void UnregisterDirtyMaterialCallback(UnityAction action) + { + m_OnDirtyMaterialCallback -= action; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs.meta new file mode 100644 index 0000000..e02d697 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Graphic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3acb46ac7ba14ff4e938138943716b11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs new file mode 100644 index 0000000..303689a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [AddComponentMenu("Event/Graphic Raycaster")] + [RequireComponent(typeof(Canvas))] + public class GraphicRaycaster : BaseRaycaster + { + protected const int kNoEventMaskSet = -1; + public enum BlockingObjects + { + None = 0, + TwoD = 1, + ThreeD = 2, + All = 3, + } + + public override int sortOrderPriority + { + get + { + // We need to return the sorting order here as distance will all be 0 for overlay. + if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) + return canvas.sortingOrder; + + return base.sortOrderPriority; + } + } + + public override int renderOrderPriority + { + get + { + // We need to return the sorting order here as distance will all be 0 for overlay. + if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) + return canvas.rootCanvas.renderOrder; + + return base.renderOrderPriority; + } + } + + [FormerlySerializedAs("ignoreReversedGraphics")] + [SerializeField] + private bool m_IgnoreReversedGraphics = true; + [FormerlySerializedAs("blockingObjects")] + [SerializeField] + private BlockingObjects m_BlockingObjects = BlockingObjects.None; + + public bool ignoreReversedGraphics { get {return m_IgnoreReversedGraphics; } set { m_IgnoreReversedGraphics = value; } } + public BlockingObjects blockingObjects { get {return m_BlockingObjects; } set { m_BlockingObjects = value; } } + + [SerializeField] + protected LayerMask m_BlockingMask = kNoEventMaskSet; + + private Canvas m_Canvas; + + protected GraphicRaycaster() + {} + + private Canvas canvas + { + get + { + if (m_Canvas != null) + return m_Canvas; + + m_Canvas = GetComponent<Canvas>(); + return m_Canvas; + } + } + + [NonSerialized] private List<Graphic> m_RaycastResults = new List<Graphic>(); + public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList) + { + if (canvas == null) + return; + + // Äõ½canvasϵÄËùÓÐgraphic + var canvasGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas); + if (canvasGraphics == null || canvasGraphics.Count == 0) + return; + + int displayIndex; + var currentEventCamera = eventCamera; // Propery can call Camera.main, so cache the reference + + if (canvas.renderMode == RenderMode.ScreenSpaceOverlay || currentEventCamera == null) + displayIndex = canvas.targetDisplay; + else + displayIndex = currentEventCamera.targetDisplay; + + var eventPosition = Display.RelativeMouseAt(eventData.position); + if (eventPosition != Vector3.zero) + { + // We support multiple display and display identification based on event position. + + int eventDisplayIndex = (int)eventPosition.z; + + // Discard events that are not part of this display so the user does not interact with multiple displays at once. + if (eventDisplayIndex != displayIndex) + return; + } + else + { + // The multiple display system is not supported on all platforms, when it is not supported the returned position + // will be all zeros so when the returned index is 0 we will default to the event data to be safe. + eventPosition = eventData.position; + + // We dont really know in which display the event occured. We will process the event assuming it occured in our display. + } + + // Convert to view space + Vector2 pos; + if (currentEventCamera == null) + { + // Multiple display support only when not the main display. For display 0 the reported + // resolution is always the desktops resolution since its part of the display API, + // so we use the standard none multiple display method. (case 741751) + float w = Screen.width; + float h = Screen.height; + if (displayIndex > 0 && displayIndex < Display.displays.Length) + { + w = Display.displays[displayIndex].systemWidth; + h = Display.displays[displayIndex].systemHeight; + } + pos = new Vector2(eventPosition.x / w, eventPosition.y / h); + } + else + pos = currentEventCamera.ScreenToViewportPoint(eventPosition); + + // If it's outside the camera's viewport, do nothing + if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f) + return; + + float hitDistance = float.MaxValue; + + Ray ray = new Ray(); + + if (currentEventCamera != null) + ray = currentEventCamera.ScreenPointToRay(eventPosition); + + if (canvas.renderMode != RenderMode.ScreenSpaceOverlay && blockingObjects != BlockingObjects.None) + { + float distanceToClipPlane = 100.0f; + + if (currentEventCamera != null) + { + float projectionDirection = ray.direction.z; + distanceToClipPlane = Mathf.Approximately(0.0f, projectionDirection) + ? Mathf.Infinity + : Mathf.Abs((currentEventCamera.farClipPlane - currentEventCamera.nearClipPlane) / projectionDirection); + } + + if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All) + { + if (ReflectionMethodsCache.Singleton.raycast3D != null) + { + var hits = ReflectionMethodsCache.Singleton.raycast3DAll(ray, distanceToClipPlane, (int)m_BlockingMask); + if (hits.Length > 0) + hitDistance = hits[0].distance; + } + } + + if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All) + { + if (ReflectionMethodsCache.Singleton.raycast2D != null) + { + var hits = ReflectionMethodsCache.Singleton.getRayIntersectionAll(ray, distanceToClipPlane, (int)m_BlockingMask); + if (hits.Length > 0) + hitDistance = hits[0].distance; + } + } + } + + m_RaycastResults.Clear(); + Raycast(canvas, currentEventCamera, eventPosition, canvasGraphics, m_RaycastResults); + + int totalCount = m_RaycastResults.Count; + for (var index = 0; index < totalCount; index++) + { + var go = m_RaycastResults[index].gameObject; + bool appendGraphic = true; + + if (ignoreReversedGraphics) + { + if (currentEventCamera == null) + { + // If we dont have a camera we know that we should always be facing forward + var dir = go.transform.rotation * Vector3.forward; + appendGraphic = Vector3.Dot(Vector3.forward, dir) > 0; + } + else + { + // If we have a camera compare the direction against the cameras forward. + var cameraFoward = currentEventCamera.transform.rotation * Vector3.forward; + var dir = go.transform.rotation * Vector3.forward; + appendGraphic = Vector3.Dot(cameraFoward, dir) > 0; + } + } + + if (appendGraphic) + { + float distance = 0; + + if (currentEventCamera == null || canvas.renderMode == RenderMode.ScreenSpaceOverlay) + distance = 0; + else + { + Transform trans = go.transform; + Vector3 transForward = trans.forward; + // http://geomalgorithms.com/a06-_intersect-2.html + distance = (Vector3.Dot(transForward, trans.position - currentEventCamera.transform.position) / Vector3.Dot(transForward, ray.direction)); + + // Check to see if the go is behind the camera. + if (distance < 0) + continue; + } + + if (distance >= hitDistance) + continue; + + var castResult = new RaycastResult + { + gameObject = go, + module = this, + distance = distance, + screenPosition = eventPosition, + index = resultAppendList.Count, + depth = m_RaycastResults[index].depth, + sortingLayer = canvas.sortingLayerID, + sortingOrder = canvas.sortingOrder + }; + resultAppendList.Add(castResult); + } + } + } + + public override Camera eventCamera + { + get + { + if (canvas.renderMode == RenderMode.ScreenSpaceOverlay || (canvas.renderMode == RenderMode.ScreenSpaceCamera && canvas.worldCamera == null)) + return null; + + return canvas.worldCamera != null ? canvas.worldCamera : Camera.main; + } + } + + // + /// <summary> + /// Perform a raycast into the screen and collect all graphics underneath it. + /// </summary> + [NonSerialized] static readonly List<Graphic> s_SortedGraphics = new List<Graphic>(); + private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, IList<Graphic> foundGraphics, List<Graphic> results) + { + // Debug.Log("ttt" + pointerPoision + ":::" + camera); + // Necessary for the event system + int totalCount = foundGraphics.Count; + for (int i = 0; i < totalCount; ++i) + { + Graphic graphic = foundGraphics[i]; + + // -1 means it hasn't been processed by the canvas, which means it isn't actually drawn + if (graphic.depth == -1 || !graphic.raycastTarget || graphic.canvasRenderer.cull) + continue; + + if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera)) + continue; + + if (graphic.Raycast(pointerPosition, eventCamera)) + { + s_SortedGraphics.Add(graphic); + } + } + + // ´Ó¸ßµ½µÍ£¬ËùÒÔ»áÒÔÉî¶ÈÓÅÏÈ¡£Ô½ÉîµÄÔ½ÏÈÏìÓ¦¡£ + s_SortedGraphics.Sort((g1, g2) => g2.depth.CompareTo(g1.depth)); + // StringBuilder cast = new StringBuilder(); + totalCount = s_SortedGraphics.Count; + for (int i = 0; i < totalCount; ++i) + results.Add(s_SortedGraphics[i]); + // Debug.Log (cast.ToString()); + + s_SortedGraphics.Clear(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs.meta new file mode 100644 index 0000000..d51fee9 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRaycaster.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0dc7198a94080b64e9e51e6f934b3e35 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs new file mode 100644 index 0000000..c081269 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs @@ -0,0 +1,38 @@ +#if UNITY_EDITOR +using System.Collections.Generic; +using UnityEngine.UI.Collections; + +namespace UnityEngine.UI +{ + public static class GraphicRebuildTracker + { + static IndexedSet<Graphic> m_Tracked = new IndexedSet<Graphic>(); + static bool s_Initialized; + + public static void TrackGraphic(Graphic g) + { + if (!s_Initialized) + { + CanvasRenderer.onRequestRebuild += OnRebuildRequested; + s_Initialized = true; + } + + m_Tracked.AddUnique(g); + } + + public static void UnTrackGraphic(Graphic g) + { + m_Tracked.Remove(g); + } + + static void OnRebuildRequested() + { + StencilMaterial.ClearAll(); + for (int i = 0; i < m_Tracked.Count; i++) + { + m_Tracked[i].OnRebuildRequested(); + } + } + } +} +#endif // if UNITY_EDITOR diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs.meta new file mode 100644 index 0000000..d0fff87 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRebuildTracker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40f1f16390b7d7842b9e0c5df6baa9d8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs new file mode 100644 index 0000000..0642792 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using UnityEngine.UI.Collections; + +namespace UnityEngine.UI +{ + // ÓÎÏ·ÖÐÖ»ÓÐÒ»·Ýµ¥Àý + public class GraphicRegistry + { + private static GraphicRegistry s_Instance; + + // °´Canvas·ÖÀàͳ¼ÆGraphic + private readonly Dictionary<Canvas, IndexedSet<Graphic>> m_Graphics = new Dictionary<Canvas, IndexedSet<Graphic>>(); + + protected GraphicRegistry() + { + // This is needed for AOT on IOS. Without it the compile doesn't get the definition of the Dictionarys +#pragma warning disable 168 + Dictionary<Graphic, int> emptyGraphicDic; + Dictionary<ICanvasElement, int> emptyElementDic; +#pragma warning restore 168 + } + + public static GraphicRegistry instance + { + get + { + if (s_Instance == null) + s_Instance = new GraphicRegistry(); + return s_Instance; + } + } + + public static void RegisterGraphicForCanvas(Canvas c, Graphic graphic) + { + if (c == null) + return; + + IndexedSet<Graphic> graphics; + instance.m_Graphics.TryGetValue(c, out graphics); + + if (graphics != null) + { + graphics.AddUnique(graphic); + return; + } + + // Dont need to AddUnique as we know its the only item in the list + graphics = new IndexedSet<Graphic>(); + graphics.Add(graphic); + instance.m_Graphics.Add(c, graphics); + } + + public static void UnregisterGraphicForCanvas(Canvas c, Graphic graphic) + { + if (c == null) + return; + + IndexedSet<Graphic> graphics; + if (instance.m_Graphics.TryGetValue(c, out graphics)) + { + graphics.Remove(graphic); + + if (graphics.Count == 0) + instance.m_Graphics.Remove(c); + } + } + + private static readonly List<Graphic> s_EmptyList = new List<Graphic>(); + public static IList<Graphic> GetGraphicsForCanvas(Canvas canvas) + { + IndexedSet<Graphic> graphics; + if (instance.m_Graphics.TryGetValue(canvas, out graphics)) + return graphics; + + return s_EmptyList; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs.meta new file mode 100644 index 0000000..bc0ed05 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/GraphicRegistry.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b0a078c41319d0f4ab759c3ad44fd733 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs new file mode 100644 index 0000000..f2becbb --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs @@ -0,0 +1,10 @@ +using System; + +namespace UnityEngine.UI +{ + [Obsolete("Not supported anymore")] + interface IGraphicEnabledDisabled + { + void OnSiblingGraphicEnabledDisabled(); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs.meta new file mode 100644 index 0000000..24c8266 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/IGraphicEnabledDisabled.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b6892dbec884b7b4482fe7cdb11bc565 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs new file mode 100644 index 0000000..65e0cfd --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs @@ -0,0 +1,1171 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + /// <summary> + /// Image is a textured element in the UI hierarchy. + /// </summary> + + [AddComponentMenu("UI/Image", 11)] + public class Image : MaskableGraphic, ISerializationCallbackReceiver, ILayoutElement, ICanvasRaycastFilter + { + public enum Type + { + Simple, + Sliced, + Tiled, + Filled + } + + public enum FillMethod + { + Horizontal, + Vertical, + Radial90, + Radial180, + Radial360, + } + + public enum OriginHorizontal + { + Left, + Right, + } + + public enum OriginVertical + { + Bottom, + Top, + } + + public enum Origin90 + { + BottomLeft, + TopLeft, + TopRight, + BottomRight, + } + + public enum Origin180 + { + Bottom, + Left, + Top, + Right, + } + + public enum Origin360 + { + Bottom, + Right, + Top, + Left, + } + + static protected Material s_ETC1DefaultUI = null; + + [FormerlySerializedAs("m_Frame")] + [SerializeField] private Sprite m_Sprite; + public Sprite sprite { get { return m_Sprite; } set { if (SetPropertyUtility.SetClass(ref m_Sprite, value)) SetAllDirty(); } } + + [NonSerialized] + private Sprite m_OverrideSprite; + public Sprite overrideSprite { get { return activeSprite; } set { if (SetPropertyUtility.SetClass(ref m_OverrideSprite, value)) SetAllDirty(); } } + + private Sprite activeSprite { get { return m_OverrideSprite != null ? m_OverrideSprite : sprite; } } + + /// How the Image is drawn. + [SerializeField] private Type m_Type = Type.Simple; + public Type type { get { return m_Type; } set { if (SetPropertyUtility.SetStruct(ref m_Type, value)) SetVerticesDirty(); } } + + [SerializeField] private bool m_PreserveAspect = false; + public bool preserveAspect { get { return m_PreserveAspect; } set { if (SetPropertyUtility.SetStruct(ref m_PreserveAspect, value)) SetVerticesDirty(); } } + + [SerializeField] private bool m_FillCenter = true; + public bool fillCenter { get { return m_FillCenter; } set { if (SetPropertyUtility.SetStruct(ref m_FillCenter, value)) SetVerticesDirty(); } } + + /// Filling method for filled sprites. + [SerializeField] private FillMethod m_FillMethod = FillMethod.Radial360; + public FillMethod fillMethod { get { return m_FillMethod; } set { if (SetPropertyUtility.SetStruct(ref m_FillMethod, value)) { SetVerticesDirty(); m_FillOrigin = 0; } } } + + /// Amount of the Image shown. 0-1 range with 0 being nothing shown, and 1 being the full Image. + [Range(0, 1)] + [SerializeField] private float m_FillAmount = 1.0f; + public float fillAmount { get { return m_FillAmount; } set { if (SetPropertyUtility.SetStruct(ref m_FillAmount, Mathf.Clamp01(value))) SetVerticesDirty(); } } + + /// Whether the Image should be filled clockwise (true) or counter-clockwise (false). + [SerializeField] private bool m_FillClockwise = true; + public bool fillClockwise { get { return m_FillClockwise; } set { if (SetPropertyUtility.SetStruct(ref m_FillClockwise, value)) SetVerticesDirty(); } } + + /// Controls the origin point of the Fill process. Value means different things with each fill method. + [SerializeField] private int m_FillOrigin; + public int fillOrigin { get { return m_FillOrigin; } set { if (SetPropertyUtility.SetStruct(ref m_FillOrigin, value)) SetVerticesDirty(); } } + + // Not serialized until we support read-enabled sprites better. + private float m_AlphaHitTestMinimumThreshold = 0; + + [Obsolete("eventAlphaThreshold has been deprecated. Use eventMinimumAlphaThreshold instead (UnityUpgradable) -> alphaHitTestMinimumThreshold")] + public float eventAlphaThreshold { get { return 1 - alphaHitTestMinimumThreshold; } set { alphaHitTestMinimumThreshold = 1 - value; } } + public float alphaHitTestMinimumThreshold { get { return m_AlphaHitTestMinimumThreshold; } set { m_AlphaHitTestMinimumThreshold = value; } } + + protected Image() + { + useLegacyMeshGeneration = false; + } + + /// <summary> + /// Default material used to draw everything if no explicit material was specified. + /// </summary> + + static public Material defaultETC1GraphicMaterial + { + get + { + if (s_ETC1DefaultUI == null) + s_ETC1DefaultUI = Canvas.GetETC1SupportedCanvasMaterial(); + return s_ETC1DefaultUI; + } + } + + /// <summary> + /// Image's texture comes from the UnityEngine.Image. + /// </summary> + public override Texture mainTexture + { + get + { + if (activeSprite == null) + { + if (material != null && material.mainTexture != null) + { + return material.mainTexture; + } + return s_WhiteTexture; + } + + return activeSprite.texture; + } + } + + /// <summary> + /// Whether the Image has a border to work with. + /// </summary> + + public bool hasBorder + { + get + { + if (activeSprite != null) + { + Vector4 v = activeSprite.border; + return v.sqrMagnitude > 0f; + } + return false; + } + } + + public float pixelsPerUnit + { + get + { + float spritePixelsPerUnit = 100; + if (activeSprite) + spritePixelsPerUnit = activeSprite.pixelsPerUnit; + + float referencePixelsPerUnit = 100; + if (canvas) + referencePixelsPerUnit = canvas.referencePixelsPerUnit; + + return spritePixelsPerUnit / referencePixelsPerUnit; + } + } + + public override Material material + { + get + { + if (m_Material != null) + return m_Material; + + if (activeSprite && activeSprite.associatedAlphaSplitTexture != null) + return defaultETC1GraphicMaterial; + + return defaultMaterial; + } + + set + { + base.material = value; + } + } + + public virtual void OnBeforeSerialize()
+ {
+ //Debug.Log("OnBeforeSerialize");
+ } + + // ÐòÁл¯Ö®ºó£¬¼´ÐÞ¸ÄÁËÐòÁл¯²ÎÊýÖ®ºó¡£Ð£ÕýһϽá¹û + public virtual void OnAfterDeserialize() + { + if (m_FillOrigin < 0) + m_FillOrigin = 0; + else if (m_FillMethod == FillMethod.Horizontal && m_FillOrigin > 1) + m_FillOrigin = 0; + else if (m_FillMethod == FillMethod.Vertical && m_FillOrigin > 1) + m_FillOrigin = 0; + else if (m_FillOrigin > 3) + m_FillOrigin = 0; + + m_FillAmount = Mathf.Clamp(m_FillAmount, 0f, 1f); + } + + /// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top. + private Vector4 GetDrawingDimensions(bool shouldPreserveAspect) + { + var padding = activeSprite == null ? Vector4.zero : Sprites.DataUtility.GetPadding(activeSprite); + var size = activeSprite == null ? Vector2.zero : new Vector2(activeSprite.rect.width, activeSprite.rect.height); + + Rect r = GetPixelAdjustedRect(); + // Debug.Log(string.Format("r:{2}, size:{0}, padding:{1}", size, padding, r)); + + int spriteW = Mathf.RoundToInt(size.x); + int spriteH = Mathf.RoundToInt(size.y); + + var v = new Vector4( + padding.x / spriteW, + padding.y / spriteH, + (spriteW - padding.z) / spriteW, + (spriteH - padding.w) / spriteH); + + if (shouldPreserveAspect && size.sqrMagnitude > 0.0f) + { + var spriteRatio = size.x / size.y; + var rectRatio = r.width / r.height; + + if (spriteRatio > rectRatio) + { + var oldHeight = r.height; + r.height = r.width * (1.0f / spriteRatio); + r.y += (oldHeight - r.height) * rectTransform.pivot.y; + } + else + { + var oldWidth = r.width; + r.width = r.height * spriteRatio; + r.x += (oldWidth - r.width) * rectTransform.pivot.x; + } + } + + v = new Vector4( + r.x + r.width * v.x, + r.y + r.height * v.y, + r.x + r.width * v.z, + r.y + r.height * v.w + ); + + return v; + } + + public override void SetNativeSize() + { + if (activeSprite != null) + { + float w = activeSprite.rect.width / pixelsPerUnit; + float h = activeSprite.rect.height / pixelsPerUnit; + rectTransform.anchorMax = rectTransform.anchorMin; + rectTransform.sizeDelta = new Vector2(w, h); + SetAllDirty(); + } + } + + /// <summary> + /// Update the UI renderer mesh. + /// </summary> + protected override void OnPopulateMesh(VertexHelper toFill) + { + if (activeSprite == null) + { + base.OnPopulateMesh(toFill); + return; + } + + switch (type) + { + case Type.Simple: + GenerateSimpleSprite(toFill, m_PreserveAspect); + break; + case Type.Sliced: + GenerateSlicedSprite(toFill); + break; + case Type.Tiled: + GenerateTiledSprite(toFill); + break; + case Type.Filled: + GenerateFilledSprite(toFill, m_PreserveAspect); + break; + } + } + + /// <summary> + /// Update the renderer's material. + /// </summary> + + protected override void UpdateMaterial() + { + base.UpdateMaterial(); + + // check if this sprite has an associated alpha texture (generated when splitting RGBA = RGB + A as two textures without alpha) + + if (activeSprite == null) + { + canvasRenderer.SetAlphaTexture(null); + return; + } + + //Èç¹ûÊÇETCѹËõ¸ñʽ£¬»áÉú³ÉÒ»·ÝalphaTexÖ»±£´æÍ¸Ã÷¶ÈÐÅÏ¢£¬²»ÔÚ_MainTexÀï + Texture2D alphaTex = activeSprite.associatedAlphaSplitTexture; + + if (alphaTex != null) + { + canvasRenderer.SetAlphaTexture(alphaTex); // _AlphaTex + } + } + + /// <summary> + /// Generate vertices for a simple Image. + /// </summary> + void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect) + { + Vector4 v = GetDrawingDimensions(lPreserveAspect); + var uv = (activeSprite != null) ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero; + + var color32 = color; + vh.Clear(); + vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(uv.x, uv.y)); + vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(uv.x, uv.w)); + vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(uv.z, uv.w)); + vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(uv.z, uv.y)); + + vh.AddTriangle(0, 1, 2); + vh.AddTriangle(2, 3, 0); + } + + /// <summary> + /// Generate vertices for a 9-sliced Image. + /// </summary> + + static readonly Vector2[] s_VertScratch = new Vector2[4]; + static readonly Vector2[] s_UVScratch = new Vector2[4]; + + private void GenerateSlicedSprite(VertexHelper toFill) + { + if (!hasBorder) + { + GenerateSimpleSprite(toFill, false); + return; + } + + Vector4 outer, inner, padding, border; + + if (activeSprite != null) + { + outer = Sprites.DataUtility.GetOuterUV(activeSprite); + inner = Sprites.DataUtility.GetInnerUV(activeSprite); + padding = Sprites.DataUtility.GetPadding(activeSprite); + border = activeSprite.border; + } + else + { + outer = Vector4.zero; + inner = Vector4.zero; + padding = Vector4.zero; + border = Vector4.zero; + } + + Rect rect = GetPixelAdjustedRect(); + Vector4 adjustedBorders = GetAdjustedBorders(border / pixelsPerUnit, rect); + padding = padding / pixelsPerUnit; + + s_VertScratch[0] = new Vector2(padding.x, padding.y); + s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w); + + s_VertScratch[1].x = adjustedBorders.x; + s_VertScratch[1].y = adjustedBorders.y; + + s_VertScratch[2].x = rect.width - adjustedBorders.z; + s_VertScratch[2].y = rect.height - adjustedBorders.w; + + for (int i = 0; i < 4; ++i) + { + s_VertScratch[i].x += rect.x; + s_VertScratch[i].y += rect.y; + } + + s_UVScratch[0] = new Vector2(outer.x, outer.y); + s_UVScratch[1] = new Vector2(inner.x, inner.y); + s_UVScratch[2] = new Vector2(inner.z, inner.w); + s_UVScratch[3] = new Vector2(outer.z, outer.w); + + toFill.Clear(); + + for (int x = 0; x < 3; ++x) + { + int x2 = x + 1; + + for (int y = 0; y < 3; ++y) + { + if (!m_FillCenter && x == 1 && y == 1) + continue; + + int y2 = y + 1; + + + AddQuad(toFill, + new Vector2(s_VertScratch[x].x, s_VertScratch[y].y), + new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y), + color, + new Vector2(s_UVScratch[x].x, s_UVScratch[y].y), + new Vector2(s_UVScratch[x2].x, s_UVScratch[y2].y)); + } + } + } + + /// <summary> + /// Generate vertices for a tiled Image. + /// </summary> + + void GenerateTiledSprite(VertexHelper toFill) + { + Vector4 outer, inner, border; + Vector2 spriteSize; + + if (activeSprite != null) + { + outer = Sprites.DataUtility.GetOuterUV(activeSprite); + inner = Sprites.DataUtility.GetInnerUV(activeSprite); + border = activeSprite.border; + spriteSize = activeSprite.rect.size; + } + else + { + outer = Vector4.zero; + inner = Vector4.zero; + border = Vector4.zero; + spriteSize = Vector2.one * 100; + } + + Rect rect = GetPixelAdjustedRect(); + float tileWidth = (spriteSize.x - border.x - border.z) / pixelsPerUnit; + float tileHeight = (spriteSize.y - border.y - border.w) / pixelsPerUnit; + border = GetAdjustedBorders(border / pixelsPerUnit, rect); + + var uvMin = new Vector2(inner.x, inner.y); + var uvMax = new Vector2(inner.z, inner.w); + + // Min to max max range for tiled region in coordinates relative to lower left corner. + float xMin = border.x; + float xMax = rect.width - border.z; + float yMin = border.y; + float yMax = rect.height - border.w; + + toFill.Clear(); + var clipped = uvMax; + + // if either width is zero we cant tile so just assume it was the full width. + if (tileWidth <= 0) + tileWidth = xMax - xMin; + + if (tileHeight <= 0) + tileHeight = yMax - yMin; + + if (activeSprite != null && (hasBorder || activeSprite.packed || activeSprite.texture.wrapMode != TextureWrapMode.Repeat)) + { + // Sprite has border, or is not in repeat mode, or cannot be repeated because of packing. + // We cannot use texture tiling so we will generate a mesh of quads to tile the texture. + + // Evaluate how many vertices we will generate. Limit this number to something sane, + // especially since meshes can not have more than 65000 vertices. + + long nTilesW = 0; + long nTilesH = 0; + if (m_FillCenter) + { + nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth); + nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight); + + double nVertices = 0; + if (hasBorder) + { + nVertices = (nTilesW + 2.0) * (nTilesH + 2.0) * 4.0; // 4 vertices per tile + } + else + { + nVertices = nTilesW * nTilesH * 4.0; // 4 vertices per tile + } + + if (nVertices > 65000.0) + { + Debug.LogError("Too many sprite tiles on Image \"" + name + "\". The tile size will be increased. To remove the limit on the number of tiles, convert the Sprite to an Advanced texture, remove the borders, clear the Packing tag and set the Wrap mode to Repeat.", this); + + double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile. + double imageRatio; + if (hasBorder) + { + imageRatio = (nTilesW + 2.0) / (nTilesH + 2.0); + } + else + { + imageRatio = (double)nTilesW / nTilesH; + } + + double targetTilesW = Math.Sqrt(maxTiles / imageRatio); + double targetTilesH = targetTilesW * imageRatio; + if (hasBorder) + { + targetTilesW -= 2; + targetTilesH -= 2; + } + + nTilesW = (long)Math.Floor(targetTilesW); + nTilesH = (long)Math.Floor(targetTilesH); + tileWidth = (xMax - xMin) / nTilesW; + tileHeight = (yMax - yMin) / nTilesH; + } + } + else + { + if (hasBorder) + { + // Texture on the border is repeated only in one direction. + nTilesW = (long)Math.Ceiling((xMax - xMin) / tileWidth); + nTilesH = (long)Math.Ceiling((yMax - yMin) / tileHeight); + double nVertices = (nTilesH + nTilesW + 2.0 /*corners*/) * 2.0 /*sides*/ * 4.0 /*vertices per tile*/; + if (nVertices > 65000.0) + { + Debug.LogError("Too many sprite tiles on Image \"" + name + "\". The tile size will be increased. To remove the limit on the number of tiles, convert the Sprite to an Advanced texture, remove the borders, clear the Packing tag and set the Wrap mode to Repeat.", this); + + double maxTiles = 65000.0 / 4.0; // Max number of vertices is 65000; 4 vertices per tile. + double imageRatio = (double)nTilesW / nTilesH; + double targetTilesW = (maxTiles - 4 /*corners*/) / (2 * (1.0 + imageRatio)); + double targetTilesH = targetTilesW * imageRatio; + + nTilesW = (long)Math.Floor(targetTilesW); + nTilesH = (long)Math.Floor(targetTilesH); + tileWidth = (xMax - xMin) / nTilesW; + tileHeight = (yMax - yMin) / nTilesH; + } + } + else + { + nTilesH = nTilesW = 0; + } + } + + if (m_FillCenter) + { + // TODO: we could share vertices between quads. If vertex sharing is implemented. update the computation for the number of vertices accordingly. + for (long j = 0; j < nTilesH; j++) + { + float y1 = yMin + j * tileHeight; + float y2 = yMin + (j + 1) * tileHeight; + if (y2 > yMax) + { + clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1); + y2 = yMax; + } + clipped.x = uvMax.x; + for (long i = 0; i < nTilesW; i++) + { + float x1 = xMin + i * tileWidth; + float x2 = xMin + (i + 1) * tileWidth; + if (x2 > xMax) + { + clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1); + x2 = xMax; + } + AddQuad(toFill, new Vector2(x1, y1) + rect.position, new Vector2(x2, y2) + rect.position, color, uvMin, clipped); + } + } + } + if (hasBorder) + { + clipped = uvMax; + for (long j = 0; j < nTilesH; j++) + { + float y1 = yMin + j * tileHeight; + float y2 = yMin + (j + 1) * tileHeight; + if (y2 > yMax) + { + clipped.y = uvMin.y + (uvMax.y - uvMin.y) * (yMax - y1) / (y2 - y1); + y2 = yMax; + } + AddQuad(toFill, + new Vector2(0, y1) + rect.position, + new Vector2(xMin, y2) + rect.position, + color, + new Vector2(outer.x, uvMin.y), + new Vector2(uvMin.x, clipped.y)); + AddQuad(toFill, + new Vector2(xMax, y1) + rect.position, + new Vector2(rect.width, y2) + rect.position, + color, + new Vector2(uvMax.x, uvMin.y), + new Vector2(outer.z, clipped.y)); + } + + // Bottom and top tiled border + clipped = uvMax; + for (long i = 0; i < nTilesW; i++) + { + float x1 = xMin + i * tileWidth; + float x2 = xMin + (i + 1) * tileWidth; + if (x2 > xMax) + { + clipped.x = uvMin.x + (uvMax.x - uvMin.x) * (xMax - x1) / (x2 - x1); + x2 = xMax; + } + AddQuad(toFill, + new Vector2(x1, 0) + rect.position, + new Vector2(x2, yMin) + rect.position, + color, + new Vector2(uvMin.x, outer.y), + new Vector2(clipped.x, uvMin.y)); + AddQuad(toFill, + new Vector2(x1, yMax) + rect.position, + new Vector2(x2, rect.height) + rect.position, + color, + new Vector2(uvMin.x, uvMax.y), + new Vector2(clipped.x, outer.w)); + } + + // Corners + AddQuad(toFill, + new Vector2(0, 0) + rect.position, + new Vector2(xMin, yMin) + rect.position, + color, + new Vector2(outer.x, outer.y), + new Vector2(uvMin.x, uvMin.y)); + AddQuad(toFill, + new Vector2(xMax, 0) + rect.position, + new Vector2(rect.width, yMin) + rect.position, + color, + new Vector2(uvMax.x, outer.y), + new Vector2(outer.z, uvMin.y)); + AddQuad(toFill, + new Vector2(0, yMax) + rect.position, + new Vector2(xMin, rect.height) + rect.position, + color, + new Vector2(outer.x, uvMax.y), + new Vector2(uvMin.x, outer.w)); + AddQuad(toFill, + new Vector2(xMax, yMax) + rect.position, + new Vector2(rect.width, rect.height) + rect.position, + color, + new Vector2(uvMax.x, uvMax.y), + new Vector2(outer.z, outer.w)); + } + } + else + { + // Texture has no border, is in repeat mode and not packed. Use texture tiling. + Vector2 uvScale = new Vector2((xMax - xMin) / tileWidth, (yMax - yMin) / tileHeight); + + if (m_FillCenter) + { + AddQuad(toFill, new Vector2(xMin, yMin) + rect.position, new Vector2(xMax, yMax) + rect.position, color, Vector2.Scale(uvMin, uvScale), Vector2.Scale(uvMax, uvScale)); + } + } + } + + static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs) + { + int startIndex = vertexHelper.currentVertCount; + + for (int i = 0; i < 4; ++i) + vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]); + + vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2); + vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex); + } + + static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, Vector2 uvMin, Vector2 uvMax) + { + int startIndex = vertexHelper.currentVertCount; + + vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, new Vector2(uvMin.x, uvMin.y)); + vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, new Vector2(uvMin.x, uvMax.y)); + vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, new Vector2(uvMax.x, uvMax.y)); + vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, new Vector2(uvMax.x, uvMin.y)); + + vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2); + vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex); + } + + private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect) + { + Rect originalRect = rectTransform.rect; + + for (int axis = 0; axis <= 1; axis++) + { + float borderScaleRatio; + + // The adjusted rect (adjusted for pixel correctness) + // may be slightly larger than the original rect. + // Adjust the border to match the adjustedRect to avoid + // small gaps between borders (case 833201). + if (originalRect.size[axis] != 0) + { + borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis]; + border[axis] *= borderScaleRatio; + border[axis + 2] *= borderScaleRatio; + } + + // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size. + // In order to avoid artefacts with overlapping borders, we scale the borders down to fit. + float combinedBorders = border[axis] + border[axis + 2]; + if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0) + { + borderScaleRatio = adjustedRect.size[axis] / combinedBorders; + border[axis] *= borderScaleRatio; + border[axis + 2] *= borderScaleRatio; + } + } + return border; + } + + /// <summary> + /// Generate vertices for a filled Image. + /// </summary> + + static readonly Vector3[] s_Xy = new Vector3[4]; + static readonly Vector3[] s_Uv = new Vector3[4]; + void GenerateFilledSprite(VertexHelper toFill, bool preserveAspect) + { + toFill.Clear(); + + if (m_FillAmount < 0.001f) + return; + + Vector4 v = GetDrawingDimensions(preserveAspect); + Vector4 outer = activeSprite != null ? Sprites.DataUtility.GetOuterUV(activeSprite) : Vector4.zero; + UIVertex uiv = UIVertex.simpleVert; + uiv.color = color; + + float tx0 = outer.x; + float ty0 = outer.y; + float tx1 = outer.z; + float ty1 = outer.w; + + // Horizontal and vertical filled sprites are simple -- just end the Image prematurely + if (m_FillMethod == FillMethod.Horizontal || m_FillMethod == FillMethod.Vertical) + { + if (fillMethod == FillMethod.Horizontal) + { + float fill = (tx1 - tx0) * m_FillAmount; + + if (m_FillOrigin == 1) + { + v.x = v.z - (v.z - v.x) * m_FillAmount; + tx0 = tx1 - fill; + } + else + { + v.z = v.x + (v.z - v.x) * m_FillAmount; + tx1 = tx0 + fill; + } + } + else if (fillMethod == FillMethod.Vertical) + { + float fill = (ty1 - ty0) * m_FillAmount; + + if (m_FillOrigin == 1) + { + v.y = v.w - (v.w - v.y) * m_FillAmount; + ty0 = ty1 - fill; + } + else + { + v.w = v.y + (v.w - v.y) * m_FillAmount; + ty1 = ty0 + fill; + } + } + } + + s_Xy[0] = new Vector2(v.x, v.y); + s_Xy[1] = new Vector2(v.x, v.w); + s_Xy[2] = new Vector2(v.z, v.w); + s_Xy[3] = new Vector2(v.z, v.y); + + s_Uv[0] = new Vector2(tx0, ty0); + s_Uv[1] = new Vector2(tx0, ty1); + s_Uv[2] = new Vector2(tx1, ty1); + s_Uv[3] = new Vector2(tx1, ty0); + + { + if (m_FillAmount < 1f && m_FillMethod != FillMethod.Horizontal && m_FillMethod != FillMethod.Vertical) + { + if (fillMethod == FillMethod.Radial90) + { + if (RadialCut(s_Xy, s_Uv, m_FillAmount, m_FillClockwise, m_FillOrigin)) + AddQuad(toFill, s_Xy, color, s_Uv); + } + else if (fillMethod == FillMethod.Radial180) + { + for (int side = 0; side < 2; ++side) + { + float fx0, fx1, fy0, fy1; + int even = m_FillOrigin > 1 ? 1 : 0; + + if (m_FillOrigin == 0 || m_FillOrigin == 2) + { + fy0 = 0f; + fy1 = 1f; + if (side == even) + { + fx0 = 0f; + fx1 = 0.5f; + } + else + { + fx0 = 0.5f; + fx1 = 1f; + } + } + else + { + fx0 = 0f; + fx1 = 1f; + if (side == even) + { + fy0 = 0.5f; + fy1 = 1f; + } + else + { + fy0 = 0f; + fy1 = 0.5f; + } + } + + s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0); + s_Xy[1].x = s_Xy[0].x; + s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1); + s_Xy[3].x = s_Xy[2].x; + + s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0); + s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1); + s_Xy[2].y = s_Xy[1].y; + s_Xy[3].y = s_Xy[0].y; + + s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0); + s_Uv[1].x = s_Uv[0].x; + s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1); + s_Uv[3].x = s_Uv[2].x; + + s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0); + s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1); + s_Uv[2].y = s_Uv[1].y; + s_Uv[3].y = s_Uv[0].y; + + float val = m_FillClockwise ? fillAmount * 2f - side : m_FillAmount * 2f - (1 - side); + + if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((side + m_FillOrigin + 3) % 4))) + { + AddQuad(toFill, s_Xy, color, s_Uv); + } + } + } + else if (fillMethod == FillMethod.Radial360) + { + for (int corner = 0; corner < 4; ++corner) + { + float fx0, fx1, fy0, fy1; + + if (corner < 2) + { + fx0 = 0f; + fx1 = 0.5f; + } + else + { + fx0 = 0.5f; + fx1 = 1f; + } + + if (corner == 0 || corner == 3) + { + fy0 = 0f; + fy1 = 0.5f; + } + else + { + fy0 = 0.5f; + fy1 = 1f; + } + + s_Xy[0].x = Mathf.Lerp(v.x, v.z, fx0); + s_Xy[1].x = s_Xy[0].x; + s_Xy[2].x = Mathf.Lerp(v.x, v.z, fx1); + s_Xy[3].x = s_Xy[2].x; + + s_Xy[0].y = Mathf.Lerp(v.y, v.w, fy0); + s_Xy[1].y = Mathf.Lerp(v.y, v.w, fy1); + s_Xy[2].y = s_Xy[1].y; + s_Xy[3].y = s_Xy[0].y; + + s_Uv[0].x = Mathf.Lerp(tx0, tx1, fx0); + s_Uv[1].x = s_Uv[0].x; + s_Uv[2].x = Mathf.Lerp(tx0, tx1, fx1); + s_Uv[3].x = s_Uv[2].x; + + s_Uv[0].y = Mathf.Lerp(ty0, ty1, fy0); + s_Uv[1].y = Mathf.Lerp(ty0, ty1, fy1); + s_Uv[2].y = s_Uv[1].y; + s_Uv[3].y = s_Uv[0].y; + + float val = m_FillClockwise ? + m_FillAmount * 4f - ((corner + m_FillOrigin) % 4) : + m_FillAmount * 4f - (3 - ((corner + m_FillOrigin) % 4)); + + if (RadialCut(s_Xy, s_Uv, Mathf.Clamp01(val), m_FillClockwise, ((corner + 2) % 4))) + AddQuad(toFill, s_Xy, color, s_Uv); + } + } + } + else + { + AddQuad(toFill, s_Xy, color, s_Uv); + } + } + } + + /// <summary> + /// Adjust the specified quad, making it be radially filled instead. + /// </summary> + + static bool RadialCut(Vector3[] xy, Vector3[] uv, float fill, bool invert, int corner) + { + // Nothing to fill + if (fill < 0.001f) return false; + + // Even corners invert the fill direction + if ((corner & 1) == 1) invert = !invert; + + // Nothing to adjust + if (!invert && fill > 0.999f) return true; + + // Convert 0-1 value into 0 to 90 degrees angle in radians + float angle = Mathf.Clamp01(fill); + if (invert) angle = 1f - angle; + angle *= 90f * Mathf.Deg2Rad; + + // Calculate the effective X and Y factors + float cos = Mathf.Cos(angle); + float sin = Mathf.Sin(angle); + + RadialCut(xy, cos, sin, invert, corner); + RadialCut(uv, cos, sin, invert, corner); + return true; + } + + /// <summary> + /// Adjust the specified quad, making it be radially filled instead. + /// </summary> + + static void RadialCut(Vector3[] xy, float cos, float sin, bool invert, int corner) + { + int i0 = corner; + int i1 = ((corner + 1) % 4); + int i2 = ((corner + 2) % 4); + int i3 = ((corner + 3) % 4); + + if ((corner & 1) == 1) + { + if (sin > cos) + { + cos /= sin; + sin = 1f; + + if (invert) + { + xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos); + xy[i2].x = xy[i1].x; + } + } + else if (cos > sin) + { + sin /= cos; + cos = 1f; + + if (!invert) + { + xy[i2].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin); + xy[i3].y = xy[i2].y; + } + } + else + { + cos = 1f; + sin = 1f; + } + + if (!invert) xy[i3].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos); + else xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin); + } + else + { + if (cos > sin) + { + sin /= cos; + cos = 1f; + + if (!invert) + { + xy[i1].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin); + xy[i2].y = xy[i1].y; + } + } + else if (sin > cos) + { + cos /= sin; + sin = 1f; + + if (invert) + { + xy[i2].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos); + xy[i3].x = xy[i2].x; + } + } + else + { + cos = 1f; + sin = 1f; + } + + if (invert) xy[i3].y = Mathf.Lerp(xy[i0].y, xy[i2].y, sin); + else xy[i1].x = Mathf.Lerp(xy[i0].x, xy[i2].x, cos); + } + } + + public virtual void CalculateLayoutInputHorizontal() {} + public virtual void CalculateLayoutInputVertical() {} + + public virtual float minWidth { get { return 0; } } + + public virtual float preferredWidth + { + get + { + if (activeSprite == null) + return 0; + if (type == Type.Sliced || type == Type.Tiled) + return Sprites.DataUtility.GetMinSize(activeSprite).x / pixelsPerUnit; + return activeSprite.rect.size.x / pixelsPerUnit; + } + } + + public virtual float flexibleWidth { get { return -1; } } + + public virtual float minHeight { get { return 0; } } + + public virtual float preferredHeight + { + get + { + if (activeSprite == null) + return 0; + if (type == Type.Sliced || type == Type.Tiled) + return Sprites.DataUtility.GetMinSize(activeSprite).y / pixelsPerUnit; + return activeSprite.rect.size.y / pixelsPerUnit; + } + } + + public virtual float flexibleHeight { get { return -1; } } + + public virtual int layoutPriority { get { return 0; } } + + //»á¸ù¾Ý͸Ã÷¶È×ö¸üϸÖµÄÉäÏß¼ì²â£¬Í¸Ã÷µÄµØ·½²»Ëã + public virtual bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) + { + if (alphaHitTestMinimumThreshold <= 0) + return true; + + if (alphaHitTestMinimumThreshold > 1) + return false; + + if (activeSprite == null) + return true; + + Vector2 local; + if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local)) + return false; + + Rect rect = GetPixelAdjustedRect(); + + // Convert to have lower left corner as reference point. + local.x += rectTransform.pivot.x * rect.width; + local.y += rectTransform.pivot.y * rect.height; + + local = MapCoordinate(local, rect); + + // Normalize local coordinates. + Rect spriteRect = activeSprite.textureRect; + Vector2 normalized = new Vector2(local.x / spriteRect.width, local.y / spriteRect.height); + + // Convert to texture space. + float x = Mathf.Lerp(spriteRect.x, spriteRect.xMax, normalized.x) / activeSprite.texture.width; + float y = Mathf.Lerp(spriteRect.y, spriteRect.yMax, normalized.y) / activeSprite.texture.height; + + try + { + return activeSprite.texture.GetPixelBilinear(x, y).a >= alphaHitTestMinimumThreshold; + } + catch (UnityException e) + { + Debug.LogError("Using alphaHitTestMinimumThreshold greater than 0 on Image whose sprite texture cannot be read. " + e.Message + " Also make sure to disable sprite packing for this sprite.", this); + return true; + } + } + + private Vector2 MapCoordinate(Vector2 local, Rect rect) + { + Rect spriteRect = activeSprite.rect; + if (type == Type.Simple || type == Type.Filled) + return new Vector2(local.x * spriteRect.width / rect.width, local.y * spriteRect.height / rect.height); + + Vector4 border = activeSprite.border; + Vector4 adjustedBorder = GetAdjustedBorders(border / pixelsPerUnit, rect); + + for (int i = 0; i < 2; i++) + { + if (local[i] <= adjustedBorder[i]) + continue; + + if (rect.size[i] - local[i] <= adjustedBorder[i + 2]) + { + local[i] -= (rect.size[i] - spriteRect.size[i]); + continue; + } + + if (type == Type.Sliced) + { + float lerp = Mathf.InverseLerp(adjustedBorder[i], rect.size[i] - adjustedBorder[i + 2], local[i]); + local[i] = Mathf.Lerp(border[i], spriteRect.size[i] - border[i + 2], lerp); + continue; + } + else + { + local[i] -= adjustedBorder[i]; + local[i] = Mathf.Repeat(local[i], spriteRect.size[i] - border[i] - border[i + 2]); + local[i] += border[i]; + continue; + } + } + + return local; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs.meta new file mode 100644 index 0000000..91ab591 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/Image.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0cba8e295482e184f9f6a5a8f2b559c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs new file mode 100644 index 0000000..0d0f327 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs @@ -0,0 +1,235 @@ +using System; +using UnityEngine.Events; +using UnityEngine.Rendering; + +namespace UnityEngine.UI +{ + public abstract class MaskableGraphic : Graphic, IClippable, IMaskable, IMaterialModifier + { + [NonSerialized] + protected bool m_ShouldRecalculateStencil = true; + + [NonSerialized] + protected Material m_MaskMaterial; + + [NonSerialized] + private RectMask2D m_ParentMask; + + // m_Maskable is whether this graphic is allowed to be masked or not. It has the matching public property maskable. + // The default for m_Maskable is true, so graphics under a mask are masked out of the box. + // The maskable property can be turned off from script by the user if masking is not desired. + // m_IncludeForMasking is whether we actually consider this graphic for masking or not - this is an implementation detail. + // m_IncludeForMasking should only be true if m_Maskable is true AND a parent of the graphic has an IMask component. + // Things would still work correctly if m_IncludeForMasking was always true when m_Maskable is, but performance would suffer. + [NonSerialized] + private bool m_Maskable = true; + + [NonSerialized] + [Obsolete("Not used anymore.", true)] + protected bool m_IncludeForMasking = false; + + [Serializable] + public class CullStateChangedEvent : UnityEvent<bool> {} + + // Event delegates triggered on click. + [SerializeField] + private CullStateChangedEvent m_OnCullStateChanged = new CullStateChangedEvent(); + + public CullStateChangedEvent onCullStateChanged + { + get { return m_OnCullStateChanged; } + set { m_OnCullStateChanged = value; } + } + + public bool maskable + { + get { return m_Maskable; } + set + { + if (value == m_Maskable) + return; + m_Maskable = value; + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + } + } + + [NonSerialized] + [Obsolete("Not used anymore", true)] + protected bool m_ShouldRecalculate = true; + + [NonSerialized] + protected int m_StencilValue; + + public virtual Material GetModifiedMaterial(Material baseMaterial) + { + var toUse = baseMaterial; + + if (m_ShouldRecalculateStencil) + { + var rootCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); + // GraphicÔÚmasksϵÄÉî¶È£¬Èç¹û²»ÊÇ0ÇÒûÓÐmask×é¼þÒâζ×ÅÊÇÆÕͨµÄ·ÇmaskÓÃgraphic£¨Èç¹ûÊÇ0Ò»¶¨ÊÇmaskÓõÄgraphic) + m_StencilValue = maskable ? MaskUtilities.GetStencilDepth(transform, rootCanvas) : 0; + m_ShouldRecalculateStencil = false; + } + + // if we have a enabled Mask component then it will + // generate the mask material. This is an optimisation + // it adds some coupling between components though :( + Mask maskComponent = GetComponent<Mask>(); + if (m_StencilValue > 0 && (maskComponent == null || !maskComponent.IsActive())) + { + // Ref = (1 << stencilValue) - 1 + // Op = Keep + // Func = Equal + // ReadMask = (1 << stencilValue) - 1 + // WriteMask = 0 + var maskMat = StencilMaterial.Add(toUse, (1 << m_StencilValue) - 1, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, (1 << m_StencilValue) - 1, 0); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMat; + toUse = m_MaskMaterial; + } + return toUse; + } + + public virtual void Cull(Rect clipRect, bool validRect) + { + var cull = !validRect || !clipRect.Overlaps(rootCanvasRect, true); + UpdateCull(cull); + } + + private void UpdateCull(bool cull) + { + var cullingChanged = canvasRenderer.cull != cull; + canvasRenderer.cull = cull; + + if (cullingChanged) + { + UISystemProfilerApi.AddMarker("MaskableGraphic.cullingChanged", this); + m_OnCullStateChanged.Invoke(cull); + SetVerticesDirty(); // ÕâÀïÐèÒª¸üÐÂÒ»ÏÂcanvasRendererµÄÍø¸ñÊý¾Ý + } + } + + public virtual void SetClipRect(Rect clipRect, bool validRect) + { + if (validRect) + canvasRenderer.EnableRectClipping(clipRect); + else + canvasRenderer.DisableRectClipping(); + } + + protected override void OnEnable() + { + base.OnEnable(); + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + + if (GetComponent<Mask>() != null) + { + MaskUtilities.NotifyStencilStateChanged(this); + } + } + + protected override void OnDisable() + { + base.OnDisable(); + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + UpdateClipParent(); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = null; + + if (GetComponent<Mask>() != null) + { + MaskUtilities.NotifyStencilStateChanged(this); + } + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + +#endif + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + + if (!isActiveAndEnabled) + return; + + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + + [Obsolete("Not used anymore.", true)] + public virtual void ParentMaskStateChanged() {} + + protected override void OnCanvasHierarchyChanged() + { + base.OnCanvasHierarchyChanged(); + + if (!isActiveAndEnabled) + return; + + m_ShouldRecalculateStencil = true; + UpdateClipParent(); + SetMaterialDirty(); + } + + readonly Vector3[] m_Corners = new Vector3[4]; + private Rect rootCanvasRect + { + get + { + rectTransform.GetWorldCorners(m_Corners); + + if (canvas) + { + Canvas rootCanvas = canvas.rootCanvas; + for (int i = 0; i < 4; ++i) + m_Corners[i] = rootCanvas.transform.InverseTransformPoint(m_Corners[i]); + } + + return new Rect(m_Corners[0].x, m_Corners[0].y, m_Corners[2].x - m_Corners[0].x, m_Corners[2].y - m_Corners[0].y); + } + } + + private void UpdateClipParent() + { + var newParent = (maskable && IsActive()) ? MaskUtilities.GetRectMaskForClippable(this) : null; + + // if the new parent is different OR is now inactive + if (m_ParentMask != null && (newParent != m_ParentMask || !newParent.IsActive())) + { + m_ParentMask.RemoveClippable(this); + UpdateCull(false); + } + + // don't re-add it if the newparent is inactive + if (newParent != null && newParent.IsActive()) + newParent.AddClippable(this); + + m_ParentMask = newParent; + } + + public virtual void RecalculateClipping() + { + UpdateClipParent(); + } + + public virtual void RecalculateMasking() + { + m_ShouldRecalculateStencil = true; + SetMaterialDirty(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta new file mode 100644 index 0000000..07f0d51 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/MaskableGraphic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1316d79994e789c448714be540d28f4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs new file mode 100644 index 0000000..e6dab1b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + /// <summary> + /// If you don't have or don't wish to create an atlas, you can simply use this script to draw a texture. + /// Keep in mind though that this will create an extra draw call with each RawImage present, so it's + /// best to use it only for backgrounds or temporary visible graphics. + /// </summary> + [AddComponentMenu("UI/Raw Image", 12)] + public class RawImage : MaskableGraphic + { + [FormerlySerializedAs("m_Tex")] + [SerializeField] Texture m_Texture; + [SerializeField] Rect m_UVRect = new Rect(0f, 0f, 1f, 1f); + + protected RawImage() + { + useLegacyMeshGeneration = false; + } + + /// <summary> + /// Returns the texture used to draw this Graphic. + /// </summary> + public override Texture mainTexture + { + get + { + if (m_Texture == null) + {
+ if (material != null && material.mainTexture != null) + { + return material.mainTexture; + } + return s_WhiteTexture; + } + return m_Texture; + } + } + + /// <summary> + /// Texture to be used. + /// </summary> + public Texture texture + { + get + { + return m_Texture; + } + set + { + if (m_Texture == value) + return; + + m_Texture = value; + SetVerticesDirty(); + SetMaterialDirty(); + } + } + + /// <summary> + /// UV rectangle used by the texture. + /// </summary> + public Rect uvRect + { + get + { + return m_UVRect; + } + set + { + if (m_UVRect == value) + return; + m_UVRect = value; + SetVerticesDirty(); + } + } + + /// <summary> + /// Adjust the scale of the Graphic to make it pixel-perfect. + /// </summary> + + public override void SetNativeSize() + { + Texture tex = mainTexture; + if (tex != null) + { + int w = Mathf.RoundToInt(tex.width * uvRect.width); + int h = Mathf.RoundToInt(tex.height * uvRect.height); + rectTransform.anchorMax = rectTransform.anchorMin; + rectTransform.sizeDelta = new Vector2(w, h); + } + } + + protected override void OnPopulateMesh(VertexHelper vh) + { + Texture tex = mainTexture; + vh.Clear(); + if (tex != null) + { + var r = GetPixelAdjustedRect(); + var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height); + var scaleX = tex.width * tex.texelSize.x; + var scaleY = tex.height * tex.texelSize.y; + { + var color32 = color; + vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMin * scaleY)); + vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(m_UVRect.xMin * scaleX, m_UVRect.yMax * scaleY)); + vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMax * scaleY)); + vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(m_UVRect.xMax * scaleX, m_UVRect.yMin * scaleY)); + + vh.AddTriangle(0, 1, 2); + vh.AddTriangle(2, 3, 0); + } + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs.meta new file mode 100644 index 0000000..2a70e35 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/RawImage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 570773b73e8b0334fb410b7457eb8b6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs new file mode 100644 index 0000000..c95e146 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [Serializable] + public struct SpriteState : IEquatable<SpriteState> + { + [FormerlySerializedAs("highlightedSprite")] + [FormerlySerializedAs("m_SelectedSprite")] + [SerializeField] + private Sprite m_HighlightedSprite; + + [FormerlySerializedAs("pressedSprite")] + [SerializeField] + private Sprite m_PressedSprite; + + [FormerlySerializedAs("disabledSprite")] + [SerializeField] + private Sprite m_DisabledSprite; + + public Sprite highlightedSprite { get { return m_HighlightedSprite; } set { m_HighlightedSprite = value; } } + public Sprite pressedSprite { get { return m_PressedSprite; } set { m_PressedSprite = value; } } + public Sprite disabledSprite { get { return m_DisabledSprite; } set { m_DisabledSprite = value; } } + + public bool Equals(SpriteState other) + { + return highlightedSprite == other.highlightedSprite && + pressedSprite == other.pressedSprite && + disabledSprite == other.disabledSprite; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs.meta new file mode 100644 index 0000000..b389ded --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Graphics/SpriteState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc6d0c85730bc354697c6b7d971eda44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout.meta new file mode 100644 index 0000000..28d0b9d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0bcd17013ce6d5a4ab037dcc71a87811 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs new file mode 100644 index 0000000..96ee135 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs @@ -0,0 +1,145 @@ +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Aspect Ratio Fitter", 142)] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + [DisallowMultipleComponent] + public class AspectRatioFitter : UIBehaviour, ILayoutSelfController + { + public enum AspectMode { None, WidthControlsHeight, HeightControlsWidth, FitInParent, EnvelopeParent } + + [SerializeField] private AspectMode m_AspectMode = AspectMode.None; + public AspectMode aspectMode { get { return m_AspectMode; } set { if (SetPropertyUtility.SetStruct(ref m_AspectMode, value)) SetDirty(); } } + + [SerializeField] private float m_AspectRatio = 1; + public float aspectRatio { get { return m_AspectRatio; } set { if (SetPropertyUtility.SetStruct(ref m_AspectRatio, value)) SetDirty(); } } + + [System.NonSerialized] + private RectTransform m_Rect; + + private RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + private DrivenRectTransformTracker m_Tracker; + + protected AspectRatioFitter() {} + + protected override void OnEnable() + { + base.OnEnable(); + SetDirty(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + base.OnDisable(); + } + + protected override void OnRectTransformDimensionsChange() + { + UpdateRect(); + } + + private void UpdateRect() + { + if (!IsActive()) + return; + + m_Tracker.Clear(); + + switch (m_AspectMode) + { +#if UNITY_EDITOR + case AspectMode.None: + { + if (!Application.isPlaying) + m_AspectRatio = Mathf.Clamp(rectTransform.rect.width / rectTransform.rect.height, 0.001f, 1000f); + + break; + } +#endif + case AspectMode.HeightControlsWidth: + { + m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaX); + rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, rectTransform.rect.height * m_AspectRatio); + break; + } + case AspectMode.WidthControlsHeight: + { + m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaY); + rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, rectTransform.rect.width / m_AspectRatio); + break; + } + case AspectMode.FitInParent: + case AspectMode.EnvelopeParent: + { + m_Tracker.Add(this, rectTransform, + DrivenTransformProperties.Anchors | + DrivenTransformProperties.AnchoredPosition | + DrivenTransformProperties.SizeDeltaX | + DrivenTransformProperties.SizeDeltaY); + + rectTransform.anchorMin = Vector2.zero; + rectTransform.anchorMax = Vector2.one; + rectTransform.anchoredPosition = Vector2.zero; + + Vector2 sizeDelta = Vector2.zero; + Vector2 parentSize = GetParentSize(); + if ((parentSize.y * aspectRatio < parentSize.x) ^ (m_AspectMode == AspectMode.FitInParent)) + { + sizeDelta.y = GetSizeDeltaToProduceSize(parentSize.x / aspectRatio, 1); + } + else + { + sizeDelta.x = GetSizeDeltaToProduceSize(parentSize.y * aspectRatio, 0); + } + rectTransform.sizeDelta = sizeDelta; + + break; + } + } + } + + private float GetSizeDeltaToProduceSize(float size, int axis) + { + return size - GetParentSize()[axis] * (rectTransform.anchorMax[axis] - rectTransform.anchorMin[axis]); + } + + private Vector2 GetParentSize() + { + RectTransform parent = rectTransform.parent as RectTransform; + if (!parent) + return Vector2.zero; + return parent.rect.size; + } + + public virtual void SetLayoutHorizontal() {} + + public virtual void SetLayoutVertical() {} + + protected void SetDirty() + { + UpdateRect(); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + m_AspectRatio = Mathf.Clamp(m_AspectRatio, 0.001f, 1000f); + SetDirty(); + } + + #endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta new file mode 100644 index 0000000..e89adeb --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/AspectRatioFitter.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 49604c30279a7aa44b531ad6ffea458c +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs new file mode 100644 index 0000000..6504ac2 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs @@ -0,0 +1,241 @@ +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [RequireComponent(typeof(Canvas))] + [ExecuteInEditMode] + [AddComponentMenu("Layout/Canvas Scaler", 101)] + public class CanvasScaler : UIBehaviour + { + public enum ScaleMode { ConstantPixelSize, ScaleWithScreenSize, ConstantPhysicalSize } + + [Tooltip("Determines how UI elements in the Canvas are scaled.")] + [SerializeField] private ScaleMode m_UiScaleMode = ScaleMode.ConstantPixelSize; + public ScaleMode uiScaleMode { get { return m_UiScaleMode; } set { m_UiScaleMode = value; } } + + [Tooltip("If a sprite has this 'Pixels Per Unit' setting, then one pixel in the sprite will cover one unit in the UI.")] + [SerializeField] protected float m_ReferencePixelsPerUnit = 100; + public float referencePixelsPerUnit { get { return m_ReferencePixelsPerUnit; } set { m_ReferencePixelsPerUnit = value; } } + + + // Constant Pixel Size settings + + [Tooltip("Scales all UI elements in the Canvas by this factor.")] + [SerializeField] protected float m_ScaleFactor = 1; + public float scaleFactor { get { return m_ScaleFactor; } set { m_ScaleFactor = Mathf.Max(0.01f, value); } } + + + // Scale With Screen Size settings + + public enum ScreenMatchMode { MatchWidthOrHeight = 0, Expand = 1, Shrink = 2 } + + [Tooltip("The resolution the UI layout is designed for. If the screen resolution is larger, the UI will be scaled up, and if it's smaller, the UI will be scaled down. This is done in accordance with the Screen Match Mode.")] + [SerializeField] protected Vector2 m_ReferenceResolution = new Vector2(800, 600); + public Vector2 referenceResolution + { + get + { + return m_ReferenceResolution; + } + set + { + m_ReferenceResolution = value; + + const float k_MinimumResolution = 0.00001f; + + if (m_ReferenceResolution.x > -k_MinimumResolution && m_ReferenceResolution.x < k_MinimumResolution) m_ReferenceResolution.x = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.x); + if (m_ReferenceResolution.y > -k_MinimumResolution && m_ReferenceResolution.y < k_MinimumResolution) m_ReferenceResolution.y = k_MinimumResolution * Mathf.Sign(m_ReferenceResolution.y); + } + } + + [Tooltip("A mode used to scale the canvas area if the aspect ratio of the current resolution doesn't fit the reference resolution.")] + [SerializeField] protected ScreenMatchMode m_ScreenMatchMode = ScreenMatchMode.MatchWidthOrHeight; + public ScreenMatchMode screenMatchMode { get { return m_ScreenMatchMode; } set { m_ScreenMatchMode = value; } } + + [Tooltip("Determines if the scaling is using the width or height as reference, or a mix in between.")] + [Range(0, 1)] + [SerializeField] protected float m_MatchWidthOrHeight = 0; + public float matchWidthOrHeight { get { return m_MatchWidthOrHeight; } set { m_MatchWidthOrHeight = value; } } + + // The log base doesn't have any influence on the results whatsoever, as long as the same base is used everywhere. + private const float kLogBase = 2; + + + // Constant Physical Size settings + + public enum Unit { Centimeters, Millimeters, Inches, Points, Picas } + + [Tooltip("The physical unit to specify positions and sizes in.")] + [SerializeField] protected Unit m_PhysicalUnit = Unit.Points; + public Unit physicalUnit { get { return m_PhysicalUnit; } set { m_PhysicalUnit = value; } } + + [Tooltip("The DPI to assume if the screen DPI is not known.")] + [SerializeField] protected float m_FallbackScreenDPI = 96; + public float fallbackScreenDPI { get { return m_FallbackScreenDPI; } set { m_FallbackScreenDPI = value; } } + + [Tooltip("The pixels per inch to use for sprites that have a 'Pixels Per Unit' setting that matches the 'Reference Pixels Per Unit' setting.")] + [SerializeField] protected float m_DefaultSpriteDPI = 96; + public float defaultSpriteDPI { get { return m_DefaultSpriteDPI; } set { m_DefaultSpriteDPI = Mathf.Max(1, value); } } + + + // World Canvas settings + + [Tooltip("The amount of pixels per unit to use for dynamically created bitmaps in the UI, such as Text.")] + [SerializeField] protected float m_DynamicPixelsPerUnit = 1; + public float dynamicPixelsPerUnit { get { return m_DynamicPixelsPerUnit; } set { m_DynamicPixelsPerUnit = value; } } + + + // General variables + + private Canvas m_Canvas; + [System.NonSerialized] + private float m_PrevScaleFactor = 1; + [System.NonSerialized] + private float m_PrevReferencePixelsPerUnit = 100; + + + protected CanvasScaler() {} + + protected override void OnEnable() + { + base.OnEnable(); + m_Canvas = GetComponent<Canvas>(); + Handle(); + } + + protected override void OnDisable() + { + SetScaleFactor(1); + SetReferencePixelsPerUnit(100); + base.OnDisable(); + } + + protected virtual void Update() + { + Handle(); + } + + protected virtual void Handle() + { + if (m_Canvas == null || !m_Canvas.isRootCanvas) + return; + + if (m_Canvas.renderMode == RenderMode.WorldSpace) + { + HandleWorldCanvas(); + return; + } + + switch (m_UiScaleMode) + { + case ScaleMode.ConstantPixelSize: HandleConstantPixelSize(); break; + case ScaleMode.ScaleWithScreenSize: HandleScaleWithScreenSize(); break; + case ScaleMode.ConstantPhysicalSize: HandleConstantPhysicalSize(); break; + } + } + + protected virtual void HandleWorldCanvas() + { + SetScaleFactor(m_DynamicPixelsPerUnit); + SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit); + } + + protected virtual void HandleConstantPixelSize() + { + SetScaleFactor(m_ScaleFactor); + SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit); + } + + protected virtual void HandleScaleWithScreenSize() + { + Vector2 screenSize = new Vector2(Screen.width, Screen.height); + + // Multiple display support only when not the main display. For display 0 the reported + // resolution is always the desktops resolution since its part of the display API, + // so we use the standard none multiple display method. (case 741751) + int displayIndex = m_Canvas.targetDisplay; + if (displayIndex > 0 && displayIndex < Display.displays.Length) + { + Display disp = Display.displays[displayIndex]; + screenSize = new Vector2(disp.renderingWidth, disp.renderingHeight); + } + + float scaleFactor = 0; + switch (m_ScreenMatchMode) + { + case ScreenMatchMode.MatchWidthOrHeight: + { + // We take the log of the relative width and height before taking the average. + // Then we transform it back in the original space. + // the reason to transform in and out of logarithmic space is to have better behavior. + // If one axis has twice resolution and the other has half, it should even out if widthOrHeight value is at 0.5. + // In normal space the average would be (0.5 + 2) / 2 = 1.25 + // In logarithmic space the average is (-1 + 1) / 2 = 0 + float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase); + float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase); + float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight); + scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage); + break; + } + case ScreenMatchMode.Expand: + { + scaleFactor = Mathf.Min(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y); + break; + } + case ScreenMatchMode.Shrink: + { + scaleFactor = Mathf.Max(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y); + break; + } + } + + SetScaleFactor(scaleFactor); + SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit); + } + + protected virtual void HandleConstantPhysicalSize() + { + float currentDpi = Screen.dpi; + float dpi = (currentDpi == 0 ? m_FallbackScreenDPI : currentDpi); + float targetDPI = 1; + switch (m_PhysicalUnit) + { + case Unit.Centimeters: targetDPI = 2.54f; break; + case Unit.Millimeters: targetDPI = 25.4f; break; + case Unit.Inches: targetDPI = 1; break; + case Unit.Points: targetDPI = 72; break; + case Unit.Picas: targetDPI = 6; break; + } + + SetScaleFactor(dpi / targetDPI); + SetReferencePixelsPerUnit(m_ReferencePixelsPerUnit * targetDPI / m_DefaultSpriteDPI); + } + + protected void SetScaleFactor(float scaleFactor) + { + if (scaleFactor == m_PrevScaleFactor) + return; + + m_Canvas.scaleFactor = scaleFactor; + m_PrevScaleFactor = scaleFactor; + } + + protected void SetReferencePixelsPerUnit(float referencePixelsPerUnit) + { + if (referencePixelsPerUnit == m_PrevReferencePixelsPerUnit) + return; + + m_Canvas.referencePixelsPerUnit = referencePixelsPerUnit; + m_PrevReferencePixelsPerUnit = referencePixelsPerUnit; + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + m_ScaleFactor = Mathf.Max(0.01f, m_ScaleFactor); + m_DefaultSpriteDPI = Mathf.Max(1, m_DefaultSpriteDPI); + } + +#endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta new file mode 100644 index 0000000..4d67413 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/CanvasScaler.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: debcf26b89013e446a6de5574715c5af +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs new file mode 100644 index 0000000..a31d14c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs @@ -0,0 +1,103 @@ +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Content Size Fitter", 141)] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + public class ContentSizeFitter : UIBehaviour, ILayoutSelfController + { + public enum FitMode + { + Unconstrained, + MinSize, + PreferredSize + } + + [SerializeField] protected FitMode m_HorizontalFit = FitMode.Unconstrained; + public FitMode horizontalFit { get { return m_HorizontalFit; } set { if (SetPropertyUtility.SetStruct(ref m_HorizontalFit, value)) SetDirty(); } } + + [SerializeField] protected FitMode m_VerticalFit = FitMode.Unconstrained; + public FitMode verticalFit { get { return m_VerticalFit; } set { if (SetPropertyUtility.SetStruct(ref m_VerticalFit, value)) SetDirty(); } } + + [System.NonSerialized] private RectTransform m_Rect; + private RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + private DrivenRectTransformTracker m_Tracker; + + protected ContentSizeFitter() + {} + + protected override void OnEnable() + { + base.OnEnable(); + SetDirty(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + base.OnDisable(); + } + + protected override void OnRectTransformDimensionsChange() + { + SetDirty(); + } + + private void HandleSelfFittingAlongAxis(int axis) + { + FitMode fitting = (axis == 0 ? horizontalFit : verticalFit); + if (fitting == FitMode.Unconstrained) + { + // Keep a reference to the tracked transform, but don't control its properties: + m_Tracker.Add(this, rectTransform, DrivenTransformProperties.None); + return; + } + + m_Tracker.Add(this, rectTransform, (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY)); + + // Set size to min or preferred size + if (fitting == FitMode.MinSize) + rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetMinSize(m_Rect, axis)); + else + rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetPreferredSize(m_Rect, axis)); + } + + public virtual void SetLayoutHorizontal() + { + m_Tracker.Clear(); + HandleSelfFittingAlongAxis(0); + } + + public virtual void SetLayoutVertical() + { + HandleSelfFittingAlongAxis(1); + } + + protected void SetDirty() + { + if (!IsActive()) + return; + + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + SetDirty(); + } + + #endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta new file mode 100644 index 0000000..9f31a6d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ContentSizeFitter.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 742ec49dc902c1f4db49d19ada047c0e +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs new file mode 100644 index 0000000..170e410 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs @@ -0,0 +1,207 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Grid Layout Group", 152)] + public class GridLayoutGroup : LayoutGroup + { + public enum Corner { UpperLeft = 0, UpperRight = 1, LowerLeft = 2, LowerRight = 3 } + public enum Axis { Horizontal = 0, Vertical = 1 } + public enum Constraint { Flexible = 0, FixedColumnCount = 1, FixedRowCount = 2 } + + [SerializeField] protected Corner m_StartCorner = Corner.UpperLeft; + public Corner startCorner { get { return m_StartCorner; } set { SetProperty(ref m_StartCorner, value); } } + + [SerializeField] protected Axis m_StartAxis = Axis.Horizontal; + public Axis startAxis { get { return m_StartAxis; } set { SetProperty(ref m_StartAxis, value); } } + + [SerializeField] protected Vector2 m_CellSize = new Vector2(100, 100); + public Vector2 cellSize { get { return m_CellSize; } set { SetProperty(ref m_CellSize, value); } } + + [SerializeField] protected Vector2 m_Spacing = Vector2.zero; + public Vector2 spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } } + + [SerializeField] protected Constraint m_Constraint = Constraint.Flexible; + public Constraint constraint { get { return m_Constraint; } set { SetProperty(ref m_Constraint, value); } } + + [SerializeField] protected int m_ConstraintCount = 2; + public int constraintCount { get { return m_ConstraintCount; } set { SetProperty(ref m_ConstraintCount, Mathf.Max(1, value)); } } + + protected GridLayoutGroup() + {} + + #if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + constraintCount = constraintCount; + } + + #endif + + public override void CalculateLayoutInputHorizontal() + { + base.CalculateLayoutInputHorizontal(); + + int minColumns = 0; + int preferredColumns = 0; + if (m_Constraint == Constraint.FixedColumnCount) + { + minColumns = preferredColumns = m_ConstraintCount; + } + else if (m_Constraint == Constraint.FixedRowCount) + { + minColumns = preferredColumns = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f); + } + else + { + minColumns = 1; + preferredColumns = Mathf.CeilToInt(Mathf.Sqrt(rectChildren.Count)); + } + + SetLayoutInputForAxis( + padding.horizontal + (cellSize.x + spacing.x) * minColumns - spacing.x, + padding.horizontal + (cellSize.x + spacing.x) * preferredColumns - spacing.x, + -1, 0); + } + + public override void CalculateLayoutInputVertical() + { + int minRows = 0; + if (m_Constraint == Constraint.FixedColumnCount) + { + minRows = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f); + } + else if (m_Constraint == Constraint.FixedRowCount) + { + minRows = m_ConstraintCount; + } + else + { + float width = rectTransform.rect.size.x; + int cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x))); + minRows = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX); + } + + float minSpace = padding.vertical + (cellSize.y + spacing.y) * minRows - spacing.y; + SetLayoutInputForAxis(minSpace, minSpace, -1, 1); + } + + public override void SetLayoutHorizontal() + { + SetCellsAlongAxis(0); + } + + public override void SetLayoutVertical() + { + SetCellsAlongAxis(1); + } + + private void SetCellsAlongAxis(int axis) + { + // Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis + // and only vertical values when invoked for the vertical axis. + // However, in this case we set both the horizontal and vertical position when invoked for the vertical axis. + // Since we only set the horizontal position and not the size, it shouldn't affect children's layout, + // and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout. + + if (axis == 0) + { + // Only set the sizes when invoked for horizontal axis, not the positions. + for (int i = 0; i < rectChildren.Count; i++) + { + RectTransform rect = rectChildren[i]; + + m_Tracker.Add(this, rect, + DrivenTransformProperties.Anchors | + DrivenTransformProperties.AnchoredPosition | + DrivenTransformProperties.SizeDelta); + + rect.anchorMin = Vector2.up; + rect.anchorMax = Vector2.up; + rect.sizeDelta = cellSize; + } + return; + } + + float width = rectTransform.rect.size.x; + float height = rectTransform.rect.size.y; + + int cellCountX = 1; + int cellCountY = 1; + if (m_Constraint == Constraint.FixedColumnCount) + { + cellCountX = m_ConstraintCount; + cellCountY = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX - 0.001f); + } + else if (m_Constraint == Constraint.FixedRowCount) + { + cellCountY = m_ConstraintCount; + cellCountX = Mathf.CeilToInt(rectChildren.Count / (float)cellCountY - 0.001f); + } + else + { + if (cellSize.x + spacing.x <= 0) + cellCountX = int.MaxValue; + else + cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x))); + + if (cellSize.y + spacing.y <= 0) + cellCountY = int.MaxValue; + else + cellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y))); + } + + int cornerX = (int)startCorner % 2; + int cornerY = (int)startCorner / 2; + + int cellsPerMainAxis, actualCellCountX, actualCellCountY; + if (startAxis == Axis.Horizontal) + { + cellsPerMainAxis = cellCountX; + actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildren.Count); + actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis)); + } + else + { + cellsPerMainAxis = cellCountY; + actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildren.Count); + actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis)); + } + + Vector2 requiredSpace = new Vector2( + actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x, + actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y + ); + Vector2 startOffset = new Vector2( + GetStartOffset(0, requiredSpace.x), + GetStartOffset(1, requiredSpace.y) + ); + + for (int i = 0; i < rectChildren.Count; i++) + { + int positionX; + int positionY; + if (startAxis == Axis.Horizontal) + { + positionX = i % cellsPerMainAxis; + positionY = i / cellsPerMainAxis; + } + else + { + positionX = i / cellsPerMainAxis; + positionY = i % cellsPerMainAxis; + } + + if (cornerX == 1) + positionX = actualCellCountX - 1 - positionX; + if (cornerY == 1) + positionY = actualCellCountY - 1 - positionY; + + SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]); + SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]); + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta new file mode 100644 index 0000000..0ca5454 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 295d2cd868a0c204f850fde4917c4551 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs new file mode 100644 index 0000000..efe8d8e --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs @@ -0,0 +1,30 @@ +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Horizontal Layout Group", 150)] + public class HorizontalLayoutGroup : HorizontalOrVerticalLayoutGroup + { + protected HorizontalLayoutGroup() + {} + + public override void CalculateLayoutInputHorizontal() + { + base.CalculateLayoutInputHorizontal(); + CalcAlongAxis(0, false); + } + + public override void CalculateLayoutInputVertical() + { + CalcAlongAxis(1, false); + } + + public override void SetLayoutHorizontal() + { + SetChildrenAlongAxis(0, false); + } + + public override void SetLayoutVertical() + { + SetChildrenAlongAxis(1, false); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta new file mode 100644 index 0000000..0b116be --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalLayoutGroup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 2e0c30f216d393d4b93475ba573aea85 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs new file mode 100644 index 0000000..3e1c923 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs @@ -0,0 +1,179 @@ +namespace UnityEngine.UI +{ + // ²¼¾ÖËã·¨µÄºËÐͼÔÚÕâ¸ö»ùÀàÀïÃæ + public abstract class HorizontalOrVerticalLayoutGroup : LayoutGroup + { + [SerializeField] protected float m_Spacing = 0; + public float spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } } + + [SerializeField] protected bool m_ChildForceExpandWidth = true; + public bool childForceExpandWidth { get { return m_ChildForceExpandWidth; } set { SetProperty(ref m_ChildForceExpandWidth, value); } } + + [SerializeField] protected bool m_ChildForceExpandHeight = true; + public bool childForceExpandHeight { get { return m_ChildForceExpandHeight; } set { SetProperty(ref m_ChildForceExpandHeight, value); } } + + [SerializeField] protected bool m_ChildControlWidth = true; + public bool childControlWidth { get { return m_ChildControlWidth; } set { SetProperty(ref m_ChildControlWidth, value); } } + + [SerializeField] protected bool m_ChildControlHeight = true; + public bool childControlHeight { get { return m_ChildControlHeight; } set { SetProperty(ref m_ChildControlHeight, value); } } + + // ¸ù¾Ý×Ó½Úµã¼ÆËãµÃµ½×ÔÉíµÄmin, preferred, flexible + protected void CalcAlongAxis(int axis, bool isVertical) + { + float combinedPadding = (axis == 0 ? padding.horizontal : padding.vertical); // paddingÊÇleft+right, top+bottom + bool controlSize = (axis == 0 ? m_ChildControlWidth : m_ChildControlHeight); + bool childForceExpandSize = (axis == 0 ? childForceExpandWidth : childForceExpandHeight); + + float totalMin = combinedPadding; // ËùÓÐ×Ó½ÚµãµÄminÖ®ºÍ + float totalPreferred = combinedPadding; // ËùÓÐ×Ó½ÚµãµÄpreferredÖ®ºÍ + float totalFlexible = 0; // ÊÇÒ»¸öÎÞµ¥Î»ÊýÖµ£¬µÈÓÚËùÓÐ×Ó½ÚµãµÄflexibleÖµÏà¼Ó + + bool alongOtherAxis = (isVertical ^ (axis == 1)); + for (int i = 0; i < rectChildren.Count; i++) + { + RectTransform child = rectChildren[i]; + float min, preferred, flexible; // ×Ó½ÚµãµÄÈý¸öÊôÐÔÖµ + GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible); + + if (alongOtherAxis) + { + totalMin = Mathf.Max(min + combinedPadding, totalMin); + totalPreferred = Mathf.Max(preferred + combinedPadding, totalPreferred); + totalFlexible = Mathf.Max(flexible, totalFlexible); + } + else + { + totalMin += min + spacing; + totalPreferred += preferred + spacing; + + // Increment flexible size with element's flexible size. + totalFlexible += flexible; + } + } + + // ¼õÈ¥×îºóÒ»¸ö×Ó½Úµã¶à¼ÓµÄspacing + if (!alongOtherAxis && rectChildren.Count > 0) + { + totalMin -= spacing; + totalPreferred -= spacing; + } + + totalPreferred = Mathf.Max(totalMin, totalPreferred); + // ±£´æµ½m_TotalMinSize, m_TotalPreferredSize, m_TotalFlexibleSize + SetLayoutInputForAxis(totalMin, totalPreferred, totalFlexible, axis); + } + + protected void SetChildrenAlongAxis(int axis, bool isVertical) + { + float size = rectTransform.rect.size[axis]; // RectTransform´óС + bool controlSize = (axis == 0 ? m_ChildControlWidth : m_ChildControlHeight); + bool childForceExpandSize = (axis == 0 ? childForceExpandWidth : childForceExpandHeight); + float alignmentOnAxis = GetAlignmentOnAxis(axis); + + bool alongOtherAxis = (isVertical ^ (axis == 1)); + if (alongOtherAxis) + { + float innerSize = size - (axis == 0 ? padding.horizontal : padding.vertical); // ÈÝÄÉ×Ó½ÚµãµÄ¿Õ¼ä + for (int i = 0; i < rectChildren.Count; i++) + { + RectTransform child = rectChildren[i]; + float min, preferred, flexible; + GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible); + + float requiredSpace = Mathf.Clamp(innerSize, min, flexible > 0 ? size : preferred); + float startOffset = GetStartOffset(axis, requiredSpace); + if (controlSize) + { + SetChildAlongAxis(child, axis, startOffset, requiredSpace); + } + else + { + float offsetInCell = (requiredSpace - child.sizeDelta[axis]) * alignmentOnAxis; + SetChildAlongAxis(child, axis, startOffset + offsetInCell); + } + } + } + else + { + float pos = (axis == 0 ? padding.left : padding.top); + if (GetTotalFlexibleSize(axis) == 0 && GetTotalPreferredSize(axis) < size) + pos = GetStartOffset(axis, GetTotalPreferredSize(axis) - (axis == 0 ? padding.horizontal : padding.vertical)); + + float minMaxLerp = 0; // Èû½øminÖ®ºóµÄÊ£Óà¿Õ¼ä/preferred-minµÄ¿Õ¼ä£¬ÊÇ×Ó½Úµã´ÓminÏòpreferredÀ©´óµÄÒÀ¾Ý + if (GetTotalMinSize(axis) != GetTotalPreferredSize(axis)) + minMaxLerp = Mathf.Clamp01((size - GetTotalMinSize(axis)) / (GetTotalPreferredSize(axis) - GetTotalMinSize(axis))); + + float itemFlexibleMultiplier = 0; // Èû½øpreferredÖ®ºó£¬½øÒ»²½ÈûÂúÊ£Óà¿Õ¼äµÄÒÀ¾Ý£¬¼´flexible + if (size > GetTotalPreferredSize(axis)) + { + if (GetTotalFlexibleSize(axis) > 0) + itemFlexibleMultiplier = (size - GetTotalPreferredSize(axis)) / GetTotalFlexibleSize(axis); + } + + for (int i = 0; i < rectChildren.Count; i++) + { + RectTransform child = rectChildren[i]; + float min, preferred, flexible; + GetChildSizes(child, axis, controlSize, childForceExpandSize, out min, out preferred, out flexible); + + float childSize = Mathf.Lerp(min, preferred, minMaxLerp); + childSize += flexible * itemFlexibleMultiplier; + if (controlSize) + { + // ÉèÖÃ×Ó½ÚµãµÄtransform + SetChildAlongAxis(child, axis, pos, childSize); + } + else + { + float offsetInCell = (childSize - child.sizeDelta[axis]) * alignmentOnAxis; + SetChildAlongAxis(child, axis, pos + offsetInCell); + } + pos += childSize + spacing; + } + } + } + + // ·µ»Ø½ÚµãµÄmin, prefered, flexible´óС + // axis 0ÊÇxÖᣬ1ÊÇyÖá + // controlSize ÊÇ·ñ¹´Ñ¡ChildControlSize + // childForceExpand ÊÇ·ñ¹´Ñ¡ChildForceExpand + private void GetChildSizes(RectTransform child, int axis, bool controlSize, bool childForceExpand, + out float min, out float preferred, out float flexible) + { + if (!controlSize) // Èç¹ûû¹´ChildControlSize£¬ÄÇô»áºöÂÔ + { + min = child.sizeDelta[axis];//sizeDeltaÕâÀïµÈ¼ÛÓÚsize£¬ÒòΪ¶¯Ì¬²¼¾ÖϵͳÀïÃæanchor¶¼ÊÇÒ»ÆðµÄ + preferred = min; + flexible = 0; + } + else + { + min = LayoutUtility.GetMinSize(child, axis); + preferred = LayoutUtility.GetPreferredSize(child, axis); + flexible = LayoutUtility.GetFlexibleSize(child, axis); + } + + if (childForceExpand) + flexible = Mathf.Max(flexible, 1); + } + +#if UNITY_EDITOR + protected override void Reset() + { + base.Reset(); + + // For new added components we want these to be set to false, + // so that the user's sizes won't be overwritten before they + // have a chance to turn these settings off. + // However, for existing components that were added before this + // feature was introduced, we want it to be on be default for + // backwardds compatibility. + // Hence their default value is on, but we set to off in reset. + m_ChildControlWidth = false; + m_ChildControlHeight = false; + } + +#endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta new file mode 100644 index 0000000..4eaf7af --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/HorizontalOrVerticalLayoutGroup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e33d83c2ebb040d459eaafaae66cc5e9 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs new file mode 100644 index 0000000..d0e1510 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs @@ -0,0 +1,50 @@ +using UnityEngine; +using System.Collections; + +namespace UnityEngine.UI +{ + public interface ILayoutElement + {
+#region LayoutGroupµÄÅÉÉúÀà²Å»áʵÏÖ£¬ÆäËûILayoutElement±ÈÈçImage£¬Text²»»áʵÏÖ + // After this method is invoked, layout horizontal input properties should return up-to-date values.
+ // Children will already have up-to-date layout horizontal inputs when this methods is called.
+ void CalculateLayoutInputHorizontal(); + // After this method is invoked, layout vertical input properties should return up-to-date values. + // Children will already have up-to-date layout vertical inputs when this methods is called. + void CalculateLayoutInputVertical();
+#endregion +
+ // Layout horizontal inputs
+ float minWidth { get; } + float preferredWidth { get; } + float flexibleWidth { get; } + // Layout vertical inputs + float minHeight { get; } + float preferredHeight { get; } + float flexibleHeight { get; } + + int layoutPriority { get; } + } + + public interface ILayoutController + { + void SetLayoutHorizontal(); + void SetLayoutVertical(); + } + + // An ILayoutGroup component should drive the RectTransforms of its children. + public interface ILayoutGroup : ILayoutController + { + } + + // An ILayoutSelfController component should drive its own RectTransform. + public interface ILayoutSelfController : ILayoutController + { + } + + // An ILayoutIgnorer component is ignored by the auto-layout system. + public interface ILayoutIgnorer + { + bool ignoreLayout { get; } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta new file mode 100644 index 0000000..f115b8f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/ILayoutElement.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9437925aea643a84f8ab4da3d03c183d +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs new file mode 100644 index 0000000..cdee245 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs @@ -0,0 +1,78 @@ +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Layout Element", 140)] + [RequireComponent(typeof(RectTransform))] + [ExecuteInEditMode] + public class LayoutElement : UIBehaviour, ILayoutElement, ILayoutIgnorer + { + [SerializeField] private bool m_IgnoreLayout = false; + [SerializeField] private float m_MinWidth = -1; + [SerializeField] private float m_MinHeight = -1; + [SerializeField] private float m_PreferredWidth = -1; + [SerializeField] private float m_PreferredHeight = -1; + [SerializeField] private float m_FlexibleWidth = -1; + [SerializeField] private float m_FlexibleHeight = -1; + [SerializeField] private int m_LayoutPriority = 1; + + + public virtual bool ignoreLayout { get { return m_IgnoreLayout; } set { if (SetPropertyUtility.SetStruct(ref m_IgnoreLayout, value)) SetDirty(); } } + + public virtual void CalculateLayoutInputHorizontal() {} + public virtual void CalculateLayoutInputVertical() {} + public virtual float minWidth { get { return m_MinWidth; } set { if (SetPropertyUtility.SetStruct(ref m_MinWidth, value)) SetDirty(); } } + public virtual float minHeight { get { return m_MinHeight; } set { if (SetPropertyUtility.SetStruct(ref m_MinHeight, value)) SetDirty(); } } + public virtual float preferredWidth { get { return m_PreferredWidth; } set { if (SetPropertyUtility.SetStruct(ref m_PreferredWidth, value)) SetDirty(); } } + public virtual float preferredHeight { get { return m_PreferredHeight; } set { if (SetPropertyUtility.SetStruct(ref m_PreferredHeight, value)) SetDirty(); } } + public virtual float flexibleWidth { get { return m_FlexibleWidth; } set { if (SetPropertyUtility.SetStruct(ref m_FlexibleWidth, value)) SetDirty(); } } + public virtual float flexibleHeight { get { return m_FlexibleHeight; } set { if (SetPropertyUtility.SetStruct(ref m_FlexibleHeight, value)) SetDirty(); } } + public virtual int layoutPriority { get { return m_LayoutPriority; } set { if (SetPropertyUtility.SetStruct(ref m_LayoutPriority, value)) SetDirty(); } } + + + protected LayoutElement() + {} + + protected override void OnEnable() + { + base.OnEnable(); + SetDirty(); + } + + protected override void OnTransformParentChanged() + { + SetDirty(); + } + + protected override void OnDisable() + { + SetDirty(); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + SetDirty(); + } + + protected override void OnBeforeTransformParentChanged() + { + SetDirty(); + } + + protected void SetDirty() + { + if (!IsActive()) + return; + LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + SetDirty(); + } + + #endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta new file mode 100644 index 0000000..40cc6f9 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutElement.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 1ae73daeb8941804886a5ec8aa41dc2a +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs new file mode 100644 index 0000000..6a17e00 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs @@ -0,0 +1,237 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [DisallowMultipleComponent] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + public abstract class LayoutGroup : UIBehaviour, ILayoutElement, ILayoutGroup + { + [SerializeField] protected RectOffset m_Padding = new RectOffset(); + public RectOffset padding { get { return m_Padding; } set { SetProperty(ref m_Padding, value); } } + + [FormerlySerializedAs("m_Alignment")] + [SerializeField] protected TextAnchor m_ChildAlignment = TextAnchor.UpperLeft; + public TextAnchor childAlignment { get { return m_ChildAlignment; } set { SetProperty(ref m_ChildAlignment, value); } } + + [System.NonSerialized] private RectTransform m_Rect; + protected RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + protected DrivenRectTransformTracker m_Tracker; + private Vector2 m_TotalMinSize = Vector2.zero; + private Vector2 m_TotalPreferredSize = Vector2.zero; + private Vector2 m_TotalFlexibleSize = Vector2.zero; + + [System.NonSerialized] private List<RectTransform> m_RectChildren = new List<RectTransform>(); + protected List<RectTransform> rectChildren { get { return m_RectChildren; } }
+
+
+ // ILayoutElement Interface
+ // ÊÕ¼¯×Ó½ÚµãÖвÎÓë²¼¾ÖµÄ½Úµã
+ public virtual void CalculateLayoutInputHorizontal() + { + m_RectChildren.Clear(); + var toIgnoreList = ListPool<Component>.Get(); + for (int i = 0; i < rectTransform.childCount; i++) + { + var rect = rectTransform.GetChild(i) as RectTransform; + if (rect == null || !rect.gameObject.activeInHierarchy) + continue; + + rect.GetComponents(typeof(ILayoutIgnorer), toIgnoreList); + + if (toIgnoreList.Count == 0) + { + m_RectChildren.Add(rect); + continue; + } + + for (int j = 0; j < toIgnoreList.Count; j++) + { + var ignorer = (ILayoutIgnorer)toIgnoreList[j]; + if (!ignorer.ignoreLayout) + { + m_RectChildren.Add(rect); + break; + } + } + } + ListPool<Component>.Release(toIgnoreList); + m_Tracker.Clear(); + } + + // Õâ¸ö·½·¨²»ÊÕ¼¯ÊÇÒòΪÔÚCalculateLayoutInputHorizontalÊÕ¼¯ÁË£¬ÔÚLayoutRebuilderµÄRebuild()·½·¨ÖÐÓÐ×¢ÊÍ + public abstract void CalculateLayoutInputVertical(); + public virtual float minWidth { get { return GetTotalMinSize(0); } } + public virtual float preferredWidth { get { return GetTotalPreferredSize(0); } } + public virtual float flexibleWidth { get { return GetTotalFlexibleSize(0); } } + public virtual float minHeight { get { return GetTotalMinSize(1); } } + public virtual float preferredHeight { get { return GetTotalPreferredSize(1); } } + public virtual float flexibleHeight { get { return GetTotalFlexibleSize(1); } } + public virtual int layoutPriority { get { return 0; } } + + // ILayoutController Interface + + public abstract void SetLayoutHorizontal(); + public abstract void SetLayoutVertical(); + + // Implementation + + protected LayoutGroup() + { + if (m_Padding == null) + m_Padding = new RectOffset(); + } + + protected override void OnEnable() + { + base.OnEnable(); + SetDirty(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + SetDirty(); + } + + protected float GetTotalMinSize(int axis) + { + return m_TotalMinSize[axis]; + } + + protected float GetTotalPreferredSize(int axis) + { + return m_TotalPreferredSize[axis]; + } + + protected float GetTotalFlexibleSize(int axis) + { + return m_TotalFlexibleSize[axis]; + } + + protected float GetStartOffset(int axis, float requiredSpaceWithoutPadding) + { + float requiredSpace = requiredSpaceWithoutPadding + (axis == 0 ? padding.horizontal : padding.vertical); // ËãÉÏpaddingºóµÄ´óС + float availableSpace = rectTransform.rect.size[axis]; // RectTransform´óС + float surplusSpace = availableSpace - requiredSpace; // Ê£Óà¿Õ¼ä + float alignmentOnAxis = GetAlignmentOnAxis(axis); // 0\0.5\1 + return (axis == 0 ? padding.left : padding.top) + surplusSpace * alignmentOnAxis; + } + + protected float GetAlignmentOnAxis(int axis) + { + if (axis == 0) + return ((int)childAlignment % 3) * 0.5f; // 0, 0.5, 1 + else + return ((int)childAlignment / 3) * 0.5f; // 0, 0.5, 1 + } + + protected void SetLayoutInputForAxis(float totalMin, float totalPreferred, float totalFlexible, int axis) + { + m_TotalMinSize[axis] = totalMin; + m_TotalPreferredSize[axis] = totalPreferred; + m_TotalFlexibleSize[axis] = totalFlexible; + } + + protected void SetChildAlongAxis(RectTransform rect, int axis, float pos) + { + if (rect == null) + return; + + m_Tracker.Add(this, rect, + DrivenTransformProperties.Anchors | + (axis == 0 ? DrivenTransformProperties.AnchoredPositionX : DrivenTransformProperties.AnchoredPositionY)); + + rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, rect.sizeDelta[axis]); + } + + protected void SetChildAlongAxis(RectTransform rect, int axis, float pos, float size) + { + if (rect == null) + return; + + m_Tracker.Add(this, rect, + DrivenTransformProperties.Anchors | + (axis == 0 ? + (DrivenTransformProperties.AnchoredPositionX | DrivenTransformProperties.SizeDeltaX) : + (DrivenTransformProperties.AnchoredPositionY | DrivenTransformProperties.SizeDeltaY) + )); + + rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, size); + } + + private bool isRootLayoutGroup + { + get + { + Transform parent = transform.parent; + if (parent == null) + return true; + return transform.parent.GetComponent(typeof(ILayoutGroup)) == null; + } + } + + protected override void OnRectTransformDimensionsChange() + { + base.OnRectTransformDimensionsChange(); + if (isRootLayoutGroup) + SetDirty(); + } + + protected virtual void OnTransformChildrenChanged() + { + SetDirty(); + } + + protected void SetProperty<T>(ref T currentValue, T newValue) + { + if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue))) + return; + currentValue = newValue; + SetDirty(); + } + + protected void SetDirty() + { + if (!IsActive()) + return; + + if (!CanvasUpdateRegistry.IsRebuildingLayout()) + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + else + StartCoroutine(DelayedSetDirty(rectTransform)); + } + + IEnumerator DelayedSetDirty(RectTransform rectTransform) + { + yield return null; + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + SetDirty(); + } + + #endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta new file mode 100644 index 0000000..2c5525c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 5094cec73437de8479168e16d201c2c6 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs new file mode 100644 index 0000000..5fba1cc --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs @@ -0,0 +1,233 @@ +using System.Collections.Generic; +using UnityEngine.Events; + +namespace UnityEngine.UI +{ + public class LayoutRebuilder : ICanvasElement + { + // m_ToRebuildÊÇÒ»¸öILayoutGroup + private RectTransform m_ToRebuild; + //There are a few of reasons we need to cache the Hash from the transform: + // - This is a ValueType (struct) and .Net calculates Hash from the Value Type fields. + // - The key of a Dictionary should have a constant Hash value. + // - It's possible for the Transform to get nulled from the Native side. + // We use this struct with the IndexedSet container, which uses a dictionary as part of it's implementation + // So this struct gets used as a key to a dictionary, so we need to guarantee a constant Hash value. + private int m_CachedHashFromTransform; + + // Ò»¸örebuilder½á¹¹µÄ³Ø×Ó + static ObjectPool<LayoutRebuilder> s_Rebuilders = new ObjectPool<LayoutRebuilder>(null, x => x.Clear()); + + private void Initialize(RectTransform controller) + { + m_ToRebuild = controller; + m_CachedHashFromTransform = controller.GetHashCode(); + } + + private void Clear() + { + m_ToRebuild = null; + m_CachedHashFromTransform = 0; + } + + static LayoutRebuilder() + { + RectTransform.reapplyDrivenProperties += ReapplyDrivenProperties; + } + + static void ReapplyDrivenProperties(RectTransform driven) + { + MarkLayoutForRebuild(driven); + } + + public Transform transform { get { return m_ToRebuild; }} + + public bool IsDestroyed() + { + return m_ToRebuild == null; + } + + static void StripDisabledBehavioursFromList(List<Component> components) + { + components.RemoveAll(e => e is Behaviour && !((Behaviour)e).isActiveAndEnabled); + } + + // Á¢¼´ÖØÐ²¼¾ÖÒ»´Î£¬¶ø²»Óõȵ½Ö¡Ä©Î²CanvasUpdateReigstry.PerformUpdateµÄʱºò + public static void ForceRebuildLayoutImmediate(RectTransform layoutRoot) + { + var rebuilder = s_Rebuilders.Get(); + rebuilder.Initialize(layoutRoot); + rebuilder.Rebuild(CanvasUpdate.Layout); + s_Rebuilders.Release(rebuilder); + } + + public void Rebuild(CanvasUpdate executing) + { + switch (executing) + { + case CanvasUpdate.Layout: + // It's unfortunate that we'll perform the same GetComponents querys for the tree 2 times, + // but each tree have to be fully iterated before going to the next action, + // so reusing the results would entail storing results in a Dictionary or similar, + // which is probably a bigger overhead than performing GetComponents multiple times. + PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputHorizontal()); + PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutHorizontal()); + PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputVertical()); + PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutVertical()); + break; + } + } + + // ´ÓÉϵ½Ï±éÀú£¬Ö´ÐÐaction + private void PerformLayoutControl(RectTransform rect, UnityAction<Component> action) + { + if (rect == null) + return; + + var components = ListPool<Component>.Get(); + rect.GetComponents(typeof(ILayoutController), components); + StripDisabledBehavioursFromList(components); + + // If there are no controllers on this rect we can skip this entire sub-tree + // We don't need to consider controllers on children deeper in the sub-tree either, + // since they will be their own roots. + if (components.Count > 0) + { + // + // Layout control needs to executed top down with parents being done before their children, + // because the children rely on the sizes of the parents. + + // ×öÁ½´Î±éÀú£¬ÏÈÖ´ÐÐILayoutSelfController±ÈÈçContentSizeFitter£¬ÔÙÖ´ÐÐILayoutGroup + + // First call layout controllers that may change their own RectTransform + for (int i = 0; i < components.Count; i++) + if (components[i] is ILayoutSelfController) + action(components[i]); + + // Then call the remaining, such as layout groups that change their children, taking their own RectTransform size into account. + for (int i = 0; i < components.Count; i++) + if (!(components[i] is ILayoutSelfController)) + action(components[i]); + + for (int i = 0; i < rect.childCount; i++) + PerformLayoutControl(rect.GetChild(i) as RectTransform, action); + } + + ListPool<Component>.Release(components); + } + + private void PerformLayoutCalculation(RectTransform rect, UnityAction<Component> action) + { + if (rect == null) + return; + + var components = ListPool<Component>.Get(); + rect.GetComponents(typeof(ILayoutElement), components); + StripDisabledBehavioursFromList(components); + + // If there are no controllers on this rect we can skip this entire sub-tree + // We don't need to consider controllers on children deeper in the sub-tree either, + // since they will be their own roots. + if (components.Count > 0 || rect.GetComponent(typeof(ILayoutGroup))) + { + + // ÏÈ´Ó×ӽڵ㿪ʼ£¬×îºóµ½¸¸½Úµã£¬ÕâÑù¸¸½Úµã¿ÉÒԵõ½×Ó½ÚµãµÄÐÅÏ¢ + // Layout calculations needs to executed bottom up with children being done before their parents, + // because the parent calculated sizes rely on the sizes of the children. + + for (int i = 0; i < rect.childCount; i++) + PerformLayoutCalculation(rect.GetChild(i) as RectTransform, action); + + for (int i = 0; i < components.Count; i++) + action(components[i]); + } + + ListPool<Component>.Release(components); + } + + // ÕÒµ½rect׿ÏȽڵãÖеÄlayoutGroup²¢¼ÓÈë¶ÓÁÐ + public static void MarkLayoutForRebuild(RectTransform rect) + { + if (rect == null) + return; + + var comps = ListPool<Component>.Get(); + RectTransform layoutRoot = rect; // ׿ÏȽڵãÖеÄlayoutGroup + while (true) + { + var parent = layoutRoot.parent as RectTransform; + if (!ValidLayoutGroup(parent, comps)) + break; + layoutRoot = parent; + } + + // We know the layout root is valid if it's not the same as the rect, + // since we checked that above. But if they're the same we still need to check. + if (layoutRoot == rect && !ValidController(layoutRoot, comps)) + { + ListPool<Component>.Release(comps); + return; + } + + MarkLayoutRootForRebuild(layoutRoot); + ListPool<Component>.Release(comps); + } + + private static bool ValidLayoutGroup(RectTransform parent, List<Component> comps) + { + if (parent == null) + return false; + + parent.GetComponents(typeof(ILayoutGroup), comps); + StripDisabledBehavioursFromList(comps); + var validCount = comps.Count > 0; + return validCount; + } + + private static bool ValidController(RectTransform layoutRoot, List<Component> comps) + { + if (layoutRoot == null) + return false; + layoutRoot.GetComponents(typeof(ILayoutController), comps); + StripDisabledBehavioursFromList(comps); + var valid = comps.Count > 0; + return valid; + } + + private static void MarkLayoutRootForRebuild(RectTransform controller) + { + if (controller == null) + return; + + var rebuilder = s_Rebuilders.Get(); + rebuilder.Initialize(controller); + // ×¢²áµ½CanvasUpdateRegistryÀï + if (!CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild(rebuilder)) + s_Rebuilders.Release(rebuilder); + } + + public void LayoutComplete() + { + // ·Å»Ø³Ø×ÓÀï + s_Rebuilders.Release(this); + } + + public void GraphicUpdateComplete() + {} + + public override int GetHashCode() + { + return m_CachedHashFromTransform; + } + + public override bool Equals(object obj) + { + return obj.GetHashCode() == GetHashCode(); + } + + public override string ToString() + { + return "(Layout Rebuilder for) " + m_ToRebuild; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta new file mode 100644 index 0000000..ad21a40 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutRebuilder.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 297af0346d9a6b24e88b4dbdfae053e0 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs new file mode 100644 index 0000000..c58abd5 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs @@ -0,0 +1,112 @@ +using UnityEngine; +using System.Collections.Generic; +using UnityEngine.Events; + +namespace UnityEngine.UI +{ + public static class LayoutUtility + { + public static float GetMinSize(RectTransform rect, int axis) + { + if (axis == 0) + return GetMinWidth(rect); + return GetMinHeight(rect); + } + + public static float GetPreferredSize(RectTransform rect, int axis) + { + if (axis == 0) + return GetPreferredWidth(rect); + return GetPreferredHeight(rect); + } + + public static float GetFlexibleSize(RectTransform rect, int axis) + { + if (axis == 0) + return GetFlexibleWidth(rect); + return GetFlexibleHeight(rect); + } + + public static float GetMinWidth(RectTransform rect) + { + return GetLayoutProperty(rect, e => e.minWidth, 0); + } + + public static float GetPreferredWidth(RectTransform rect) + { + return Mathf.Max(GetLayoutProperty(rect, e => e.minWidth, 0), GetLayoutProperty(rect, e => e.preferredWidth, 0)); + } + + public static float GetFlexibleWidth(RectTransform rect) + { + return GetLayoutProperty(rect, e => e.flexibleWidth, 0); + } + + public static float GetMinHeight(RectTransform rect) + { + return GetLayoutProperty(rect, e => e.minHeight, 0); + } + + public static float GetPreferredHeight(RectTransform rect) + { + return Mathf.Max(GetLayoutProperty(rect, e => e.minHeight, 0), GetLayoutProperty(rect, e => e.preferredHeight, 0)); + } + + public static float GetFlexibleHeight(RectTransform rect) + { + return GetLayoutProperty(rect, e => e.flexibleHeight, 0); + } + + public static float GetLayoutProperty(RectTransform rect, System.Func<ILayoutElement, float> property, float defaultValue) + { + ILayoutElement dummy; + return GetLayoutProperty(rect, property, defaultValue, out dummy); + } + + public static float GetLayoutProperty(RectTransform rect, System.Func<ILayoutElement, float> property, float defaultValue, out ILayoutElement source) + { + source = null; + if (rect == null) + return 0; + float min = defaultValue; + int maxPriority = System.Int32.MinValue; + var components = ListPool<Component>.Get(); + rect.GetComponents(typeof(ILayoutElement), components); + + for (int i = 0; i < components.Count; i++) + { + var layoutComp = components[i] as ILayoutElement; // + if (layoutComp is Behaviour && !((Behaviour)layoutComp).isActiveAndEnabled) + continue; + + int priority = layoutComp.layoutPriority; + // If this layout components has lower priority than a previously used, ignore it. + if (priority < maxPriority) + continue; + float prop = property(layoutComp); + // If this layout property is set to a negative value, it means it should be ignored. + if (prop < 0) + continue; + + // If this layout component has higher priority than all previous ones, + // overwrite with this one's value. + if (priority > maxPriority) + { + min = prop; + maxPriority = priority; + source = layoutComp; + } + // If the layout component has the same priority as a previously used, + // use the largest of the values with the same priority. + else if (prop > min) + { + min = prop; + source = layoutComp; + } + } + + ListPool<Component>.Release(components); + return min; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta new file mode 100644 index 0000000..e0d1878 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutUtility.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: d180430718b19fe4786c73f6e7c798fa +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs new file mode 100644 index 0000000..e24b842 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs @@ -0,0 +1,30 @@ +namespace UnityEngine.UI +{ + [AddComponentMenu("Layout/Vertical Layout Group", 151)] + public class VerticalLayoutGroup : HorizontalOrVerticalLayoutGroup + { + protected VerticalLayoutGroup() + {} + + public override void CalculateLayoutInputHorizontal() + { + base.CalculateLayoutInputHorizontal(); + CalcAlongAxis(0, true); + } + + public override void CalculateLayoutInputVertical() + { + CalcAlongAxis(1, true); + } + + public override void SetLayoutHorizontal() + { + SetChildrenAlongAxis(0, true); + } + + public override void SetLayoutVertical() + { + SetChildrenAlongAxis(1, true); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta new file mode 100644 index 0000000..9b945bf --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/VerticalLayoutGroup.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f050f1af13388a145b34f3d0b59c8955 +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask.meta new file mode 100644 index 0000000..ad6af48 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3bc3203fe03d7b049ae99a951f541714 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs new file mode 100644 index 0000000..ffe7aed --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs @@ -0,0 +1,11 @@ +using System; + +namespace UnityEngine.UI +{ + [Obsolete("Not supported anymore.", true)] + public interface IMask + { + bool Enabled(); + RectTransform rectTransform { get; } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta new file mode 100644 index 0000000..2eab58a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d54c702726ac4fa4daf18719b41de69f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs new file mode 100644 index 0000000..8f8a28c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs @@ -0,0 +1,9 @@ +using System; + +namespace UnityEngine.UI +{ + public interface IMaskable + { + void RecalculateMasking(); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta new file mode 100644 index 0000000..298aac8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/IMaskable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5775a30dcbc6e484c8795bb7e18ada44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs new file mode 100644 index 0000000..c67ec42 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs @@ -0,0 +1,203 @@ +using System; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.Rendering; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Mask", 13)] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + [DisallowMultipleComponent] + public class Mask : UIBehaviour, ICanvasRaycastFilter, IMaterialModifier + { + [NonSerialized] + private RectTransform m_RectTransform; + public RectTransform rectTransform + { + get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); } + } + + [SerializeField] + [FormerlySerializedAs("m_ShowGraphic")] + private bool m_ShowMaskGraphic = true; + public bool showMaskGraphic + { + get { return m_ShowMaskGraphic; } + set + { + if (m_ShowMaskGraphic == value) + return; + + m_ShowMaskGraphic = value; + if (graphic != null) + graphic.SetMaterialDirty(); + } + } + + [NonSerialized] private Graphic m_Graphic; + public Graphic graphic + { + get { return m_Graphic ?? (m_Graphic = GetComponent<Graphic>()); } + }
+
+ [NonSerialized] private Material m_MaskMaterial;
+
+ [NonSerialized] private Material m_UnmaskMaterial; + + protected Mask() + {} + + public virtual bool MaskEnabled() { return IsActive() && graphic != null; } + + [Obsolete("Not used anymore.")] + public virtual void OnSiblingGraphicEnabledDisabled() {} + + protected override void OnEnable() + { + base.OnEnable(); + if (graphic != null) + { + graphic.canvasRenderer.hasPopInstruction = true; + graphic.SetMaterialDirty(); + } + + MaskUtilities.NotifyStencilStateChanged(this); + } + + protected override void OnDisable() + { + // we call base OnDisable first here + // as we need to have the IsActive return the + // correct value when we notify the children + // that the mask state has changed. + base.OnDisable(); + if (graphic != null) + { + graphic.SetMaterialDirty(); + graphic.canvasRenderer.hasPopInstruction = false; + graphic.canvasRenderer.popMaterialCount = 0; + } + + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = null; + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = null; + + MaskUtilities.NotifyStencilStateChanged(this); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + if (!IsActive()) + return; + + if (graphic != null) + graphic.SetMaterialDirty(); + + MaskUtilities.NotifyStencilStateChanged(this); + } + +#endif + + public virtual bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) + { + if (!isActiveAndEnabled) + return true; + + return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, sp, eventCamera); + } + + /// Stencil calculation time! + public virtual Material GetModifiedMaterial(Material baseMaterial) + { + if (!MaskEnabled()) + return baseMaterial; + + var rootSortCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform); + var stencilDepth = MaskUtilities.GetStencilDepth(transform, rootSortCanvas); + if (stencilDepth >= 8) // ²»Ö§³Ö8²ã¼°ÒÔÉϵÄmask, 0-7Ö§³Ö£¬ÕâÊÇÒòΪstencilRefºÍstencilMaskÖ»ÓÐÒ»¸ö×Ö½Ú + { + Debug.LogError("Attempting to use a stencil mask with depth > 8", gameObject); + return baseMaterial; + } + + int desiredStencilBit = 1 << stencilDepth; + + // if we are at the first level... + // we want to destroy what is there + if (desiredStencilBit == 1) // ×îÉϲãµÄmask + {
+ // Ref = 1
+ // Op = Replace
+ // Func = Always
+ // ReadMask = 255
+ // WriteMask = 255
+ var maskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMaterial;
+
+ // Ref = 1
+ // Op = Zero
+ // Func = Always
+ // ReadMask = 255
+ // WriteMask = 255
+ var unmaskMaterial = StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0); + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = unmaskMaterial; + graphic.canvasRenderer.popMaterialCount = 1; + graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); + + return m_MaskMaterial; + } + + // Ref = desiredStencilBit | (desiredStencilBit - 1) + // Op = Replace + // Func = Equal + // ReadMask = desiredStencilBit - 1 + // WriteMask = desiredStencilBit | (desiredStencilBit - 1) + + //otherwise we need to be a bit smarter and set some read / write masks + var maskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); + StencilMaterial.Remove(m_MaskMaterial); + m_MaskMaterial = maskMaterial2; + + // Ref = desiredStencilBit - 1 + // Op = Replace + // Func = Equal + // ReadMask = desiredStencilBit - 1 + // WriteMask = desiredStencilBit | (desiredStencilBit - 1) + graphic.canvasRenderer.hasPopInstruction = true; + var unmaskMaterial2 = StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1)); + StencilMaterial.Remove(m_UnmaskMaterial); + m_UnmaskMaterial = unmaskMaterial2; + graphic.canvasRenderer.popMaterialCount = 1; + graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0); + + return m_MaskMaterial; + }
+
+
+ #region UGUI_DEBUG +
+ Vector3[] cornors = new Vector3[4];
+ + void OnDrawGizmos()
+ {
+ Rect rect = rectTransform.rect;
+ Gizmos.color = Color.yellow;
+ rectTransform.GetWorldCorners(cornors);
+ for (int i = 0; i < cornors.Length; ++i)
+ {
+ Gizmos.DrawLine(cornors[i], cornors[(i + 1) % cornors.Length]);
+ }
+ } + + #endregion + + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta new file mode 100644 index 0000000..50caa3d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/Mask.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfc675de41855c44aaedb7af695ba899 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs new file mode 100644 index 0000000..6abce5a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs @@ -0,0 +1,187 @@ +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + public class MaskUtilities + { + public static void Notify2DMaskStateChanged(Component mask) + { + var components = ListPool<Component>.Get(); + mask.GetComponentsInChildren(components); + for (var i = 0; i < components.Count; i++) + { + if (components[i] == null || components[i].gameObject == mask.gameObject) + continue; + + var toNotify = components[i] as IClippable; + if (toNotify != null) + toNotify.RecalculateClipping(); + } + ListPool<Component>.Release(components); + } + + public static void NotifyStencilStateChanged(Component mask) + { + var components = ListPool<Component>.Get(); + mask.GetComponentsInChildren(components); + for (var i = 0; i < components.Count; i++) + { + if (components[i] == null || components[i].gameObject == mask.gameObject) + continue; + + var toNotify = components[i] as IMaskable; + if (toNotify != null) + toNotify.RecalculateMasking(); + } + ListPool<Component>.Release(components); + } + + //´ÓÏÂÍùÉÏÕÒµ½µÚÒ»¸öOverrideSortingµÄcanvas»òÕßroot(¼´null) + public static Transform FindRootSortOverrideCanvas(Transform start) + { + var canvasList = ListPool<Canvas>.Get(); + start.GetComponentsInParent(false, canvasList); + Canvas canvas = null; + + for (int i = 0; i < canvasList.Count; ++i) + { + canvas = canvasList[i]; + + // We found the canvas we want to use break + if (canvas.overrideSorting) + break; + } + ListPool<Canvas>.Release(canvasList); + + return canvas != null ? canvas.transform : null; + } + + // ·µ»ØMaskÔÚcanvasÏ£¨canvasÏÂËùÓеÄmasksÏÂ)µÄÉî¶È + public static int GetStencilDepth(Transform transform, Transform stopAfter) + { + var depth = 0; + if (transform == stopAfter) + return depth; + + var t = transform.parent; + var components = ListPool<Mask>.Get(); + while (t != null) + { + t.GetComponents<Mask>(components); + for (var i = 0; i < components.Count; ++i) + { + if (components[i] != null && components[i].MaskEnabled() && components[i].graphic.IsActive()) + { + ++depth; + break; + } + } + + if (t == stopAfter) + break; + + t = t.parent; + } + ListPool<Mask>.Release(components); + return depth; + } + + // fatherÊÇchildµÄ׿ÏȽڵã»òÕßfather == child + public static bool IsDescendantOrSelf(Transform father, Transform child) + { + if (father == null || child == null) + return false; + + if (father == child) + return true; + + while (child.parent != null) + { + if (child.parent == father) + return true; + + child = child.parent; + } + + return false; + } + + public static RectMask2D GetRectMaskForClippable(IClippable clippable) + { + List<RectMask2D> rectMaskComponents = ListPool<RectMask2D>.Get(); + List<Canvas> canvasComponents = ListPool<Canvas>.Get(); + RectMask2D componentToReturn = null; + + clippable.rectTransform.GetComponentsInParent(false, rectMaskComponents); + + if (rectMaskComponents.Count > 0) + { + for (int rmi = 0; rmi < rectMaskComponents.Count; rmi++) + { + componentToReturn = rectMaskComponents[rmi]; + if (componentToReturn.gameObject == clippable.gameObject) + { + componentToReturn = null; + continue; + } + if (!componentToReturn.isActiveAndEnabled) + { + componentToReturn = null; + continue; + } + clippable.rectTransform.GetComponentsInParent(false, canvasComponents); + for (int i = canvasComponents.Count - 1; i >= 0; i--) + { + if (!IsDescendantOrSelf(canvasComponents[i].transform, componentToReturn.transform) && canvasComponents[i].overrideSorting) + { + componentToReturn = null; + break; + } + } + return componentToReturn; + } + } + + ListPool<RectMask2D>.Release(rectMaskComponents); + ListPool<Canvas>.Release(canvasComponents); + + return componentToReturn; + } + + public static void GetRectMasksForClip(RectMask2D clipper, List<RectMask2D> masks) + { + masks.Clear(); + + List<Canvas> canvasComponents = ListPool<Canvas>.Get(); + List<RectMask2D> rectMaskComponents = ListPool<RectMask2D>.Get(); + clipper.transform.GetComponentsInParent(false, rectMaskComponents); + + if (rectMaskComponents.Count > 0) + { + clipper.transform.GetComponentsInParent(false, canvasComponents); + for (int i = rectMaskComponents.Count - 1; i >= 0; i--) + { + if (!rectMaskComponents[i].IsActive()) + continue; + bool shouldAdd = true; + for (int j = canvasComponents.Count - 1; j >= 0; j--) + { + // Èç¹ûrectMask2DÊÇcanvasµÄ׿ÏȽڵãÇÒÕâ¸öcanvas¹´Ñ¡ÁËOverrideSorting,ÄÇôÕâ¸örectMask2D¾Í»áʧЧ + if (!IsDescendantOrSelf(canvasComponents[j].transform, rectMaskComponents[i].transform) + && canvasComponents[j].overrideSorting) + { + shouldAdd = false; + break; + } + } + if (shouldAdd) + masks.Add(rectMaskComponents[i]); + } + } + + ListPool<RectMask2D>.Release(rectMaskComponents); + ListPool<Canvas>.Release(canvasComponents); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta new file mode 100644 index 0000000..5e7829c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/MaskUtilities.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 469f0aa53de5d4c4fb69e83419090a01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs new file mode 100644 index 0000000..d973b34 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Rect Mask 2D", 13)] + [ExecuteInEditMode] + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class RectMask2D : UIBehaviour, IClipper, ICanvasRaycastFilter + { + [NonSerialized] + private readonly RectangularVertexClipper m_VertexClipper = new RectangularVertexClipper(); + + [NonSerialized] + private RectTransform m_RectTransform; + + // ¿É²Ã¼ôµÄGraphics + [NonSerialized] + private HashSet<IClippable> m_ClipTargets = new HashSet<IClippable>(); + + [NonSerialized] + private bool m_ShouldRecalculateClipRects; + + // ¸¸½ÚµãµÄËùÓÐRectMask2D£¬ÓÃÀ´Ëã½»¼¯ + [NonSerialized] + private List<RectMask2D> m_Clippers = new List<RectMask2D>(); + + [NonSerialized] + private Rect m_LastClipRectCanvasSpace; + [NonSerialized] + private bool m_LastValidClipRect; + [NonSerialized] + private bool m_ForceClip; + + public Rect canvasRect + { + get + { + Canvas canvas = null; + var list = ListPool<Canvas>.Get(); + gameObject.GetComponentsInParent(false, list); + if (list.Count > 0) + canvas = list[list.Count - 1]; + ListPool<Canvas>.Release(list); + + return m_VertexClipper.GetCanvasRect(rectTransform, canvas); + } + } + + public RectTransform rectTransform + { + get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); } + } + + protected RectMask2D() + {} + + protected override void OnEnable() + { + base.OnEnable(); + m_ShouldRecalculateClipRects = true; + ClipperRegistry.Register(this); + MaskUtilities.Notify2DMaskStateChanged(this); + } + + protected override void OnDisable() + { + // we call base OnDisable first here + // as we need to have the IsActive return the + // correct value when we notify the children + // that the mask state has changed. + base.OnDisable(); + m_ClipTargets.Clear(); + m_Clippers.Clear(); + ClipperRegistry.Unregister(this); + MaskUtilities.Notify2DMaskStateChanged(this); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + m_ShouldRecalculateClipRects = true; + + if (!IsActive()) + return; + + MaskUtilities.Notify2DMaskStateChanged(this); + } + +#endif + + public virtual bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) + { + if (!isActiveAndEnabled) + return true; + + return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, sp, eventCamera); + } + + public virtual void PerformClipping() + { + //TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771) + + // if the parents are changed + // or something similar we + // do a recalculate here + if (m_ShouldRecalculateClipRects) + { + MaskUtilities.GetRectMasksForClip(this, m_Clippers); + m_ShouldRecalculateClipRects = false; + } + + // ²Ã¼ô + + // get the compound rects from + // the clippers that are valid + bool validRect = true; + Rect clipRect = Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect); + bool clipRectChanged = clipRect != m_LastClipRectCanvasSpace; + if (clipRectChanged || m_ForceClip) + { + foreach (IClippable clipTarget in m_ClipTargets) + clipTarget.SetClipRect(clipRect, validRect); + + m_LastClipRectCanvasSpace = clipRect; + m_LastValidClipRect = validRect; + } + + // ÌÞ³ý + + foreach (IClippable clipTarget in m_ClipTargets) + { + var maskable = clipTarget as MaskableGraphic; + if (maskable != null && !maskable.canvasRenderer.hasMoved && !clipRectChanged) + continue; + + clipTarget.Cull(m_LastClipRectCanvasSpace, m_LastValidClipRect); + } + } + + public void AddClippable(IClippable clippable) + { + if (clippable == null) + return; + m_ShouldRecalculateClipRects = true; + if (!m_ClipTargets.Contains(clippable)) + m_ClipTargets.Add(clippable); + + m_ForceClip = true; + } + + public void RemoveClippable(IClippable clippable) + { + if (clippable == null) + return; + + m_ShouldRecalculateClipRects = true; + clippable.SetClipRect(new Rect(), false); + m_ClipTargets.Remove(clippable); + + m_ForceClip = true; + } + + protected override void OnTransformParentChanged() + { + base.OnTransformParentChanged(); + m_ShouldRecalculateClipRects = true; + } + + protected override void OnCanvasHierarchyChanged() + { + base.OnCanvasHierarchyChanged(); + m_ShouldRecalculateClipRects = true; + }
+
+
+ #region UGUI_DEBUG +
+ Vector3[] cornors = new Vector3[4];
+ + void OnDrawGizmos()
+ {
+ Rect rect = rectTransform.rect;
+ Gizmos.color = Color.red;
+ rectTransform.GetWorldCorners(cornors);
+ for (int i = 0; i < cornors.Length; ++i)
+ {
+ Gizmos.DrawLine(cornors[i], cornors[(i + 1) % cornors.Length]);
+ }
+ } + + #endregion +
+ } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta new file mode 100644 index 0000000..3f31967 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/RectMask2D.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c06d6b758f7cbc148afa25153c439510 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs new file mode 100644 index 0000000..c12f209 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Rendering; + +namespace UnityEngine.UI +{ + /// <summary> + /// Dynamic material class makes it possible to create custom materials on the fly on a per-Graphic basis, + /// and still have them get cleaned up correctly. + /// </summary> + public static class StencilMaterial + { + private class MatEntry + { + public Material baseMat; + public Material customMat; + public int count; + + public int stencilId; + public StencilOp operation = StencilOp.Keep; + public CompareFunction compareFunction = CompareFunction.Always; + public int readMask; + public int writeMask; + public bool useAlphaClip; + public ColorWriteMask colorMask; + } + + private static List<MatEntry> m_List = new List<MatEntry>(); + + [Obsolete("Use Material.Add instead.", true)] + public static Material Add(Material baseMat, int stencilID) { return null; } + + /// <summary> + /// Add a new material using the specified base and stencil ID. + /// </summary> + public static Material Add(Material baseMat, int stencilID, StencilOp operation, CompareFunction compareFunction, ColorWriteMask colorWriteMask) + { + return Add(baseMat, stencilID, operation, compareFunction, colorWriteMask, 255, 255); + } + + /// <summary> + /// Add a new material using the specified base and stencil ID. + /// </summary> + public static Material Add(Material baseMat, int stencilID, StencilOp operation, CompareFunction compareFunction, ColorWriteMask colorWriteMask, int readMask, int writeMask) + { + if ((stencilID <= 0 && colorWriteMask == ColorWriteMask.All) || baseMat == null) + return baseMat; + + if (!baseMat.HasProperty("_Stencil")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _Stencil property", baseMat); + return baseMat; + } + if (!baseMat.HasProperty("_StencilOp")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilOp property", baseMat); + return baseMat; + } + if (!baseMat.HasProperty("_StencilComp")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilComp property", baseMat); + return baseMat; + } + if (!baseMat.HasProperty("_StencilReadMask")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilReadMask property", baseMat); + return baseMat; + } + if (!baseMat.HasProperty("_StencilWriteMask")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _StencilWriteMask property", baseMat); + return baseMat; + } + if (!baseMat.HasProperty("_ColorMask")) + { + Debug.LogWarning("Material " + baseMat.name + " doesn't have _ColorMask property", baseMat); + return baseMat; + } + + for (int i = 0; i < m_List.Count; ++i) + { + MatEntry ent = m_List[i]; + + if (ent.baseMat == baseMat + && ent.stencilId == stencilID + && ent.operation == operation + && ent.compareFunction == compareFunction + && ent.readMask == readMask + && ent.writeMask == writeMask + && ent.colorMask == colorWriteMask) + { + ++ent.count; + return ent.customMat; + } + } + + var newEnt = new MatEntry(); + newEnt.count = 1; + newEnt.baseMat = baseMat; + newEnt.customMat = new Material(baseMat); + newEnt.customMat.hideFlags = HideFlags.HideAndDontSave; + newEnt.stencilId = stencilID; + newEnt.operation = operation; + newEnt.compareFunction = compareFunction; + newEnt.readMask = readMask; + newEnt.writeMask = writeMask; + newEnt.colorMask = colorWriteMask; + newEnt.useAlphaClip = operation != StencilOp.Keep && writeMask > 0; + + newEnt.customMat.name = string.Format("Stencil Id:{0}, Op:{1}, Comp:{2}, WriteMask:{3}, ReadMask:{4}, ColorMask:{5} AlphaClip:{6} ({7})", stencilID, operation, compareFunction, writeMask, readMask, colorWriteMask, newEnt.useAlphaClip, baseMat.name); + + newEnt.customMat.SetInt("_Stencil", stencilID); + newEnt.customMat.SetInt("_StencilOp", (int)operation); + newEnt.customMat.SetInt("_StencilComp", (int)compareFunction); + newEnt.customMat.SetInt("_StencilReadMask", readMask); + newEnt.customMat.SetInt("_StencilWriteMask", writeMask); + newEnt.customMat.SetInt("_ColorMask", (int)colorWriteMask); + + // left for backwards compatability + if (newEnt.customMat.HasProperty("_UseAlphaClip")) + newEnt.customMat.SetInt("_UseAlphaClip", newEnt.useAlphaClip ? 1 : 0); + + if (newEnt.useAlphaClip) + newEnt.customMat.EnableKeyword("UNITY_UI_ALPHACLIP"); + else + newEnt.customMat.DisableKeyword("UNITY_UI_ALPHACLIP"); + + m_List.Add(newEnt); + return newEnt.customMat; + } + + /// <summary> + /// Remove an existing material, automatically cleaning it up if it's no longer in use. + /// </summary> + public static void Remove(Material customMat) + { + if (customMat == null) + return; + + for (int i = 0; i < m_List.Count; ++i) + { + MatEntry ent = m_List[i]; + + if (ent.customMat != customMat) + continue; + + if (--ent.count == 0) + { + Misc.DestroyImmediate(ent.customMat); + ent.baseMat = null; + m_List.RemoveAt(i); + } + return; + } + } + + public static void ClearAll() + { + for (int i = 0; i < m_List.Count; ++i) + { + MatEntry ent = m_List[i]; + + Misc.DestroyImmediate(ent.customMat); + ent.baseMat = null; + } + m_List.Clear(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs.meta new file mode 100644 index 0000000..3fd6a69 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Mask/StencilMaterial.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2d445d28188ffd745990df17f1ce8914 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers.meta new file mode 100644 index 0000000..73eacd4 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 50b4029219e854d4c9407fad9b48266b +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs new file mode 100644 index 0000000..56e4777 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs @@ -0,0 +1,7 @@ +namespace UnityEngine.UI +{ + public interface IMaterialModifier + { + Material GetModifiedMaterial(Material baseMaterial); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs.meta new file mode 100644 index 0000000..a234594 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/MaterialModifiers/IMaterialModifier.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: fff5a5576fa3b2944a873226445ef7ef +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs new file mode 100644 index 0000000..66e2892 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs @@ -0,0 +1,44 @@ +namespace UnityEngine.UI +{ + /// <summary> + /// Helper class containing generic functions used throughout the UI library. + /// </summary> + + internal static class Misc + { + /// <summary> + /// Destroy the specified object, immediately if in edit mode. + /// </summary> + + static public void Destroy(UnityEngine.Object obj) + { + if (obj != null) + { + if (Application.isPlaying) + { + if (obj is GameObject) + { + GameObject go = obj as GameObject; + go.transform.parent = null; + } + + Object.Destroy(obj); + } + else Object.DestroyImmediate(obj); + } + } + + /// <summary> + /// Destroy the specified object immediately, unless not in the editor, in which case the regular Destroy is used instead. + /// </summary> + + static public void DestroyImmediate(Object obj) + { + if (obj != null) + { + if (Application.isEditor) Object.DestroyImmediate(obj); + else Object.Destroy(obj); + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs.meta new file mode 100644 index 0000000..51bdc37 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Misc.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 78074a60b29244441988db79bcd84a23 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections.meta new file mode 100644 index 0000000..af9c70d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0402250d11c7a2042bdcab33f69be1a6 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs new file mode 100644 index 0000000..0f37983 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine.UI.Collections +{ + internal class IndexedSet<T> : IList<T> + { + //This is a container that gives: + // - Unique items + // - Fast random removal + // - Fast unique inclusion to the end + // - Sequential access + //Downsides: + // - Uses more memory + // - Ordering is not persistent + // - Not Serialization Friendly. + + //We use a Dictionary to speed up list lookup, this makes it cheaper to guarantee no duplicates (set) + //When removing we move the last item to the removed item position, this way we only need to update the index cache of a single item. (fast removal) + //Order of the elements is not guaranteed. A removal will change the order of the items. + + readonly List<T> m_List = new List<T>(); + Dictionary<T, int> m_Dictionary = new Dictionary<T, int>(); + + public void Add(T item) + { + m_List.Add(item); + m_Dictionary.Add(item, m_List.Count - 1); + } + + public bool AddUnique(T item) + { + if (m_Dictionary.ContainsKey(item)) + return false; + + m_List.Add(item); + m_Dictionary.Add(item, m_List.Count - 1); + + return true; + } + + public bool Remove(T item) + { + int index = -1; + if (!m_Dictionary.TryGetValue(item, out index)) + return false; + + RemoveAt(index); + return true; + } + + public IEnumerator<T> GetEnumerator() + { + throw new System.NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public void Clear() + { + m_List.Clear(); + m_Dictionary.Clear(); + } + + public bool Contains(T item) + { + return m_Dictionary.ContainsKey(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + m_List.CopyTo(array, arrayIndex); + } + + public int Count { get { return m_List.Count; } } + public bool IsReadOnly { get { return false; } } + public int IndexOf(T item) + { + int index = -1; + m_Dictionary.TryGetValue(item, out index); + return index; + } + + public void Insert(int index, T item) + { + //We could support this, but the semantics would be weird. Order is not guaranteed.. + throw new NotSupportedException("Random Insertion is semantically invalid, since this structure does not guarantee ordering."); + } + + public void RemoveAt(int index) + { + T item = m_List[index]; + m_Dictionary.Remove(item); + if (index == m_List.Count - 1) + m_List.RemoveAt(index); + else + { + int replaceItemIndex = m_List.Count - 1; + T replaceItem = m_List[replaceItemIndex]; + m_List[index] = replaceItem; + m_Dictionary[replaceItem] = index; + m_List.RemoveAt(replaceItemIndex); + } + } + + public T this[int index] + { + get { return m_List[index]; } + set + { + T item = m_List[index]; + m_Dictionary.Remove(item); + m_List[index] = value; + m_Dictionary.Add(item, index); // ÕâÀïÓÐÎÊÌ⣬Ӧ¸ÃÊÇvalue + } + } + + public void RemoveAll(Predicate<T> match) + { + //I guess this could be optmized by instead of removing the items from the list immediatly, + //We move them to the end, and then remove all in one go. + //But I don't think this is going to be the bottleneck, so leaving as is for now. + int i = 0; + while (i < m_List.Count) + { + T item = m_List[i]; + if (match(item)) + Remove(item); + else + i++; + } + } + + //Sorts the internal list, this makes the exposed index accessor sorted as well. + //But note that any insertion or deletion, can unorder the collection again. + public void Sort(Comparison<T> sortLayoutFunction) + { + //There might be better ways to sort and keep the dictionary index up to date. + m_List.Sort(sortLayoutFunction); + //Rebuild the dictionary index. + for (int i = 0; i < m_List.Count; ++i) + { + T item = m_List[i]; + m_Dictionary[item] = i; + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs.meta new file mode 100644 index 0000000..942f3d7 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/SpecializedCollections/IndexedSet.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: cfa32e72467bc124294369b8b0b2045e +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls.meta new file mode 100644 index 0000000..4dfd750 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5a1494dd81f8d794282718b40b1ea46e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs new file mode 100644 index 0000000..e42871b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs @@ -0,0 +1,36 @@ +using System; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [Serializable] + public class AnimationTriggers + { + private const string kDefaultNormalAnimName = "Normal"; + private const string kDefaultSelectedAnimName = "Highlighted"; + private const string kDefaultPressedAnimName = "Pressed"; + private const string kDefaultDisabledAnimName = "Disabled"; + + [FormerlySerializedAs("normalTrigger")] + [SerializeField] + private string m_NormalTrigger = kDefaultNormalAnimName; + + [FormerlySerializedAs("highlightedTrigger")] + [FormerlySerializedAs("m_SelectedTrigger")] + [SerializeField] + private string m_HighlightedTrigger = kDefaultSelectedAnimName; + + [FormerlySerializedAs("pressedTrigger")] + [SerializeField] + private string m_PressedTrigger = kDefaultPressedAnimName; + + [FormerlySerializedAs("disabledTrigger")] + [SerializeField] + private string m_DisabledTrigger = kDefaultDisabledAnimName; + + public string normalTrigger { get { return m_NormalTrigger; } set { m_NormalTrigger = value; } } + public string highlightedTrigger { get { return m_HighlightedTrigger; } set { m_HighlightedTrigger = value; } } + public string pressedTrigger { get { return m_PressedTrigger; } set { m_PressedTrigger = value; } } + public string disabledTrigger { get { return m_DisabledTrigger; } set { m_DisabledTrigger = value; } } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs.meta new file mode 100644 index 0000000..52f2ca0 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/AnimationTriggers.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd02e9c578e561646b10984381250bf5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs new file mode 100644 index 0000000..d0c9ae3 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + // Button that's meant to work with mouse or touch-based devices. + [AddComponentMenu("UI/Button", 30)] + public class Button + : Selectable + , IPointerClickHandler // Êó±êµã»÷\´¥Ãþ + , ISubmitHandler // Input>Submit´¥·¢£¬±ÈÈçÊÖ±ú¡¢¼üÅÌij¸ö°´¼ü°´Ï + { + [Serializable] + public class ButtonClickedEvent : UnityEvent {} + + // Event delegates triggered on click. + [FormerlySerializedAs("onClick")] + [SerializeField] + private ButtonClickedEvent m_OnClick = new ButtonClickedEvent(); + + protected Button() + {} + + public ButtonClickedEvent onClick + { + get { return m_OnClick; } + set { m_OnClick = value; } + } + + // µ÷»Øµ÷ + private void Press() + { + if (!IsActive() || !IsInteractable()) + return; + + UISystemProfilerApi.AddMarker("Button.onClick", this); + m_OnClick.Invoke(); + } + + // Trigger all registered callbacks. + public virtual void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + Press(); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + LogHelper.Log("OnSubmit() " + gameObject.name); + + Press(); + + // if we get set disabled during the press + // don't run the coroutine. + if (!IsActive() || !IsInteractable()) + return; + + DoStateTransition(SelectionState.Pressed, false); + StartCoroutine(OnFinishSubmit()); + } + + private IEnumerator OnFinishSubmit() + { + var fadeTime = colors.fadeDuration; + var elapsedTime = 0f; + + while (elapsedTime < fadeTime) + { + elapsedTime += Time.unscaledDeltaTime; + yield return null; + } + + DoStateTransition(currentSelectionState, false); + } + + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs.meta new file mode 100644 index 0000000..cbdb3a1 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Button.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a754c749030e1d848bed7a3cb2e5520f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs new file mode 100644 index 0000000..c78d617 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs @@ -0,0 +1,91 @@ +using System; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [Serializable] + public struct ColorBlock : IEquatable<ColorBlock> + { + [FormerlySerializedAs("normalColor")] + [SerializeField] + private Color m_NormalColor; + + [FormerlySerializedAs("highlightedColor")] + [FormerlySerializedAs("m_SelectedColor")] + [SerializeField] + private Color m_HighlightedColor; + + [FormerlySerializedAs("pressedColor")] + [SerializeField] + private Color m_PressedColor; + + [FormerlySerializedAs("disabledColor")] + [SerializeField] + private Color m_DisabledColor; + + [Range(1, 5)] + [SerializeField] + private float m_ColorMultiplier; + + [FormerlySerializedAs("fadeDuration")] + [SerializeField] + private float m_FadeDuration; + + public Color normalColor { get { return m_NormalColor; } set { m_NormalColor = value; } } + public Color highlightedColor { get { return m_HighlightedColor; } set { m_HighlightedColor = value; } } + public Color pressedColor { get { return m_PressedColor; } set { m_PressedColor = value; } } + public Color disabledColor { get { return m_DisabledColor; } set { m_DisabledColor = value; } } + public float colorMultiplier { get { return m_ColorMultiplier; } set { m_ColorMultiplier = value; } } + public float fadeDuration { get { return m_FadeDuration; } set { m_FadeDuration = value; } } + + public static ColorBlock defaultColorBlock + { + get + { + var c = new ColorBlock + { + m_NormalColor = new Color32(255, 255, 255, 255), + m_HighlightedColor = new Color32(245, 245, 245, 255), + m_PressedColor = new Color32(200, 200, 200, 255), + m_DisabledColor = new Color32(200, 200, 200, 128), + colorMultiplier = 1.0f, + fadeDuration = 0.1f + }; + return c; + } + } + + public override bool Equals(object obj) + { + if (!(obj is ColorBlock)) + return false; + + return Equals((ColorBlock)obj); + } + + public bool Equals(ColorBlock other) + { + return normalColor == other.normalColor && + highlightedColor == other.highlightedColor && + pressedColor == other.pressedColor && + disabledColor == other.disabledColor && + colorMultiplier == other.colorMultiplier && + fadeDuration == other.fadeDuration; + } + + public static bool operator==(ColorBlock point1, ColorBlock point2) + { + return point1.Equals(point2); + } + + public static bool operator!=(ColorBlock point1, ColorBlock point2) + { + return !point1.Equals(point2); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs.meta new file mode 100644 index 0000000..8680539 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ColorBlock.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7d25b8a109dd134fa40749f78bbd907 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs new file mode 100644 index 0000000..a22ff9a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs @@ -0,0 +1,581 @@ +using UnityEngine; +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + public static class DefaultControls + { + public struct Resources + { + public Sprite standard; + public Sprite background; + public Sprite inputField; + public Sprite knob; + public Sprite checkmark; + public Sprite dropdown; + public Sprite mask; + } + + private const float kWidth = 160f; + private const float kThickHeight = 30f; + private const float kThinHeight = 20f; + private static Vector2 s_ThickElementSize = new Vector2(kWidth, kThickHeight); + private static Vector2 s_ThinElementSize = new Vector2(kWidth, kThinHeight); + private static Vector2 s_ImageElementSize = new Vector2(100f, 100f); + private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f); + private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f); + private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f); + + // Helper methods at top + + private static GameObject CreateUIElementRoot(string name, Vector2 size) + { + GameObject child = new GameObject(name); + RectTransform rectTransform = child.AddComponent<RectTransform>(); + rectTransform.sizeDelta = size; + return child; + } + + static GameObject CreateUIObject(string name, GameObject parent) + { + GameObject go = new GameObject(name); + go.AddComponent<RectTransform>(); + SetParentAndAlign(go, parent); + return go; + } + + private static void SetDefaultTextValues(Text lbl) + { + // Set text values we want across UI elements in default controls. + // Don't set values which are the same as the default values for the Text component, + // since there's no point in that, and it's good to keep them as consistent as possible. + lbl.color = s_TextColor; + + // Reset() is not called when playing. We still want the default font to be assigned + lbl.AssignDefaultFont(); + } + + private static void SetDefaultColorTransitionValues(Selectable slider) + { + ColorBlock colors = slider.colors; + colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f); + colors.pressedColor = new Color(0.698f, 0.698f, 0.698f); + colors.disabledColor = new Color(0.521f, 0.521f, 0.521f); + } + + private static void SetParentAndAlign(GameObject child, GameObject parent) + { + if (parent == null) + return; + + child.transform.SetParent(parent.transform, false); + SetLayerRecursively(child, parent.layer); + } + + private static void SetLayerRecursively(GameObject go, int layer) + { + go.layer = layer; + Transform t = go.transform; + for (int i = 0; i < t.childCount; i++) + SetLayerRecursively(t.GetChild(i).gameObject, layer); + } + + // Actual controls + + public static GameObject CreatePanel(Resources resources) + { + GameObject panelRoot = CreateUIElementRoot("Panel", s_ThickElementSize); + + // Set RectTransform to stretch + RectTransform rectTransform = panelRoot.GetComponent<RectTransform>(); + rectTransform.anchorMin = Vector2.zero; + rectTransform.anchorMax = Vector2.one; + rectTransform.anchoredPosition = Vector2.zero; + rectTransform.sizeDelta = Vector2.zero; + + Image image = panelRoot.AddComponent<Image>(); + image.sprite = resources.background; + image.type = Image.Type.Sliced; + image.color = s_PanelColor; + + return panelRoot; + } + + public static GameObject CreateButton(Resources resources) + { + GameObject buttonRoot = CreateUIElementRoot("Button", s_ThickElementSize); + + GameObject childText = new GameObject("Text"); + childText.AddComponent<RectTransform>(); + SetParentAndAlign(childText, buttonRoot); + + Image image = buttonRoot.AddComponent<Image>(); + image.sprite = resources.standard; + image.type = Image.Type.Sliced; + image.color = s_DefaultSelectableColor; + + Button bt = buttonRoot.AddComponent<Button>(); + SetDefaultColorTransitionValues(bt); + + Text text = childText.AddComponent<Text>(); + text.text = "Button"; + text.alignment = TextAnchor.MiddleCenter; + SetDefaultTextValues(text); + + RectTransform textRectTransform = childText.GetComponent<RectTransform>(); + textRectTransform.anchorMin = Vector2.zero; + textRectTransform.anchorMax = Vector2.one; + textRectTransform.sizeDelta = Vector2.zero; + + return buttonRoot; + } + + public static GameObject CreateText(Resources resources) + { + GameObject go = CreateUIElementRoot("Text", s_ThickElementSize); + + Text lbl = go.AddComponent<Text>(); + lbl.text = "New Text"; + SetDefaultTextValues(lbl); + + return go; + } + + public static GameObject CreateImage(Resources resources) + { + GameObject go = CreateUIElementRoot("Image", s_ImageElementSize); + go.AddComponent<Image>(); + return go; + } + + public static GameObject CreateRawImage(Resources resources) + { + GameObject go = CreateUIElementRoot("RawImage", s_ImageElementSize); + go.AddComponent<RawImage>(); + return go; + } + + public static GameObject CreateSlider(Resources resources) + { + // Create GOs Hierarchy + GameObject root = CreateUIElementRoot("Slider", s_ThinElementSize); + + GameObject background = CreateUIObject("Background", root); + GameObject fillArea = CreateUIObject("Fill Area", root); + GameObject fill = CreateUIObject("Fill", fillArea); + GameObject handleArea = CreateUIObject("Handle Slide Area", root); + GameObject handle = CreateUIObject("Handle", handleArea); + + // Background + Image backgroundImage = background.AddComponent<Image>(); + backgroundImage.sprite = resources.background; + backgroundImage.type = Image.Type.Sliced; + backgroundImage.color = s_DefaultSelectableColor; + RectTransform backgroundRect = background.GetComponent<RectTransform>(); + backgroundRect.anchorMin = new Vector2(0, 0.25f); + backgroundRect.anchorMax = new Vector2(1, 0.75f); + backgroundRect.sizeDelta = new Vector2(0, 0); + + // Fill Area + RectTransform fillAreaRect = fillArea.GetComponent<RectTransform>(); + fillAreaRect.anchorMin = new Vector2(0, 0.25f); + fillAreaRect.anchorMax = new Vector2(1, 0.75f); + fillAreaRect.anchoredPosition = new Vector2(-5, 0); + fillAreaRect.sizeDelta = new Vector2(-20, 0); + + // Fill + Image fillImage = fill.AddComponent<Image>(); + fillImage.sprite = resources.standard; + fillImage.type = Image.Type.Sliced; + fillImage.color = s_DefaultSelectableColor; + + RectTransform fillRect = fill.GetComponent<RectTransform>(); + fillRect.sizeDelta = new Vector2(10, 0); + + // Handle Area + RectTransform handleAreaRect = handleArea.GetComponent<RectTransform>(); + handleAreaRect.sizeDelta = new Vector2(-20, 0); + handleAreaRect.anchorMin = new Vector2(0, 0); + handleAreaRect.anchorMax = new Vector2(1, 1); + + // Handle + Image handleImage = handle.AddComponent<Image>(); + handleImage.sprite = resources.knob; + handleImage.color = s_DefaultSelectableColor; + + RectTransform handleRect = handle.GetComponent<RectTransform>(); + handleRect.sizeDelta = new Vector2(20, 0); + + // Setup slider component + Slider slider = root.AddComponent<Slider>(); + slider.fillRect = fill.GetComponent<RectTransform>(); + slider.handleRect = handle.GetComponent<RectTransform>(); + slider.targetGraphic = handleImage; + slider.direction = Slider.Direction.LeftToRight; + SetDefaultColorTransitionValues(slider); + + return root; + } + + public static GameObject CreateScrollbar(Resources resources) + { + // Create GOs Hierarchy + GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", s_ThinElementSize); + + GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot); + GameObject handle = CreateUIObject("Handle", sliderArea); + + Image bgImage = scrollbarRoot.AddComponent<Image>(); + bgImage.sprite = resources.background; + bgImage.type = Image.Type.Sliced; + bgImage.color = s_DefaultSelectableColor; + + Image handleImage = handle.AddComponent<Image>(); + handleImage.sprite = resources.standard; + handleImage.type = Image.Type.Sliced; + handleImage.color = s_DefaultSelectableColor; + + RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>(); + sliderAreaRect.sizeDelta = new Vector2(-20, -20); + sliderAreaRect.anchorMin = Vector2.zero; + sliderAreaRect.anchorMax = Vector2.one; + + RectTransform handleRect = handle.GetComponent<RectTransform>(); + handleRect.sizeDelta = new Vector2(20, 20); + + Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>(); + scrollbar.handleRect = handleRect; + scrollbar.targetGraphic = handleImage; + SetDefaultColorTransitionValues(scrollbar); + + return scrollbarRoot; + } + + public static GameObject CreateToggle(Resources resources) + { + // Set up hierarchy + GameObject toggleRoot = CreateUIElementRoot("Toggle", s_ThinElementSize); + + GameObject background = CreateUIObject("Background", toggleRoot); + GameObject checkmark = CreateUIObject("Checkmark", background); + GameObject childLabel = CreateUIObject("Label", toggleRoot); + + // Set up components + Toggle toggle = toggleRoot.AddComponent<Toggle>(); + toggle.isOn = true; + + Image bgImage = background.AddComponent<Image>(); + bgImage.sprite = resources.standard; + bgImage.type = Image.Type.Sliced; + bgImage.color = s_DefaultSelectableColor; + + Image checkmarkImage = checkmark.AddComponent<Image>(); + checkmarkImage.sprite = resources.checkmark; + + Text label = childLabel.AddComponent<Text>(); + label.text = "Toggle"; + SetDefaultTextValues(label); + + toggle.graphic = checkmarkImage; + toggle.targetGraphic = bgImage; + SetDefaultColorTransitionValues(toggle); + + RectTransform bgRect = background.GetComponent<RectTransform>(); + bgRect.anchorMin = new Vector2(0f, 1f); + bgRect.anchorMax = new Vector2(0f, 1f); + bgRect.anchoredPosition = new Vector2(10f, -10f); + bgRect.sizeDelta = new Vector2(kThinHeight, kThinHeight); + + RectTransform checkmarkRect = checkmark.GetComponent<RectTransform>(); + checkmarkRect.anchorMin = new Vector2(0.5f, 0.5f); + checkmarkRect.anchorMax = new Vector2(0.5f, 0.5f); + checkmarkRect.anchoredPosition = Vector2.zero; + checkmarkRect.sizeDelta = new Vector2(20f, 20f); + + RectTransform labelRect = childLabel.GetComponent<RectTransform>(); + labelRect.anchorMin = new Vector2(0f, 0f); + labelRect.anchorMax = new Vector2(1f, 1f); + labelRect.offsetMin = new Vector2(23f, 1f); + labelRect.offsetMax = new Vector2(-5f, -2f); + + return toggleRoot; + } + + public static GameObject CreateInputField(Resources resources) + { + GameObject root = CreateUIElementRoot("InputField", s_ThickElementSize); + + GameObject childPlaceholder = CreateUIObject("Placeholder", root); + GameObject childText = CreateUIObject("Text", root); + + Image image = root.AddComponent<Image>(); + image.sprite = resources.inputField; + image.type = Image.Type.Sliced; + image.color = s_DefaultSelectableColor; + + InputField inputField = root.AddComponent<InputField>(); + SetDefaultColorTransitionValues(inputField); + + Text text = childText.AddComponent<Text>(); + text.text = ""; + text.supportRichText = false; + SetDefaultTextValues(text); + + Text placeholder = childPlaceholder.AddComponent<Text>(); + placeholder.text = "Enter text..."; + placeholder.fontStyle = FontStyle.Italic; + // Make placeholder color half as opaque as normal text color. + Color placeholderColor = text.color; + placeholderColor.a *= 0.5f; + placeholder.color = placeholderColor; + + RectTransform textRectTransform = childText.GetComponent<RectTransform>(); + textRectTransform.anchorMin = Vector2.zero; + textRectTransform.anchorMax = Vector2.one; + textRectTransform.sizeDelta = Vector2.zero; + textRectTransform.offsetMin = new Vector2(10, 6); + textRectTransform.offsetMax = new Vector2(-10, -7); + + RectTransform placeholderRectTransform = childPlaceholder.GetComponent<RectTransform>(); + placeholderRectTransform.anchorMin = Vector2.zero; + placeholderRectTransform.anchorMax = Vector2.one; + placeholderRectTransform.sizeDelta = Vector2.zero; + placeholderRectTransform.offsetMin = new Vector2(10, 6); + placeholderRectTransform.offsetMax = new Vector2(-10, -7); + + inputField.textComponent = text; + inputField.placeholder = placeholder; + + return root; + } + + public static GameObject CreateDropdown(Resources resources) + { + GameObject root = CreateUIElementRoot("Dropdown", s_ThickElementSize); + + GameObject label = CreateUIObject("Label", root); + GameObject arrow = CreateUIObject("Arrow", root); + GameObject template = CreateUIObject("Template", root); + GameObject viewport = CreateUIObject("Viewport", template); + GameObject content = CreateUIObject("Content", viewport); + GameObject item = CreateUIObject("Item", content); + GameObject itemBackground = CreateUIObject("Item Background", item); + GameObject itemCheckmark = CreateUIObject("Item Checkmark", item); + GameObject itemLabel = CreateUIObject("Item Label", item); + + // Sub controls. + + GameObject scrollbar = CreateScrollbar(resources); + scrollbar.name = "Scrollbar"; + SetParentAndAlign(scrollbar, template); + + Scrollbar scrollbarScrollbar = scrollbar.GetComponent<Scrollbar>(); + scrollbarScrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true); + + RectTransform vScrollbarRT = scrollbar.GetComponent<RectTransform>(); + vScrollbarRT.anchorMin = Vector2.right; + vScrollbarRT.anchorMax = Vector2.one; + vScrollbarRT.pivot = Vector2.one; + vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0); + + // Setup item UI components. + + Text itemLabelText = itemLabel.AddComponent<Text>(); + SetDefaultTextValues(itemLabelText); + itemLabelText.alignment = TextAnchor.MiddleLeft; + + Image itemBackgroundImage = itemBackground.AddComponent<Image>(); + itemBackgroundImage.color = new Color32(245, 245, 245, 255); + + Image itemCheckmarkImage = itemCheckmark.AddComponent<Image>(); + itemCheckmarkImage.sprite = resources.checkmark; + + Toggle itemToggle = item.AddComponent<Toggle>(); + itemToggle.targetGraphic = itemBackgroundImage; + itemToggle.graphic = itemCheckmarkImage; + itemToggle.isOn = true; + + // Setup template UI components. + + Image templateImage = template.AddComponent<Image>(); + templateImage.sprite = resources.standard; + templateImage.type = Image.Type.Sliced; + + ScrollRect templateScrollRect = template.AddComponent<ScrollRect>(); + templateScrollRect.content = (RectTransform)content.transform; + templateScrollRect.viewport = (RectTransform)viewport.transform; + templateScrollRect.horizontal = false; + templateScrollRect.movementType = ScrollRect.MovementType.Clamped; + templateScrollRect.verticalScrollbar = scrollbarScrollbar; + templateScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; + templateScrollRect.verticalScrollbarSpacing = -3; + + Mask scrollRectMask = viewport.AddComponent<Mask>(); + scrollRectMask.showMaskGraphic = false; + + Image viewportImage = viewport.AddComponent<Image>(); + viewportImage.sprite = resources.mask; + viewportImage.type = Image.Type.Sliced; + + // Setup dropdown UI components. + + Text labelText = label.AddComponent<Text>(); + SetDefaultTextValues(labelText); + labelText.alignment = TextAnchor.MiddleLeft; + + Image arrowImage = arrow.AddComponent<Image>(); + arrowImage.sprite = resources.dropdown; + + Image backgroundImage = root.AddComponent<Image>(); + backgroundImage.sprite = resources.standard; + backgroundImage.color = s_DefaultSelectableColor; + backgroundImage.type = Image.Type.Sliced; + + Dropdown dropdown = root.AddComponent<Dropdown>(); + dropdown.targetGraphic = backgroundImage; + SetDefaultColorTransitionValues(dropdown); + dropdown.template = template.GetComponent<RectTransform>(); + dropdown.captionText = labelText; + dropdown.itemText = itemLabelText; + + // Setting default Item list. + itemLabelText.text = "Option A"; + dropdown.options.Add(new Dropdown.OptionData {text = "Option A"}); + dropdown.options.Add(new Dropdown.OptionData {text = "Option B"}); + dropdown.options.Add(new Dropdown.OptionData {text = "Option C"}); + dropdown.RefreshShownValue(); + + // Set up RectTransforms. + + RectTransform labelRT = label.GetComponent<RectTransform>(); + labelRT.anchorMin = Vector2.zero; + labelRT.anchorMax = Vector2.one; + labelRT.offsetMin = new Vector2(10, 6); + labelRT.offsetMax = new Vector2(-25, -7); + + RectTransform arrowRT = arrow.GetComponent<RectTransform>(); + arrowRT.anchorMin = new Vector2(1, 0.5f); + arrowRT.anchorMax = new Vector2(1, 0.5f); + arrowRT.sizeDelta = new Vector2(20, 20); + arrowRT.anchoredPosition = new Vector2(-15, 0); + + RectTransform templateRT = template.GetComponent<RectTransform>(); + templateRT.anchorMin = new Vector2(0, 0); + templateRT.anchorMax = new Vector2(1, 0); + templateRT.pivot = new Vector2(0.5f, 1); + templateRT.anchoredPosition = new Vector2(0, 2); + templateRT.sizeDelta = new Vector2(0, 150); + + RectTransform viewportRT = viewport.GetComponent<RectTransform>(); + viewportRT.anchorMin = new Vector2(0, 0); + viewportRT.anchorMax = new Vector2(1, 1); + viewportRT.sizeDelta = new Vector2(-18, 0); + viewportRT.pivot = new Vector2(0, 1); + + RectTransform contentRT = content.GetComponent<RectTransform>(); + contentRT.anchorMin = new Vector2(0f, 1); + contentRT.anchorMax = new Vector2(1f, 1); + contentRT.pivot = new Vector2(0.5f, 1); + contentRT.anchoredPosition = new Vector2(0, 0); + contentRT.sizeDelta = new Vector2(0, 28); + + RectTransform itemRT = item.GetComponent<RectTransform>(); + itemRT.anchorMin = new Vector2(0, 0.5f); + itemRT.anchorMax = new Vector2(1, 0.5f); + itemRT.sizeDelta = new Vector2(0, 20); + + RectTransform itemBackgroundRT = itemBackground.GetComponent<RectTransform>(); + itemBackgroundRT.anchorMin = Vector2.zero; + itemBackgroundRT.anchorMax = Vector2.one; + itemBackgroundRT.sizeDelta = Vector2.zero; + + RectTransform itemCheckmarkRT = itemCheckmark.GetComponent<RectTransform>(); + itemCheckmarkRT.anchorMin = new Vector2(0, 0.5f); + itemCheckmarkRT.anchorMax = new Vector2(0, 0.5f); + itemCheckmarkRT.sizeDelta = new Vector2(20, 20); + itemCheckmarkRT.anchoredPosition = new Vector2(10, 0); + + RectTransform itemLabelRT = itemLabel.GetComponent<RectTransform>(); + itemLabelRT.anchorMin = Vector2.zero; + itemLabelRT.anchorMax = Vector2.one; + itemLabelRT.offsetMin = new Vector2(20, 1); + itemLabelRT.offsetMax = new Vector2(-10, -2); + + template.SetActive(false); + + return root; + } + + public static GameObject CreateScrollView(Resources resources) + { + GameObject root = CreateUIElementRoot("Scroll View", new Vector2(200, 200)); + + GameObject viewport = CreateUIObject("Viewport", root); + GameObject content = CreateUIObject("Content", viewport); + + // Sub controls. + + GameObject hScrollbar = CreateScrollbar(resources); + hScrollbar.name = "Scrollbar Horizontal"; + SetParentAndAlign(hScrollbar, root); + RectTransform hScrollbarRT = hScrollbar.GetComponent<RectTransform>(); + hScrollbarRT.anchorMin = Vector2.zero; + hScrollbarRT.anchorMax = Vector2.right; + hScrollbarRT.pivot = Vector2.zero; + hScrollbarRT.sizeDelta = new Vector2(0, hScrollbarRT.sizeDelta.y); + + GameObject vScrollbar = CreateScrollbar(resources); + vScrollbar.name = "Scrollbar Vertical"; + SetParentAndAlign(vScrollbar, root); + vScrollbar.GetComponent<Scrollbar>().SetDirection(Scrollbar.Direction.BottomToTop, true); + RectTransform vScrollbarRT = vScrollbar.GetComponent<RectTransform>(); + vScrollbarRT.anchorMin = Vector2.right; + vScrollbarRT.anchorMax = Vector2.one; + vScrollbarRT.pivot = Vector2.one; + vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0); + + // Setup RectTransforms. + + // Make viewport fill entire scroll view. + RectTransform viewportRT = viewport.GetComponent<RectTransform>(); + viewportRT.anchorMin = Vector2.zero; + viewportRT.anchorMax = Vector2.one; + viewportRT.sizeDelta = Vector2.zero; + viewportRT.pivot = Vector2.up; + + // Make context match viewpoprt width and be somewhat taller. + // This will show the vertical scrollbar and not the horizontal one. + RectTransform contentRT = content.GetComponent<RectTransform>(); + contentRT.anchorMin = Vector2.up; + contentRT.anchorMax = Vector2.one; + contentRT.sizeDelta = new Vector2(0, 300); + contentRT.pivot = Vector2.up; + + // Setup UI components. + + ScrollRect scrollRect = root.AddComponent<ScrollRect>(); + scrollRect.content = contentRT; + scrollRect.viewport = viewportRT; + scrollRect.horizontalScrollbar = hScrollbar.GetComponent<Scrollbar>(); + scrollRect.verticalScrollbar = vScrollbar.GetComponent<Scrollbar>(); + scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; + scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; + scrollRect.horizontalScrollbarSpacing = -3; + scrollRect.verticalScrollbarSpacing = -3; + + Image rootImage = root.AddComponent<Image>(); + rootImage.sprite = resources.background; + rootImage.type = Image.Type.Sliced; + rootImage.color = s_PanelColor; + + Mask viewportMask = viewport.AddComponent<Mask>(); + viewportMask.showMaskGraphic = false; + + Image viewportImage = viewport.AddComponent<Image>(); + viewportImage.sprite = resources.mask; + viewportImage.type = Image.Type.Sliced; + + return root; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs.meta new file mode 100644 index 0000000..4365d7a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/DefaultControls.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca969270ec2be6848bd9453f8c69a4b3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs new file mode 100644 index 0000000..86bed37 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs @@ -0,0 +1,649 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.UI.CoroutineTween; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Dropdown", 35)] + [RequireComponent(typeof(RectTransform))] + public class Dropdown : Selectable, IPointerClickHandler, ISubmitHandler, ICancelHandler + { + protected internal class DropdownItem : MonoBehaviour, IPointerEnterHandler, ICancelHandler + { + [SerializeField] + private Text m_Text; + [SerializeField] + private Image m_Image; + [SerializeField] + private RectTransform m_RectTransform; + [SerializeField] + private Toggle m_Toggle; + + public Text text { get { return m_Text; } set { m_Text = value; } } + public Image image { get { return m_Image; } set { m_Image = value; } } + public RectTransform rectTransform { get { return m_RectTransform; } set { m_RectTransform = value; } } + public Toggle toggle { get { return m_Toggle; } set { m_Toggle = value; } } + + public virtual void OnPointerEnter(PointerEventData eventData) + { + EventSystem.current.SetSelectedGameObject(gameObject); + } + + public virtual void OnCancel(BaseEventData eventData) + { + Dropdown dropdown = GetComponentInParent<Dropdown>(); + if (dropdown) + dropdown.Hide(); + } + } + + [Serializable] + public class OptionData + { + [SerializeField] + private string m_Text; + [SerializeField] + private Sprite m_Image; + + public string text { get { return m_Text; } set { m_Text = value; } } + public Sprite image { get { return m_Image; } set { m_Image = value; } } + + public OptionData() + { + } + + public OptionData(string text) + { + this.text = text; + } + + public OptionData(Sprite image) + { + this.image = image; + } + + public OptionData(string text, Sprite image) + { + this.text = text; + this.image = image; + } + } + + [Serializable] + public class OptionDataList + { + [SerializeField] + private List<OptionData> m_Options; + public List<OptionData> options { get { return m_Options; } set { m_Options = value; } } + + + public OptionDataList() + { + options = new List<OptionData>(); + } + } + + [Serializable] + public class DropdownEvent : UnityEvent<int> {} + + // Template used to create the dropdown. + [SerializeField] + private RectTransform m_Template; + public RectTransform template { get { return m_Template; } set { m_Template = value; RefreshShownValue(); } } + + // Text to be used as a caption for the current value. It's not required, but it's kept here for convenience. + [SerializeField] + private Text m_CaptionText; + public Text captionText { get { return m_CaptionText; } set { m_CaptionText = value; RefreshShownValue(); } } + + [SerializeField] + private Image m_CaptionImage; + public Image captionImage { get { return m_CaptionImage; } set { m_CaptionImage = value; RefreshShownValue(); } } + + [Space] + + [SerializeField] + private Text m_ItemText; + public Text itemText { get { return m_ItemText; } set { m_ItemText = value; RefreshShownValue(); } } + + [SerializeField] + private Image m_ItemImage; + public Image itemImage { get { return m_ItemImage; } set { m_ItemImage = value; RefreshShownValue(); } } + + [Space] + + [SerializeField] + private int m_Value; + + [Space] + + // Items that will be visible when the dropdown is shown. + // We box this into its own class so we can use a Property Drawer for it. + [SerializeField] + private OptionDataList m_Options = new OptionDataList(); + public List<OptionData> options + { + get { return m_Options.options; } + set { m_Options.options = value; RefreshShownValue(); } + } + + [Space] + + // Notification triggered when the dropdown changes. + [SerializeField] + private DropdownEvent m_OnValueChanged = new DropdownEvent(); + public DropdownEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } } + + private GameObject m_Dropdown; + private GameObject m_Blocker; + private List<DropdownItem> m_Items = new List<DropdownItem>(); + private TweenRunner<FloatTween> m_AlphaTweenRunner; + private bool validTemplate = false; + + private static OptionData s_NoOptionData = new OptionData(); + + // Current value. + public int value + { + get + { + return m_Value; + } + set + { + if (Application.isPlaying && (value == m_Value || options.Count == 0)) + return; + + m_Value = Mathf.Clamp(value, 0, options.Count - 1); + RefreshShownValue(); + + // Notify all listeners + UISystemProfilerApi.AddMarker("Dropdown.value", this); + m_OnValueChanged.Invoke(m_Value); + } + } + + protected Dropdown() + {} + + protected override void Awake() + { + #if UNITY_EDITOR + if (!Application.isPlaying) + return; + #endif + + m_AlphaTweenRunner = new TweenRunner<FloatTween>(); + m_AlphaTweenRunner.Init(this); + + if (m_CaptionImage) + m_CaptionImage.enabled = (m_CaptionImage.sprite != null); + + if (m_Template) + m_Template.gameObject.SetActive(false); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + if (!IsActive()) + return; + + RefreshShownValue(); + } + + #endif + + public void RefreshShownValue() + { + OptionData data = s_NoOptionData; + + if (options.Count > 0) + data = options[Mathf.Clamp(m_Value, 0, options.Count - 1)]; + + if (m_CaptionText) + { + if (data != null && data.text != null) + m_CaptionText.text = data.text; + else + m_CaptionText.text = ""; + } + + if (m_CaptionImage) + { + if (data != null) + m_CaptionImage.sprite = data.image; + else + m_CaptionImage.sprite = null; + m_CaptionImage.enabled = (m_CaptionImage.sprite != null); + } + } + + public void AddOptions(List<OptionData> options) + { + this.options.AddRange(options); + RefreshShownValue(); + } + + public void AddOptions(List<string> options) + { + for (int i = 0; i < options.Count; i++) + this.options.Add(new OptionData(options[i])); + RefreshShownValue(); + } + + public void AddOptions(List<Sprite> options) + { + for (int i = 0; i < options.Count; i++) + this.options.Add(new OptionData(options[i])); + RefreshShownValue(); + } + + public void ClearOptions() + { + options.Clear(); + RefreshShownValue(); + } + + private void SetupTemplate() + { + validTemplate = false; + + if (!m_Template) + { + Debug.LogError("The dropdown template is not assigned. The template needs to be assigned and must have a child GameObject with a Toggle component serving as the item.", this); + return; + } + + GameObject templateGo = m_Template.gameObject; + templateGo.SetActive(true); + Toggle itemToggle = m_Template.GetComponentInChildren<Toggle>(); + + validTemplate = true; + if (!itemToggle || itemToggle.transform == template) + { + validTemplate = false; + Debug.LogError("The dropdown template is not valid. The template must have a child GameObject with a Toggle component serving as the item.", template); + } + else if (!(itemToggle.transform.parent is RectTransform)) + { + validTemplate = false; + Debug.LogError("The dropdown template is not valid. The child GameObject with a Toggle component (the item) must have a RectTransform on its parent.", template); + } + else if (itemText != null && !itemText.transform.IsChildOf(itemToggle.transform)) + { + validTemplate = false; + Debug.LogError("The dropdown template is not valid. The Item Text must be on the item GameObject or children of it.", template); + } + else if (itemImage != null && !itemImage.transform.IsChildOf(itemToggle.transform)) + { + validTemplate = false; + Debug.LogError("The dropdown template is not valid. The Item Image must be on the item GameObject or children of it.", template); + } + + if (!validTemplate) + { + templateGo.SetActive(false); + return; + } + + DropdownItem item = itemToggle.gameObject.AddComponent<DropdownItem>(); + item.text = m_ItemText; + item.image = m_ItemImage; + item.toggle = itemToggle; + item.rectTransform = (RectTransform)itemToggle.transform; + + Canvas popupCanvas = GetOrAddComponent<Canvas>(templateGo); + popupCanvas.overrideSorting = true; + popupCanvas.sortingOrder = 30000; + + GetOrAddComponent<GraphicRaycaster>(templateGo); + GetOrAddComponent<CanvasGroup>(templateGo); + templateGo.SetActive(false); + + validTemplate = true; + } + + private static T GetOrAddComponent<T>(GameObject go) where T : Component + { + T comp = go.GetComponent<T>(); + if (!comp) + comp = go.AddComponent<T>(); + return comp; + } + + public virtual void OnPointerClick(PointerEventData eventData) + { + Show(); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + Show(); + } + + public virtual void OnCancel(BaseEventData eventData) + { + Hide(); + } + + // Show the dropdown. + // + // Plan for dropdown scrolling to ensure dropdown is contained within screen. + // + // We assume the Canvas is the screen that the dropdown must be kept inside. + // This is always valid for screen space canvas modes. + // For world space canvases we don't know how it's used, but it could be e.g. for an in-game monitor. + // We consider it a fair constraint that the canvas must be big enough to contains dropdowns. + public void Show() + { + if (!IsActive() || !IsInteractable() || m_Dropdown != null) + return; + + if (!validTemplate) + { + SetupTemplate(); + if (!validTemplate) + return; + } + + // Get root Canvas. + var list = ListPool<Canvas>.Get(); + gameObject.GetComponentsInParent(false, list); + if (list.Count == 0) + return; + Canvas rootCanvas = list[0]; + ListPool<Canvas>.Release(list); + + m_Template.gameObject.SetActive(true); + + // Instantiate the drop-down template + m_Dropdown = CreateDropdownList(m_Template.gameObject); + m_Dropdown.name = "Dropdown List"; + m_Dropdown.SetActive(true); + + // Make drop-down RectTransform have same values as original. + RectTransform dropdownRectTransform = m_Dropdown.transform as RectTransform; + dropdownRectTransform.SetParent(m_Template.transform.parent, false); + + // Instantiate the drop-down list items + + // Find the dropdown item and disable it. + DropdownItem itemTemplate = m_Dropdown.GetComponentInChildren<DropdownItem>(); + + GameObject content = itemTemplate.rectTransform.parent.gameObject; + RectTransform contentRectTransform = content.transform as RectTransform; + itemTemplate.rectTransform.gameObject.SetActive(true); + + // Get the rects of the dropdown and item + Rect dropdownContentRect = contentRectTransform.rect; + Rect itemTemplateRect = itemTemplate.rectTransform.rect; + + // Calculate the visual offset between the item's edges and the background's edges + Vector2 offsetMin = itemTemplateRect.min - dropdownContentRect.min + (Vector2)itemTemplate.rectTransform.localPosition; + Vector2 offsetMax = itemTemplateRect.max - dropdownContentRect.max + (Vector2)itemTemplate.rectTransform.localPosition; + Vector2 itemSize = itemTemplateRect.size; + + m_Items.Clear(); + + Toggle prev = null; + for (int i = 0; i < options.Count; ++i) + { + OptionData data = options[i]; + DropdownItem item = AddItem(data, value == i, itemTemplate, m_Items); + if (item == null) + continue; + + // Automatically set up a toggle state change listener + item.toggle.isOn = value == i; + item.toggle.onValueChanged.AddListener(x => OnSelectItem(item.toggle)); + + // Select current option + if (item.toggle.isOn) + item.toggle.Select(); + + // Automatically set up explicit navigation + if (prev != null) + { + Navigation prevNav = prev.navigation; + Navigation toggleNav = item.toggle.navigation; + prevNav.mode = Navigation.Mode.Explicit; + toggleNav.mode = Navigation.Mode.Explicit; + + prevNav.selectOnDown = item.toggle; + prevNav.selectOnRight = item.toggle; + toggleNav.selectOnLeft = prev; + toggleNav.selectOnUp = prev; + + prev.navigation = prevNav; + item.toggle.navigation = toggleNav; + } + prev = item.toggle; + } + + // Reposition all items now that all of them have been added + Vector2 sizeDelta = contentRectTransform.sizeDelta; + sizeDelta.y = itemSize.y * m_Items.Count + offsetMin.y - offsetMax.y; + contentRectTransform.sizeDelta = sizeDelta; + + float extraSpace = dropdownRectTransform.rect.height - contentRectTransform.rect.height; + if (extraSpace > 0) + dropdownRectTransform.sizeDelta = new Vector2(dropdownRectTransform.sizeDelta.x, dropdownRectTransform.sizeDelta.y - extraSpace); + + // Invert anchoring and position if dropdown is partially or fully outside of canvas rect. + // Typically this will have the effect of placing the dropdown above the button instead of below, + // but it works as inversion regardless of initial setup. + Vector3[] corners = new Vector3[4]; + dropdownRectTransform.GetWorldCorners(corners); + + RectTransform rootCanvasRectTransform = rootCanvas.transform as RectTransform; + Rect rootCanvasRect = rootCanvasRectTransform.rect; + for (int axis = 0; axis < 2; axis++) + { + bool outside = false; + for (int i = 0; i < 4; i++) + { + Vector3 corner = rootCanvasRectTransform.InverseTransformPoint(corners[i]); + if (corner[axis] < rootCanvasRect.min[axis] || corner[axis] > rootCanvasRect.max[axis]) + { + outside = true; + break; + } + } + if (outside) + RectTransformUtility.FlipLayoutOnAxis(dropdownRectTransform, axis, false, false); + } + + for (int i = 0; i < m_Items.Count; i++) + { + RectTransform itemRect = m_Items[i].rectTransform; + itemRect.anchorMin = new Vector2(itemRect.anchorMin.x, 0); + itemRect.anchorMax = new Vector2(itemRect.anchorMax.x, 0); + itemRect.anchoredPosition = new Vector2(itemRect.anchoredPosition.x, offsetMin.y + itemSize.y * (m_Items.Count - 1 - i) + itemSize.y * itemRect.pivot.y); + itemRect.sizeDelta = new Vector2(itemRect.sizeDelta.x, itemSize.y); + } + + // Fade in the popup + AlphaFadeList(0.15f, 0f, 1f); + + // Make drop-down template and item template inactive + m_Template.gameObject.SetActive(false); + itemTemplate.gameObject.SetActive(false); + + m_Blocker = CreateBlocker(rootCanvas); + } + + protected virtual GameObject CreateBlocker(Canvas rootCanvas) + { + // Create blocker GameObject. + GameObject blocker = new GameObject("Blocker"); + + // Setup blocker RectTransform to cover entire root canvas area. + RectTransform blockerRect = blocker.AddComponent<RectTransform>(); + blockerRect.SetParent(rootCanvas.transform, false); + blockerRect.anchorMin = Vector3.zero; + blockerRect.anchorMax = Vector3.one; + blockerRect.sizeDelta = Vector2.zero; + + // Make blocker be in separate canvas in same layer as dropdown and in layer just below it. + Canvas blockerCanvas = blocker.AddComponent<Canvas>(); + blockerCanvas.overrideSorting = true; + Canvas dropdownCanvas = m_Dropdown.GetComponent<Canvas>(); + blockerCanvas.sortingLayerID = dropdownCanvas.sortingLayerID; + blockerCanvas.sortingOrder = dropdownCanvas.sortingOrder - 1; + + // Add raycaster since it's needed to block. + blocker.AddComponent<GraphicRaycaster>(); + + // Add image since it's needed to block, but make it clear. + Image blockerImage = blocker.AddComponent<Image>(); + blockerImage.color = Color.clear; + + // Add button since it's needed to block, and to close the dropdown when blocking area is clicked. + Button blockerButton = blocker.AddComponent<Button>(); + blockerButton.onClick.AddListener(Hide); + + return blocker; + } + + protected virtual void DestroyBlocker(GameObject blocker) + { + Destroy(blocker); + } + + protected virtual GameObject CreateDropdownList(GameObject template) + { + return (GameObject)Instantiate(template); + } + + protected virtual void DestroyDropdownList(GameObject dropdownList) + { + Destroy(dropdownList); + } + + protected virtual DropdownItem CreateItem(DropdownItem itemTemplate) + { + return (DropdownItem)Instantiate(itemTemplate); + } + + protected virtual void DestroyItem(DropdownItem item) + { + // No action needed since destroying the dropdown list destroys all contained items as well. + } + + // Add a new drop-down list item with the specified values. + private DropdownItem AddItem(OptionData data, bool selected, DropdownItem itemTemplate, List<DropdownItem> items) + { + // Add a new item to the dropdown. + DropdownItem item = CreateItem(itemTemplate); + item.rectTransform.SetParent(itemTemplate.rectTransform.parent, false); + + item.gameObject.SetActive(true); + item.gameObject.name = "Item " + items.Count + (data.text != null ? ": " + data.text : ""); + + if (item.toggle != null) + { + item.toggle.isOn = false; + } + + // Set the item's data + if (item.text) + item.text.text = data.text; + if (item.image) + { + item.image.sprite = data.image; + item.image.enabled = (item.image.sprite != null); + } + + items.Add(item); + return item; + } + + private void AlphaFadeList(float duration, float alpha) + { + CanvasGroup group = m_Dropdown.GetComponent<CanvasGroup>(); + AlphaFadeList(duration, group.alpha, alpha); + } + + private void AlphaFadeList(float duration, float start, float end) + { + if (end.Equals(start)) + return; + + FloatTween tween = new FloatTween {duration = duration, startValue = start, targetValue = end}; + tween.AddOnChangedCallback(SetAlpha); + tween.ignoreTimeScale = true; + m_AlphaTweenRunner.StartTween(tween); + } + + private void SetAlpha(float alpha) + { + if (!m_Dropdown) + return; + CanvasGroup group = m_Dropdown.GetComponent<CanvasGroup>(); + group.alpha = alpha; + } + + // Hide the dropdown. + public void Hide() + { + if (m_Dropdown != null) + { + AlphaFadeList(0.15f, 0f); + + // User could have disabled the dropdown during the OnValueChanged call. + if (IsActive()) + StartCoroutine(DelayedDestroyDropdownList(0.15f)); + } + if (m_Blocker != null) + DestroyBlocker(m_Blocker); + m_Blocker = null; + Select(); + } + + private IEnumerator DelayedDestroyDropdownList(float delay) + { + yield return new WaitForSecondsRealtime(delay); + for (int i = 0; i < m_Items.Count; i++) + { + if (m_Items[i] != null) + DestroyItem(m_Items[i]); + } + m_Items.Clear(); + if (m_Dropdown != null) + DestroyDropdownList(m_Dropdown); + m_Dropdown = null; + } + + // Change the value and hide the dropdown. + private void OnSelectItem(Toggle toggle) + { + if (!toggle.isOn) + toggle.isOn = true; + + int selectedIndex = -1; + Transform tr = toggle.transform; + Transform parent = tr.parent; + for (int i = 0; i < parent.childCount; i++) + { + if (parent.GetChild(i) == tr) + { + // Subtract one to account for template child. + selectedIndex = i - 1; + break; + } + } + + if (selectedIndex < 0) + return; + + value = selectedIndex; + Hide(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs.meta new file mode 100644 index 0000000..a80360c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Dropdown.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfed003f40ad7ff4ba0ba7ccf49021aa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs new file mode 100644 index 0000000..1f3267a --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs @@ -0,0 +1,2484 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace UnityEngine.UI +{ + /// <summary> + /// Editable text input field. + /// </summary> + + [AddComponentMenu("UI/Input Field", 31)] + public class InputField + : Selectable, + IUpdateSelectedHandler, + IBeginDragHandler, + IDragHandler, + IEndDragHandler, + IPointerClickHandler, + ISubmitHandler, + ICanvasElement, + ILayoutElement + { + // Setting the content type acts as a shortcut for setting a combination of InputType, CharacterValidation, LineType, and TouchScreenKeyboardType + public enum ContentType + { + Standard, + Autocorrected, + IntegerNumber, + DecimalNumber, + Alphanumeric, + Name, + EmailAddress, + Password, + Pin, + Custom + } + + public enum InputType + { + Standard, + AutoCorrect, + Password, + } + + public enum CharacterValidation + { + None, + Integer, + Decimal, + Alphanumeric, + Name, + EmailAddress + } + + public enum LineType + { + SingleLine, + MultiLineSubmit, + MultiLineNewline + } + + public delegate char OnValidateInput(string text, int charIndex, char addedChar); + + [Serializable] + public class SubmitEvent : UnityEvent<string> {} + + [Serializable] + public class OnChangeEvent : UnityEvent<string> {} + + protected TouchScreenKeyboard m_Keyboard; + static private readonly char[] kSeparators = { ' ', '.', ',', '\t', '\r', '\n' }; + + /// <summary> + /// Text Text used to display the input's value. + /// </summary> + + [SerializeField] + [FormerlySerializedAs("text")] + protected Text m_TextComponent; + + [SerializeField] + protected Graphic m_Placeholder; + + [SerializeField] + private ContentType m_ContentType = ContentType.Standard; + + /// <summary> + /// Type of data expected by the input field. + /// </summary> + [FormerlySerializedAs("inputType")] + [SerializeField] + private InputType m_InputType = InputType.Standard; + + /// <summary> + /// The character used to hide text in password field. + /// </summary> + [FormerlySerializedAs("asteriskChar")] + [SerializeField] + private char m_AsteriskChar = '*'; + + /// <summary> + /// Keyboard type applies to mobile keyboards that get shown. + /// </summary> + [FormerlySerializedAs("keyboardType")] + [SerializeField] + private TouchScreenKeyboardType m_KeyboardType = TouchScreenKeyboardType.Default; + + [SerializeField] + private LineType m_LineType = LineType.SingleLine; + + /// <summary> + /// Should hide mobile input. + /// </summary> + + [FormerlySerializedAs("hideMobileInput")] + [SerializeField] + private bool m_HideMobileInput = false; + + /// <summary> + /// What kind of validation to use with the input field's data. + /// </summary> + [FormerlySerializedAs("validation")] + [SerializeField] + private CharacterValidation m_CharacterValidation = CharacterValidation.None; + + /// <summary> + /// Maximum number of characters allowed before input no longer works. + /// </summary> + [FormerlySerializedAs("characterLimit")] + [SerializeField] + private int m_CharacterLimit = 0; + + /// <summary> + /// Event delegates triggered when the input field submits its data. + /// </summary> + [FormerlySerializedAs("onSubmit")] + [FormerlySerializedAs("m_OnSubmit")] + [FormerlySerializedAs("m_EndEdit")] + [SerializeField] + private SubmitEvent m_OnEndEdit = new SubmitEvent(); + + /// <summary> + /// Event delegates triggered when the input field changes its data. + /// </summary> + [FormerlySerializedAs("onValueChange")] + [FormerlySerializedAs("m_OnValueChange")] + [SerializeField] + private OnChangeEvent m_OnValueChanged = new OnChangeEvent(); + + /// <summary> + /// Custom validation callback. + /// </summary> + [FormerlySerializedAs("onValidateInput")] + [SerializeField] + private OnValidateInput m_OnValidateInput; + + [SerializeField] + private Color m_CaretColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f); + + [SerializeField] + private bool m_CustomCaretColor = false; + + [FormerlySerializedAs("selectionColor")] + [SerializeField] + private Color m_SelectionColor = new Color(168f / 255f, 206f / 255f, 255f / 255f, 192f / 255f); + + /// <summary> + /// Input field's value. + /// </summary> + + [SerializeField] + [FormerlySerializedAs("mValue")] + protected string m_Text = string.Empty; + + [SerializeField] + [Range(0f, 4f)] + private float m_CaretBlinkRate = 0.85f; + + [SerializeField] + [Range(1, 5)] + private int m_CaretWidth = 1; + + [SerializeField] + private bool m_ReadOnly = false; + + protected int m_CaretPosition = 0; + protected int m_CaretSelectPosition = 0; + private RectTransform caretRectTrans = null; + protected UIVertex[] m_CursorVerts = null; + private TextGenerator m_InputTextCache; + private CanvasRenderer m_CachedInputRenderer; + private bool m_PreventFontCallback = false; + [NonSerialized] protected Mesh m_Mesh; + private bool m_AllowInput = false; + private bool m_ShouldActivateNextUpdate = false; + private bool m_UpdateDrag = false; + private bool m_DragPositionOutOfBounds = false; + private const float kHScrollSpeed = 0.05f; + private const float kVScrollSpeed = 0.10f; + protected bool m_CaretVisible; + private Coroutine m_BlinkCoroutine = null; + private float m_BlinkStartTime = 0.0f; + protected int m_DrawStart = 0; + protected int m_DrawEnd = 0; + private Coroutine m_DragCoroutine = null; + private string m_OriginalText = ""; + private bool m_WasCanceled = false; + private bool m_HasDoneFocusTransition = false; + + private BaseInput input + { + get + { + if (EventSystem.current && EventSystem.current.currentInputModule) + return EventSystem.current.currentInputModule.input; + return null; + } + } + + private string compositionString + { + get { return input != null ? input.compositionString : Input.compositionString; } + } + + // Doesn't include dot and @ on purpose! See usage for details. + const string kEmailSpecialCharacters = "!#$%&'*+-/=?^_`{|}~"; + + protected InputField() + { + EnforceTextHOverflow(); + } + + protected Mesh mesh + { + get + { + if (m_Mesh == null) + m_Mesh = new Mesh(); + return m_Mesh; + } + } + + protected TextGenerator cachedInputTextGenerator + { + get + { + if (m_InputTextCache == null) + m_InputTextCache = new TextGenerator(); + + return m_InputTextCache; + } + } + + /// <summary> + /// Should the mobile keyboard input be hidden. + /// </summary> + + public bool shouldHideMobileInput + { + set + { + SetPropertyUtility.SetStruct(ref m_HideMobileInput, value); + } + get + { + switch (Application.platform) + { + case RuntimePlatform.Android: + case RuntimePlatform.IPhonePlayer: + case RuntimePlatform.TizenPlayer: + case RuntimePlatform.tvOS: + return m_HideMobileInput; + } + + return true; + } + } + + bool shouldActivateOnSelect + { + get + { + return Application.platform != RuntimePlatform.tvOS; + } + } + + /// <summary> + /// Input field's current text value. + /// </summary> + + public string text + { + get + { + return m_Text; + } + set + { + if (this.text == value) + return; + if (value == null) + value = ""; + value = value.Replace("\0", string.Empty); // remove embedded nulls + if (m_LineType == LineType.SingleLine) + value = value.Replace("\n", "").Replace("\t", ""); + + // If we have an input validator, validate the input and apply the character limit at the same time. + if (onValidateInput != null || characterValidation != CharacterValidation.None) + { + m_Text = ""; + OnValidateInput validatorMethod = onValidateInput ?? Validate; + m_CaretPosition = m_CaretSelectPosition = value.Length; + int charactersToCheck = characterLimit > 0 ? Math.Min(characterLimit, value.Length) : value.Length; + for (int i = 0; i < charactersToCheck; ++i) + { + char c = validatorMethod(m_Text, m_Text.Length, value[i]); + if (c != 0) + m_Text += c; + } + } + else + { + m_Text = characterLimit > 0 && value.Length > characterLimit ? value.Substring(0, characterLimit) : value; + } + +#if UNITY_EDITOR + if (!Application.isPlaying) + { + SendOnValueChangedAndUpdateLabel(); + return; + } +#endif + + if (m_Keyboard != null) + m_Keyboard.text = m_Text; + + if (m_CaretPosition > m_Text.Length) + m_CaretPosition = m_CaretSelectPosition = m_Text.Length; + else if (m_CaretSelectPosition > m_Text.Length) + m_CaretSelectPosition = m_Text.Length; + SendOnValueChangedAndUpdateLabel(); + } + } + + public bool isFocused + { + get { return m_AllowInput; } + } + + public float caretBlinkRate + { + get { return m_CaretBlinkRate; } + set + { + if (SetPropertyUtility.SetStruct(ref m_CaretBlinkRate, value)) + { + if (m_AllowInput) + SetCaretActive(); + } + } + } + + public int caretWidth { get { return m_CaretWidth; } set { if (SetPropertyUtility.SetStruct(ref m_CaretWidth, value)) MarkGeometryAsDirty(); } } + + public Text textComponent + { + get { return m_TextComponent; } + set + { + if (m_TextComponent != null) + { + m_TextComponent.UnregisterDirtyVerticesCallback(MarkGeometryAsDirty); + m_TextComponent.UnregisterDirtyVerticesCallback(UpdateLabel); + m_TextComponent.UnregisterDirtyMaterialCallback(UpdateCaretMaterial); + } + + if (SetPropertyUtility.SetClass(ref m_TextComponent, value)) + { + EnforceTextHOverflow(); + if (m_TextComponent != null) + { + m_TextComponent.RegisterDirtyVerticesCallback(MarkGeometryAsDirty); + m_TextComponent.RegisterDirtyVerticesCallback(UpdateLabel); + m_TextComponent.RegisterDirtyMaterialCallback(UpdateCaretMaterial); + } + } + } + } + + public Graphic placeholder { get { return m_Placeholder; } set { SetPropertyUtility.SetClass(ref m_Placeholder, value); } } + + public Color caretColor { get { return customCaretColor ? m_CaretColor : textComponent.color; } set { if (SetPropertyUtility.SetColor(ref m_CaretColor, value)) MarkGeometryAsDirty(); } } + + public bool customCaretColor { get { return m_CustomCaretColor; } set { if (m_CustomCaretColor != value) { m_CustomCaretColor = value; MarkGeometryAsDirty(); } } } + + public Color selectionColor { get { return m_SelectionColor; } set { if (SetPropertyUtility.SetColor(ref m_SelectionColor, value)) MarkGeometryAsDirty(); } } + + public SubmitEvent onEndEdit { get { return m_OnEndEdit; } set { SetPropertyUtility.SetClass(ref m_OnEndEdit, value); } } + + [Obsolete("onValueChange has been renamed to onValueChanged")] + public OnChangeEvent onValueChange { get { return onValueChanged; } set { onValueChanged = value; } } + + public OnChangeEvent onValueChanged { get { return m_OnValueChanged; } set { SetPropertyUtility.SetClass(ref m_OnValueChanged, value); } } + + public OnValidateInput onValidateInput { get { return m_OnValidateInput; } set { SetPropertyUtility.SetClass(ref m_OnValidateInput, value); } } + + public int characterLimit { get { return m_CharacterLimit; } set { if (SetPropertyUtility.SetStruct(ref m_CharacterLimit, Math.Max(0, value))) UpdateLabel(); } } + + // Content Type related + + public ContentType contentType { get { return m_ContentType; } set { if (SetPropertyUtility.SetStruct(ref m_ContentType, value)) EnforceContentType(); } } + + public LineType lineType + { + get { return m_LineType; } + set + { + if (SetPropertyUtility.SetStruct(ref m_LineType, value)) + { + SetToCustomIfContentTypeIsNot(ContentType.Standard, ContentType.Autocorrected); + EnforceTextHOverflow(); + } + } + } + + public InputType inputType { get { return m_InputType; } set { if (SetPropertyUtility.SetStruct(ref m_InputType, value)) SetToCustom(); } } + + public TouchScreenKeyboardType keyboardType + { + get { return m_KeyboardType; } + set + { +#if UNITY_EDITOR + if (EditorUserBuildSettings.activeBuildTarget != BuildTarget.WiiU) + { + if (value == TouchScreenKeyboardType.NintendoNetworkAccount) + Debug.LogWarning("Invalid InputField.keyboardType value set. TouchScreenKeyboardType.NintendoNetworkAccount only applies to the Wii U. InputField.keyboardType will default to TouchScreenKeyboardType.Default ."); + } +#elif !UNITY_WIIU + if (value == TouchScreenKeyboardType.NintendoNetworkAccount) + Debug.LogWarning("Invalid InputField.keyboardType value set. TouchScreenKeyboardType.NintendoNetworkAccount only applies to the Wii U. InputField.keyboardType will default to TouchScreenKeyboardType.Default ."); +#endif + if (SetPropertyUtility.SetStruct(ref m_KeyboardType, value)) + SetToCustom(); + } + } + + public CharacterValidation characterValidation { get { return m_CharacterValidation; } set { if (SetPropertyUtility.SetStruct(ref m_CharacterValidation, value)) SetToCustom(); } } + + public bool readOnly { get { return m_ReadOnly; } set { m_ReadOnly = value; } } + + // Derived property + public bool multiLine { get { return m_LineType == LineType.MultiLineNewline || lineType == LineType.MultiLineSubmit; } } + // Not shown in Inspector. + public char asteriskChar { get { return m_AsteriskChar; } set { if (SetPropertyUtility.SetStruct(ref m_AsteriskChar, value)) UpdateLabel(); } } + public bool wasCanceled { get { return m_WasCanceled; } } + + protected void ClampPos(ref int pos) + { + if (pos < 0) pos = 0; + else if (pos > text.Length) pos = text.Length; + } + + /// <summary> + /// Current position of the cursor. + /// Getters are public Setters are protected + /// </summary> + + protected int caretPositionInternal { get { return m_CaretPosition + compositionString.Length; } set { m_CaretPosition = value; ClampPos(ref m_CaretPosition); } } + protected int caretSelectPositionInternal { get { return m_CaretSelectPosition + compositionString.Length; } set { m_CaretSelectPosition = value; ClampPos(ref m_CaretSelectPosition); } } + private bool hasSelection { get { return caretPositionInternal != caretSelectPositionInternal; } } + +#if UNITY_EDITOR + [Obsolete("caretSelectPosition has been deprecated. Use selectionFocusPosition instead (UnityUpgradable) -> selectionFocusPosition", true)] + public int caretSelectPosition { get { return selectionFocusPosition; } protected set { selectionFocusPosition = value; } } +#endif + + /// <summary> + /// Get: Returns the focus position as thats the position that moves around even during selection. + /// Set: Set both the anchor and focus position such that a selection doesn't happen + /// </summary> + + public int caretPosition + { + get { return m_CaretSelectPosition + compositionString.Length; } + set { selectionAnchorPosition = value; selectionFocusPosition = value; } + } + + /// <summary> + /// Get: Returns the fixed position of selection + /// Set: If Input.compositionString is 0 set the fixed position + /// </summary> + + public int selectionAnchorPosition + { + get { return m_CaretPosition + compositionString.Length; } + set + { + if (compositionString.Length != 0) + return; + + m_CaretPosition = value; + ClampPos(ref m_CaretPosition); + } + } + + /// <summary> + /// Get: Returns the variable position of selection + /// Set: If Input.compositionString is 0 set the variable position + /// </summary> + + public int selectionFocusPosition + { + get { return m_CaretSelectPosition + compositionString.Length; } + set + { + if (compositionString.Length != 0) + return; + + m_CaretSelectPosition = value; + ClampPos(ref m_CaretSelectPosition); + } + } + + #if UNITY_EDITOR + // Remember: This is NOT related to text validation! + // This is Unity's own OnValidate method which is invoked when changing values in the Inspector. + protected override void OnValidate() + { + base.OnValidate(); + EnforceContentType(); + EnforceTextHOverflow(); + + m_CharacterLimit = Math.Max(0, m_CharacterLimit); + + //This can be invoked before OnEnabled is called. So we shouldn't be accessing other objects, before OnEnable is called. + if (!IsActive()) + return; + + UpdateLabel(); + if (m_AllowInput) + SetCaretActive(); + } + + #endif // if UNITY_EDITOR + + protected override void OnEnable() + { + base.OnEnable(); + if (m_Text == null) + m_Text = string.Empty; + m_DrawStart = 0; + m_DrawEnd = m_Text.Length; + + // If we have a cached renderer then we had OnDisable called so just restore the material. + if (m_CachedInputRenderer != null) + m_CachedInputRenderer.SetMaterial(m_TextComponent.GetModifiedMaterial(Graphic.defaultGraphicMaterial), Texture2D.whiteTexture); + + if (m_TextComponent != null) + { + m_TextComponent.RegisterDirtyVerticesCallback(MarkGeometryAsDirty); + m_TextComponent.RegisterDirtyVerticesCallback(UpdateLabel); + m_TextComponent.RegisterDirtyMaterialCallback(UpdateCaretMaterial); + UpdateLabel(); + } + } + + protected override void OnDisable() + { + // the coroutine will be terminated, so this will ensure it restarts when we are next activated + m_BlinkCoroutine = null; + + DeactivateInputField(); + if (m_TextComponent != null) + { + m_TextComponent.UnregisterDirtyVerticesCallback(MarkGeometryAsDirty); + m_TextComponent.UnregisterDirtyVerticesCallback(UpdateLabel); + m_TextComponent.UnregisterDirtyMaterialCallback(UpdateCaretMaterial); + } + CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild(this); + + // Clear needs to be called otherwise sync never happens as the object is disabled. + if (m_CachedInputRenderer != null) + m_CachedInputRenderer.Clear(); + + if (m_Mesh != null) + DestroyImmediate(m_Mesh); + m_Mesh = null; + + base.OnDisable(); + } + + IEnumerator CaretBlink() + { + // Always ensure caret is initially visible since it can otherwise be confusing for a moment. + m_CaretVisible = true; + yield return null; + + while (isFocused && m_CaretBlinkRate > 0) + { + // the blink rate is expressed as a frequency + float blinkPeriod = 1f / m_CaretBlinkRate; + + // the caret should be ON if we are in the first half of the blink period + bool blinkState = (Time.unscaledTime - m_BlinkStartTime) % blinkPeriod < blinkPeriod / 2; + if (m_CaretVisible != blinkState) + { + m_CaretVisible = blinkState; + if (!hasSelection) + MarkGeometryAsDirty(); + } + + // Then wait again. + yield return null; + } + m_BlinkCoroutine = null; + } + + void SetCaretVisible() + { + if (!m_AllowInput) + return; + + m_CaretVisible = true; + m_BlinkStartTime = Time.unscaledTime; + SetCaretActive(); + } + + // SetCaretActive will not set the caret immediately visible - it will wait for the next time to blink. + // However, it will handle things correctly if the blink speed changed from zero to non-zero or non-zero to zero. + void SetCaretActive() + { + if (!m_AllowInput) + return; + + if (m_CaretBlinkRate > 0.0f) + { + if (m_BlinkCoroutine == null) + m_BlinkCoroutine = StartCoroutine(CaretBlink()); + } + else + { + m_CaretVisible = true; + } + } + + private void UpdateCaretMaterial() + { + if (m_TextComponent != null && m_CachedInputRenderer != null) + m_CachedInputRenderer.SetMaterial(m_TextComponent.GetModifiedMaterial(Graphic.defaultGraphicMaterial), Texture2D.whiteTexture); + } + + protected void OnFocus() + { + SelectAll(); + } + + protected void SelectAll() + { + caretPositionInternal = text.Length; + caretSelectPositionInternal = 0; + } + + public void MoveTextEnd(bool shift) + { + int position = text.Length; + + if (shift) + { + caretSelectPositionInternal = position; + } + else + { + caretPositionInternal = position; + caretSelectPositionInternal = caretPositionInternal; + } + UpdateLabel(); + } + + public void MoveTextStart(bool shift) + { + int position = 0; + + if (shift) + { + caretSelectPositionInternal = position; + } + else + { + caretPositionInternal = position; + caretSelectPositionInternal = caretPositionInternal; + } + + UpdateLabel(); + } + + static string clipboard + { + get + { + return GUIUtility.systemCopyBuffer; + } + set + { + GUIUtility.systemCopyBuffer = value; + } + } + + private bool InPlaceEditing() + { + return !TouchScreenKeyboard.isSupported; + } + + void UpdateCaretFromKeyboard() + { + var selectionRange = m_Keyboard.selection; + + var selectionStart = selectionRange.start; + var selectionEnd = selectionRange.end; + + var caretChanged = false; + + if (caretPositionInternal != selectionStart) + { + caretChanged = true; + caretPositionInternal = selectionStart; + } + + if (caretSelectPositionInternal != selectionEnd) + { + caretSelectPositionInternal = selectionEnd; + caretChanged = true; + } + + if (caretChanged) + { + m_BlinkStartTime = Time.unscaledTime; + + UpdateLabel(); + } + } + + /// <summary> + /// Update the text based on input. + /// </summary> + // TODO: Make LateUpdate a coroutine instead. Allows us to control the update to only be when the field is active. + protected virtual void LateUpdate() + { + // Only activate if we are not already activated. + if (m_ShouldActivateNextUpdate) + { + if (!isFocused) + { + ActivateInputFieldInternal(); + m_ShouldActivateNextUpdate = false; + return; + } + + // Reset as we are already activated. + m_ShouldActivateNextUpdate = false; + } + + if (InPlaceEditing() || !isFocused) + return; + + AssignPositioningIfNeeded(); + + if (m_Keyboard == null || m_Keyboard.done) + { + if (m_Keyboard != null) + { + if (!m_ReadOnly) + text = m_Keyboard.text; + + if (m_Keyboard.wasCanceled) + m_WasCanceled = true; + } + + OnDeselect(null); + return; + } + + string val = m_Keyboard.text; + + if (m_Text != val) + { + if (m_ReadOnly) + { + m_Keyboard.text = m_Text; + } + else + { + m_Text = ""; + + for (int i = 0; i < val.Length; ++i) + { + char c = val[i]; + + if (c == '\r' || (int)c == 3) + c = '\n'; + + if (onValidateInput != null) + c = onValidateInput(m_Text, m_Text.Length, c); + else if (characterValidation != CharacterValidation.None) + c = Validate(m_Text, m_Text.Length, c); + + if (lineType == LineType.MultiLineSubmit && c == '\n') + { + m_Keyboard.text = m_Text; + + OnDeselect(null); + return; + } + + if (c != 0) + m_Text += c; + } + + if (characterLimit > 0 && m_Text.Length > characterLimit) + m_Text = m_Text.Substring(0, characterLimit); + + if (m_Keyboard.canGetSelection) + { + UpdateCaretFromKeyboard(); + } + else + { + caretPositionInternal = caretSelectPositionInternal = m_Text.Length; + } + + // Set keyboard text before updating label, as we might have changed it with validation + // and update label will take the old value from keyboard if we don't change it here + if (m_Text != val) + m_Keyboard.text = m_Text; + + SendOnValueChangedAndUpdateLabel(); + } + } + else if (m_Keyboard.canGetSelection) + { + UpdateCaretFromKeyboard(); + } + + + if (m_Keyboard.done) + { + if (m_Keyboard.wasCanceled) + m_WasCanceled = true; + + OnDeselect(null); + } + } + + [Obsolete("This function is no longer used. Please use RectTransformUtility.ScreenPointToLocalPointInRectangle() instead.")] + public Vector2 ScreenToLocal(Vector2 screen) + { + var theCanvas = m_TextComponent.canvas; + if (theCanvas == null) + return screen; + + Vector3 pos = Vector3.zero; + if (theCanvas.renderMode == RenderMode.ScreenSpaceOverlay) + { + pos = m_TextComponent.transform.InverseTransformPoint(screen); + } + else if (theCanvas.worldCamera != null) + { + Ray mouseRay = theCanvas.worldCamera.ScreenPointToRay(screen); + float dist; + Plane plane = new Plane(m_TextComponent.transform.forward, m_TextComponent.transform.position); + plane.Raycast(mouseRay, out dist); + pos = m_TextComponent.transform.InverseTransformPoint(mouseRay.GetPoint(dist)); + } + return new Vector2(pos.x, pos.y); + } + + private int GetUnclampedCharacterLineFromPosition(Vector2 pos, TextGenerator generator) + { + if (!multiLine) + return 0; + + // transform y to local scale + float y = pos.y * m_TextComponent.pixelsPerUnit; + float lastBottomY = 0.0f; + + for (int i = 0; i < generator.lineCount; ++i) + { + float topY = generator.lines[i].topY; + float bottomY = topY - generator.lines[i].height; + + // pos is somewhere in the leading above this line + if (y > topY) + { + // determine which line we're closer to + float leading = topY - lastBottomY; + if (y > topY - 0.5f * leading) + return i - 1; + else + return i; + } + + if (y > bottomY) + return i; + + lastBottomY = bottomY; + } + + // Position is after last line. + return generator.lineCount; + } + + /// <summary> + /// Given an input position in local space on the Text return the index for the selection cursor at this position. + /// </summary> + + protected int GetCharacterIndexFromPosition(Vector2 pos) + { + TextGenerator gen = m_TextComponent.cachedTextGenerator; + + if (gen.lineCount == 0) + return 0; + + int line = GetUnclampedCharacterLineFromPosition(pos, gen); + if (line < 0) + return 0; + if (line >= gen.lineCount) + return gen.characterCountVisible; + + int startCharIndex = gen.lines[line].startCharIdx; + int endCharIndex = GetLineEndPosition(gen, line); + + for (int i = startCharIndex; i < endCharIndex; i++) + { + if (i >= gen.characterCountVisible) + break; + + UICharInfo charInfo = gen.characters[i]; + Vector2 charPos = charInfo.cursorPos / m_TextComponent.pixelsPerUnit; + + float distToCharStart = pos.x - charPos.x; + float distToCharEnd = charPos.x + (charInfo.charWidth / m_TextComponent.pixelsPerUnit) - pos.x; + if (distToCharStart < distToCharEnd) + return i; + } + + return endCharIndex; + } + + private bool MayDrag(PointerEventData eventData) + { + return IsActive() && + IsInteractable() && + eventData.button == PointerEventData.InputButton.Left && + m_TextComponent != null && + m_Keyboard == null; + } + + public virtual void OnBeginDrag(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + m_UpdateDrag = true; + } + + public virtual void OnDrag(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + Vector2 localMousePos; + RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, eventData.position, eventData.pressEventCamera, out localMousePos); + caretSelectPositionInternal = GetCharacterIndexFromPosition(localMousePos) + m_DrawStart; + MarkGeometryAsDirty(); + + m_DragPositionOutOfBounds = !RectTransformUtility.RectangleContainsScreenPoint(textComponent.rectTransform, eventData.position, eventData.pressEventCamera); + if (m_DragPositionOutOfBounds && m_DragCoroutine == null) + m_DragCoroutine = StartCoroutine(MouseDragOutsideRect(eventData)); + + eventData.Use(); + } + + IEnumerator MouseDragOutsideRect(PointerEventData eventData) + { + while (m_UpdateDrag && m_DragPositionOutOfBounds) + { + Vector2 localMousePos; + RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, eventData.position, eventData.pressEventCamera, out localMousePos); + + Rect rect = textComponent.rectTransform.rect; + + if (multiLine) + { + if (localMousePos.y > rect.yMax) + MoveUp(true, true); + else if (localMousePos.y < rect.yMin) + MoveDown(true, true); + } + else + { + if (localMousePos.x < rect.xMin) + MoveLeft(true, false); + else if (localMousePos.x > rect.xMax) + MoveRight(true, false); + } + UpdateLabel(); + float delay = multiLine ? kVScrollSpeed : kHScrollSpeed; + yield return new WaitForSecondsRealtime(delay); + } + m_DragCoroutine = null; + } + + public virtual void OnEndDrag(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + m_UpdateDrag = false; + } + + public override void OnPointerDown(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + EventSystem.current.SetSelectedGameObject(gameObject, eventData); + + bool hadFocusBefore = m_AllowInput; + base.OnPointerDown(eventData); + + if (!InPlaceEditing()) + { + if (m_Keyboard == null || !m_Keyboard.active) + { + OnSelect(eventData); + return; + } + } + + // Only set caret position if we didn't just get focus now. + // Otherwise it will overwrite the select all on focus. + if (hadFocusBefore) + { + Vector2 localMousePos; + RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, eventData.position, eventData.pressEventCamera, out localMousePos); + + caretSelectPositionInternal = caretPositionInternal = GetCharacterIndexFromPosition(localMousePos) + m_DrawStart; + } + UpdateLabel(); + eventData.Use(); + } + + protected enum EditState + { + Continue, + Finish + } + + protected EditState KeyPressed(Event evt) + { + var currentEventModifiers = evt.modifiers; + bool ctrl = SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX ? (currentEventModifiers & EventModifiers.Command) != 0 : (currentEventModifiers & EventModifiers.Control) != 0; + bool shift = (currentEventModifiers & EventModifiers.Shift) != 0; + bool alt = (currentEventModifiers & EventModifiers.Alt) != 0; + bool ctrlOnly = ctrl && !alt && !shift; + + switch (evt.keyCode) + { + case KeyCode.Backspace: + { + Backspace(); + return EditState.Continue; + } + + case KeyCode.Delete: + { + ForwardSpace(); + return EditState.Continue; + } + + case KeyCode.Home: + { + MoveTextStart(shift); + return EditState.Continue; + } + + case KeyCode.End: + { + MoveTextEnd(shift); + return EditState.Continue; + } + + // Select All + case KeyCode.A: + { + if (ctrlOnly) + { + SelectAll(); + return EditState.Continue; + } + break; + } + + // Copy + case KeyCode.C: + { + if (ctrlOnly) + { + if (inputType != InputType.Password) + clipboard = GetSelectedString(); + else + clipboard = ""; + return EditState.Continue; + } + break; + } + + // Paste + case KeyCode.V: + { + if (ctrlOnly) + { + Append(clipboard); + return EditState.Continue; + } + break; + } + + // Cut + case KeyCode.X: + { + if (ctrlOnly) + { + if (inputType != InputType.Password) + clipboard = GetSelectedString(); + else + clipboard = ""; + Delete(); + SendOnValueChangedAndUpdateLabel(); + return EditState.Continue; + } + break; + } + + case KeyCode.LeftArrow: + { + MoveLeft(shift, ctrl); + return EditState.Continue; + } + + case KeyCode.RightArrow: + { + MoveRight(shift, ctrl); + return EditState.Continue; + } + + case KeyCode.UpArrow: + { + MoveUp(shift); + return EditState.Continue; + } + + case KeyCode.DownArrow: + { + MoveDown(shift); + return EditState.Continue; + } + + // Submit + case KeyCode.Return: + case KeyCode.KeypadEnter: + { + if (lineType != LineType.MultiLineNewline) + { + return EditState.Finish; + } + break; + } + + case KeyCode.Escape: + { + m_WasCanceled = true; + return EditState.Finish; + } + } + + char c = evt.character; + // Don't allow return chars or tabulator key to be entered into single line fields. + if (!multiLine && (c == '\t' || c == '\r' || c == 10)) + return EditState.Continue; + + // Convert carriage return and end-of-text characters to newline. + if (c == '\r' || (int)c == 3) + c = '\n'; + + if (IsValidChar(c)) + { + Append(c); + } + + if (c == 0) + { + if (compositionString.Length > 0) + { + UpdateLabel(); + } + } + return EditState.Continue; + } + + private bool IsValidChar(char c) + { + // Delete key on mac + if ((int)c == 127) + return false; + // Accept newline and tab + if (c == '\t' || c == '\n') + return true; + + return m_TextComponent.font.HasCharacter(c); + } + + /// <summary> + /// Handle the specified event. + /// </summary> + private Event m_ProcessingEvent = new Event(); + + public void ProcessEvent(Event e) + { + KeyPressed(e); + } + + //c IUpdateSelectedHandlerµÄ½Ó¿Ú + public virtual void OnUpdateSelected(BaseEventData eventData) + { + if (!isFocused) + return; + + bool consumedEvent = false; + while (Event.PopEvent(m_ProcessingEvent)) + { + if (m_ProcessingEvent.rawType == EventType.KeyDown) + { + consumedEvent = true; + var shouldContinue = KeyPressed(m_ProcessingEvent); + if (shouldContinue == EditState.Finish) + { + DeactivateInputField(); + break; + } + } + + switch (m_ProcessingEvent.type) + { + case EventType.ValidateCommand: + case EventType.ExecuteCommand: + switch (m_ProcessingEvent.commandName) + { + case "SelectAll": + SelectAll(); + consumedEvent = true; + break; + } + break; + } + } + + if (consumedEvent) + UpdateLabel(); + + eventData.Use(); + } + + private string GetSelectedString() + { + if (!hasSelection) + return ""; + + int startPos = caretPositionInternal; + int endPos = caretSelectPositionInternal; + + // Ensure startPos is always less then endPos to make the code simpler + if (startPos > endPos) + { + int temp = startPos; + startPos = endPos; + endPos = temp; + } + + return text.Substring(startPos, endPos - startPos); + } + + private int FindtNextWordBegin() + { + if (caretSelectPositionInternal + 1 >= text.Length) + return text.Length; + + int spaceLoc = text.IndexOfAny(kSeparators, caretSelectPositionInternal + 1); + + if (spaceLoc == -1) + spaceLoc = text.Length; + else + spaceLoc++; + + return spaceLoc; + } + + private void MoveRight(bool shift, bool ctrl) + { + if (hasSelection && !shift) + { + // By convention, if we have a selection and move right without holding shift, + // we just place the cursor at the end. + caretPositionInternal = caretSelectPositionInternal = Mathf.Max(caretPositionInternal, caretSelectPositionInternal); + return; + } + + int position; + if (ctrl) + position = FindtNextWordBegin(); + else + position = caretSelectPositionInternal + 1; + + if (shift) + caretSelectPositionInternal = position; + else + caretSelectPositionInternal = caretPositionInternal = position; + } + + private int FindtPrevWordBegin() + { + if (caretSelectPositionInternal - 2 < 0) + return 0; + + int spaceLoc = text.LastIndexOfAny(kSeparators, caretSelectPositionInternal - 2); + + if (spaceLoc == -1) + spaceLoc = 0; + else + spaceLoc++; + + return spaceLoc; + } + + private void MoveLeft(bool shift, bool ctrl) + { + if (hasSelection && !shift) + { + // By convention, if we have a selection and move left without holding shift, + // we just place the cursor at the start. + caretPositionInternal = caretSelectPositionInternal = Mathf.Min(caretPositionInternal, caretSelectPositionInternal); + return; + } + + int position; + if (ctrl) + position = FindtPrevWordBegin(); + else + position = caretSelectPositionInternal - 1; + + if (shift) + caretSelectPositionInternal = position; + else + caretSelectPositionInternal = caretPositionInternal = position; + } + + private int DetermineCharacterLine(int charPos, TextGenerator generator) + { + for (int i = 0; i < generator.lineCount - 1; ++i) + { + if (generator.lines[i + 1].startCharIdx > charPos) + return i; + } + + return generator.lineCount - 1; + } + + /// <summary> + /// Use cachedInputTextGenerator as the y component for the UICharInfo is not required + /// </summary> + + private int LineUpCharacterPosition(int originalPos, bool goToFirstChar) + { + if (originalPos >= cachedInputTextGenerator.characters.Count) + return 0; + + UICharInfo originChar = cachedInputTextGenerator.characters[originalPos]; + int originLine = DetermineCharacterLine(originalPos, cachedInputTextGenerator); + + // We are on the first line return first character + if (originLine <= 0) + return goToFirstChar ? 0 : originalPos; + + int endCharIdx = cachedInputTextGenerator.lines[originLine].startCharIdx - 1; + + for (int i = cachedInputTextGenerator.lines[originLine - 1].startCharIdx; i < endCharIdx; ++i) + { + if (cachedInputTextGenerator.characters[i].cursorPos.x >= originChar.cursorPos.x) + return i; + } + return endCharIdx; + } + + /// <summary> + /// Use cachedInputTextGenerator as the y component for the UICharInfo is not required + /// </summary> + + private int LineDownCharacterPosition(int originalPos, bool goToLastChar) + { + if (originalPos >= cachedInputTextGenerator.characterCountVisible) + return text.Length; + + UICharInfo originChar = cachedInputTextGenerator.characters[originalPos]; + int originLine = DetermineCharacterLine(originalPos, cachedInputTextGenerator); + + // We are on the last line return last character + if (originLine + 1 >= cachedInputTextGenerator.lineCount) + return goToLastChar ? text.Length : originalPos; + + // Need to determine end line for next line. + int endCharIdx = GetLineEndPosition(cachedInputTextGenerator, originLine + 1); + + for (int i = cachedInputTextGenerator.lines[originLine + 1].startCharIdx; i < endCharIdx; ++i) + { + if (cachedInputTextGenerator.characters[i].cursorPos.x >= originChar.cursorPos.x) + return i; + } + return endCharIdx; + } + + private void MoveDown(bool shift) + { + MoveDown(shift, true); + } + + private void MoveDown(bool shift, bool goToLastChar) + { + if (hasSelection && !shift) + { + // If we have a selection and press down without shift, + // set caret position to end of selection before we move it down. + caretPositionInternal = caretSelectPositionInternal = Mathf.Max(caretPositionInternal, caretSelectPositionInternal); + } + + int position = multiLine ? LineDownCharacterPosition(caretSelectPositionInternal, goToLastChar) : text.Length; + + if (shift) + caretSelectPositionInternal = position; + else + caretPositionInternal = caretSelectPositionInternal = position; + } + + private void MoveUp(bool shift) + { + MoveUp(shift, true); + } + + private void MoveUp(bool shift, bool goToFirstChar) + { + if (hasSelection && !shift) + { + // If we have a selection and press up without shift, + // set caret position to start of selection before we move it up. + caretPositionInternal = caretSelectPositionInternal = Mathf.Min(caretPositionInternal, caretSelectPositionInternal); + } + + int position = multiLine ? LineUpCharacterPosition(caretSelectPositionInternal, goToFirstChar) : 0; + + if (shift) + caretSelectPositionInternal = position; + else + caretSelectPositionInternal = caretPositionInternal = position; + } + + private void Delete() + { + if (m_ReadOnly) + return; + + if (caretPositionInternal == caretSelectPositionInternal) + return; + + if (caretPositionInternal < caretSelectPositionInternal) + { + m_Text = text.Substring(0, caretPositionInternal) + text.Substring(caretSelectPositionInternal, text.Length - caretSelectPositionInternal); + caretSelectPositionInternal = caretPositionInternal; + } + else + { + m_Text = text.Substring(0, caretSelectPositionInternal) + text.Substring(caretPositionInternal, text.Length - caretPositionInternal); + caretPositionInternal = caretSelectPositionInternal; + } + } + + private void ForwardSpace() + { + if (m_ReadOnly) + return; + + if (hasSelection) + { + Delete(); + SendOnValueChangedAndUpdateLabel(); + } + else + { + if (caretPositionInternal < text.Length) + { + m_Text = text.Remove(caretPositionInternal, 1); + SendOnValueChangedAndUpdateLabel(); + } + } + } + + private void Backspace() + { + if (m_ReadOnly) + return; + + if (hasSelection) + { + Delete(); + SendOnValueChangedAndUpdateLabel(); + } + else + { + if (caretPositionInternal > 0) + { + m_Text = text.Remove(caretPositionInternal - 1, 1); + caretSelectPositionInternal = caretPositionInternal = caretPositionInternal - 1; + SendOnValueChangedAndUpdateLabel(); + } + } + } + + // Insert the character and update the label. + private void Insert(char c) + { + if (m_ReadOnly) + return; + + string replaceString = c.ToString(); + Delete(); + + // Can't go past the character limit + if (characterLimit > 0 && text.Length >= characterLimit) + return; + + m_Text = text.Insert(m_CaretPosition, replaceString); + caretSelectPositionInternal = caretPositionInternal += replaceString.Length; + + SendOnValueChanged(); + } + + private void SendOnValueChangedAndUpdateLabel() + { + SendOnValueChanged(); + UpdateLabel(); + } + + private void SendOnValueChanged() + { + UISystemProfilerApi.AddMarker("InputField.value", this); + if (onValueChanged != null) + onValueChanged.Invoke(text); + } + + /// <summary> + /// Submit the input field's text. + /// </summary> + + protected void SendOnSubmit() + { + UISystemProfilerApi.AddMarker("InputField.onSubmit", this); + if (onEndEdit != null) + onEndEdit.Invoke(m_Text); + } + + /// <summary> + /// Append the specified text to the end of the current. + /// </summary> + + protected virtual void Append(string input) + { + if (m_ReadOnly) + return; + + if (!InPlaceEditing()) + return; + + for (int i = 0, imax = input.Length; i < imax; ++i) + { + char c = input[i]; + + if (c >= ' ' || c == '\t' || c == '\r' || c == 10 || c == '\n') + { + Append(c); + } + } + } + + protected virtual void Append(char input) + { + if (m_ReadOnly) + return; + + if (!InPlaceEditing()) + return; + + // If we have an input validator, validate the input first + int insertionPoint = Math.Min(selectionFocusPosition, selectionAnchorPosition); + if (onValidateInput != null) + input = onValidateInput(text, insertionPoint, input); + else if (characterValidation != CharacterValidation.None) + input = Validate(text, insertionPoint, input); + + // If the input is invalid, skip it + if (input == 0) + return; + + // Append the character and update the label + Insert(input); + } + + /// <summary> + /// Update the visual text Text. + /// </summary> + + protected void UpdateLabel() + { + if (m_TextComponent != null && m_TextComponent.font != null && !m_PreventFontCallback) + { + // TextGenerator.Populate invokes a callback that's called for anything + // that needs to be updated when the data for that font has changed. + // This makes all Text components that use that font update their vertices. + // In turn, this makes the InputField that's associated with that Text component + // update its label by calling this UpdateLabel method. + // This is a recursive call we want to prevent, since it makes the InputField + // update based on font data that didn't yet finish executing, or alternatively + // hang on infinite recursion, depending on whether the cached value is cached + // before or after the calculation. + // + // This callback also occurs when assigning text to our Text component, i.e., + // m_TextComponent.text = processed; + + m_PreventFontCallback = true; + + string fullText; + if (compositionString.Length > 0) + fullText = text.Substring(0, m_CaretPosition) + compositionString + text.Substring(m_CaretPosition); + else + fullText = text; + + string processed; + if (inputType == InputType.Password) + processed = new string(asteriskChar, fullText.Length); + else + processed = fullText; + + bool isEmpty = string.IsNullOrEmpty(fullText); + + if (m_Placeholder != null) + m_Placeholder.enabled = isEmpty; + + // If not currently editing the text, set the visible range to the whole text. + // The UpdateLabel method will then truncate it to the part that fits inside the Text area. + // We can't do this when text is being edited since it would discard the current scroll, + // which is defined by means of the m_DrawStart and m_DrawEnd indices. + if (!m_AllowInput) + { + m_DrawStart = 0; + m_DrawEnd = m_Text.Length; + } + + if (!isEmpty) + { + // Determine what will actually fit into the given line + Vector2 extents = m_TextComponent.rectTransform.rect.size; + + var settings = m_TextComponent.GetGenerationSettings(extents); + settings.generateOutOfBounds = true; + + cachedInputTextGenerator.PopulateWithErrors(processed, settings, gameObject); + + SetDrawRangeToContainCaretPosition(caretSelectPositionInternal); + + processed = processed.Substring(m_DrawStart, Mathf.Min(m_DrawEnd, processed.Length) - m_DrawStart); + + SetCaretVisible(); + } + m_TextComponent.text = processed; + MarkGeometryAsDirty(); + m_PreventFontCallback = false; + } + } + + private bool IsSelectionVisible() + { + if (m_DrawStart > caretPositionInternal || m_DrawStart > caretSelectPositionInternal) + return false; + + if (m_DrawEnd < caretPositionInternal || m_DrawEnd < caretSelectPositionInternal) + return false; + + return true; + } + + private static int GetLineStartPosition(TextGenerator gen, int line) + { + line = Mathf.Clamp(line, 0, gen.lines.Count - 1); + return gen.lines[line].startCharIdx; + } + + private static int GetLineEndPosition(TextGenerator gen, int line) + { + line = Mathf.Max(line, 0); + if (line + 1 < gen.lines.Count) + return gen.lines[line + 1].startCharIdx - 1; + return gen.characterCountVisible; + } + + private void SetDrawRangeToContainCaretPosition(int caretPos) + { + // We don't have any generated lines generation is not valid. + if (cachedInputTextGenerator.lineCount <= 0) + return; + + // the extents gets modified by the pixel density, so we need to use the generated extents since that will be in the same 'space' as + // the values returned by the TextGenerator.lines[x].height for instance. + Vector2 extents = cachedInputTextGenerator.rectExtents.size; + + if (multiLine) + { + var lines = cachedInputTextGenerator.lines; + int caretLine = DetermineCharacterLine(caretPos, cachedInputTextGenerator); + + if (caretPos > m_DrawEnd) + { + // Caret comes after drawEnd, so we need to move drawEnd to the end of the line with the caret + m_DrawEnd = GetLineEndPosition(cachedInputTextGenerator, caretLine); + float bottomY = lines[caretLine].topY - lines[caretLine].height; + if (caretLine == lines.Count - 1) + { + // Remove interline spacing on last line. + bottomY += lines[caretLine].leading; + } + int startLine = caretLine; + while (startLine > 0) + { + float topY = lines[startLine - 1].topY; + if (topY - bottomY > extents.y) + break; + startLine--; + } + m_DrawStart = GetLineStartPosition(cachedInputTextGenerator, startLine); + } + else + { + if (caretPos < m_DrawStart) + { + // Caret comes before drawStart, so we need to move drawStart to an earlier line start that comes before caret. + m_DrawStart = GetLineStartPosition(cachedInputTextGenerator, caretLine); + } + + int startLine = DetermineCharacterLine(m_DrawStart, cachedInputTextGenerator); + int endLine = startLine; + + float topY = lines[startLine].topY; + float bottomY = lines[endLine].topY - lines[endLine].height; + + if (endLine == lines.Count - 1) + { + // Remove interline spacing on last line. + bottomY += lines[endLine].leading; + } + + while (endLine < lines.Count - 1) + { + bottomY = lines[endLine + 1].topY - lines[endLine + 1].height; + + if (endLine + 1 == lines.Count - 1) + { + // Remove interline spacing on last line. + bottomY += lines[endLine + 1].leading; + } + + if (topY - bottomY > extents.y) + break; + ++endLine; + } + + m_DrawEnd = GetLineEndPosition(cachedInputTextGenerator, endLine); + + while (startLine > 0) + { + topY = lines[startLine - 1].topY; + if (topY - bottomY > extents.y) + break; + startLine--; + } + m_DrawStart = GetLineStartPosition(cachedInputTextGenerator, startLine); + } + } + else + { + var characters = cachedInputTextGenerator.characters; + if (m_DrawEnd > cachedInputTextGenerator.characterCountVisible) + m_DrawEnd = cachedInputTextGenerator.characterCountVisible; + + float width = 0.0f; + if (caretPos > m_DrawEnd || (caretPos == m_DrawEnd && m_DrawStart > 0)) + { + // fit characters from the caretPos leftward + m_DrawEnd = caretPos; + for (m_DrawStart = m_DrawEnd - 1; m_DrawStart >= 0; --m_DrawStart) + { + if (width + characters[m_DrawStart].charWidth > extents.x) + break; + + width += characters[m_DrawStart].charWidth; + } + ++m_DrawStart; // move right one to the last character we could fit on the left + } + else + { + if (caretPos < m_DrawStart) + m_DrawStart = caretPos; + + m_DrawEnd = m_DrawStart; + } + + // fit characters rightward + for (; m_DrawEnd < cachedInputTextGenerator.characterCountVisible; ++m_DrawEnd) + { + width += characters[m_DrawEnd].charWidth; + if (width > extents.x) + break; + } + } + } + + public void ForceLabelUpdate() + { + UpdateLabel(); + } + + private void MarkGeometryAsDirty() + { +#if UNITY_EDITOR + if (!Application.isPlaying || UnityEditor.PrefabUtility.GetPrefabObject(gameObject) != null) + return; +#endif + + CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); + } + + public virtual void Rebuild(CanvasUpdate update) + { + switch (update) + { + case CanvasUpdate.LatePreRender: + UpdateGeometry(); + break; + } + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + private void UpdateGeometry() + { +#if UNITY_EDITOR + if (!Application.isPlaying) + return; +#endif + // No need to draw a cursor on mobile as its handled by the devices keyboard. + if (!shouldHideMobileInput) + return; + + if (m_CachedInputRenderer == null && m_TextComponent != null) + { + GameObject go = new GameObject(transform.name + " Input Caret", typeof(RectTransform), typeof(CanvasRenderer)); + go.hideFlags = HideFlags.DontSave; + go.transform.SetParent(m_TextComponent.transform.parent); + go.transform.SetAsFirstSibling(); + go.layer = gameObject.layer; + + caretRectTrans = go.GetComponent<RectTransform>(); + m_CachedInputRenderer = go.GetComponent<CanvasRenderer>(); + m_CachedInputRenderer.SetMaterial(m_TextComponent.GetModifiedMaterial(Graphic.defaultGraphicMaterial), Texture2D.whiteTexture); + + // Needed as if any layout is present we want the caret to always be the same as the text area. + go.AddComponent<LayoutElement>().ignoreLayout = true; + + AssignPositioningIfNeeded(); + } + + if (m_CachedInputRenderer == null) + return; + + OnFillVBO(mesh); + m_CachedInputRenderer.SetMesh(mesh); + } + + private void AssignPositioningIfNeeded() + { + if (m_TextComponent != null && caretRectTrans != null && + (caretRectTrans.localPosition != m_TextComponent.rectTransform.localPosition || + caretRectTrans.localRotation != m_TextComponent.rectTransform.localRotation || + caretRectTrans.localScale != m_TextComponent.rectTransform.localScale || + caretRectTrans.anchorMin != m_TextComponent.rectTransform.anchorMin || + caretRectTrans.anchorMax != m_TextComponent.rectTransform.anchorMax || + caretRectTrans.anchoredPosition != m_TextComponent.rectTransform.anchoredPosition || + caretRectTrans.sizeDelta != m_TextComponent.rectTransform.sizeDelta || + caretRectTrans.pivot != m_TextComponent.rectTransform.pivot)) + { + caretRectTrans.localPosition = m_TextComponent.rectTransform.localPosition; + caretRectTrans.localRotation = m_TextComponent.rectTransform.localRotation; + caretRectTrans.localScale = m_TextComponent.rectTransform.localScale; + caretRectTrans.anchorMin = m_TextComponent.rectTransform.anchorMin; + caretRectTrans.anchorMax = m_TextComponent.rectTransform.anchorMax; + caretRectTrans.anchoredPosition = m_TextComponent.rectTransform.anchoredPosition; + caretRectTrans.sizeDelta = m_TextComponent.rectTransform.sizeDelta; + caretRectTrans.pivot = m_TextComponent.rectTransform.pivot; + } + } + + private void OnFillVBO(Mesh vbo) + { + using (var helper = new VertexHelper()) + { + if (!isFocused) + { + helper.FillMesh(vbo); + return; + } + + Vector2 roundingOffset = m_TextComponent.PixelAdjustPoint(Vector2.zero); + if (!hasSelection) + GenerateCaret(helper, roundingOffset); + else + GenerateHightlight(helper, roundingOffset); + + helper.FillMesh(vbo); + } + } + + private void GenerateCaret(VertexHelper vbo, Vector2 roundingOffset) + { + if (!m_CaretVisible) + return; + + if (m_CursorVerts == null) + { + CreateCursorVerts(); + } + + float width = m_CaretWidth; + int adjustedPos = Mathf.Max(0, caretPositionInternal - m_DrawStart); + TextGenerator gen = m_TextComponent.cachedTextGenerator; + + if (gen == null) + return; + + if (gen.lineCount == 0) + return; + + Vector2 startPosition = Vector2.zero; + + // Calculate startPosition + if (adjustedPos < gen.characters.Count) + { + UICharInfo cursorChar = gen.characters[adjustedPos]; + startPosition.x = cursorChar.cursorPos.x; + } + startPosition.x /= m_TextComponent.pixelsPerUnit; + + // TODO: Only clamp when Text uses horizontal word wrap. + if (startPosition.x > m_TextComponent.rectTransform.rect.xMax) + startPosition.x = m_TextComponent.rectTransform.rect.xMax; + + int characterLine = DetermineCharacterLine(adjustedPos, gen); + startPosition.y = gen.lines[characterLine].topY / m_TextComponent.pixelsPerUnit; + float height = gen.lines[characterLine].height / m_TextComponent.pixelsPerUnit; + + for (int i = 0; i < m_CursorVerts.Length; i++) + m_CursorVerts[i].color = caretColor; + + m_CursorVerts[0].position = new Vector3(startPosition.x, startPosition.y - height, 0.0f); + m_CursorVerts[1].position = new Vector3(startPosition.x + width, startPosition.y - height, 0.0f); + m_CursorVerts[2].position = new Vector3(startPosition.x + width, startPosition.y, 0.0f); + m_CursorVerts[3].position = new Vector3(startPosition.x, startPosition.y, 0.0f); + + if (roundingOffset != Vector2.zero) + { + for (int i = 0; i < m_CursorVerts.Length; i++) + { + UIVertex uiv = m_CursorVerts[i]; + uiv.position.x += roundingOffset.x; + uiv.position.y += roundingOffset.y; + } + } + + vbo.AddUIVertexQuad(m_CursorVerts); + + int screenHeight = Screen.height; + // Multiple display support only when not the main display. For display 0 the reported + // resolution is always the desktops resolution since its part of the display API, + // so we use the standard none multiple display method. (case 741751) + int displayIndex = m_TextComponent.canvas.targetDisplay; + if (displayIndex > 0 && displayIndex < Display.displays.Length) + screenHeight = Display.displays[displayIndex].renderingHeight; + + startPosition.y = screenHeight - startPosition.y; + input.compositionCursorPos = startPosition; + } + + private void CreateCursorVerts() + { + m_CursorVerts = new UIVertex[4]; + + for (int i = 0; i < m_CursorVerts.Length; i++) + { + m_CursorVerts[i] = UIVertex.simpleVert; + m_CursorVerts[i].uv0 = Vector2.zero; + } + } + + private void GenerateHightlight(VertexHelper vbo, Vector2 roundingOffset) + { + int startChar = Mathf.Max(0, caretPositionInternal - m_DrawStart); + int endChar = Mathf.Max(0, caretSelectPositionInternal - m_DrawStart); + + // Ensure pos is always less then selPos to make the code simpler + if (startChar > endChar) + { + int temp = startChar; + startChar = endChar; + endChar = temp; + } + + endChar -= 1; + TextGenerator gen = m_TextComponent.cachedTextGenerator; + + if (gen.lineCount <= 0) + return; + + int currentLineIndex = DetermineCharacterLine(startChar, gen); + + int lastCharInLineIndex = GetLineEndPosition(gen, currentLineIndex); + + UIVertex vert = UIVertex.simpleVert; + vert.uv0 = Vector2.zero; + vert.color = selectionColor; + + int currentChar = startChar; + while (currentChar <= endChar && currentChar < gen.characterCount) + { + if (currentChar == lastCharInLineIndex || currentChar == endChar) + { + UICharInfo startCharInfo = gen.characters[startChar]; + UICharInfo endCharInfo = gen.characters[currentChar]; + Vector2 startPosition = new Vector2(startCharInfo.cursorPos.x / m_TextComponent.pixelsPerUnit, gen.lines[currentLineIndex].topY / m_TextComponent.pixelsPerUnit); + Vector2 endPosition = new Vector2((endCharInfo.cursorPos.x + endCharInfo.charWidth) / m_TextComponent.pixelsPerUnit, startPosition.y - gen.lines[currentLineIndex].height / m_TextComponent.pixelsPerUnit); + + // Checking xMin as well due to text generator not setting position if char is not rendered. + if (endPosition.x > m_TextComponent.rectTransform.rect.xMax || endPosition.x < m_TextComponent.rectTransform.rect.xMin) + endPosition.x = m_TextComponent.rectTransform.rect.xMax; + + var startIndex = vbo.currentVertCount; + vert.position = new Vector3(startPosition.x, endPosition.y, 0.0f) + (Vector3)roundingOffset; + vbo.AddVert(vert); + + vert.position = new Vector3(endPosition.x, endPosition.y, 0.0f) + (Vector3)roundingOffset; + vbo.AddVert(vert); + + vert.position = new Vector3(endPosition.x, startPosition.y, 0.0f) + (Vector3)roundingOffset; + vbo.AddVert(vert); + + vert.position = new Vector3(startPosition.x, startPosition.y, 0.0f) + (Vector3)roundingOffset; + vbo.AddVert(vert); + + vbo.AddTriangle(startIndex, startIndex + 1, startIndex + 2); + vbo.AddTriangle(startIndex + 2, startIndex + 3, startIndex + 0); + + startChar = currentChar + 1; + currentLineIndex++; + + lastCharInLineIndex = GetLineEndPosition(gen, currentLineIndex); + } + currentChar++; + } + } + + /// <summary> + /// Validate the specified input. + /// </summary> + + protected char Validate(string text, int pos, char ch) + { + // Validation is disabled + if (characterValidation == CharacterValidation.None || !enabled) + return ch; + + if (characterValidation == CharacterValidation.Integer || characterValidation == CharacterValidation.Decimal) + { + // Integer and decimal + bool cursorBeforeDash = (pos == 0 && text.Length > 0 && text[0] == '-'); + bool dashInSelection = text.Length > 0 && text[0] == '-' && ((caretPositionInternal == 0 && caretSelectPositionInternal > 0) || (caretSelectPositionInternal == 0 && caretPositionInternal > 0)); + bool selectionAtStart = caretPositionInternal == 0 || caretSelectPositionInternal == 0; + if (!cursorBeforeDash || dashInSelection) + { + if (ch >= '0' && ch <= '9') return ch; + if (ch == '-' && (pos == 0 || selectionAtStart)) return ch; + if (ch == '.' && characterValidation == CharacterValidation.Decimal && !text.Contains(".")) return ch; + } + } + else if (characterValidation == CharacterValidation.Alphanumeric) + { + // All alphanumeric characters + if (ch >= 'A' && ch <= 'Z') return ch; + if (ch >= 'a' && ch <= 'z') return ch; + if (ch >= '0' && ch <= '9') return ch; + } + else if (characterValidation == CharacterValidation.Name) + { + // FIXME: some actions still lead to invalid input: + // - Hitting delete in front of an uppercase letter + // - Selecting an uppercase letter and deleting it + // - Typing some text, hitting Home and typing more text (we then have an uppercase letter in the middle of a word) + // - Typing some text, hitting Home and typing a space (we then have a leading space) + // - Erasing a space between two words (we then have an uppercase letter in the middle of a word) + // - We accept a trailing space + // - We accept the insertion of a space between two lowercase letters. + // - Typing text in front of an existing uppercase letter + // - ... and certainly more + // + // The rule we try to implement are too complex for this kind of verification. + + if (char.IsLetter(ch)) + { + // Character following a space should be in uppercase. + if (char.IsLower(ch) && ((pos == 0) || (text[pos - 1] == ' '))) + { + return char.ToUpper(ch); + } + + // Character not following a space or an apostrophe should be in lowercase. + if (char.IsUpper(ch) && (pos > 0) && (text[pos - 1] != ' ') && (text[pos - 1] != '\'')) + { + return char.ToLower(ch); + } + + return ch; + } + + if (ch == '\'') + { + // Don't allow more than one apostrophe + if (!text.Contains("'")) + // Don't allow consecutive spaces and apostrophes. + if (!(((pos > 0) && ((text[pos - 1] == ' ') || (text[pos - 1] == '\''))) || + ((pos < text.Length) && ((text[pos] == ' ') || (text[pos] == '\''))))) + return ch; + } + + if (ch == ' ') + { + // Don't allow consecutive spaces and apostrophes. + if (!(((pos > 0) && ((text[pos - 1] == ' ') || (text[pos - 1] == '\''))) || + ((pos < text.Length) && ((text[pos] == ' ') || (text[pos] == '\''))))) + return ch; + } + } + else if (characterValidation == CharacterValidation.EmailAddress) + { + // From StackOverflow about allowed characters in email addresses: + // Uppercase and lowercase English letters (a-z, A-Z) + // Digits 0 to 9 + // Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~ + // Character . (dot, period, full stop) provided that it is not the first or last character, + // and provided also that it does not appear two or more times consecutively. + + if (ch >= 'A' && ch <= 'Z') return ch; + if (ch >= 'a' && ch <= 'z') return ch; + if (ch >= '0' && ch <= '9') return ch; + if (ch == '@' && text.IndexOf('@') == -1) return ch; + if (kEmailSpecialCharacters.IndexOf(ch) != -1) return ch; + if (ch == '.') + { + char lastChar = (text.Length > 0) ? text[Mathf.Clamp(pos, 0, text.Length - 1)] : ' '; + char nextChar = (text.Length > 0) ? text[Mathf.Clamp(pos + 1, 0, text.Length - 1)] : '\n'; + if (lastChar != '.' && nextChar != '.') + return ch; + } + } + return (char)0; + } + + public void ActivateInputField() + { + if (m_TextComponent == null || m_TextComponent.font == null || !IsActive() || !IsInteractable()) + return; + + if (isFocused) + { + if (m_Keyboard != null && !m_Keyboard.active) + { + m_Keyboard.active = true; + m_Keyboard.text = m_Text; + } + } + + m_ShouldActivateNextUpdate = true; + } + + private void ActivateInputFieldInternal() + { + if (EventSystem.current == null) + return; + + if (EventSystem.current.currentSelectedGameObject != gameObject) + EventSystem.current.SetSelectedGameObject(gameObject); + + if (TouchScreenKeyboard.isSupported) + { + if (input.touchSupported) + { + TouchScreenKeyboard.hideInput = shouldHideMobileInput; + } + + m_Keyboard = (inputType == InputType.Password) ? + TouchScreenKeyboard.Open(m_Text, keyboardType, false, multiLine, true) : + TouchScreenKeyboard.Open(m_Text, keyboardType, inputType == InputType.AutoCorrect, multiLine); + + // Mimics OnFocus but as mobile doesn't properly support select all + // just set it to the end of the text (where it would move when typing starts) + MoveTextEnd(false); + } + else + { + input.imeCompositionMode = IMECompositionMode.On; + OnFocus(); + } + + m_AllowInput = true; + m_OriginalText = text; + m_WasCanceled = false; + SetCaretVisible(); + UpdateLabel(); + } + + public override void OnSelect(BaseEventData eventData) + { + base.OnSelect(eventData); + + if (shouldActivateOnSelect) + ActivateInputField(); + } + + public virtual void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + ActivateInputField(); + } + + public void DeactivateInputField() + { + // Not activated do nothing. + if (!m_AllowInput) + return; + + m_HasDoneFocusTransition = false; + m_AllowInput = false; + + if (m_Placeholder != null) + m_Placeholder.enabled = string.IsNullOrEmpty(m_Text); + + if (m_TextComponent != null && IsInteractable()) + { + if (m_WasCanceled) + text = m_OriginalText; + + if (m_Keyboard != null) + { + m_Keyboard.active = false; + m_Keyboard = null; + } + + m_CaretPosition = m_CaretSelectPosition = 0; + + SendOnSubmit(); + + input.imeCompositionMode = IMECompositionMode.Auto; + } + + MarkGeometryAsDirty(); + } + + public override void OnDeselect(BaseEventData eventData) + { + DeactivateInputField(); + base.OnDeselect(eventData); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + if (!IsActive() || !IsInteractable()) + return; + + if (!isFocused) + m_ShouldActivateNextUpdate = true; + } + + private void EnforceContentType() + { + switch (contentType) + { + case ContentType.Standard: + { + // Don't enforce line type for this content type. + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.Default; + m_CharacterValidation = CharacterValidation.None; + break; + } + case ContentType.Autocorrected: + { + // Don't enforce line type for this content type. + m_InputType = InputType.AutoCorrect; + m_KeyboardType = TouchScreenKeyboardType.Default; + m_CharacterValidation = CharacterValidation.None; + break; + } + case ContentType.IntegerNumber: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.NumberPad; + m_CharacterValidation = CharacterValidation.Integer; + break; + } + case ContentType.DecimalNumber: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.NumbersAndPunctuation; + m_CharacterValidation = CharacterValidation.Decimal; + break; + } + case ContentType.Alphanumeric: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.ASCIICapable; + m_CharacterValidation = CharacterValidation.Alphanumeric; + break; + } + case ContentType.Name: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.NamePhonePad; + m_CharacterValidation = CharacterValidation.Name; + break; + } + case ContentType.EmailAddress: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Standard; + m_KeyboardType = TouchScreenKeyboardType.EmailAddress; + m_CharacterValidation = CharacterValidation.EmailAddress; + break; + } + case ContentType.Password: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Password; + m_KeyboardType = TouchScreenKeyboardType.Default; + m_CharacterValidation = CharacterValidation.None; + break; + } + case ContentType.Pin: + { + m_LineType = LineType.SingleLine; + m_InputType = InputType.Password; + m_KeyboardType = TouchScreenKeyboardType.NumberPad; + m_CharacterValidation = CharacterValidation.Integer; + break; + } + default: + { + // Includes Custom type. Nothing should be enforced. + break; + } + } + + EnforceTextHOverflow(); + } + + void EnforceTextHOverflow() + { + if (m_TextComponent != null) + if (multiLine) + m_TextComponent.horizontalOverflow = HorizontalWrapMode.Wrap; + else + m_TextComponent.horizontalOverflow = HorizontalWrapMode.Overflow; + } + + void SetToCustomIfContentTypeIsNot(params ContentType[] allowedContentTypes) + { + if (contentType == ContentType.Custom) + return; + + for (int i = 0; i < allowedContentTypes.Length; i++) + if (contentType == allowedContentTypes[i]) + return; + + contentType = ContentType.Custom; + } + + void SetToCustom() + { + if (contentType == ContentType.Custom) + return; + + contentType = ContentType.Custom; + } + + protected override void DoStateTransition(SelectionState state, bool instant) + { + if (m_HasDoneFocusTransition) + state = SelectionState.Highlighted; + else if (state == SelectionState.Pressed) + m_HasDoneFocusTransition = true; + + base.DoStateTransition(state, instant); + } + + public virtual void CalculateLayoutInputHorizontal() {} + public virtual void CalculateLayoutInputVertical() {} + + public virtual float minWidth { get { return 0; } } + + public virtual float preferredWidth + { + get + { + if (textComponent == null) + return 0; + var settings = textComponent.GetGenerationSettings(Vector2.zero); + return textComponent.cachedTextGeneratorForLayout.GetPreferredWidth(m_Text, settings) / textComponent.pixelsPerUnit; + } + } + public virtual float flexibleWidth { get { return -1; } } + public virtual float minHeight { get { return 0; } } + + public virtual float preferredHeight + { + get + { + if (textComponent == null) + return 0; + var settings = textComponent.GetGenerationSettings(new Vector2(textComponent.rectTransform.rect.size.x, 0.0f)); + return textComponent.cachedTextGeneratorForLayout.GetPreferredHeight(m_Text, settings) / textComponent.pixelsPerUnit; + } + } + + public virtual float flexibleHeight { get { return -1; } } + public virtual int layoutPriority { get { return 1; } } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs.meta new file mode 100644 index 0000000..a11780b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/InputField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fd5762ccacc914a428b1e5e5ae0f0edb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs new file mode 100644 index 0000000..98e77f9 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs @@ -0,0 +1,74 @@ +using System; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [Serializable] + public struct Navigation : IEquatable<Navigation> + { + /* + * This looks like it's not flags, but it is flags, + * the reason is that Automatic is considered horizontal + * and verical mode combined + */ + [Flags] + public enum Mode + { + None = 0, // 0 No navigation + Horizontal = 1, // 1 Automatic horizontal navigation + Vertical = 2, // 10 Automatic vertical navigation + Automatic = 3, // 11 Automatic navigation in both dimensions + Explicit = 4, // Explicitly specified only + } + + // Which method of navigation will be used. + [FormerlySerializedAs("mode")] + [SerializeField] + private Mode m_Mode; + + // Game object selected when the joystick moves up. Used when navigation is set to "Explicit". + [FormerlySerializedAs("selectOnUp")] + [SerializeField] + private Selectable m_SelectOnUp; + + // Game object selected when the joystick moves down. Used when navigation is set to "Explicit". + [FormerlySerializedAs("selectOnDown")] + [SerializeField] + private Selectable m_SelectOnDown; + + // Game object selected when the joystick moves left. Used when navigation is set to "Explicit". + [FormerlySerializedAs("selectOnLeft")] + [SerializeField] + private Selectable m_SelectOnLeft; + + // Game object selected when the joystick moves right. Used when navigation is set to "Explicit". + [FormerlySerializedAs("selectOnRight")] + [SerializeField] + private Selectable m_SelectOnRight; + + public Mode mode { get { return m_Mode; } set { m_Mode = value; } } + public Selectable selectOnUp { get { return m_SelectOnUp; } set { m_SelectOnUp = value; } } + public Selectable selectOnDown { get { return m_SelectOnDown; } set { m_SelectOnDown = value; } } + public Selectable selectOnLeft { get { return m_SelectOnLeft; } set { m_SelectOnLeft = value; } } + public Selectable selectOnRight { get { return m_SelectOnRight; } set { m_SelectOnRight = value; } } + + static public Navigation defaultNavigation + { + get + { + var defaultNav = new Navigation(); + defaultNav.m_Mode = Mode.Automatic; + return defaultNav; + } + } + + public bool Equals(Navigation other) + { + return mode == other.mode && + selectOnUp == other.selectOnUp && + selectOnDown == other.selectOnDown && + selectOnLeft == other.selectOnLeft && + selectOnRight == other.selectOnRight; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs.meta new file mode 100644 index 0000000..a5f02d3 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Navigation.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7565fbbe496d6e749a2a17d8acb60c80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs new file mode 100644 index 0000000..106f15c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs @@ -0,0 +1,873 @@ +using System; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Scroll Rect", 37)] + [SelectionBase] + [ExecuteInEditMode] + [DisallowMultipleComponent] + [RequireComponent(typeof(RectTransform))] + public class ScrollRect + : UIBehaviour + , IInitializePotentialDragHandler + , IBeginDragHandler + , IEndDragHandler + , IDragHandler + , IScrollHandler + , ICanvasElement + , ILayoutElement + , ILayoutGroup + { + public enum MovementType + { + Unrestricted, // Unrestricted movement -- can scroll forever + Elastic, // Restricted but flexible -- can go past the edges, but springs back in place + Clamped, // Restricted movement where it's not possible to go past the edges + } + + public enum ScrollbarVisibility + { + Permanent, + AutoHide, + AutoHideAndExpandViewport, + } + + [Serializable] + public class ScrollRectEvent : UnityEvent<Vector2> {} + + [SerializeField] + private RectTransform m_Content; + public RectTransform content { get { return m_Content; } set { m_Content = value; } } + + [SerializeField] + private bool m_Horizontal = true; + public bool horizontal { get { return m_Horizontal; } set { m_Horizontal = value; } } + + [SerializeField] + private bool m_Vertical = true; + public bool vertical { get { return m_Vertical; } set { m_Vertical = value; } } + + [SerializeField] + private MovementType m_MovementType = MovementType.Elastic; + public MovementType movementType { get { return m_MovementType; } set { m_MovementType = value; } } + + [SerializeField] + private float m_Elasticity = 0.1f; // Only used for MovementType.Elastic + public float elasticity { get { return m_Elasticity; } set { m_Elasticity = value; } } + + [SerializeField] + private bool m_Inertia = true; + public bool inertia { get { return m_Inertia; } set { m_Inertia = value; } } + + [SerializeField] + private float m_DecelerationRate = 0.135f; // Only used when inertia is enabled + public float decelerationRate { get { return m_DecelerationRate; } set { m_DecelerationRate = value; } } + + [SerializeField] + private float m_ScrollSensitivity = 1.0f; + public float scrollSensitivity { get { return m_ScrollSensitivity; } set { m_ScrollSensitivity = value; } } + + [SerializeField] + private RectTransform m_Viewport; + public RectTransform viewport { get { return m_Viewport; } set { m_Viewport = value; SetDirtyCaching(); } } + + [SerializeField] + private Scrollbar m_HorizontalScrollbar; + public Scrollbar horizontalScrollbar + { + get + { + return m_HorizontalScrollbar; + } + set + { + if (m_HorizontalScrollbar) + m_HorizontalScrollbar.onValueChanged.RemoveListener(SetHorizontalNormalizedPosition); + m_HorizontalScrollbar = value; + if (m_HorizontalScrollbar) + m_HorizontalScrollbar.onValueChanged.AddListener(SetHorizontalNormalizedPosition); + SetDirtyCaching(); + } + } + + [SerializeField] + private Scrollbar m_VerticalScrollbar; + public Scrollbar verticalScrollbar + { + get + { + return m_VerticalScrollbar; + } + set + { + if (m_VerticalScrollbar) + m_VerticalScrollbar.onValueChanged.RemoveListener(SetVerticalNormalizedPosition); + m_VerticalScrollbar = value; + if (m_VerticalScrollbar) + m_VerticalScrollbar.onValueChanged.AddListener(SetVerticalNormalizedPosition); + SetDirtyCaching(); + } + } + + [SerializeField] + private ScrollbarVisibility m_HorizontalScrollbarVisibility; + public ScrollbarVisibility horizontalScrollbarVisibility { get { return m_HorizontalScrollbarVisibility; } set { m_HorizontalScrollbarVisibility = value; SetDirtyCaching(); } } + + [SerializeField] + private ScrollbarVisibility m_VerticalScrollbarVisibility; + public ScrollbarVisibility verticalScrollbarVisibility { get { return m_VerticalScrollbarVisibility; } set { m_VerticalScrollbarVisibility = value; SetDirtyCaching(); } } + + [SerializeField] + private float m_HorizontalScrollbarSpacing; + public float horizontalScrollbarSpacing { get { return m_HorizontalScrollbarSpacing; } set { m_HorizontalScrollbarSpacing = value; SetDirty(); } } + + [SerializeField] + private float m_VerticalScrollbarSpacing; + public float verticalScrollbarSpacing { get { return m_VerticalScrollbarSpacing; } set { m_VerticalScrollbarSpacing = value; SetDirty(); } } + + [SerializeField] + private ScrollRectEvent m_OnValueChanged = new ScrollRectEvent(); + public ScrollRectEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } } + + // The offset from handle position to mouse down position + private Vector2 m_PointerStartLocalCursor = Vector2.zero; + protected Vector2 m_ContentStartPosition = Vector2.zero; + + private RectTransform m_ViewRect; + + protected RectTransform viewRect + { + get + { + if (m_ViewRect == null) + m_ViewRect = m_Viewport; + if (m_ViewRect == null) + m_ViewRect = (RectTransform)transform; + return m_ViewRect; + } + } + + protected Bounds m_ContentBounds; + private Bounds m_ViewBounds; + + private Vector2 m_Velocity; + public Vector2 velocity { get { return m_Velocity; } set { m_Velocity = value; } } + + private bool m_Dragging; + + private Vector2 m_PrevPosition = Vector2.zero; + private Bounds m_PrevContentBounds; + private Bounds m_PrevViewBounds; + [NonSerialized] + private bool m_HasRebuiltLayout = false; + + private bool m_HSliderExpand; + private bool m_VSliderExpand; + private float m_HSliderHeight; + private float m_VSliderWidth; + + [System.NonSerialized] private RectTransform m_Rect; + private RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + private RectTransform m_HorizontalScrollbarRect; + private RectTransform m_VerticalScrollbarRect; + + private DrivenRectTransformTracker m_Tracker; + + protected ScrollRect() + {} + + public virtual void Rebuild(CanvasUpdate executing) + { + if (executing == CanvasUpdate.Prelayout) + { + UpdateCachedData(); + } + + if (executing == CanvasUpdate.PostLayout) + { + UpdateBounds(); + UpdateScrollbars(Vector2.zero); + UpdatePrevData(); + + m_HasRebuiltLayout = true; + } + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + void UpdateCachedData() + { + Transform transform = this.transform; + m_HorizontalScrollbarRect = m_HorizontalScrollbar == null ? null : m_HorizontalScrollbar.transform as RectTransform; + m_VerticalScrollbarRect = m_VerticalScrollbar == null ? null : m_VerticalScrollbar.transform as RectTransform; + + // These are true if either the elements are children, or they don't exist at all. + bool viewIsChild = (viewRect.parent == transform); + bool hScrollbarIsChild = (!m_HorizontalScrollbarRect || m_HorizontalScrollbarRect.parent == transform); + bool vScrollbarIsChild = (!m_VerticalScrollbarRect || m_VerticalScrollbarRect.parent == transform); + bool allAreChildren = (viewIsChild && hScrollbarIsChild && vScrollbarIsChild); + + m_HSliderExpand = allAreChildren && m_HorizontalScrollbarRect && horizontalScrollbarVisibility == ScrollbarVisibility.AutoHideAndExpandViewport; + m_VSliderExpand = allAreChildren && m_VerticalScrollbarRect && verticalScrollbarVisibility == ScrollbarVisibility.AutoHideAndExpandViewport; + m_HSliderHeight = (m_HorizontalScrollbarRect == null ? 0 : m_HorizontalScrollbarRect.rect.height); + m_VSliderWidth = (m_VerticalScrollbarRect == null ? 0 : m_VerticalScrollbarRect.rect.width); + } + + protected override void OnEnable() + { + base.OnEnable(); + + if (m_HorizontalScrollbar) + m_HorizontalScrollbar.onValueChanged.AddListener(SetHorizontalNormalizedPosition); + if (m_VerticalScrollbar) + m_VerticalScrollbar.onValueChanged.AddListener(SetVerticalNormalizedPosition); + + CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); + } + + protected override void OnDisable() + { + CanvasUpdateRegistry.UnRegisterCanvasElementForRebuild(this); + + if (m_HorizontalScrollbar) + m_HorizontalScrollbar.onValueChanged.RemoveListener(SetHorizontalNormalizedPosition); + if (m_VerticalScrollbar) + m_VerticalScrollbar.onValueChanged.RemoveListener(SetVerticalNormalizedPosition); + + m_HasRebuiltLayout = false; + m_Tracker.Clear(); + m_Velocity = Vector2.zero; + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + base.OnDisable(); + } + + public override bool IsActive() + { + return base.IsActive() && m_Content != null; + } + + private void EnsureLayoutHasRebuilt() + { + if (!m_HasRebuiltLayout && !CanvasUpdateRegistry.IsRebuildingLayout()) + Canvas.ForceUpdateCanvases(); + } + + public virtual void StopMovement() + { + m_Velocity = Vector2.zero; + } + + public virtual void OnScroll(PointerEventData data) + { + if (!IsActive()) + return; + + EnsureLayoutHasRebuilt(); + UpdateBounds(); + + Vector2 delta = data.scrollDelta; + // Down is positive for scroll events, while in UI system up is positive. + delta.y *= -1; + if (vertical && !horizontal) + { + if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) + delta.y = delta.x; + delta.x = 0; + } + if (horizontal && !vertical) + { + if (Mathf.Abs(delta.y) > Mathf.Abs(delta.x)) + delta.x = delta.y; + delta.y = 0; + } + + Vector2 position = m_Content.anchoredPosition; + position += delta * m_ScrollSensitivity; + if (m_MovementType == MovementType.Clamped) + position += CalculateOffset(position - m_Content.anchoredPosition); + + SetContentAnchoredPosition(position); + UpdateBounds(); + } + + public virtual void OnInitializePotentialDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + m_Velocity = Vector2.zero; + } + + public virtual void OnBeginDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + if (!IsActive()) + return; + + UpdateBounds(); + + m_PointerStartLocalCursor = Vector2.zero; + RectTransformUtility.ScreenPointToLocalPointInRectangle(viewRect, eventData.position, eventData.pressEventCamera, out m_PointerStartLocalCursor); + m_ContentStartPosition = m_Content.anchoredPosition; + m_Dragging = true; + } + + public virtual void OnEndDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + m_Dragging = false; + } + + public virtual void OnDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + if (!IsActive()) + return; + + Vector2 localCursor; + if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(viewRect, eventData.position, eventData.pressEventCamera, out localCursor)) + return; + + UpdateBounds(); + + var pointerDelta = localCursor - m_PointerStartLocalCursor; + Vector2 position = m_ContentStartPosition + pointerDelta; + + // Offset to get content into place in the view. + Vector2 offset = CalculateOffset(position - m_Content.anchoredPosition); + position += offset; + if (m_MovementType == MovementType.Elastic) + { + if (offset.x != 0) + position.x = position.x - RubberDelta(offset.x, m_ViewBounds.size.x); + if (offset.y != 0) + position.y = position.y - RubberDelta(offset.y, m_ViewBounds.size.y); + } + + SetContentAnchoredPosition(position); + } + + protected virtual void SetContentAnchoredPosition(Vector2 position) + { + if (!m_Horizontal) + position.x = m_Content.anchoredPosition.x; + if (!m_Vertical) + position.y = m_Content.anchoredPosition.y; + + if (position != m_Content.anchoredPosition) + { + m_Content.anchoredPosition = position; + UpdateBounds(); + } + } + + protected virtual void LateUpdate() + { + if (!m_Content) + return; + + EnsureLayoutHasRebuilt(); + UpdateScrollbarVisibility(); + UpdateBounds(); + float deltaTime = Time.unscaledDeltaTime; + Vector2 offset = CalculateOffset(Vector2.zero); + if (!m_Dragging && (offset != Vector2.zero || m_Velocity != Vector2.zero)) + { + Vector2 position = m_Content.anchoredPosition; + for (int axis = 0; axis < 2; axis++) + { + // Apply spring physics if movement is elastic and content has an offset from the view. + if (m_MovementType == MovementType.Elastic && offset[axis] != 0) + { + float speed = m_Velocity[axis]; + position[axis] = Mathf.SmoothDamp(m_Content.anchoredPosition[axis], m_Content.anchoredPosition[axis] + offset[axis], ref speed, m_Elasticity, Mathf.Infinity, deltaTime); + if (Mathf.Abs(speed) < 1) + speed = 0; + m_Velocity[axis] = speed; + } + // Else move content according to velocity with deceleration applied. + else if (m_Inertia) + { + m_Velocity[axis] *= Mathf.Pow(m_DecelerationRate, deltaTime); + if (Mathf.Abs(m_Velocity[axis]) < 1) + m_Velocity[axis] = 0; + position[axis] += m_Velocity[axis] * deltaTime; + } + // If we have neither elaticity or friction, there shouldn't be any velocity. + else + { + m_Velocity[axis] = 0; + } + } + + if (m_Velocity != Vector2.zero) + { + if (m_MovementType == MovementType.Clamped) + { + offset = CalculateOffset(position - m_Content.anchoredPosition); + position += offset; + } + + SetContentAnchoredPosition(position); + } + } + + if (m_Dragging && m_Inertia) + { + Vector3 newVelocity = (m_Content.anchoredPosition - m_PrevPosition) / deltaTime; + m_Velocity = Vector3.Lerp(m_Velocity, newVelocity, deltaTime * 10); + } + + if (m_ViewBounds != m_PrevViewBounds || m_ContentBounds != m_PrevContentBounds || m_Content.anchoredPosition != m_PrevPosition) + { + UpdateScrollbars(offset); + UISystemProfilerApi.AddMarker("ScrollRect.value", this); + m_OnValueChanged.Invoke(normalizedPosition); + UpdatePrevData(); + } + } + + protected void UpdatePrevData() + { + if (m_Content == null) + m_PrevPosition = Vector2.zero; + else + m_PrevPosition = m_Content.anchoredPosition; + m_PrevViewBounds = m_ViewBounds; + m_PrevContentBounds = m_ContentBounds; + } + + private void UpdateScrollbars(Vector2 offset) + { + if (m_HorizontalScrollbar) + { + if (m_ContentBounds.size.x > 0) + m_HorizontalScrollbar.size = Mathf.Clamp01((m_ViewBounds.size.x - Mathf.Abs(offset.x)) / m_ContentBounds.size.x); + else + m_HorizontalScrollbar.size = 1; + + m_HorizontalScrollbar.value = horizontalNormalizedPosition; + } + + if (m_VerticalScrollbar) + { + if (m_ContentBounds.size.y > 0) + m_VerticalScrollbar.size = Mathf.Clamp01((m_ViewBounds.size.y - Mathf.Abs(offset.y)) / m_ContentBounds.size.y); + else + m_VerticalScrollbar.size = 1; + + m_VerticalScrollbar.value = verticalNormalizedPosition; + } + } + + public Vector2 normalizedPosition + { + get + { + return new Vector2(horizontalNormalizedPosition, verticalNormalizedPosition); + } + set + { + SetNormalizedPosition(value.x, 0); + SetNormalizedPosition(value.y, 1); + } + } + + public float horizontalNormalizedPosition + { + get + { + UpdateBounds(); + if (m_ContentBounds.size.x <= m_ViewBounds.size.x) + return (m_ViewBounds.min.x > m_ContentBounds.min.x) ? 1 : 0; + return (m_ViewBounds.min.x - m_ContentBounds.min.x) / (m_ContentBounds.size.x - m_ViewBounds.size.x); + } + set + { + SetNormalizedPosition(value, 0); + } + } + + public float verticalNormalizedPosition + { + get + { + UpdateBounds(); + if (m_ContentBounds.size.y <= m_ViewBounds.size.y) + return (m_ViewBounds.min.y > m_ContentBounds.min.y) ? 1 : 0; + ; + return (m_ViewBounds.min.y - m_ContentBounds.min.y) / (m_ContentBounds.size.y - m_ViewBounds.size.y); + } + set + { + SetNormalizedPosition(value, 1); + } + } + + private void SetHorizontalNormalizedPosition(float value) { SetNormalizedPosition(value, 0); } + private void SetVerticalNormalizedPosition(float value) { SetNormalizedPosition(value, 1); } + + protected virtual void SetNormalizedPosition(float value, int axis) + { + EnsureLayoutHasRebuilt(); + UpdateBounds(); + // How much the content is larger than the view. + float hiddenLength = m_ContentBounds.size[axis] - m_ViewBounds.size[axis]; + // Where the position of the lower left corner of the content bounds should be, in the space of the view. + float contentBoundsMinPosition = m_ViewBounds.min[axis] - value * hiddenLength; + // The new content localPosition, in the space of the view. + float newLocalPosition = m_Content.localPosition[axis] + contentBoundsMinPosition - m_ContentBounds.min[axis]; + + Vector3 localPosition = m_Content.localPosition; + if (Mathf.Abs(localPosition[axis] - newLocalPosition) > 0.01f) + { + localPosition[axis] = newLocalPosition; + m_Content.localPosition = localPosition; + m_Velocity[axis] = 0; + UpdateBounds(); + } + } + + private static float RubberDelta(float overStretching, float viewSize) + { + return (1 - (1 / ((Mathf.Abs(overStretching) * 0.55f / viewSize) + 1))) * viewSize * Mathf.Sign(overStretching); + } + + protected override void OnRectTransformDimensionsChange() + { + SetDirty(); + } + + private bool hScrollingNeeded + { + get + { + if (Application.isPlaying) + return m_ContentBounds.size.x > m_ViewBounds.size.x + 0.01f; + return true; + } + } + private bool vScrollingNeeded + { + get + { + if (Application.isPlaying) + return m_ContentBounds.size.y > m_ViewBounds.size.y + 0.01f; + return true; + } + } + + public virtual void CalculateLayoutInputHorizontal() {} + public virtual void CalculateLayoutInputVertical() {} + + public virtual float minWidth { get { return -1; } } + public virtual float preferredWidth { get { return -1; } } + public virtual float flexibleWidth { get { return -1; } } + + public virtual float minHeight { get { return -1; } } + public virtual float preferredHeight { get { return -1; } } + public virtual float flexibleHeight { get { return -1; } } + + public virtual int layoutPriority { get { return -1; } } + + public virtual void SetLayoutHorizontal() + { + m_Tracker.Clear(); + + if (m_HSliderExpand || m_VSliderExpand) + { + m_Tracker.Add(this, viewRect, + DrivenTransformProperties.Anchors | + DrivenTransformProperties.SizeDelta | + DrivenTransformProperties.AnchoredPosition); + + // Make view full size to see if content fits. + viewRect.anchorMin = Vector2.zero; + viewRect.anchorMax = Vector2.one; + viewRect.sizeDelta = Vector2.zero; + viewRect.anchoredPosition = Vector2.zero; + + // Recalculate content layout with this size to see if it fits when there are no scrollbars. + LayoutRebuilder.ForceRebuildLayoutImmediate(content); + m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size); + m_ContentBounds = GetBounds(); + } + + // If it doesn't fit vertically, enable vertical scrollbar and shrink view horizontally to make room for it. + if (m_VSliderExpand && vScrollingNeeded) + { + viewRect.sizeDelta = new Vector2(-(m_VSliderWidth + m_VerticalScrollbarSpacing), viewRect.sizeDelta.y); + + // Recalculate content layout with this size to see if it fits vertically + // when there is a vertical scrollbar (which may reflowed the content to make it taller). + LayoutRebuilder.ForceRebuildLayoutImmediate(content); + m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size); + m_ContentBounds = GetBounds(); + } + + // If it doesn't fit horizontally, enable horizontal scrollbar and shrink view vertically to make room for it. + if (m_HSliderExpand && hScrollingNeeded) + { + viewRect.sizeDelta = new Vector2(viewRect.sizeDelta.x, -(m_HSliderHeight + m_HorizontalScrollbarSpacing)); + m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size); + m_ContentBounds = GetBounds(); + } + + // If the vertical slider didn't kick in the first time, and the horizontal one did, + // we need to check again if the vertical slider now needs to kick in. + // If it doesn't fit vertically, enable vertical scrollbar and shrink view horizontally to make room for it. + if (m_VSliderExpand && vScrollingNeeded && viewRect.sizeDelta.x == 0 && viewRect.sizeDelta.y < 0) + { + viewRect.sizeDelta = new Vector2(-(m_VSliderWidth + m_VerticalScrollbarSpacing), viewRect.sizeDelta.y); + } + } + + public virtual void SetLayoutVertical() + { + UpdateScrollbarLayout(); + m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size); + m_ContentBounds = GetBounds(); + } + + void UpdateScrollbarVisibility() + { + UpdateOneScrollbarVisibility(vScrollingNeeded, m_Vertical, m_VerticalScrollbarVisibility, m_VerticalScrollbar); + UpdateOneScrollbarVisibility(hScrollingNeeded, m_Horizontal, m_HorizontalScrollbarVisibility, m_HorizontalScrollbar); + } + + private static void UpdateOneScrollbarVisibility(bool xScrollingNeeded, bool xAxisEnabled, ScrollbarVisibility scrollbarVisibility, Scrollbar scrollbar) + { + if (scrollbar) + { + if (scrollbarVisibility == ScrollbarVisibility.Permanent) + { + if (scrollbar.gameObject.activeSelf != xAxisEnabled) + scrollbar.gameObject.SetActive(xAxisEnabled); + } + else + { + if (scrollbar.gameObject.activeSelf != xScrollingNeeded) + scrollbar.gameObject.SetActive(xScrollingNeeded); + } + } + } + + void UpdateScrollbarLayout() + { + if (m_VSliderExpand && m_HorizontalScrollbar) + { + m_Tracker.Add(this, m_HorizontalScrollbarRect, + DrivenTransformProperties.AnchorMinX | + DrivenTransformProperties.AnchorMaxX | + DrivenTransformProperties.SizeDeltaX | + DrivenTransformProperties.AnchoredPositionX); + m_HorizontalScrollbarRect.anchorMin = new Vector2(0, m_HorizontalScrollbarRect.anchorMin.y); + m_HorizontalScrollbarRect.anchorMax = new Vector2(1, m_HorizontalScrollbarRect.anchorMax.y); + m_HorizontalScrollbarRect.anchoredPosition = new Vector2(0, m_HorizontalScrollbarRect.anchoredPosition.y); + if (vScrollingNeeded) + m_HorizontalScrollbarRect.sizeDelta = new Vector2(-(m_VSliderWidth + m_VerticalScrollbarSpacing), m_HorizontalScrollbarRect.sizeDelta.y); + else + m_HorizontalScrollbarRect.sizeDelta = new Vector2(0, m_HorizontalScrollbarRect.sizeDelta.y); + } + + if (m_HSliderExpand && m_VerticalScrollbar) + { + m_Tracker.Add(this, m_VerticalScrollbarRect, + DrivenTransformProperties.AnchorMinY | + DrivenTransformProperties.AnchorMaxY | + DrivenTransformProperties.SizeDeltaY | + DrivenTransformProperties.AnchoredPositionY); + m_VerticalScrollbarRect.anchorMin = new Vector2(m_VerticalScrollbarRect.anchorMin.x, 0); + m_VerticalScrollbarRect.anchorMax = new Vector2(m_VerticalScrollbarRect.anchorMax.x, 1); + m_VerticalScrollbarRect.anchoredPosition = new Vector2(m_VerticalScrollbarRect.anchoredPosition.x, 0); + if (hScrollingNeeded) + m_VerticalScrollbarRect.sizeDelta = new Vector2(m_VerticalScrollbarRect.sizeDelta.x, -(m_HSliderHeight + m_HorizontalScrollbarSpacing)); + else + m_VerticalScrollbarRect.sizeDelta = new Vector2(m_VerticalScrollbarRect.sizeDelta.x, 0); + } + } + + protected void UpdateBounds() + { + m_ViewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size); + m_ContentBounds = GetBounds(); + + if (m_Content == null) + return; + + Vector3 contentSize = m_ContentBounds.size; + Vector3 contentPos = m_ContentBounds.center; + var contentPivot = m_Content.pivot; + AdjustBounds(ref m_ViewBounds, ref contentPivot, ref contentSize, ref contentPos); + m_ContentBounds.size = contentSize; + m_ContentBounds.center = contentPos; + + if (movementType == MovementType.Clamped) + { + // Adjust content so that content bounds bottom (right side) is never higher (to the left) than the view bounds bottom (right side). + // top (left side) is never lower (to the right) than the view bounds top (left side). + // All this can happen if content has shrunk. + // This works because content size is at least as big as view size (because of the call to InternalUpdateBounds above). + Vector2 delta = Vector2.zero; + if (m_ViewBounds.max.x > m_ContentBounds.max.x) + { + delta.x = Math.Min(m_ViewBounds.min.x - m_ContentBounds.min.x, m_ViewBounds.max.x - m_ContentBounds.max.x); + } + else if (m_ViewBounds.min.x < m_ContentBounds.min.x) + { + delta.x = Math.Max(m_ViewBounds.min.x - m_ContentBounds.min.x, m_ViewBounds.max.x - m_ContentBounds.max.x); + } + + if (m_ViewBounds.min.y < m_ContentBounds.min.y) + { + delta.y = Math.Max(m_ViewBounds.min.y - m_ContentBounds.min.y, m_ViewBounds.max.y - m_ContentBounds.max.y); + } + else if (m_ViewBounds.max.y > m_ContentBounds.max.y) + { + delta.y = Math.Min(m_ViewBounds.min.y - m_ContentBounds.min.y, m_ViewBounds.max.y - m_ContentBounds.max.y); + } + if (delta.sqrMagnitude > float.Epsilon) + { + contentPos = m_Content.anchoredPosition + delta; + if (!m_Horizontal) + contentPos.x = m_Content.anchoredPosition.x; + if (!m_Vertical) + contentPos.y = m_Content.anchoredPosition.y; + AdjustBounds(ref m_ViewBounds, ref contentPivot, ref contentSize, ref contentPos); + } + } + } + + internal static void AdjustBounds(ref Bounds viewBounds, ref Vector2 contentPivot, ref Vector3 contentSize, ref Vector3 contentPos) + { + // Make sure content bounds are at least as large as view by adding padding if not. + // One might think at first that if the content is smaller than the view, scrolling should be allowed. + // However, that's not how scroll views normally work. + // Scrolling is *only* possible when content is *larger* than view. + // We use the pivot of the content rect to decide in which directions the content bounds should be expanded. + // E.g. if pivot is at top, bounds are expanded downwards. + // This also works nicely when ContentSizeFitter is used on the content. + Vector3 excess = viewBounds.size - contentSize; + if (excess.x > 0) + { + contentPos.x -= excess.x * (contentPivot.x - 0.5f); + contentSize.x = viewBounds.size.x; + } + if (excess.y > 0) + { + contentPos.y -= excess.y * (contentPivot.y - 0.5f); + contentSize.y = viewBounds.size.y; + } + } + + private readonly Vector3[] m_Corners = new Vector3[4]; + private Bounds GetBounds() + { + if (m_Content == null) + return new Bounds(); + m_Content.GetWorldCorners(m_Corners); + var viewWorldToLocalMatrix = viewRect.worldToLocalMatrix; + return InternalGetBounds(m_Corners, ref viewWorldToLocalMatrix); + } + + internal static Bounds InternalGetBounds(Vector3[] corners, ref Matrix4x4 viewWorldToLocalMatrix) + { + var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); + var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue); + + for (int j = 0; j < 4; j++) + { + Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(corners[j]); + vMin = Vector3.Min(v, vMin); + vMax = Vector3.Max(v, vMax); + } + + var bounds = new Bounds(vMin, Vector3.zero); + bounds.Encapsulate(vMax); + return bounds; + } + + private Vector2 CalculateOffset(Vector2 delta) + { + return InternalCalculateOffset(ref m_ViewBounds, ref m_ContentBounds, m_Horizontal, m_Vertical, m_MovementType, ref delta); + } + + internal static Vector2 InternalCalculateOffset(ref Bounds viewBounds, ref Bounds contentBounds, bool horizontal, bool vertical, MovementType movementType, ref Vector2 delta) + { + Vector2 offset = Vector2.zero; + if (movementType == MovementType.Unrestricted) + return offset; + + Vector2 min = contentBounds.min; + Vector2 max = contentBounds.max; + + if (horizontal) + { + min.x += delta.x; + max.x += delta.x; + if (min.x > viewBounds.min.x) + offset.x = viewBounds.min.x - min.x; + else if (max.x < viewBounds.max.x) + offset.x = viewBounds.max.x - max.x; + } + + if (vertical) + { + min.y += delta.y; + max.y += delta.y; + if (max.y < viewBounds.max.y) + offset.y = viewBounds.max.y - max.y; + else if (min.y > viewBounds.min.y) + offset.y = viewBounds.min.y - min.y; + } + + return offset; + } + + protected void SetDirty() + { + if (!IsActive()) + return; + + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + protected void SetDirtyCaching() + { + if (!IsActive()) + return; + + CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + SetDirtyCaching(); + } + + #endif + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs.meta new file mode 100644 index 0000000..98d9f63 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ScrollRect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 209674c43848ab24e8778e3f7bcd0f11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs new file mode 100644 index 0000000..c280305 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Scrollbar", 34)] + [RequireComponent(typeof(RectTransform))] + public class Scrollbar + : Selectable + , IBeginDragHandler + , IDragHandler + , IInitializePotentialDragHandler + , ICanvasElement + { + public enum Direction + { + LeftToRight, + RightToLeft, + BottomToTop, + TopToBottom, + } + + [Serializable] + public class ScrollEvent : UnityEvent<float> {} + + [SerializeField] + private RectTransform m_HandleRect; + public RectTransform handleRect { get { return m_HandleRect; } set { if (SetPropertyUtility.SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } } + + // Direction of movement. + [SerializeField] + private Direction m_Direction = Direction.LeftToRight; + public Direction direction { get { return m_Direction; } set { if (SetPropertyUtility.SetStruct(ref m_Direction, value)) UpdateVisuals(); } } + + protected Scrollbar() + {} + + // Scroll bar's current value in 0 to 1 range. + [Range(0f, 1f)] + [SerializeField] + private float m_Value; + public float value + { + get + { + float val = m_Value; + if (m_NumberOfSteps > 1) + val = Mathf.Round(val * (m_NumberOfSteps - 1)) / (m_NumberOfSteps - 1); + return val; + } + set + { + Set(value); + } + } + + // Scroll bar's current size in 0 to 1 range. + [Range(0f, 1f)] + [SerializeField] + private float m_Size = 0.2f; + public float size { get { return m_Size; } set { if (SetPropertyUtility.SetStruct(ref m_Size, Mathf.Clamp01(value))) UpdateVisuals(); } } + + // Number of steps the scroll bar should be divided into. For example 5 means possible values of 0, 0.25, 0.5, 0.75, and 1.0. + [Range(0, 11)] + [SerializeField] + private int m_NumberOfSteps = 0; + public int numberOfSteps { get { return m_NumberOfSteps; } set { if (SetPropertyUtility.SetStruct(ref m_NumberOfSteps, value)) { Set(m_Value); UpdateVisuals(); } } } + + [Space(6)] + + // Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers. + [SerializeField] + private ScrollEvent m_OnValueChanged = new ScrollEvent(); + public ScrollEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } } + + // Private fields + + private RectTransform m_ContainerRect; + + // The offset from handle position to mouse down position + private Vector2 m_Offset = Vector2.zero; + + // Size of each step. + float stepSize { get { return (m_NumberOfSteps > 1) ? 1f / (m_NumberOfSteps - 1) : 0.1f; } } + + private DrivenRectTransformTracker m_Tracker; + private Coroutine m_PointerDownRepeat; + private bool isPointerDownAndNotDragging = false; + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + m_Size = Mathf.Clamp01(m_Size); + + //This can be invoked before OnEnabled is called. So we shouldn't be accessing other objects, before OnEnable is called. + if (IsActive()) + { + UpdateCachedReferences(); + Set(m_Value, false); + // Update rects since other things might affect them even if value didn't change. + UpdateVisuals(); + } + + var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this); + if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying) + CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); + } + +#endif // if UNITY_EDITOR + + public virtual void Rebuild(CanvasUpdate executing) + { +#if UNITY_EDITOR + if (executing == CanvasUpdate.Prelayout) + onValueChanged.Invoke(value); +#endif + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + protected override void OnEnable() + { + base.OnEnable(); + UpdateCachedReferences(); + Set(m_Value, false); + // Update rects since they need to be initialized correctly. + UpdateVisuals(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + base.OnDisable(); + } + + void UpdateCachedReferences() + { + if (m_HandleRect && m_HandleRect.parent != null) + m_ContainerRect = m_HandleRect.parent.GetComponent<RectTransform>(); + else + m_ContainerRect = null; + } + + // Update the visible Image. + void Set(float input) + { + Set(input, true); + } + + void Set(float input, bool sendCallback) + { + float currentValue = m_Value; + // Clamp the input + m_Value = Mathf.Clamp01(input); + + // If the stepped value doesn't match the last one, it's time to update + if (currentValue == value) + return; + + UpdateVisuals(); + if (sendCallback) + { + UISystemProfilerApi.AddMarker("Scrollbar.value", this); + m_OnValueChanged.Invoke(value); + } + } + + protected override void OnRectTransformDimensionsChange() + { + base.OnRectTransformDimensionsChange(); + + //This can be invoked before OnEnabled is called. So we shouldn't be accessing other objects, before OnEnable is called. + if (!IsActive()) + return; + + UpdateVisuals(); + } + + enum Axis + { + Horizontal = 0, + Vertical = 1 + } + + Axis axis { get { return (m_Direction == Direction.LeftToRight || m_Direction == Direction.RightToLeft) ? Axis.Horizontal : Axis.Vertical; } } + bool reverseValue { get { return m_Direction == Direction.RightToLeft || m_Direction == Direction.TopToBottom; } } + + // Force-update the scroll bar. Useful if you've changed the properties and want it to update visually. + private void UpdateVisuals() + { +#if UNITY_EDITOR + if (!Application.isPlaying) + UpdateCachedReferences(); +#endif + m_Tracker.Clear(); + + if (m_ContainerRect != null) + { + m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors); + Vector2 anchorMin = Vector2.zero; + Vector2 anchorMax = Vector2.one; + + float movement = value * (1 - size); + if (reverseValue) + { + anchorMin[(int)axis] = 1 - movement - size; + anchorMax[(int)axis] = 1 - movement; + } + else + { + anchorMin[(int)axis] = movement; + anchorMax[(int)axis] = movement + size; + } + + m_HandleRect.anchorMin = anchorMin; + m_HandleRect.anchorMax = anchorMax; + } + } + + // Update the scroll bar's position based on the mouse. + void UpdateDrag(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + if (m_ContainerRect == null) + return; + + Vector2 localCursor; + if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(m_ContainerRect, eventData.position, eventData.pressEventCamera, out localCursor)) + return; + + Vector2 handleCenterRelativeToContainerCorner = localCursor - m_Offset - m_ContainerRect.rect.position; + Vector2 handleCorner = handleCenterRelativeToContainerCorner - (m_HandleRect.rect.size - m_HandleRect.sizeDelta) * 0.5f; + + float parentSize = axis == 0 ? m_ContainerRect.rect.width : m_ContainerRect.rect.height; + float remainingSize = parentSize * (1 - size); + if (remainingSize <= 0) + return; + + switch (m_Direction) + { + case Direction.LeftToRight: + Set(handleCorner.x / remainingSize); + break; + case Direction.RightToLeft: + Set(1f - (handleCorner.x / remainingSize)); + break; + case Direction.BottomToTop: + Set(handleCorner.y / remainingSize); + break; + case Direction.TopToBottom: + Set(1f - (handleCorner.y / remainingSize)); + break; + } + } + + private bool MayDrag(PointerEventData eventData) + { + return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left; + } + + public virtual void OnBeginDrag(PointerEventData eventData) + { + isPointerDownAndNotDragging = false; + + if (!MayDrag(eventData)) + return; + + if (m_ContainerRect == null) + return; + + m_Offset = Vector2.zero; + if (RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera)) + { + Vector2 localMousePos; + if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos)) + m_Offset = localMousePos - m_HandleRect.rect.center; + } + } + + public virtual void OnDrag(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + if (m_ContainerRect != null) + UpdateDrag(eventData); + } + + public override void OnPointerDown(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + base.OnPointerDown(eventData); + isPointerDownAndNotDragging = true; + m_PointerDownRepeat = StartCoroutine(ClickRepeat(eventData)); + } + + protected IEnumerator ClickRepeat(PointerEventData eventData) + { + while (isPointerDownAndNotDragging) + { + if (!RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera)) + { + Vector2 localMousePos; + if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos)) + { + var axisCoordinate = axis == 0 ? localMousePos.x : localMousePos.y; + if (axisCoordinate < 0) + value -= size; + else + value += size; + } + } + yield return new WaitForEndOfFrame(); + } + StopCoroutine(m_PointerDownRepeat); + } + + public override void OnPointerUp(PointerEventData eventData) + { + base.OnPointerUp(eventData); + isPointerDownAndNotDragging = false; + } + + public override void OnMove(AxisEventData eventData) + { + if (!IsActive() || !IsInteractable()) + { + base.OnMove(eventData); + return; + } + + switch (eventData.moveDir) + { + case MoveDirection.Left: + if (axis == Axis.Horizontal && FindSelectableOnLeft() == null) + Set(reverseValue ? value + stepSize : value - stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Right: + if (axis == Axis.Horizontal && FindSelectableOnRight() == null) + Set(reverseValue ? value - stepSize : value + stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Up: + if (axis == Axis.Vertical && FindSelectableOnUp() == null) + Set(reverseValue ? value - stepSize : value + stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Down: + if (axis == Axis.Vertical && FindSelectableOnDown() == null) + Set(reverseValue ? value + stepSize : value - stepSize); + else + base.OnMove(eventData); + break; + } + } + + public override Selectable FindSelectableOnLeft() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal) + return null; + return base.FindSelectableOnLeft(); + } + + public override Selectable FindSelectableOnRight() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal) + return null; + return base.FindSelectableOnRight(); + } + + public override Selectable FindSelectableOnUp() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical) + return null; + return base.FindSelectableOnUp(); + } + + public override Selectable FindSelectableOnDown() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical) + return null; + return base.FindSelectableOnDown(); + } + + public virtual void OnInitializePotentialDrag(PointerEventData eventData) + { + eventData.useDragThreshold = false; + } + + public void SetDirection(Direction direction, bool includeRectLayouts) + { + Axis oldAxis = axis; + bool oldReverse = reverseValue; + this.direction = direction; + + if (!includeRectLayouts) + return; + + if (axis != oldAxis) + RectTransformUtility.FlipLayoutAxes(transform as RectTransform, true, true); + + if (reverseValue != oldReverse) + RectTransformUtility.FlipLayoutOnAxis(transform as RectTransform, (int)axis, true, true); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs.meta new file mode 100644 index 0000000..04b16c4 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Scrollbar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 340d739069b7eae4daa7634ca999bcf8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs new file mode 100644 index 0000000..9cc6178 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs @@ -0,0 +1,672 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Serialization; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + // Simple selectable object - derived from to create a control. + [AddComponentMenu("UI/Selectable", 70)] + [ExecuteInEditMode] + [SelectionBase] + [DisallowMultipleComponent] + public class Selectable + : + UIBehaviour, + IMoveHandler, // Input>Horizontal\VerticalÒÆ¶¯Ê±ÊÕµ½Õâ¸öÏûÏ¢ + IPointerDownHandler, IPointerUpHandler, // µã»÷click + IPointerEnterHandler, IPointerExitHandler, // ÐüÍ£hover + ISelectHandler, IDeselectHandler // navigation»ñµÃ½¹µãʱÊÕµ½Õâ¸öÏûÏ¢ + { + // Selection state + + // µ±Ç°³¡¾°ÖеÄSelectable×é¼þ + // List of all the selectable objects currently active in the scene + private static List<Selectable> s_List = new List<Selectable>(); + public static List<Selectable> allSelectables { get { return s_List; } } + + // Navigation information. + [FormerlySerializedAs("navigation")] + [SerializeField] + private Navigation m_Navigation = Navigation.defaultNavigation; + + // Highlighting state + public enum Transition + { + None, + ColorTint, + SpriteSwap, + Animation + } + + // Type of the transition that occurs when the button state changes. + [FormerlySerializedAs("transition")] + [SerializeField] + private Transition m_Transition = Transition.ColorTint; + + // Colors used for a color tint-based transition. + [FormerlySerializedAs("colors")] + [SerializeField] + private ColorBlock m_Colors = ColorBlock.defaultColorBlock; + + // Sprites used for a Image swap-based transition. + [FormerlySerializedAs("spriteState")] + [SerializeField] + private SpriteState m_SpriteState; + + [FormerlySerializedAs("animationTriggers")] + [SerializeField] + private AnimationTriggers m_AnimationTriggers = new AnimationTriggers(); + + [Tooltip("Can the Selectable be interacted with?")] + [SerializeField] + private bool m_Interactable = true; + + //c m_TargetGraphic Ö»ÊÇÓÃÀ´×öչʾ£¬Õâ¸ö±äÁ¿²»»áÓÃÀ´½øÐÐÉäÏß¼ì²â£¬ÔÚAwake()Àï×¢Ê͵ôÒ²»¹»á´¥·¢µã»÷ʼþ + // Graphic that will be colored. + [FormerlySerializedAs("highlightGraphic")] + [FormerlySerializedAs("m_HighlightGraphic")] + [SerializeField] + private Graphic m_TargetGraphic; + + + private bool m_GroupsAllowInteraction = true; + + private SelectionState m_CurrentSelectionState; + + public Navigation navigation { get { return m_Navigation; } set { if (SetPropertyUtility.SetStruct(ref m_Navigation, value)) OnSetProperty(); } } + public Transition transition { get { return m_Transition; } set { if (SetPropertyUtility.SetStruct(ref m_Transition, value)) OnSetProperty(); } } + public ColorBlock colors { get { return m_Colors; } set { if (SetPropertyUtility.SetStruct(ref m_Colors, value)) OnSetProperty(); } } + public SpriteState spriteState { get { return m_SpriteState; } set { if (SetPropertyUtility.SetStruct(ref m_SpriteState, value)) OnSetProperty(); } } + public AnimationTriggers animationTriggers { get { return m_AnimationTriggers; } set { if (SetPropertyUtility.SetClass(ref m_AnimationTriggers, value)) OnSetProperty(); } } + public Graphic targetGraphic { + get { + return m_TargetGraphic; + } + set { + if (SetPropertyUtility.SetClass(ref m_TargetGraphic, value)) + OnSetProperty(); + } + } + public bool interactable + { + get { return m_Interactable; } + set + { + if (SetPropertyUtility.SetStruct(ref m_Interactable, value)) + { + if (!m_Interactable && EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject) + EventSystem.current.SetSelectedGameObject(null); + if (m_Interactable) + UpdateSelectionState(null); + OnSetProperty(); + } + } + } + + private bool isPointerInside { get; set; } + private bool isPointerDown { get; set; } + private bool hasSelection { get; set; } + + protected Selectable() + {} + + // Convenience function that converts the Graphic to a Image, if possible + public Image image + { + get { + return m_TargetGraphic as Image; + } + set { + m_TargetGraphic = value; + } + } + + // Get the animator + public Animator animator + { + get { return GetComponent<Animator>(); } + } + + protected override void Awake() + { + if (m_TargetGraphic == null) + m_TargetGraphic = GetComponent<Graphic>(); + } + + private readonly List<CanvasGroup> m_CanvasGroupCache = new List<CanvasGroup>(); + protected override void OnCanvasGroupChanged() + { + // Figure out if parent groups allow interaction + // If no interaction is alowed... then we need + // to not do that :) + var groupAllowInteraction = true; + Transform t = transform; + while (t != null) + { + t.GetComponents(m_CanvasGroupCache); + bool shouldBreak = false; + for (var i = 0; i < m_CanvasGroupCache.Count; i++) + { + // if the parent group does not allow interaction + // we need to break + if (!m_CanvasGroupCache[i].interactable) + { + groupAllowInteraction = false; + shouldBreak = true; + } + // if this is a 'fresh' group, then break + // as we should not consider parents + if (m_CanvasGroupCache[i].ignoreParentGroups) + shouldBreak = true; + } + if (shouldBreak) + break; + + t = t.parent; + } + + if (groupAllowInteraction != m_GroupsAllowInteraction) + { + m_GroupsAllowInteraction = groupAllowInteraction; + OnSetProperty(); + } + } + + public virtual bool IsInteractable() + { + return m_GroupsAllowInteraction && m_Interactable; + } + + // Call from unity if animation properties have changed + protected override void OnDidApplyAnimationProperties() + { + OnSetProperty(); + } + + // Select on enable and add to the list. + protected override void OnEnable() + { + base.OnEnable(); + + s_List.Add(this); + var state = SelectionState.Normal; + + // The button will be highlighted even in some cases where it shouldn't. + // For example: We only want to set the State as Highlighted if the StandaloneInputModule.m_CurrentInputMode == InputMode.Buttons + // But we dont have access to this, and it might not apply to other InputModules. + // TODO: figure out how to solve this. Case 617348. + if (hasSelection) + state = SelectionState.Highlighted; + + m_CurrentSelectionState = state; + InternalEvaluateAndTransitionToSelectionState(true); + } + + private void OnSetProperty() + { +#if UNITY_EDITOR + if (!Application.isPlaying) + InternalEvaluateAndTransitionToSelectionState(true); + else +#endif + InternalEvaluateAndTransitionToSelectionState(false); + } + + // Remove from the list. + protected override void OnDisable() + { + s_List.Remove(this); + InstantClearState(); + base.OnDisable(); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + m_Colors.fadeDuration = Mathf.Max(m_Colors.fadeDuration, 0.0f); + + // OnValidate can be called before OnEnable, this makes it unsafe to access other components + // since they might not have been initialized yet. + // OnSetProperty potentially access Animator or Graphics. (case 618186) + if (isActiveAndEnabled) + { + if (!interactable && EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject) + EventSystem.current.SetSelectedGameObject(null); + // Need to clear out the override image on the target... + DoSpriteSwap(null); + + // If the transition mode got changed, we need to clear all the transitions, since we don't know what the old transition mode was. + StartColorTween(Color.white, true); + TriggerAnimation(m_AnimationTriggers.normalTrigger); + + // And now go to the right state. + InternalEvaluateAndTransitionToSelectionState(true); + } + } + + protected override void Reset() + { + m_TargetGraphic = GetComponent<Graphic>(); + } + +#endif // if UNITY_EDITOR + + protected SelectionState currentSelectionState + { + get { return m_CurrentSelectionState; } + } + + protected virtual void InstantClearState() + { + string triggerName = m_AnimationTriggers.normalTrigger; + + isPointerInside = false; + isPointerDown = false; + hasSelection = false; + + switch (m_Transition) + { + case Transition.ColorTint: + StartColorTween(Color.white, true); + break; + case Transition.SpriteSwap: + DoSpriteSwap(null); + break; + case Transition.Animation: + TriggerAnimation(triggerName); + break; + } + } + + protected virtual void DoStateTransition(SelectionState state, bool instant) + { + Color tintColor; + Sprite transitionSprite; + string triggerName; + + switch (state) + { + case SelectionState.Normal: + tintColor = m_Colors.normalColor; + transitionSprite = null; + triggerName = m_AnimationTriggers.normalTrigger; + break; + case SelectionState.Highlighted: + tintColor = m_Colors.highlightedColor; + transitionSprite = m_SpriteState.highlightedSprite; + triggerName = m_AnimationTriggers.highlightedTrigger; + break; + case SelectionState.Pressed: + tintColor = m_Colors.pressedColor; + transitionSprite = m_SpriteState.pressedSprite; + triggerName = m_AnimationTriggers.pressedTrigger; + break; + case SelectionState.Disabled: + tintColor = m_Colors.disabledColor; + transitionSprite = m_SpriteState.disabledSprite; + triggerName = m_AnimationTriggers.disabledTrigger; + break; + default: + tintColor = Color.black; + transitionSprite = null; + triggerName = string.Empty; + break; + } + + if (gameObject.activeInHierarchy) + { + switch (m_Transition) + { + case Transition.ColorTint: + StartColorTween(tintColor * m_Colors.colorMultiplier, instant); + break; + case Transition.SpriteSwap: + DoSpriteSwap(transitionSprite); + break; + case Transition.Animation: + TriggerAnimation(triggerName); + break; + } + } + } + + protected enum SelectionState + { + Normal, + Highlighted, + Pressed, + Disabled + } + + // Selection logic + + // Find the next selectable object in the specified world-space direction. + public Selectable FindSelectable(Vector3 dir) + { + dir = dir.normalized; + Vector3 localDir = Quaternion.Inverse(transform.rotation) * dir; + Vector3 pos = transform.TransformPoint(GetPointOnRectEdge(transform as RectTransform, localDir)); + float maxScore = Mathf.NegativeInfinity; + Selectable bestPick = null; + for (int i = 0; i < s_List.Count; ++i) // ±éÀúµ±Ç°³¡¾°ÖеÄËùÓÐselectable×é¼þ + { + Selectable sel = s_List[i]; + + if (sel == this || sel == null) + continue; + + if (!sel.IsInteractable() || sel.navigation.mode == Navigation.Mode.None) + continue; + + var selRect = sel.transform as RectTransform; + Vector3 selCenter = selRect != null ? (Vector3)selRect.rect.center : Vector3.zero; + Vector3 myVector = sel.transform.TransformPoint(selCenter) - pos; + + // Value that is the distance out along the direction. + float dot = Vector3.Dot(dir, myVector); + + // Skip elements that are in the wrong direction or which have zero distance. + // This also ensures that the scoring formula below will not have a division by zero error. + if (dot <= 0) + continue; + + // This scoring function has two priorities: + // - Score higher for positions that are closer. + // - Score higher for positions that are located in the right direction. + // This scoring function combines both of these criteria. + // It can be seen as this: + // Dot (dir, myVector.normalized) / myVector.magnitude + // The first part equals 1 if the direction of myVector is the same as dir, and 0 if it's orthogonal. + // The second part scores lower the greater the distance is by dividing by the distance. + // The formula below is equivalent but more optimized. + // + // If a given score is chosen, the positions that evaluate to that score will form a circle + // that touches pos and whose center is located along dir. A way to visualize the resulting functionality is this: + // From the position pos, blow up a circular balloon so it grows in the direction of dir. + // The first Selectable whose center the circular balloon touches is the one that's chosen. + float score = dot / myVector.sqrMagnitude; + + if (score > maxScore) + { + maxScore = score; + bestPick = sel; + } + } + return bestPick; + } + + private static Vector3 GetPointOnRectEdge(RectTransform rect, Vector2 dir) + { + if (rect == null) + return Vector3.zero; + if (dir != Vector2.zero) + dir /= Mathf.Max(Mathf.Abs(dir.x), Mathf.Abs(dir.y)); + dir = rect.rect.center + Vector2.Scale(rect.rect.size, dir * 0.5f); + return dir; + } + + // Convenience function -- change the selection to the specified object if it's not null and happens to be active. + void Navigate(AxisEventData eventData, Selectable sel) + { + if (sel != null && sel.IsActive()) + eventData.selectedObject = sel.gameObject; // »á·¢ËÍÒ»¸öselectHandlerʼþ + } + + // Find the selectable object to the left of this one. + public virtual Selectable FindSelectableOnLeft() + { + if (m_Navigation.mode == Navigation.Mode.Explicit) + { + return m_Navigation.selectOnLeft; + } + if ((m_Navigation.mode & Navigation.Mode.Horizontal) != 0) + { + return FindSelectable(transform.rotation * Vector3.left); + } + return null; + } + + // Find the selectable object to the right of this one. + public virtual Selectable FindSelectableOnRight() + { + if (m_Navigation.mode == Navigation.Mode.Explicit) + { + return m_Navigation.selectOnRight; + } + if ((m_Navigation.mode & Navigation.Mode.Horizontal) != 0) + { + return FindSelectable(transform.rotation * Vector3.right); + } + return null; + } + + // Find the selectable object above this one + public virtual Selectable FindSelectableOnUp() + { + if (m_Navigation.mode == Navigation.Mode.Explicit) + { + return m_Navigation.selectOnUp; + } + if ((m_Navigation.mode & Navigation.Mode.Vertical) != 0) + { + return FindSelectable(transform.rotation * Vector3.up); + } + return null; + } + + // Find the selectable object below this one. + public virtual Selectable FindSelectableOnDown() + { + if (m_Navigation.mode == Navigation.Mode.Explicit) + { + return m_Navigation.selectOnDown; + } + if ((m_Navigation.mode & Navigation.Mode.Vertical) != 0) + { + return FindSelectable(transform.rotation * Vector3.down); + } + return null; + } + + // input>horizontal\vertical²úÉúÕâ¸öʼþ£¬ + public virtual void OnMove(AxisEventData eventData) + { + LogHelper.Log("OnMove() " + gameObject.name ); + + switch (eventData.moveDir) + { + case MoveDirection.Right: + Navigate(eventData, FindSelectableOnRight()); // »áÏòÏÂÒ»¸öselectableObj·¢ËÍÒ»¸öOnSelectÏûÏ¢ + break; + + case MoveDirection.Up: + Navigate(eventData, FindSelectableOnUp()); + break; + + case MoveDirection.Left: + Navigate(eventData, FindSelectableOnLeft()); + break; + + case MoveDirection.Down: + Navigate(eventData, FindSelectableOnDown()); + break; + } + } + + void StartColorTween(Color targetColor, bool instant) + { + if (m_TargetGraphic == null) + return; + + // ÆðÒ»¸öгÌ×ötween¶¯» + m_TargetGraphic.CrossFadeColor(targetColor, instant ? 0f : m_Colors.fadeDuration, true, true); + } + + void DoSpriteSwap(Sprite newSprite) + { + if (image == null) + return; + + image.overrideSprite = newSprite; + } + + void TriggerAnimation(string triggername) + { + if (transition != Transition.Animation || animator == null || !animator.isActiveAndEnabled || !animator.hasBoundPlayables || string.IsNullOrEmpty(triggername)) + return; + + LogHelper.Log("trigger animation"); + + animator.ResetTrigger(m_AnimationTriggers.normalTrigger); + animator.ResetTrigger(m_AnimationTriggers.pressedTrigger); + animator.ResetTrigger(m_AnimationTriggers.highlightedTrigger); + animator.ResetTrigger(m_AnimationTriggers.disabledTrigger); + + animator.SetTrigger(triggername); + } + + // Whether the control should be 'selected'. + protected bool IsHighlighted(BaseEventData eventData) + { + if (!IsActive()) + return false; + + if (IsPressed()) + return false; + + bool selected = hasSelection; + if (eventData is PointerEventData) + { + var pointerData = eventData as PointerEventData; + selected |= + (isPointerDown && !isPointerInside && pointerData.pointerPress == gameObject) // This object pressed, but pointer moved off + || (!isPointerDown && isPointerInside && pointerData.pointerPress == gameObject) // This object pressed, but pointer released over (PointerUp event) + || (!isPointerDown && isPointerInside && pointerData.pointerPress == null); // Nothing pressed, but pointer is over + } + else + { + selected |= isPointerInside; + } + return selected; + } + + [Obsolete("Is Pressed no longer requires eventData", false)] + protected bool IsPressed(BaseEventData eventData) + { + return IsPressed(); + } + + // Whether the control should be pressed. + protected bool IsPressed() + { + if (!IsActive()) + return false; + + return isPointerInside && isPointerDown; + } + + // The current visual state of the control. + protected void UpdateSelectionState(BaseEventData eventData) + { + if (IsPressed()) + { + m_CurrentSelectionState = SelectionState.Pressed; + return; + } + + if (IsHighlighted(eventData)) + { + m_CurrentSelectionState = SelectionState.Highlighted; + return; + } + + m_CurrentSelectionState = SelectionState.Normal; + } + + // ¸üÐÂ״̬²¥·Å¶¯» + // Change the button to the correct state + private void EvaluateAndTransitionToSelectionState(BaseEventData eventData) + { + if (!IsActive() || !IsInteractable()) + return; + + UpdateSelectionState(eventData); + InternalEvaluateAndTransitionToSelectionState(false); + } + + private void InternalEvaluateAndTransitionToSelectionState(bool instant) + { + var transitionState = m_CurrentSelectionState; + if (IsActive() && !IsInteractable()) + transitionState = SelectionState.Disabled; + DoStateTransition(transitionState, instant); + } + + public virtual void OnPointerDown(PointerEventData eventData) + { + LogHelper.Log("OnPointerDown() "+ gameObject.name); + + if (eventData.button != PointerEventData.InputButton.Left) + return; + + // Selection tracking + if (IsInteractable() && navigation.mode != Navigation.Mode.None && EventSystem.current != null) + EventSystem.current.SetSelectedGameObject(gameObject, eventData); // Ñ¡ÖÐÕâ¸öUI×é¼þ + + isPointerDown = true; + EvaluateAndTransitionToSelectionState(eventData); + } + + public virtual void OnPointerUp(PointerEventData eventData) + { + LogHelper.Log("OnPointerUp() " + gameObject.name); + + if (eventData.button != PointerEventData.InputButton.Left) + return; + + isPointerDown = false; + EvaluateAndTransitionToSelectionState(eventData); + } + + public virtual void OnPointerEnter(PointerEventData eventData) + { + LogHelper.Log("OnPointerEnter() " + gameObject.name); + + isPointerInside = true; + EvaluateAndTransitionToSelectionState(eventData); + } + + public virtual void OnPointerExit(PointerEventData eventData) + { + LogHelper.Log("OnPointerExit() " + gameObject.name); + + isPointerInside = false; + EvaluateAndTransitionToSelectionState(eventData); + } + + // ±»Ñ¡ÖÐ + public virtual void OnSelect(BaseEventData eventData) + { + LogHelper.Log("OnSelect() " + gameObject.name); + hasSelection = true; + EvaluateAndTransitionToSelectionState(eventData); + } + + public virtual void OnDeselect(BaseEventData eventData) + { + LogHelper.Log("OnDeselect() " + gameObject.name); + hasSelection = false; + EvaluateAndTransitionToSelectionState(eventData); + } + + public virtual void Select() + { + if (EventSystem.current == null || EventSystem.current.alreadySelecting) + return; + + EventSystem.current.SetSelectedGameObject(gameObject); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs.meta new file mode 100644 index 0000000..394fcbd --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Selectable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af75b3d5d7b48814da1f058ff4ae7653 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs new file mode 100644 index 0000000..4aad4e8 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs @@ -0,0 +1,450 @@ +using System; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Slider", 33)] + [RequireComponent(typeof(RectTransform))] + public class Slider + : Selectable + , IDragHandler + , IInitializePotentialDragHandler // ÍÏק֮ǰ + , ICanvasElement // ±à¼Æ÷ϲŻáÓõ½ + { + public enum Direction + { + LeftToRight, + RightToLeft, + BottomToTop, + TopToBottom, + } + + [Serializable] + public class SliderEvent : UnityEvent<float> {} + + [SerializeField] + private RectTransform m_FillRect; + public RectTransform fillRect { get { return m_FillRect; } set { if (SetPropertyUtility.SetClass(ref m_FillRect, value)) {UpdateCachedReferences(); UpdateVisuals(); } } } + + [SerializeField] + private RectTransform m_HandleRect; + public RectTransform handleRect { get { return m_HandleRect; } set { if (SetPropertyUtility.SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } } + + [Space] + + [SerializeField] + private Direction m_Direction = Direction.LeftToRight; + public Direction direction { get { return m_Direction; } set { if (SetPropertyUtility.SetStruct(ref m_Direction, value)) UpdateVisuals(); } } + + [SerializeField] + private float m_MinValue = 0; + public float minValue { get { return m_MinValue; } set { if (SetPropertyUtility.SetStruct(ref m_MinValue, value)) { Set(m_Value); UpdateVisuals(); } } } + + [SerializeField] + private float m_MaxValue = 1; + public float maxValue { get { return m_MaxValue; } set { if (SetPropertyUtility.SetStruct(ref m_MaxValue, value)) { Set(m_Value); UpdateVisuals(); } } } + + [SerializeField] + private bool m_WholeNumbers = false; + public bool wholeNumbers { get { return m_WholeNumbers; } set { if (SetPropertyUtility.SetStruct(ref m_WholeNumbers, value)) { Set(m_Value); UpdateVisuals(); } } } + + [SerializeField] + protected float m_Value; + public virtual float value + { + get + { + if (wholeNumbers) + return Mathf.Round(m_Value); + return m_Value; + } + set + { + Set(value); + } + } + + public float normalizedValue + { + get + { + if (Mathf.Approximately(minValue, maxValue)) + return 0; + return Mathf.InverseLerp(minValue, maxValue, value); + } + set + { + this.value = Mathf.Lerp(minValue, maxValue, value); + } + } + + [Space] + + // Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers. + [SerializeField] + private SliderEvent m_OnValueChanged = new SliderEvent(); + public SliderEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } } + + // Private fields + + private Image m_FillImage; + private Transform m_FillTransform; + private RectTransform m_FillContainerRect; + private Transform m_HandleTransform; + private RectTransform m_HandleContainerRect; + + // The offset from handle position to mouse down position + private Vector2 m_Offset = Vector2.zero; + + private DrivenRectTransformTracker m_Tracker; + + // Size of each step. + float stepSize { get { return wholeNumbers ? 1 : (maxValue - minValue) * 0.1f; } } // 1/10Ê®·ÖÖ®Ò» + + protected Slider() + {} + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + if (wholeNumbers) + { + m_MinValue = Mathf.Round(m_MinValue); + m_MaxValue = Mathf.Round(m_MaxValue); + } + + //Onvalidate is called before OnEnabled. We need to make sure not to touch any other objects before OnEnable is run. + if (IsActive()) + { + UpdateCachedReferences(); + Set(m_Value, false); + // Update rects since other things might affect them even if value didn't change. + UpdateVisuals(); + } + + var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this); + if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying) + CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); + } + +#endif // if UNITY_EDITOR + + public virtual void Rebuild(CanvasUpdate executing) + { +#if UNITY_EDITOR + if (executing == CanvasUpdate.Prelayout) + onValueChanged.Invoke(value); +#endif + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + protected override void OnEnable() + { + base.OnEnable(); + UpdateCachedReferences(); + Set(m_Value, false); + // Update rects since they need to be initialized correctly. + UpdateVisuals(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + // Has value changed? Various elements of the slider have the old normalisedValue assigned, we can use this to perform a comparison. + // We also need to ensure the value stays within min/max. + m_Value = ClampValue(m_Value); + float oldNormalizedValue = normalizedValue; + if (m_FillContainerRect != null) + { + if (m_FillImage != null && m_FillImage.type == Image.Type.Filled) + oldNormalizedValue = m_FillImage.fillAmount; + else + oldNormalizedValue = (reverseValue ? 1 - m_FillRect.anchorMin[(int)axis] : m_FillRect.anchorMax[(int)axis]); + } + else if (m_HandleContainerRect != null) + oldNormalizedValue = (reverseValue ? 1 - m_HandleRect.anchorMin[(int)axis] : m_HandleRect.anchorMin[(int)axis]); + + UpdateVisuals(); + + if (oldNormalizedValue != normalizedValue) + { + UISystemProfilerApi.AddMarker("Slider.value", this); + onValueChanged.Invoke(m_Value); + } + } + + void UpdateCachedReferences() + { + if (m_FillRect) + { + m_FillTransform = m_FillRect.transform; + m_FillImage = m_FillRect.GetComponent<Image>(); + if (m_FillTransform.parent != null) + m_FillContainerRect = m_FillTransform.parent.GetComponent<RectTransform>(); + } + else + { + m_FillContainerRect = null; + m_FillImage = null; + } + + if (m_HandleRect) + { + m_HandleTransform = m_HandleRect.transform; + if (m_HandleTransform.parent != null) + m_HandleContainerRect = m_HandleTransform.parent.GetComponent<RectTransform>(); + } + else + { + m_HandleContainerRect = null; + } + } + + float ClampValue(float input) + { + float newValue = Mathf.Clamp(input, minValue, maxValue); + if (wholeNumbers) + newValue = Mathf.Round(newValue); + return newValue; + } + + // Set the valueUpdate the visible Image. + void Set(float input) + { + Set(input, true); + } + + protected virtual void Set(float input, bool sendCallback) + { + // Clamp the input + float newValue = ClampValue(input); + + // If the stepped value doesn't match the last one, it's time to update + if (m_Value == newValue) + return; + + m_Value = newValue; + UpdateVisuals(); + if (sendCallback) + { + UISystemProfilerApi.AddMarker("Slider.value", this); + m_OnValueChanged.Invoke(newValue); + } + } + + protected override void OnRectTransformDimensionsChange() + { + base.OnRectTransformDimensionsChange(); + + //This can be invoked before OnEnabled is called. So we shouldn't be accessing other objects, before OnEnable is called. + if (!IsActive()) + return; + + UpdateVisuals(); + } + + enum Axis + { + Horizontal = 0, + Vertical = 1 + } + + Axis axis { get { return (m_Direction == Direction.LeftToRight || m_Direction == Direction.RightToLeft) ? Axis.Horizontal : Axis.Vertical; } } + bool reverseValue { get { return m_Direction == Direction.RightToLeft || m_Direction == Direction.TopToBottom; } } + + // Force-update the slider. Useful if you've changed the properties and want it to update visually. + private void UpdateVisuals() + { + LogHelper.Log("UpdateVisuals"); + +#if UNITY_EDITOR + if (!Application.isPlaying) + UpdateCachedReferences(); +#endif + + m_Tracker.Clear(); + + if (m_FillContainerRect != null) + { + m_Tracker.Add(this, m_FillRect, DrivenTransformProperties.Anchors); + Vector2 anchorMin = Vector2.zero; + Vector2 anchorMax = Vector2.one; + + if (m_FillImage != null && m_FillImage.type == Image.Type.Filled) + { + m_FillImage.fillAmount = normalizedValue; + } + else + { + if (reverseValue) + anchorMin[(int)axis] = 1 - normalizedValue; + else + anchorMax[(int)axis] = normalizedValue; + } + + m_FillRect.anchorMin = anchorMin; + m_FillRect.anchorMax = anchorMax; + } + + if (m_HandleContainerRect != null) + { + m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors); + Vector2 anchorMin = Vector2.zero; + Vector2 anchorMax = Vector2.one; + anchorMin[(int)axis] = anchorMax[(int)axis] = (reverseValue ? (1 - normalizedValue) : normalizedValue); + m_HandleRect.anchorMin = anchorMin; + m_HandleRect.anchorMax = anchorMax; + } + } + + // Update the slider's position based on the mouse. + void UpdateDrag(PointerEventData eventData, Camera cam) + { + RectTransform clickRect = m_HandleContainerRect ?? m_FillContainerRect; + if (clickRect != null && clickRect.rect.size[(int)axis] > 0) + { + Vector2 localCursor; + if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, eventData.position, cam, out localCursor)) + return; + localCursor -= clickRect.rect.position; + + float val = Mathf.Clamp01((localCursor - m_Offset)[(int)axis] / clickRect.rect.size[(int)axis]); + normalizedValue = (reverseValue ? 1f - val : val); + } + } + + private bool MayDrag(PointerEventData eventData) + { + return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left; + } + + public override void OnPointerDown(PointerEventData eventData) + { + if (!MayDrag(eventData)) + return; + + base.OnPointerDown(eventData); + + m_Offset = Vector2.zero; + if (m_HandleContainerRect != null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera)) + { + Vector2 localMousePos; + if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos)) + m_Offset = localMousePos; + } + else + { + // Outside the slider handle - jump to this point instead + UpdateDrag(eventData, eventData.pressEventCamera); + } + } + + public virtual void OnDrag(PointerEventData eventData) + { + LogHelper.Log("OnDrag() " + gameObject.name); + if (!MayDrag(eventData)) + return; + UpdateDrag(eventData, eventData.pressEventCamera); + } + + public override void OnMove(AxisEventData eventData) + { + if (!IsActive() || !IsInteractable()) + { + base.OnMove(eventData); + return; + } + + switch (eventData.moveDir) + { + case MoveDirection.Left: + if (axis == Axis.Horizontal && FindSelectableOnLeft() == null) + Set(reverseValue ? value + stepSize : value - stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Right: + if (axis == Axis.Horizontal && FindSelectableOnRight() == null) + Set(reverseValue ? value - stepSize : value + stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Up: + if (axis == Axis.Vertical && FindSelectableOnUp() == null) + Set(reverseValue ? value - stepSize : value + stepSize); + else + base.OnMove(eventData); + break; + case MoveDirection.Down: + if (axis == Axis.Vertical && FindSelectableOnDown() == null) + Set(reverseValue ? value + stepSize : value - stepSize); + else + base.OnMove(eventData); + break; + } + } + + public override Selectable FindSelectableOnLeft() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal) + return null; + return base.FindSelectableOnLeft(); + } + + public override Selectable FindSelectableOnRight() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal) + return null; + return base.FindSelectableOnRight(); + } + + public override Selectable FindSelectableOnUp() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical) + return null; + return base.FindSelectableOnUp(); + } + + public override Selectable FindSelectableOnDown() + { + if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical) + return null; + return base.FindSelectableOnDown(); + } + + // + public virtual void OnInitializePotentialDrag(PointerEventData eventData) + { + eventData.useDragThreshold = false; + } + + public void SetDirection(Direction direction, bool includeRectLayouts) + { + Axis oldAxis = axis; + bool oldReverse = reverseValue; + this.direction = direction; + + if (!includeRectLayouts) + return; + + if (axis != oldAxis) + RectTransformUtility.FlipLayoutAxes(transform as RectTransform, true, true); + + if (reverseValue != oldReverse) + RectTransformUtility.FlipLayoutOnAxis(transform as RectTransform, (int)axis, true, true); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs.meta new file mode 100644 index 0000000..dce4469 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Slider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4735d34897dc608419d8f2b983b58420 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs new file mode 100644 index 0000000..f2dc8b9 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs @@ -0,0 +1,246 @@ +using System; +using UnityEngine.Events; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + /// <summary> + /// Simple toggle -- something that has an 'on' and 'off' states: checkbox, toggle button, radio button, etc. + /// </summary> + [AddComponentMenu("UI/Toggle", 31)] + [RequireComponent(typeof(RectTransform))] + public class Toggle + : Selectable + , IPointerClickHandler + , ISubmitHandler + , ICanvasElement // 编辑器下用到 + { + public enum ToggleTransition + { + None, + Fade + } + + [Serializable] + public class ToggleEvent : UnityEvent<bool> + {} + + /// <summary> + /// Transition type. + /// </summary> + public ToggleTransition toggleTransition = ToggleTransition.Fade; + + /// <summary> + /// Graphic the toggle should be working with. + /// </summary> + public Graphic graphic; + + // group that this toggle can belong to + [SerializeField] + private ToggleGroup m_Group; + + public ToggleGroup group + { + get { return m_Group; } + set + { + m_Group = value; +#if UNITY_EDITOR + if (Application.isPlaying) +#endif + { + SetToggleGroup(m_Group, true); + PlayEffect(true); + } + } + } + + /// <summary> + /// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers. + /// </summary> + public ToggleEvent onValueChanged = new ToggleEvent(); + + // Whether the toggle is on + [FormerlySerializedAs("m_IsActive")] + [Tooltip("Is the toggle currently on or off?")] + [SerializeField] + private bool m_IsOn; + + protected Toggle() + {} + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + + var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this); + if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying) + CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); + } + +#endif // if UNITY_EDITOR + + public virtual void Rebuild(CanvasUpdate executing) + { +#if UNITY_EDITOR + if (executing == CanvasUpdate.Prelayout) + onValueChanged.Invoke(m_IsOn); +#endif + } + + public virtual void LayoutComplete() + {} + + public virtual void GraphicUpdateComplete() + {} + + protected override void OnEnable() + { + base.OnEnable(); + SetToggleGroup(m_Group, false); + PlayEffect(true); + } + + protected override void OnDisable() + { + SetToggleGroup(null, false); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + // Check if isOn has been changed by the animation. + // Unfortunately there is no way to check if we don�t have a graphic. + if (graphic != null) + { + bool oldValue = !Mathf.Approximately(graphic.canvasRenderer.GetColor().a, 0); + if (m_IsOn != oldValue) + { + m_IsOn = oldValue; + Set(!oldValue); + } + } + + base.OnDidApplyAnimationProperties(); + } + + private void SetToggleGroup(ToggleGroup newGroup, bool setMemberValue) + { + ToggleGroup oldGroup = m_Group; + + // Sometimes IsActive returns false in OnDisable so don't check for it. + // Rather remove the toggle too often than too little. + if (m_Group != null) + m_Group.UnregisterToggle(this); + + // At runtime the group variable should be set but not when calling this method from OnEnable or OnDisable. + // That's why we use the setMemberValue parameter. + if (setMemberValue) + m_Group = newGroup; + + // Only register to the new group if this Toggle is active. + if (newGroup != null && IsActive()) + newGroup.RegisterToggle(this); + + // If we are in a new group, and this toggle is on, notify group. + // Note: Don't refer to m_Group here as it's not guaranteed to have been set. + if (newGroup != null && newGroup != oldGroup && isOn && IsActive()) + newGroup.NotifyToggleOn(this); + } + + /// <summary> + /// Whether the toggle is currently active. + /// </summary> + public bool isOn + { + get { return m_IsOn; } + set + { + Set(value); + } + } + + void Set(bool value) + { + Set(value, true); + } + + void Set(bool value, bool sendCallback) + { + if (m_IsOn == value) + return; + + // if we are in a group and set to true, do group logic + m_IsOn = value; + if (m_Group != null && IsActive()) + { + if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.allowSwitchOff)) + { + m_IsOn = true; + m_Group.NotifyToggleOn(this); + } + } + + // Always send event when toggle is clicked, even if value didn't change + // due to already active toggle in a toggle group being clicked. + // Controls like Dropdown rely on this. + // It's up to the user to ignore a selection being set to the same value it already was, if desired. + PlayEffect(toggleTransition == ToggleTransition.None); + if (sendCallback) + { + UISystemProfilerApi.AddMarker("Toggle.value", this); + onValueChanged.Invoke(m_IsOn); + } + } + + /// <summary> + /// Play the appropriate effect. + /// </summary> + private void PlayEffect(bool instant) + { + if (graphic == null) + return; + +#if UNITY_EDITOR + if (!Application.isPlaying) + graphic.canvasRenderer.SetAlpha(m_IsOn ? 1f : 0f); + else +#endif + graphic.CrossFadeAlpha(m_IsOn ? 1f : 0f, instant ? 0f : 0.1f, true); + } + + /// <summary> + /// Assume the correct visual state. + /// </summary> + protected override void Start() + { + PlayEffect(true); + } + + private void InternalToggle() + { + if (!IsActive() || !IsInteractable()) + return; + + isOn = !isOn; + } + + /// <summary> + /// React to clicks. + /// </summary> + public virtual void OnPointerClick(PointerEventData eventData) + { + if (eventData.button != PointerEventData.InputButton.Left) + return; + + InternalToggle(); + } + + public virtual void OnSubmit(BaseEventData eventData) + { + InternalToggle(); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs.meta new file mode 100644 index 0000000..b4a15b7 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/Toggle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34e74f28b4633794eb61b9c3f6d97b37 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs new file mode 100644 index 0000000..da5e021 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs @@ -0,0 +1,73 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Toggle Group", 32)] + [DisallowMultipleComponent] + public class ToggleGroup : UIBehaviour + { + [SerializeField] private bool m_AllowSwitchOff = false; + public bool allowSwitchOff { get { return m_AllowSwitchOff; } set { m_AllowSwitchOff = value; } } + + private List<Toggle> m_Toggles = new List<Toggle>(); + + protected ToggleGroup() + {} + + private void ValidateToggleIsInGroup(Toggle toggle) + { + if (toggle == null || !m_Toggles.Contains(toggle)) + throw new ArgumentException(string.Format("Toggle {0} is not part of ToggleGroup {1}", new object[] {toggle, this})); + } + + public void NotifyToggleOn(Toggle toggle) + { + ValidateToggleIsInGroup(toggle); + + // disable all toggles in the group + for (var i = 0; i < m_Toggles.Count; i++) + { + if (m_Toggles[i] == toggle) + continue; + + m_Toggles[i].isOn = false; + } + } + + public void UnregisterToggle(Toggle toggle) + { + if (m_Toggles.Contains(toggle)) + m_Toggles.Remove(toggle); + } + + public void RegisterToggle(Toggle toggle) + { + if (!m_Toggles.Contains(toggle)) + m_Toggles.Add(toggle); + } + + public bool AnyTogglesOn() + { + return m_Toggles.Find(x => x.isOn) != null; + } + + public IEnumerable<Toggle> ActiveToggles() + { + return m_Toggles.Where(x => x.isOn); + } + + public void SetAllTogglesOff() + { + bool oldAllowSwitchOff = m_AllowSwitchOff; + m_AllowSwitchOff = true; + + for (var i = 0; i < m_Toggles.Count; i++) + m_Toggles[i].isOn = false; + + m_AllowSwitchOff = oldAllowSwitchOff; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs.meta new file mode 100644 index 0000000..0649cf7 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/UIControls/ToggleGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 10b2fd7b649a75145b1e4a36a3c91dfd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility.meta new file mode 100644 index 0000000..117221b --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1cb75217bdcbf9f429e9f763df2b27d4 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs new file mode 100644 index 0000000..1a7cc5e --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEngine.UI +{ + internal static class ListPool<T> + { + // Object pool to avoid allocations. + private static readonly ObjectPool<List<T>> s_ListPool = new ObjectPool<List<T>>(null, l => l.Clear()); + + public static List<T> Get() + { + return s_ListPool.Get(); + } + + public static void Release(List<T> toRelease) + { + s_ListPool.Release(toRelease); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs.meta new file mode 100644 index 0000000..e54f9f7 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ListPool.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 12520643c37454344b5a1dd60cc2bdbd +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs new file mode 100644 index 0000000..b506d80 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using UnityEngine.Events; + +namespace UnityEngine.UI +{ + internal class ObjectPool<T> where T : new() + { + private readonly Stack<T> m_Stack = new Stack<T>(); + private readonly UnityAction<T> m_ActionOnGet; + private readonly UnityAction<T> m_ActionOnRelease; + + public int countAll { get; private set; } + public int countActive { get { return countAll - countInactive; } } + public int countInactive { get { return m_Stack.Count; } } + + public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease) + { + m_ActionOnGet = actionOnGet; + m_ActionOnRelease = actionOnRelease; + } + + public T Get() + { + T element; + if (m_Stack.Count == 0) + { + element = new T(); + countAll++; + } + else + { + element = m_Stack.Pop(); + } + if (m_ActionOnGet != null) + m_ActionOnGet(element); + return element; + } + + public void Release(T element) + { + if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) + Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); + if (m_ActionOnRelease != null) + m_ActionOnRelease(element); + m_Stack.Push(element); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs.meta new file mode 100644 index 0000000..942cd48 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ObjectPool.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: e74077e6b05099a4589f683a80cc92ff +timeCreated: 1602119380 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs new file mode 100644 index 0000000..638fa03 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace UnityEngine.UI +{ + internal class ReflectionMethodsCache + { + public delegate bool Raycast3DCallback(Ray r, out RaycastHit hit, float f, int i); + public delegate RaycastHit2D Raycast2DCallback(Vector2 p1, Vector2 p2, float f, int i); + public delegate RaycastHit[] RaycastAllCallback(Ray r, float f, int i); + public delegate RaycastHit2D[] GetRayIntersectionAllCallback(Ray r, float f, int i); + + // We call Physics.Raycast and Physics2D.Raycast through reflection to avoid creating a hard dependency from + // this class to the Physics/Physics2D modules, which would otherwise make it impossible to make content with UI + // without force-including both modules. + public ReflectionMethodsCache() + { + var raycast3DMethodInfo = typeof(Physics).GetMethod("Raycast", new[] {typeof(Ray), typeof(RaycastHit).MakeByRefType(), typeof(float), typeof(int)}); + if (raycast3DMethodInfo != null) + raycast3D = (Raycast3DCallback)UnityEngineInternal.ScriptingUtils.CreateDelegate(typeof(Raycast3DCallback), raycast3DMethodInfo); + + var raycast2DMethodInfo = typeof(Physics2D).GetMethod("Raycast", new[] {typeof(Vector2), typeof(Vector2), typeof(float), typeof(int)}); + if (raycast2DMethodInfo != null) + raycast2D = (Raycast2DCallback)UnityEngineInternal.ScriptingUtils.CreateDelegate(typeof(Raycast2DCallback), raycast2DMethodInfo); + + var raycastAllMethodInfo = typeof(Physics).GetMethod("RaycastAll", new[] {typeof(Ray), typeof(float), typeof(int)}); + if (raycastAllMethodInfo != null) + raycast3DAll = (RaycastAllCallback)UnityEngineInternal.ScriptingUtils.CreateDelegate(typeof(RaycastAllCallback), raycastAllMethodInfo); + + var getRayIntersectionAllMethodInfo = typeof(Physics2D).GetMethod("GetRayIntersectionAll", new[] {typeof(Ray), typeof(float), typeof(int)}); + if (getRayIntersectionAllMethodInfo != null) + getRayIntersectionAll = (GetRayIntersectionAllCallback)UnityEngineInternal.ScriptingUtils.CreateDelegate(typeof(GetRayIntersectionAllCallback), getRayIntersectionAllMethodInfo); + } + + public Raycast3DCallback raycast3D = null; + public RaycastAllCallback raycast3DAll = null; + public Raycast2DCallback raycast2D = null; + public GetRayIntersectionAllCallback getRayIntersectionAll = null; + + private static ReflectionMethodsCache s_ReflectionMethodsCache = null; + + public static ReflectionMethodsCache Singleton + { + get + { + if (s_ReflectionMethodsCache == null) + s_ReflectionMethodsCache = new ReflectionMethodsCache(); + return s_ReflectionMethodsCache; + } + } + }; +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs.meta new file mode 100644 index 0000000..8aa76ec --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/ReflectionMethodsCache.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: a4c9f67a29a841b479c2abbec238e83c +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs new file mode 100644 index 0000000..15d8519 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Events; + +namespace UnityEngine.UI +{ + internal static class SetPropertyUtility + { + public static bool SetColor(ref Color currentValue, Color newValue) + { + if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a) + return false; + + currentValue = newValue; + return true; + } + + public static bool SetStruct<T>(ref T currentValue, T newValue) where T : struct + { + if (EqualityComparer<T>.Default.Equals(currentValue, newValue)) + return false; + + currentValue = newValue; + return true; + } + + public static bool SetClass<T>(ref T currentValue, T newValue) where T : class + { + if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue))) + return false; + + currentValue = newValue; + return true; + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs.meta new file mode 100644 index 0000000..ee3936e --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/SetPropertyUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c7eb311d761ee3d409de0593312d6fa2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs new file mode 100644 index 0000000..3020d4d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + public class VertexHelper : IDisposable + { + //c ¸Ä³Épublic·½±ã¿´ + /*private*/ public List<Vector3> m_Positions = ListPool<Vector3>.Get(); + /*private*/ public List<Color32> m_Colors = ListPool<Color32>.Get(); + /*private*/ public List<Vector2> m_Uv0S = ListPool<Vector2>.Get(); + /*private*/ public List<Vector2> m_Uv1S = ListPool<Vector2>.Get(); + /*private*/ public List<Vector2> m_Uv2S = ListPool<Vector2>.Get(); + /*private*/ public List<Vector2> m_Uv3S = ListPool<Vector2>.Get(); + /*private*/ public List<Vector3> m_Normals = ListPool<Vector3>.Get(); + /*private*/ public List<Vector4> m_Tangents = ListPool<Vector4>.Get(); + /*private*/ public List<int> m_Indices = ListPool<int>.Get(); + + private static readonly Vector4 s_DefaultTangent = new Vector4(1.0f, 0.0f, 0.0f, -1.0f); + private static readonly Vector3 s_DefaultNormal = Vector3.back; + + public VertexHelper() + {} + + public VertexHelper(Mesh m) + { + m_Positions.AddRange(m.vertices); + m_Colors.AddRange(m.colors32); + m_Uv0S.AddRange(m.uv); + m_Uv1S.AddRange(m.uv2); + m_Uv2S.AddRange(m.uv3); + m_Uv3S.AddRange(m.uv4); + m_Normals.AddRange(m.normals); + m_Tangents.AddRange(m.tangents); + m_Indices.AddRange(m.GetIndices(0)); + } + + public void Clear() + { + m_Positions.Clear(); + m_Colors.Clear(); + m_Uv0S.Clear(); + m_Uv1S.Clear(); + m_Uv2S.Clear(); + m_Uv3S.Clear(); + m_Normals.Clear(); + m_Tangents.Clear(); + m_Indices.Clear(); + } + + public int currentVertCount + { + get { return m_Positions.Count; } + } + public int currentIndexCount + { + get { return m_Indices.Count; } + } + + public void PopulateUIVertex(ref UIVertex vertex, int i) + { + vertex.position = m_Positions[i]; + vertex.color = m_Colors[i]; + vertex.uv0 = m_Uv0S[i]; + vertex.uv1 = m_Uv1S[i]; + vertex.uv2 = m_Uv2S[i]; + vertex.uv3 = m_Uv3S[i]; + vertex.normal = m_Normals[i]; + vertex.tangent = m_Tangents[i]; + } + + public void SetUIVertex(UIVertex vertex, int i) + { + m_Positions[i] = vertex.position; + m_Colors[i] = vertex.color; + m_Uv0S[i] = vertex.uv0; + m_Uv1S[i] = vertex.uv1; + m_Uv2S[i] = vertex.uv2; + m_Uv3S[i] = vertex.uv3; + m_Normals[i] = vertex.normal; + m_Tangents[i] = vertex.tangent; + } + + public void FillMesh(Mesh mesh) + { + mesh.Clear(); + + if (m_Positions.Count >= 65000) + throw new ArgumentException("Mesh can not have more than 65000 vertices"); + + mesh.SetVertices(m_Positions); + mesh.SetColors(m_Colors); + mesh.SetUVs(0, m_Uv0S); + mesh.SetUVs(1, m_Uv1S); + mesh.SetUVs(2, m_Uv2S); + mesh.SetUVs(3, m_Uv3S); + mesh.SetNormals(m_Normals); + mesh.SetTangents(m_Tangents); + mesh.SetTriangles(m_Indices, 0); + mesh.RecalculateBounds(); + } + + public void Dispose() + { + ListPool<Vector3>.Release(m_Positions); + ListPool<Color32>.Release(m_Colors); + ListPool<Vector2>.Release(m_Uv0S); + ListPool<Vector2>.Release(m_Uv1S); + ListPool<Vector2>.Release(m_Uv2S); + ListPool<Vector2>.Release(m_Uv3S); + ListPool<Vector3>.Release(m_Normals); + ListPool<Vector4>.Release(m_Tangents); + ListPool<int>.Release(m_Indices); + + m_Positions = null; + m_Colors = null; + m_Uv0S = null; + m_Uv1S = null; + m_Uv2S = null; + m_Uv3S = null; + m_Normals = null; + m_Tangents = null; + m_Indices = null; + } + + public void AddVert(Vector3 position, Color32 color, Vector2 uv0, Vector2 uv1, Vector3 normal, Vector4 tangent) + { + m_Positions.Add(position); + m_Colors.Add(color); + m_Uv0S.Add(uv0); + m_Uv1S.Add(uv1); + m_Uv2S.Add(Vector2.zero); + m_Uv3S.Add(Vector2.zero); + m_Normals.Add(normal); + m_Tangents.Add(tangent); + } + + public void AddVert(Vector3 position, Color32 color, Vector2 uv0) + { + AddVert(position, color, uv0, Vector2.zero, s_DefaultNormal, s_DefaultTangent); + } + + public void AddVert(UIVertex v) + { + AddVert(v.position, v.color, v.uv0, v.uv1, v.normal, v.tangent); + } + + public void AddTriangle(int idx0, int idx1, int idx2) + { + m_Indices.Add(idx0); + m_Indices.Add(idx1); + m_Indices.Add(idx2); + } + + public void AddUIVertexQuad(UIVertex[] verts) + { + int startIndex = currentVertCount; + + for (int i = 0; i < 4; i++) + AddVert(verts[i].position, verts[i].color, verts[i].uv0, verts[i].uv1, verts[i].normal, verts[i].tangent); + + AddTriangle(startIndex, startIndex + 1, startIndex + 2); + AddTriangle(startIndex + 2, startIndex + 3, startIndex); + } + + public void AddUIVertexStream(List<UIVertex> verts, List<int> indices) + { + if (verts != null) + { + CanvasRenderer.AddUIVertexStream(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Uv2S, m_Uv3S, m_Normals, m_Tangents); + } + + if (indices != null) + { + m_Indices.AddRange(indices); + } + } + + public void AddUIVertexTriangleStream(List<UIVertex> verts) + { + if (verts == null) + return; + CanvasRenderer.SplitUIVertexStreams(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Uv2S, m_Uv3S, m_Normals, m_Tangents, m_Indices); + } + + public void GetUIVertexStream(List<UIVertex> stream) + { + if (stream == null) + return; + + CanvasRenderer.CreateUIVertexStream(stream, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Uv2S, m_Uv3S, m_Normals, m_Tangents, m_Indices); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs.meta new file mode 100644 index 0000000..df0d085 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 462296566c1ff9443bbf18a80a326dda +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers.meta new file mode 100644 index 0000000..f58dea5 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 78044a61d69e4ef48bba3cbf60320235 +folderAsset: yes +timeCreated: 1602119280 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs new file mode 100644 index 0000000..aac679d --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using UnityEngine.EventSystems; + +namespace UnityEngine.UI +{ + [Obsolete("Use BaseMeshEffect instead", true)] + public abstract class BaseVertexEffect + { + [Obsolete("Use BaseMeshEffect.ModifyMeshes instead", true)] //We can't upgrade automatically since the signature changed. + public abstract void ModifyVertices(List<UIVertex> vertices); + }
+
+ // ¹Ø¼üÔÚÓÚʵÏÖIMeshModifier½Ó¿Ú£¬×Ô¼ºÐ´Ð§¹û£¬²»Ò»¶¨Òª¼Ì³ÐÕâ¸öÀà
+ [ExecuteInEditMode] + public abstract class BaseMeshEffect : UIBehaviour, IMeshModifier + { + [NonSerialized] + private Graphic m_Graphic; + + protected Graphic graphic + { + get + { + if (m_Graphic == null) + m_Graphic = GetComponent<Graphic>(); + + return m_Graphic; + } + } + + protected override void OnEnable() + { + base.OnEnable(); + if (graphic != null) + graphic.SetVerticesDirty(); + } + + protected override void OnDisable() + { + if (graphic != null) + graphic.SetVerticesDirty(); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + if (graphic != null) + graphic.SetVerticesDirty(); + base.OnDidApplyAnimationProperties(); + } + +#if UNITY_EDITOR + protected override void OnValidate() + { + base.OnValidate(); + if (graphic != null) + graphic.SetVerticesDirty(); + } + +#endif + + public virtual void ModifyMesh(Mesh mesh) + { + using (var vh = new VertexHelper(mesh)) + { + ModifyMesh(vh); + vh.FillMesh(mesh); + } + } + + public abstract void ModifyMesh(VertexHelper vh); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs.meta new file mode 100644 index 0000000..9f4a3df --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/BaseMeshEffect.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 9e33e594b9e3bfb41b97c11432334978 +timeCreated: 1602119379 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs new file mode 100644 index 0000000..582a820 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + + //[Obsolete("Use IMeshModifier instead", true)] + //public interface IVertexModifier + //{ + // [Obsolete("use IMeshModifier.ModifyMesh (VertexHelper verts) instead", true)] + // void ModifyVertices(List<UIVertex> verts); + //} + + public interface IMeshModifier + { + [Obsolete("use IMeshModifier.ModifyMesh (VertexHelper verts) instead", false)] + void ModifyMesh(Mesh mesh); + void ModifyMesh(VertexHelper verts); + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs.meta new file mode 100644 index 0000000..df53941 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/IMeshModifier.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 6b4c52564d8d47540a091497d8f9dd49 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs new file mode 100644 index 0000000..e14c862 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Effects/Outline", 15)] + public class Outline : Shadow + { + protected Outline() + {} + + public override void ModifyMesh(VertexHelper vh) + { + if (!IsActive()) + return; + + var verts = ListPool<UIVertex>.Get(); + vh.GetUIVertexStream(verts); + + var neededCpacity = verts.Count * 5; + if (verts.Capacity < neededCpacity) + verts.Capacity = neededCpacity; + + var start = 0; + var end = verts.Count; + ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, effectDistance.y); + + start = end; + end = verts.Count; + ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, effectDistance.x, -effectDistance.y); + + start = end; + end = verts.Count; + ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, effectDistance.y); + + start = end; + end = verts.Count; + ApplyShadowZeroAlloc(verts, effectColor, start, verts.Count, -effectDistance.x, -effectDistance.y); + + vh.Clear(); + vh.AddUIVertexTriangleStream(verts); + ListPool<UIVertex>.Release(verts); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs.meta new file mode 100644 index 0000000..a27dd26 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Outline.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 5978620b88847af4a8835c7008c813b8 +timeCreated: 1602119378 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs new file mode 100644 index 0000000..d396bfa --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs @@ -0,0 +1,22 @@ +using System.Linq; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Effects/Position As UV1", 16)] + public class PositionAsUV1 : BaseMeshEffect + { + protected PositionAsUV1() + {} + + public override void ModifyMesh(VertexHelper vh) + { + UIVertex vert = new UIVertex(); + for (int i = 0; i < vh.currentVertCount; i++) + { + vh.PopulateUIVertex(ref vert, i); + vert.uv1 = new Vector2(vert.position.x, vert.position.y); + vh.SetUIVertex(vert, i); + } + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs.meta new file mode 100644 index 0000000..847c79f --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/PositionAsUV1.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 19ed27a46ca366b439439e63862c762b +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs new file mode 100644 index 0000000..e0a813c --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs @@ -0,0 +1,126 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEngine.UI +{ + [AddComponentMenu("UI/Effects/Shadow", 14)] + public class Shadow : BaseMeshEffect + { + [SerializeField] + private Color m_EffectColor = new Color(0f, 0f, 0f, 0.5f); + + [SerializeField] + private Vector2 m_EffectDistance = new Vector2(1f, -1f); + + [SerializeField] + private bool m_UseGraphicAlpha = true; + + private const float kMaxEffectDistance = 600f; + + protected Shadow() + {} + +#if UNITY_EDITOR + protected override void OnValidate() + { + effectDistance = m_EffectDistance; + base.OnValidate(); + } + +#endif + + public Color effectColor + { + get { return m_EffectColor; } + set + { + m_EffectColor = value; + if (graphic != null) + graphic.SetVerticesDirty(); + } + } + + public Vector2 effectDistance + { + get { return m_EffectDistance; } + set + { + if (value.x > kMaxEffectDistance) + value.x = kMaxEffectDistance; + if (value.x < -kMaxEffectDistance) + value.x = -kMaxEffectDistance; + + if (value.y > kMaxEffectDistance) + value.y = kMaxEffectDistance; + if (value.y < -kMaxEffectDistance) + value.y = -kMaxEffectDistance; + + if (m_EffectDistance == value) + return; + + m_EffectDistance = value; + + if (graphic != null) + graphic.SetVerticesDirty(); + } + } + + public bool useGraphicAlpha + { + get { return m_UseGraphicAlpha; } + set + { + m_UseGraphicAlpha = value; + if (graphic != null) + graphic.SetVerticesDirty(); + } + } + + //x,yÊÇÆ«ÒÆÁ¿ + protected void ApplyShadowZeroAlloc(List<UIVertex> verts, Color32 color, int start, int end, float x, float y) + { + UIVertex vt; + + var neededCapacity = verts.Count + end - start; + if (verts.Capacity < neededCapacity) + verts.Capacity = neededCapacity; + + for (int i = start; i < end; ++i) + { + vt = verts[i]; + verts.Add(vt); + + Vector3 v = vt.position; + v.x += x; + v.y += y; + vt.position = v; + + var newColor = color; + if (m_UseGraphicAlpha) + newColor.a = (byte)((newColor.a * verts[i].color.a) / 255); + + vt.color = newColor; + verts[i] = vt; + } + } + + protected void ApplyShadow(List<UIVertex> verts, Color32 color, int start, int end, float x, float y) + { + ApplyShadowZeroAlloc(verts, color, start, end, x, y); + } + + public override void ModifyMesh(VertexHelper vh) + { + if (!IsActive()) + return; + + var output = ListPool<UIVertex>.Get(); + vh.GetUIVertexStream(output); + + ApplyShadow(output, effectColor, 0, output.Count, effectDistance.x, effectDistance.y); + vh.Clear(); + vh.AddUIVertexTriangleStream(output); + ListPool<UIVertex>.Release(output); + } + } +} diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs.meta b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs.meta new file mode 100644 index 0000000..75dc2fc --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/VertexModifiers/Shadow.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 128369c085053c246bab60ca7bb68a64 +timeCreated: 1602119377 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..da61125 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 0 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..78992f0 --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..6dc24f7 --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..7b42695 --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Hidden Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..74d7b53 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,61 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/NetworkManager.asset b/ProjectSettings/NetworkManager.asset new file mode 100644 index 0000000..5dc6a83 --- /dev/null +++ b/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..132ee6b --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_ChangeStopsCallbacks: 0 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..cc106e0 --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,642 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 14 + productGUID: bba5d68420d059946a9cbd5e35b5e9d9 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: UI_Extensions + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + tizenShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidBlitType: 0 + defaultIsFullScreen: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 0 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + macFullscreenMode: 2 + d3d11FullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + n3dsDisableStereoscopicView: 0 + n3dsEnableSharedListOpt: 1 + n3dsEnableVSync: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + videoMemoryForVertexBuffers: 0 + psp2PowerMode: 0 + psp2AcquireBGM: 1 + wiiUTVResolution: 0 + wiiUGamePadMSAA: 1 + wiiUSupportsNunchuk: 0 + wiiUSupportsClassicController: 0 + wiiUSupportsBalanceBoard: 0 + wiiUSupportsMotionPlus: 0 + wiiUSupportsProController: 0 + wiiUAllowScreenCapture: 1 + wiiUControllerCount: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 1.0 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + protectGraphicsMemory: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 0 + VertexChannelCompressionMask: + serializedVersion: 2 + m_Bits: 238 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 7.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + appleEnableAutomaticSigning: 0 + clonedFromGUID: 00000000000000000000000000000000 + AndroidTargetDevice: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: [] + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + wiiUTitleID: 0005000011000000 + wiiUGroupID: 00010000 + wiiUCommonSaveSize: 4096 + wiiUAccountSaveSize: 2048 + wiiUOlvAccessKey: 0 + wiiUTinCode: 0 + wiiUJoinGameId: 0 + wiiUJoinGameModeMask: 0000000000000000 + wiiUCommonBossSize: 0 + wiiUAccountBossSize: 0 + wiiUAddOnUniqueIDs: [] + wiiUMainThreadStackSize: 3072 + wiiULoaderThreadStackSize: 1024 + wiiUSystemHeapSize: 128 + wiiUTVStartupScreen: {fileID: 0} + wiiUGamePadStartupScreen: {fileID: 0} + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: + playModeTestRunnerEnabled: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSupportedNpadStyles: 3 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + psp2Splashimage: {fileID: 0} + psp2NPTrophyPackPath: + psp2NPSupportGBMorGJP: 0 + psp2NPAgeRating: 12 + psp2NPTitleDatPath: + psp2NPCommsID: + psp2NPCommunicationsID: + psp2NPCommsPassphrase: + psp2NPCommsSig: + psp2ParamSfxPath: + psp2ManualPath: + psp2LiveAreaGatePath: + psp2LiveAreaBackroundPath: + psp2LiveAreaPath: + psp2LiveAreaTrialPath: + psp2PatchChangeInfoPath: + psp2PatchOriginalPackage: + psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui + psp2KeystoneFile: + psp2MemoryExpansionMode: 0 + psp2DRMType: 0 + psp2StorageType: 0 + psp2MediaCapacity: 0 + psp2DLCConfigPath: + psp2ThumbnailPath: + psp2BackgroundPath: + psp2SoundPath: + psp2TrophyCommId: + psp2TrophyPackagePath: + psp2PackagedResourcesPath: + psp2SaveDataQuota: 10240 + psp2ParentalLevel: 1 + psp2ShortTitle: Not Set + psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF + psp2Category: 0 + psp2MasterVersion: 01.00 + psp2AppVersion: 01.00 + psp2TVBootMode: 0 + psp2EnterButtonAssignment: 2 + psp2TVDisableEmu: 0 + psp2AllowTwitterDialog: 1 + psp2Upgradable: 0 + psp2HealthWarning: 0 + psp2UseLibLocation: 0 + psp2InfoBarOnStartup: 0 + psp2InfoBarColor: 0 + psp2ScriptOptimizationLevel: 0 + psmSplashimage: {fileID: 0} + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 0 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLUseWasm: 0 + webGLCompressionFormat: 1 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: {} + incrementalIl2cppBuild: {} + additionalIl2CppArgs: + scriptingRuntimeVersion: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: UI_Extensions + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: UI_Extensions + wsaImages: {} + metroTileShortName: + metroCommandLineArgsFile: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + tizenProductDescription: + tizenProductURL: + tizenSigningProfileName: + tizenGPSPermissions: 0 + tizenMicrophonePermissions: 0 + tizenDeploymentTarget: + tizenDeploymentTargetType: -1 + tizenMinOSVersion: 1 + n3dsUseExtSaveData: 0 + n3dsCompressStaticMem: 1 + n3dsExtSaveDataNumber: 0x12345 + n3dsStackSize: 131072 + n3dsTargetPlatform: 2 + n3dsRegion: 7 + n3dsMediaSize: 0 + n3dsLogoStyle: 3 + n3dsTitle: GameName + n3dsProductCode: + n3dsApplicationId: 0xFF3FF + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: {} + facebookSdkVersion: 7.9.4 + apiCompatibilityLevel: 2 + cloudProjectId: 43eb37ed-43b2-4c1c-95f9-24e4f4969ab3 + projectName: UI_Extensions + organizationId: chaifix + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..fdd37c4 --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2017.4.13f1 diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..05daac3 --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,191 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSM: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..f327fe1 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + m_Enabled: 0 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes + m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate + m_Enabled: 0 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 1 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_TestEventUrl: + m_TestConfigUrl: + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/UnityPackageManager/manifest.json b/UnityPackageManager/manifest.json new file mode 100644 index 0000000..526aca6 --- /dev/null +++ b/UnityPackageManager/manifest.json @@ -0,0 +1,4 @@ +{ + "dependencies": { + } +} |