recycle view
This commit is contained in:
parent
232e5d4ef2
commit
9e6e3ccdee
76 changed files with 2963 additions and 40 deletions
|
@ -25,7 +25,7 @@ MonoBehaviour:
|
|||
m_SupportsTerrainHoles: 1
|
||||
m_SupportsHDR: 1
|
||||
m_HDRColorBufferPrecision: 0
|
||||
m_MSAA: 1
|
||||
m_MSAA: 2
|
||||
m_RenderScale: 1
|
||||
m_UpscalingFilter: 0
|
||||
m_FsrOverrideSharpness: 0
|
||||
|
|
BIN
Assets/Resources/Glock17.fbx
Normal file
BIN
Assets/Resources/Glock17.fbx
Normal file
Binary file not shown.
107
Assets/Resources/Glock17.fbx.meta
Normal file
107
Assets/Resources/Glock17.fbx.meta
Normal file
|
@ -0,0 +1,107 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf9d862a19647f28795df2e666425003
|
||||
ModelImporter:
|
||||
serializedVersion: 22200
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
materials:
|
||||
materialImportMode: 2
|
||||
materialName: 0
|
||||
materialSearch: 1
|
||||
materialLocation: 1
|
||||
animations:
|
||||
legacyGenerateAnimations: 4
|
||||
bakeSimulation: 0
|
||||
resampleCurves: 1
|
||||
optimizeGameObjects: 0
|
||||
removeConstantScaleCurves: 0
|
||||
motionNodeName:
|
||||
animationImportErrors:
|
||||
animationImportWarnings:
|
||||
animationRetargetingWarnings:
|
||||
animationDoRetargetingWarnings: 0
|
||||
importAnimatedCustomProperties: 0
|
||||
importConstraints: 0
|
||||
animationCompression: 1
|
||||
animationRotationError: 0.5
|
||||
animationPositionError: 0.5
|
||||
animationScaleError: 0.5
|
||||
animationWrapMode: 0
|
||||
extraExposedTransformPaths: []
|
||||
extraUserProperties: []
|
||||
clipAnimations: []
|
||||
isReadable: 0
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
globalScale: 1
|
||||
meshCompression: 0
|
||||
addColliders: 0
|
||||
useSRGBMaterialColor: 1
|
||||
sortHierarchyByName: 1
|
||||
importPhysicalCameras: 1
|
||||
importVisibility: 1
|
||||
importBlendShapes: 1
|
||||
importCameras: 1
|
||||
importLights: 1
|
||||
nodeNameCollisionStrategy: 1
|
||||
fileIdsGeneration: 2
|
||||
swapUVChannels: 0
|
||||
generateSecondaryUV: 0
|
||||
useFileUnits: 1
|
||||
keepQuads: 0
|
||||
weldVertices: 1
|
||||
bakeAxisConversion: 0
|
||||
preserveHierarchy: 0
|
||||
skinWeightsMode: 0
|
||||
maxBonesPerVertex: 4
|
||||
minBoneWeight: 0.001
|
||||
optimizeBones: 1
|
||||
meshOptimizationFlags: -1
|
||||
indexFormat: 0
|
||||
secondaryUVAngleDistortion: 8
|
||||
secondaryUVAreaDistortion: 15.000001
|
||||
secondaryUVHardAngle: 88
|
||||
secondaryUVMarginMethod: 1
|
||||
secondaryUVMinLightmapResolution: 40
|
||||
secondaryUVMinObjectScale: 1
|
||||
secondaryUVPackMargin: 4
|
||||
useFileScale: 1
|
||||
strictVertexDataChecks: 0
|
||||
tangentSpace:
|
||||
normalSmoothAngle: 60
|
||||
normalImportMode: 0
|
||||
tangentImportMode: 3
|
||||
normalCalculationMode: 4
|
||||
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||
blendShapeNormalImportMode: 1
|
||||
normalSmoothingSource: 0
|
||||
referencedClips: []
|
||||
importAnimation: 1
|
||||
humanDescription:
|
||||
serializedVersion: 3
|
||||
human: []
|
||||
skeleton: []
|
||||
armTwist: 0.5
|
||||
foreArmTwist: 0.5
|
||||
upperLegTwist: 0.5
|
||||
legTwist: 0.5
|
||||
armStretch: 0.05
|
||||
legStretch: 0.05
|
||||
feetSpacing: 0
|
||||
globalScale: 1
|
||||
rootMotionBoneName:
|
||||
hasTranslationDoF: 0
|
||||
hasExtraRoot: 0
|
||||
skeletonHasParents: 1
|
||||
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||
autoGenerateAvatarMappingIfUnspecified: 1
|
||||
animationType: 2
|
||||
humanoidOversampling: 1
|
||||
avatarSetup: 0
|
||||
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||
importBlendShapeDeformPercent: 1
|
||||
remapMaterialsIfMaterialImportModeIsNone: 0
|
||||
additionalBone: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Assets/Resources/Main.glb
Normal file
BIN
Assets/Resources/Main.glb
Normal file
Binary file not shown.
7
Assets/Resources/Main.glb.meta
Normal file
7
Assets/Resources/Main.glb.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 16d8ce8164e4d9a59bd9c28737489417
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -19,6 +19,6 @@ MonoBehaviour:
|
|||
type: 0
|
||||
stackable: 0
|
||||
maxStackCount: 10
|
||||
icon: {fileID: 0}
|
||||
icon: {fileID: -1304905567622442630, guid: 4e01e0da3979f115d951c3cb798e4313, type: 3}
|
||||
instancePrefab: {fileID: 2892703864492016621, guid: 51202e3c62c3d3e1c9bb0ff9c09a608f, type: 3}
|
||||
previewPrefab: {fileID: 0}
|
||||
|
|
|
@ -12,5 +12,7 @@ MonoBehaviour:
|
|||
m_Script: {fileID: 11500000, guid: 9702da9b93bb25bf089c54dc37cc44e7, type: 3}
|
||||
m_Name: TestInventory
|
||||
m_EditorClassIdentifier:
|
||||
serializableItems: []
|
||||
serializableItems:
|
||||
- Item: {fileID: 11400000, guid: 3a9b5fc9b523890cf8abd310dbc64940, type: 2}
|
||||
count: 1
|
||||
capacity: 8
|
||||
|
|
406
Assets/Scenes/RecycleView.unity
Normal file
406
Assets/Scenes/RecycleView.unity
Normal file
|
@ -0,0 +1,406 @@
|
|||
%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: 10
|
||||
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_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
m_BakeOnSceneLoad: 0
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 512
|
||||
m_PVRBounces: 2
|
||||
m_PVREnvironmentSampleCount: 256
|
||||
m_PVREnvironmentReferencePointCount: 2048
|
||||
m_PVRFilteringMode: 1
|
||||
m_PVRDenoiserTypeDirect: 1
|
||||
m_PVRDenoiserTypeIndirect: 1
|
||||
m_PVRDenoiserTypeAO: 1
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVREnvironmentMIS: 1
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 1
|
||||
m_PVRFilteringGaussRadiusAO: 1
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_LightProbeSampleCountMultiplier: 4
|
||||
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LightingSettings: {fileID: 0}
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 3
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
buildHeightMesh: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &1223357529
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1223357531}
|
||||
- component: {fileID: 1223357530}
|
||||
- component: {fileID: 1223357532}
|
||||
m_Layer: 5
|
||||
m_Name: UIDocument
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1223357530
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1223357529}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_PanelSettings: {fileID: 11400000, guid: d8894ba51a816c451b072d957a1cfe45, type: 2}
|
||||
m_ParentUI: {fileID: 0}
|
||||
sourceAsset: {fileID: 9197481963319205126, guid: 0c1a0528290b37272b20d94b19311768, type: 3}
|
||||
m_SortingOrder: 0
|
||||
m_WorldSpaceSizeMode: 1
|
||||
m_WorldSpaceWidth: 1920
|
||||
m_WorldSpaceHeight: 1080
|
||||
--- !u!4 &1223357531
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1223357529}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1223357532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1223357529}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2a819c4e399f6cc6c84ace2a31f18d56, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
uiDocument: {fileID: 1223357530}
|
||||
--- !u!1 &1411077289
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1411077291}
|
||||
- component: {fileID: 1411077290}
|
||||
- component: {fileID: 1411077292}
|
||||
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 &1411077290
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1411077289}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 11
|
||||
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_InnerSpotAngle: 21.80208
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_CullingMatrixOverride:
|
||||
e00: 1
|
||||
e01: 0
|
||||
e02: 0
|
||||
e03: 0
|
||||
e10: 0
|
||||
e11: 1
|
||||
e12: 0
|
||||
e13: 0
|
||||
e20: 0
|
||||
e21: 0
|
||||
e22: 1
|
||||
e23: 0
|
||||
e30: 0
|
||||
e31: 0
|
||||
e32: 0
|
||||
e33: 1
|
||||
m_UseCullingMatrixOverride: 0
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingLayerMask: 1
|
||||
m_Lightmapping: 4
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_UseBoundingSphereOverride: 0
|
||||
m_UseViewFrustumForShadowCasterCull: 1
|
||||
m_ForceVisible: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
m_LightUnit: 1
|
||||
m_LuxAtDistance: 1
|
||||
m_EnableSpotReflector: 1
|
||||
--- !u!4 &1411077291
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1411077289}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!114 &1411077292
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1411077289}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Version: 3
|
||||
m_UsePipelineSettings: 1
|
||||
m_AdditionalLightsShadowResolutionTier: 2
|
||||
m_LightLayerMask: 1
|
||||
m_RenderingLayers: 1
|
||||
m_CustomShadowLayers: 0
|
||||
m_ShadowLayerMask: 1
|
||||
m_ShadowRenderingLayers: 1
|
||||
m_LightCookieSize: {x: 1, y: 1}
|
||||
m_LightCookieOffset: {x: 0, y: 0}
|
||||
m_SoftShadowQuality: 0
|
||||
--- !u!1 &1889780342
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1889780345}
|
||||
- component: {fileID: 1889780344}
|
||||
- component: {fileID: 1889780343}
|
||||
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 &1889780343
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1889780342}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &1889780344
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1889780342}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 1
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &1889780345
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1889780342}
|
||||
serializedVersion: 2
|
||||
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_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 1889780345}
|
||||
- {fileID: 1411077291}
|
||||
- {fileID: 1223357531}
|
7
Assets/Scenes/RecycleView.unity.meta
Normal file
7
Assets/Scenes/RecycleView.unity.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 374b635465e0bf8888b5381eb4a6d9b6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -527,7 +527,7 @@ Camera:
|
|||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_Bits: 255
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
|
@ -2755,7 +2755,7 @@ GameObject:
|
|||
m_Layer: 6
|
||||
m_Name: Interaction Collider
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: -5397416234189338067, guid: 0000000000000000d000000000000000, type: 0}
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
|
|
518
Assets/Scenes/UI.unity
Normal file
518
Assets/Scenes/UI.unity
Normal file
|
@ -0,0 +1,518 @@
|
|||
%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: 10
|
||||
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_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
m_BakeOnSceneLoad: 0
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 512
|
||||
m_PVRBounces: 2
|
||||
m_PVREnvironmentSampleCount: 256
|
||||
m_PVREnvironmentReferencePointCount: 2048
|
||||
m_PVRFilteringMode: 1
|
||||
m_PVRDenoiserTypeDirect: 1
|
||||
m_PVRDenoiserTypeIndirect: 1
|
||||
m_PVRDenoiserTypeAO: 1
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVREnvironmentMIS: 1
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 1
|
||||
m_PVRFilteringGaussRadiusAO: 1
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_LightProbeSampleCountMultiplier: 4
|
||||
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LightingSettings: {fileID: 0}
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 3
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
buildHeightMesh: 0
|
||||
maxJobWorkers: 0
|
||||
preserveTilesOutsideBounds: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1001 &344266626
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: -5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.8535535
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0.35355338
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0.35355338
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0.1464466
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: -45
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: -45
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5922622823359544968, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5568371526223589888, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -2407699025559542186, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -2059808378567916338, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -1919110505097373512, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Glock17
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6619225641134156614, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7556193500268387829, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
propertyPath: m_Layer
|
||||
value: 8
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: bf9d862a19647f28795df2e666425003, type: 3}
|
||||
--- !u!1 &955626052
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 955626054}
|
||||
- component: {fileID: 955626053}
|
||||
- component: {fileID: 955626055}
|
||||
m_Layer: 8
|
||||
m_Name: Directional Light
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!108 &955626053
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955626052}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 11
|
||||
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_InnerSpotAngle: 21.80208
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_CullingMatrixOverride:
|
||||
e00: 1
|
||||
e01: 0
|
||||
e02: 0
|
||||
e03: 0
|
||||
e10: 0
|
||||
e11: 1
|
||||
e12: 0
|
||||
e13: 0
|
||||
e20: 0
|
||||
e21: 0
|
||||
e22: 1
|
||||
e23: 0
|
||||
e30: 0
|
||||
e31: 0
|
||||
e32: 0
|
||||
e33: 1
|
||||
m_UseCullingMatrixOverride: 0
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingLayerMask: 128
|
||||
m_Lightmapping: 4
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_UseBoundingSphereOverride: 0
|
||||
m_UseViewFrustumForShadowCasterCull: 1
|
||||
m_ForceVisible: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
m_LightUnit: 1
|
||||
m_LuxAtDistance: 1
|
||||
m_EnableSpotReflector: 1
|
||||
--- !u!4 &955626054
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955626052}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!114 &955626055
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 955626052}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Version: 3
|
||||
m_UsePipelineSettings: 1
|
||||
m_AdditionalLightsShadowResolutionTier: 2
|
||||
m_LightLayerMask: 1
|
||||
m_RenderingLayers: 128
|
||||
m_CustomShadowLayers: 0
|
||||
m_ShadowLayerMask: 1
|
||||
m_ShadowRenderingLayers: 1
|
||||
m_LightCookieSize: {x: 1, y: 1}
|
||||
m_LightCookieOffset: {x: 0, y: 0}
|
||||
m_SoftShadowQuality: 0
|
||||
--- !u!1 &1368180367
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1368180370}
|
||||
- component: {fileID: 1368180369}
|
||||
- component: {fileID: 1368180371}
|
||||
m_Layer: 8
|
||||
m_Name: Preview Camera
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!20 &1368180369
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1368180367}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 4
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_GateFitMode: 2
|
||||
m_FOVAxisMode: 0
|
||||
m_Iso: 200
|
||||
m_ShutterSpeed: 0.005
|
||||
m_Aperture: 16
|
||||
m_FocusDistance: 10
|
||||
m_FocalLength: 50
|
||||
m_BladeCount: 5
|
||||
m_Curvature: {x: 2, y: 11}
|
||||
m_BarrelClipping: 0.25
|
||||
m_Anamorphism: 0
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 256
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 8400000, guid: fc19a022409ab0d408fa0e78cfeab827, type: 2}
|
||||
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 &1368180370
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1368180367}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: -5, z: -3}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1368180371
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1368180367}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_RenderShadows: 1
|
||||
m_RequiresDepthTextureOption: 2
|
||||
m_RequiresOpaqueTextureOption: 2
|
||||
m_CameraType: 0
|
||||
m_Cameras: []
|
||||
m_RendererIndex: -1
|
||||
m_VolumeLayerMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 1
|
||||
m_VolumeTrigger: {fileID: 0}
|
||||
m_VolumeFrameworkUpdateModeOption: 2
|
||||
m_RenderPostProcessing: 0
|
||||
m_Antialiasing: 0
|
||||
m_AntialiasingQuality: 2
|
||||
m_StopNaN: 0
|
||||
m_Dithering: 0
|
||||
m_ClearDepth: 1
|
||||
m_AllowXRRendering: 1
|
||||
m_AllowHDROutput: 1
|
||||
m_UseScreenCoordOverride: 0
|
||||
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_RequiresDepthTexture: 0
|
||||
m_RequiresColorTexture: 0
|
||||
m_Version: 2
|
||||
m_TaaSettings:
|
||||
m_Quality: 3
|
||||
m_FrameInfluence: 0.1
|
||||
m_JitterScale: 1
|
||||
m_MipBias: 0
|
||||
m_VarianceClampScale: 0.9
|
||||
m_ContrastAdaptiveSharpening: 0
|
||||
--- !u!1 &2064440267
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2064440269}
|
||||
- component: {fileID: 2064440268}
|
||||
m_Layer: 8
|
||||
m_Name: UIDocument
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &2064440268
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2064440267}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_PanelSettings: {fileID: 11400000, guid: d8894ba51a816c451b072d957a1cfe45, type: 2}
|
||||
m_ParentUI: {fileID: 0}
|
||||
sourceAsset: {fileID: 9197481963319205126, guid: deb1ce82aafbc3b128a0ec5a8cc03439, type: 3}
|
||||
m_SortingOrder: 0
|
||||
m_WorldSpaceSizeMode: 1
|
||||
m_WorldSpaceWidth: 1920
|
||||
m_WorldSpaceHeight: 1080
|
||||
--- !u!4 &2064440269
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2064440267}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 955626054}
|
||||
- {fileID: 2064440269}
|
||||
- {fileID: 1368180370}
|
||||
- {fileID: 344266626}
|
7
Assets/Scenes/UI.unity.meta
Normal file
7
Assets/Scenes/UI.unity.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f04d37138af3f5f50aaec2e381a77f12
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using KitsuneCafe.System.Attributes;
|
||||
using Unity.Properties;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
[CustomPropertyDrawer(typeof(ConditionalDisplayAttribute), true)]
|
||||
public class ConditionalDisplayPropertyDrawer : PropertyDrawer
|
||||
|
@ -11,17 +11,36 @@ public class ConditionalDisplayPropertyDrawer : PropertyDrawer
|
|||
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
||||
{
|
||||
var attribute = this.attribute as ConditionalDisplayAttribute;
|
||||
var serializedObject = property.serializedObject;
|
||||
var names = attribute.Properties;
|
||||
var length = names.Length;
|
||||
var properties = new SerializedProperty[length];
|
||||
var properties = GetPropertiesFrom(property, attribute.Properties);
|
||||
return new SimpleConditionPropertyField(properties, attribute, property);
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
private SerializedProperty[] GetPropertiesFrom(SerializedProperty property, string[] propertyNames)
|
||||
{
|
||||
var len = propertyNames.Length;
|
||||
var properties = new SerializedProperty[len];
|
||||
var path = property.propertyPath;
|
||||
var index = path.LastIndexOf('.');
|
||||
var obj = property.serializedObject;
|
||||
|
||||
if (index > -1)
|
||||
{
|
||||
properties[i] = serializedObject.FindProperty(names[i]);
|
||||
var parentPath = path[..path.LastIndexOf('.')];
|
||||
var parent = obj.FindProperty(parentPath);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
properties[i] = parent.FindPropertyRelative(propertyNames[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
properties[i] = obj.FindProperty(propertyNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return new BoolConditionPropertyField(properties, attribute, property);
|
||||
return properties;
|
||||
}
|
||||
|
||||
public abstract class ConditionalPropertyField : PropertyField
|
||||
|
@ -57,13 +76,13 @@ public class ConditionalDisplayPropertyDrawer : PropertyDrawer
|
|||
protected abstract void OnTrackedValueChanged(SerializedProperty property);
|
||||
}
|
||||
|
||||
public class BoolConditionPropertyField : ConditionalPropertyField
|
||||
public class SimpleConditionPropertyField : ConditionalPropertyField
|
||||
{
|
||||
public BoolConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property) : base(properties, attribute, property)
|
||||
public SimpleConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property) : base(properties, attribute, property)
|
||||
{
|
||||
}
|
||||
|
||||
public BoolConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property, string label) : base(properties, attribute, property, label)
|
||||
public SimpleConditionPropertyField(SerializedProperty[] properties, ConditionalDisplayAttribute attribute, SerializedProperty property, string label) : base(properties, attribute, property, label)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,16 +95,105 @@ public class ConditionalDisplayPropertyDrawer : PropertyDrawer
|
|||
_ => false
|
||||
};
|
||||
|
||||
for (int i = 0; i < properties.Length; i++)
|
||||
var display = attribute.LogicalOperator switch
|
||||
{
|
||||
if (properties[i].boolValue == value)
|
||||
LogicalOperator.And => All(properties, attribute.Value, attribute.ComparisonOperator),
|
||||
LogicalOperator.Or => Any(properties, attribute.Value, attribute.ComparisonOperator),
|
||||
};
|
||||
|
||||
DisplayElement(display);
|
||||
}
|
||||
|
||||
protected bool Compare<T>(T self, T other, ComparisonOperator op) where T : IComparable<T>
|
||||
{
|
||||
var value = self.CompareTo(other);
|
||||
|
||||
return op switch
|
||||
{
|
||||
ComparisonOperator.Less => value < 0,
|
||||
ComparisonOperator.Equal => value == 0,
|
||||
ComparisonOperator.LessEqual => value <= 0,
|
||||
ComparisonOperator.Greater => value > 0,
|
||||
ComparisonOperator.NotEqual => value != 0,
|
||||
ComparisonOperator.GreaterEqual => value >= 0,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
}
|
||||
|
||||
protected bool Compare<T>(T self, object other, ComparisonOperator op) where T : IComparable<T>
|
||||
{
|
||||
return other is T otherValue && Compare(self, otherValue, op);
|
||||
}
|
||||
|
||||
protected bool Compare(SerializedProperty self, object other, ComparisonOperator op)
|
||||
{
|
||||
return self.propertyType switch
|
||||
{
|
||||
SerializedPropertyType.Generic => false,
|
||||
SerializedPropertyType.Float or SerializedPropertyType.Integer => self.numericType switch
|
||||
{
|
||||
DisplayElement(value);
|
||||
return;
|
||||
SerializedPropertyNumericType.Unknown => false,
|
||||
SerializedPropertyNumericType.UInt8 or SerializedPropertyNumericType.UInt16 or SerializedPropertyNumericType.UInt32 => Compare(self.uintValue, other, op),
|
||||
SerializedPropertyNumericType.Int8 or SerializedPropertyNumericType.Int16 or SerializedPropertyNumericType.Int32 => Compare(self.intValue, other, op),
|
||||
SerializedPropertyNumericType.Int64 => Compare(self.longValue, other, op),
|
||||
SerializedPropertyNumericType.UInt64 => Compare(self.ulongValue, other, op),
|
||||
SerializedPropertyNumericType.Float => Compare(self.floatValue, other, op),
|
||||
SerializedPropertyNumericType.Double => Compare(self.doubleValue, other, op),
|
||||
_ => false,
|
||||
},
|
||||
SerializedPropertyType.Boolean => Compare(self.boolValue, other, op),
|
||||
SerializedPropertyType.String => Compare(self.stringValue, other, op),
|
||||
// SerializedPropertyType.Color => Compare(self.colorValue, other, op),
|
||||
SerializedPropertyType.ObjectReference => false,
|
||||
SerializedPropertyType.LayerMask => Compare(self.intValue, other, op),
|
||||
SerializedPropertyType.Enum => Compare(self.intValue, other, op),
|
||||
// SerializedPropertyType.Vector2 => Compare(self.vector2Value, other, op),
|
||||
// SerializedPropertyType.Vector3 => Compare(self.vector3Value, other, op),
|
||||
// SerializedPropertyType.Vector4 => Compare(self.vector4Value, other, op),
|
||||
// SerializedPropertyType.Rect => Compare(self.rectValue, other, op),
|
||||
SerializedPropertyType.ArraySize => Compare(self.arraySize, other, op),
|
||||
SerializedPropertyType.Character => Compare(self.stringValue, other, op),
|
||||
// SerializedPropertyType.AnimationCurve => Compare(self.animationCurveValue, other, op),
|
||||
// SerializedPropertyType.Bounds => Compare(self.boundsValue, other, op),
|
||||
// SerializedPropertyType.Gradient => Compare(self.gradientValue, other, op),
|
||||
// SerializedPropertyType.Quaternion => Compare(self.quaternionValue, other, op),
|
||||
SerializedPropertyType.ExposedReference => false,
|
||||
// SerializedPropertyType.FixedBufferSize => Compare(self.fixedBufferSize, other, op),
|
||||
// SerializedPropertyType.Vector2Int => Compare(self.vector2IntValue, other, op),
|
||||
// SerializedPropertyType.Vector3Int => Compare(self.vector3IntValue, other, op),
|
||||
// SerializedPropertyType.RectInt => Compare(self.rectIntValue, other, op),
|
||||
// SerializedPropertyType.BoundsInt => Compare(self.boundsIntValue, other, op),
|
||||
SerializedPropertyType.ManagedReference => false,
|
||||
SerializedPropertyType.Hash128 => Compare(self.hash128Value, other, op),
|
||||
SerializedPropertyType.RenderingLayerMask => Compare(self.intValue, other, op),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
protected bool All(SerializedProperty[] properties, object value, ComparisonOperator op)
|
||||
{
|
||||
foreach (var prop in properties)
|
||||
{
|
||||
if (!Compare(prop, value, op))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayElement(!value);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool Any(SerializedProperty[] properties, object value, ComparisonOperator op)
|
||||
{
|
||||
foreach (var prop in properties)
|
||||
{
|
||||
if (Compare(prop, value, op))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DisplayElement(bool displayed)
|
||||
|
|
|
@ -1,6 +1,47 @@
|
|||
using System;
|
||||
|
||||
namespace KitsuneCafe.Extension
|
||||
{
|
||||
public static class CollectionExtension
|
||||
{
|
||||
public static bool IsTypeOf<T, U>()
|
||||
{
|
||||
return IsTypeOf(typeof(T), typeof(U));
|
||||
}
|
||||
|
||||
public static bool IsTypeOf<T>(this object value)
|
||||
{
|
||||
return IsTypeOf(value.GetType(), typeof(T));
|
||||
}
|
||||
|
||||
public static bool IsTypeOf(this object value, Type type)
|
||||
{
|
||||
return IsTypeOf(value.GetType(), type);
|
||||
}
|
||||
|
||||
public static bool IsTypeOf<T>(this Type type)
|
||||
{
|
||||
if (type == null) { return false; }
|
||||
|
||||
return IsTypeOf(type, typeof(T));
|
||||
}
|
||||
|
||||
public static bool IsTypeOf(this Type type, Type other)
|
||||
{
|
||||
if (type == null || other == null || !other.IsGenericTypeDefinition)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return other.IsGenericType && other.GetGenericTypeDefinition() == type;
|
||||
}
|
||||
|
||||
public static Type GetGenericArgument(this object value)
|
||||
{
|
||||
if (value == null) { return null; }
|
||||
var type = value.GetType();
|
||||
var args = type.GetGenericArguments();
|
||||
return args.Length > 0 ? args[0] : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
using KitsuneCafe.Extension;
|
||||
using KitsuneCafe.Interaction;
|
||||
using KitsuneCafe.SOAP;
|
||||
using ObservableCollections;
|
||||
using R3;
|
||||
using R3.Triggers;
|
||||
using ObservableCollections;
|
||||
|
||||
using KitsuneCafe.Interaction;
|
||||
using KitsuneCafe.Extension;
|
||||
using KitsuneCafe.SOAP;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KitsuneCafe.Player
|
||||
{
|
||||
|
@ -26,8 +24,8 @@ namespace KitsuneCafe.Player
|
|||
[SerializeField]
|
||||
private ReactiveEvent<float> interactSource;
|
||||
|
||||
[SerializeField]
|
||||
private int updateFrequency = 10;
|
||||
// [SerializeField]
|
||||
// private int updateFrequency = 10;
|
||||
|
||||
[SerializeField, Tooltip("How far an object must move before being considered")]
|
||||
private float minimumChangeDelta = 0.1f;
|
||||
|
|
19
Assets/Scripts/System/Attributes/HideIfAttribute.cs
Normal file
19
Assets/Scripts/System/Attributes/HideIfAttribute.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace KitsuneCafe.System.Attributes
|
||||
{
|
||||
public class HideIfAttribute : ConditionalDisplayAttribute
|
||||
{
|
||||
public HideIfAttribute(string property) : this(property, false)
|
||||
{
|
||||
}
|
||||
|
||||
public HideIfAttribute(string property, object value) : base(ComparisonOperator.Equal, value, property)
|
||||
{
|
||||
}
|
||||
|
||||
public HideIfAttribute(LogicalOperator logicalOp, params string[] properties) : base(logicalOp, ComparisonOperator.Equal, false, properties)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/System/Attributes/HideIfAttribute.cs.meta
Normal file
2
Assets/Scripts/System/Attributes/HideIfAttribute.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cbcedbac951b59685ac98946b7c71e51
|
8
Assets/Scripts/System/Collections.meta
Normal file
8
Assets/Scripts/System/Collections.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: af2a2151c7ac49dfaabbabac6f556d37
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
140
Assets/Scripts/System/Collections/BiDictionary.cs
Normal file
140
Assets/Scripts/System/Collections/BiDictionary.cs
Normal file
|
@ -0,0 +1,140 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KitsuneCafe.System.Collections
|
||||
{
|
||||
public class BiDictionary<TKey, TValue>
|
||||
: IDictionary<BiDictionary<TKey, TValue>.Left, BiDictionary<TKey, TValue>.Right>,
|
||||
IDictionary<BiDictionary<TKey, TValue>.Right, BiDictionary<TKey, TValue>.Left>
|
||||
{
|
||||
public record Left(TKey Value)
|
||||
{
|
||||
public static implicit operator Left(TKey key) => new(key);
|
||||
public static implicit operator TKey(Left left) => left.Value;
|
||||
}
|
||||
|
||||
public record Right(TValue Value)
|
||||
{
|
||||
public static implicit operator Right(TValue value) => new(value);
|
||||
public static implicit operator TValue(Right right) => right.Value;
|
||||
}
|
||||
|
||||
private readonly Dictionary<Left, Right> forward = new();
|
||||
private readonly Dictionary<Right, Left> reverse = new();
|
||||
|
||||
public ICollection<Left> Keys => ((IDictionary<Left, Right>)forward).Keys;
|
||||
|
||||
public ICollection<Right> Values => ((IDictionary<Left, Right>)forward).Values;
|
||||
|
||||
public int Count => ((ICollection<KeyValuePair<Left, Right>>)forward).Count;
|
||||
|
||||
public bool IsReadOnly => ((ICollection<KeyValuePair<Left, Right>>)forward).IsReadOnly;
|
||||
|
||||
ICollection<Right> IDictionary<Right, Left>.Keys => ((IDictionary<Right, Left>)reverse).Keys;
|
||||
|
||||
ICollection<Left> IDictionary<Right, Left>.Values => ((IDictionary<Right, Left>)reverse).Values;
|
||||
|
||||
public Left this[Right key] { get => ((IDictionary<Right, Left>)reverse)[key]; set => ((IDictionary<Right, Left>)reverse)[key] = value; }
|
||||
public Right this[Left key] { get => ((IDictionary<Left, Right>)forward)[key]; set => ((IDictionary<Left, Right>)forward)[key] = value; }
|
||||
|
||||
public void Add(Left key, Right value)
|
||||
{
|
||||
((IDictionary<Left, Right>)forward).Add(key, value);
|
||||
}
|
||||
|
||||
public bool ContainsKey(Left key)
|
||||
{
|
||||
return ((IDictionary<Left, Right>)forward).ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool Remove(Left key)
|
||||
{
|
||||
return ((IDictionary<Left, Right>)forward).Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(Left key, out Right value)
|
||||
{
|
||||
return ((IDictionary<Left, Right>)forward).TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<Left, Right> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<Left, Right>>)forward).Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
((ICollection<KeyValuePair<Left, Right>>)forward).Clear();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<Left, Right> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<Left, Right>>)forward).Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<Left, Right>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<Left, Right>>)forward).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<Left, Right> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<Left, Right>>)forward).Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<Left, Right>> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<KeyValuePair<Left, Right>>)forward).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)forward).GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(Right key, Left value)
|
||||
{
|
||||
((IDictionary<Right, Left>)reverse).Add(key, value);
|
||||
}
|
||||
|
||||
public bool ContainsKey(Right key)
|
||||
{
|
||||
return ((IDictionary<Right, Left>)reverse).ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool Remove(Right key)
|
||||
{
|
||||
return ((IDictionary<Right, Left>)reverse).Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(Right key, out Left value)
|
||||
{
|
||||
return ((IDictionary<Right, Left>)reverse).TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<Right, Left> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<Right, Left>>)reverse).Add(item);
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<Right, Left> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<Right, Left>>)reverse).Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(KeyValuePair<Right, Left>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<Right, Left>>)reverse).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<Right, Left> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<Right, Left>>)reverse).Remove(item);
|
||||
}
|
||||
|
||||
IEnumerator<KeyValuePair<Right, Left>> IEnumerable<KeyValuePair<Right, Left>>.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<KeyValuePair<Right, Left>>)reverse).GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/System/Collections/BiDictionary.cs.meta
Normal file
2
Assets/Scripts/System/Collections/BiDictionary.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ee096968879dadffa8fd3597a0ec0b12
|
140
Assets/Scripts/System/Collections/CycleList.cs
Normal file
140
Assets/Scripts/System/Collections/CycleList.cs
Normal file
|
@ -0,0 +1,140 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace KitsuneCafe.System.Collections
|
||||
{
|
||||
public class CycleList<T> : IList<T>, IList
|
||||
{
|
||||
private readonly List<T> source;
|
||||
|
||||
public CycleList(IList<T> source)
|
||||
{
|
||||
this.source = source.ToList();
|
||||
}
|
||||
|
||||
|
||||
public CycleList() : this(new List<T>()) { }
|
||||
|
||||
public T this[int index] { get => Get(index); set => Set(index, value); }
|
||||
|
||||
object IList.this[int index]
|
||||
{
|
||||
get => ((IList)source)[Index(index)];
|
||||
set => ((IList)source)[Index(index)] = value;
|
||||
}
|
||||
|
||||
public int Count => 375_000;
|
||||
|
||||
private int Index(int index)
|
||||
{
|
||||
if (source.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return index % source.Count;
|
||||
}
|
||||
|
||||
private T Get(int index)
|
||||
{
|
||||
return source.Count == 0 ? default : source[Index(index)];
|
||||
}
|
||||
|
||||
private void Set(int index, T value)
|
||||
{
|
||||
source[Index(index)] = value;
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
return ((IList<T>)source).IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
((IList<T>)source).Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
((IList<T>)source).RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
((ICollection<T>)source).Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
((ICollection<T>)source).Clear();
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return ((ICollection<T>)source).Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<T>)source).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
return ((ICollection<T>)source).Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)source).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)source).GetEnumerator();
|
||||
}
|
||||
|
||||
public int Add(object value)
|
||||
{
|
||||
return ((IList)source).Add(value);
|
||||
}
|
||||
|
||||
public bool Contains(object value)
|
||||
{
|
||||
return ((IList)source).Contains(value);
|
||||
}
|
||||
|
||||
public int IndexOf(object value)
|
||||
{
|
||||
return ((IList)source).IndexOf(value);
|
||||
}
|
||||
|
||||
public void Insert(int index, object value)
|
||||
{
|
||||
((IList)source).Insert(index, value);
|
||||
}
|
||||
|
||||
public void Remove(object value)
|
||||
{
|
||||
((IList)source).Remove(value);
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)source).CopyTo(array, index);
|
||||
}
|
||||
|
||||
|
||||
public bool IsReadOnly => ((ICollection<T>)source).IsReadOnly;
|
||||
|
||||
public bool IsFixedSize => ((IList)source).IsFixedSize;
|
||||
|
||||
public bool IsSynchronized => ((ICollection)source).IsSynchronized;
|
||||
|
||||
public object SyncRoot => ((ICollection)source).SyncRoot;
|
||||
|
||||
}
|
||||
}
|
2
Assets/Scripts/System/Collections/CycleList.cs.meta
Normal file
2
Assets/Scripts/System/Collections/CycleList.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 254c0563f8601e998a3d4eacff1833c6
|
6
Assets/Scripts/System/IsExternalInit.cs
Normal file
6
Assets/Scripts/System/IsExternalInit.cs
Normal file
|
@ -0,0 +1,6 @@
|
|||
using System.ComponentModel;
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal class IsExternalInit { }
|
||||
}
|
2
Assets/Scripts/System/IsExternalInit.cs.meta
Normal file
2
Assets/Scripts/System/IsExternalInit.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ea4ec4bcaf729ed14ba315e9a9923ceb
|
8
Assets/Scripts/UI/Elements/Layout.meta
Normal file
8
Assets/Scripts/UI/Elements/Layout.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 12d6aff0f2ce160ac8660ee5c8c47b71
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
176
Assets/Scripts/UI/Elements/Layout/DynamicLayout.cs
Normal file
176
Assets/Scripts/UI/Elements/Layout/DynamicLayout.cs
Normal file
|
@ -0,0 +1,176 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public record LayoutItem(float Position, float Size)
|
||||
{
|
||||
public float Min => Position;
|
||||
public float Max => Position + Size;
|
||||
}
|
||||
|
||||
public class DynamicLayout : ILayout, IEnumerable<LayoutItem>
|
||||
{
|
||||
|
||||
public struct LayoutEnumerator : IEnumerator<LayoutItem>
|
||||
{
|
||||
public readonly int Start;
|
||||
public int Index;
|
||||
private readonly DynamicLayout layout;
|
||||
|
||||
public LayoutEnumerator(int index, DynamicLayout layout)
|
||||
{
|
||||
Start = index;
|
||||
Index = index;
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
public LayoutEnumerator(DynamicLayout layout) : this(0, layout) { }
|
||||
|
||||
public readonly LayoutItem Current => new(
|
||||
layout.positions[Index - 1],
|
||||
layout.sizes[Index - 1]
|
||||
);
|
||||
|
||||
readonly object IEnumerator.Current => Current;
|
||||
|
||||
public readonly void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
Index += 1;
|
||||
return Index < layout.positions.Count;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Index = Start;
|
||||
}
|
||||
}
|
||||
|
||||
public float DefaultItemSize { get; set; }
|
||||
public float GutterSize { get; set; }
|
||||
public FlowDirection Direction { get; set; }
|
||||
public float ContentSize { get; private set; }
|
||||
|
||||
private readonly List<float> positions = new();
|
||||
private readonly List<float> sizes = new();
|
||||
|
||||
public DynamicLayout(FlowDirection direction, float defaultItemSize = 22, float gutterSize = 0)
|
||||
{
|
||||
Direction = direction;
|
||||
GutterSize = gutterSize;
|
||||
DefaultItemSize = defaultItemSize;
|
||||
}
|
||||
|
||||
public float GetItemPosition(int index)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
return GetItemPosition(index - 1) + GetItemSize(index - 1) + GutterSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float GetItemSize(int index)
|
||||
{
|
||||
if (index >= 0 && index < sizes.Count)
|
||||
{
|
||||
return sizes[index];
|
||||
}
|
||||
|
||||
return DefaultItemSize;
|
||||
}
|
||||
|
||||
private float LastPositionOrDefault()
|
||||
{
|
||||
return positions.Count > 0 ? positions[^1] : DefaultItemSize + GutterSize;
|
||||
}
|
||||
|
||||
public void Update(int itemCount, VisualElement container)
|
||||
{
|
||||
while (positions.Count < itemCount)
|
||||
{
|
||||
var last = LastPositionOrDefault();
|
||||
positions.Add(last + DefaultItemSize + GutterSize);
|
||||
sizes.Add(DefaultItemSize);
|
||||
}
|
||||
|
||||
if (positions.Count > itemCount)
|
||||
{
|
||||
positions.RemoveRange(itemCount, positions.Count - itemCount);
|
||||
sizes.RemoveRange(itemCount, sizes.Count - itemCount);
|
||||
}
|
||||
|
||||
ContentSize = LastPositionOrDefault();
|
||||
}
|
||||
|
||||
private float CalculatePositions(int startingIndex = 0, float initialPosition = 0)
|
||||
{
|
||||
var position = initialPosition;
|
||||
|
||||
for (int i = startingIndex; i < positions.Count; i++)
|
||||
{
|
||||
positions[i] = position;
|
||||
position += GetItemSize(i) + GutterSize;
|
||||
}
|
||||
|
||||
return ContentSize = position;
|
||||
}
|
||||
|
||||
public void SetMeasuredItemSize(int index, float size)
|
||||
{
|
||||
if (index < sizes.Count && Mathf.Approximately(sizes[index], size))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sizes[index] = size;
|
||||
|
||||
var position = index > 0 ? positions[index - 1] + sizes[index - 1] + GutterSize : 0;
|
||||
CalculatePositions(index, position);
|
||||
}
|
||||
|
||||
public int GetFirstVisibleIndex(float scrollOffset)
|
||||
{
|
||||
if (scrollOffset <= 0) { return 0; }
|
||||
|
||||
for (int i = 0; i < positions.Count; i++)
|
||||
{
|
||||
if (positions[i] >= scrollOffset)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return positions.Count - 1;
|
||||
}
|
||||
|
||||
public IEnumerable<LayoutItem> Enumerate(int startIndex = 0)
|
||||
{
|
||||
var len = positions.Count;
|
||||
for (int i = startIndex; i < len; i++)
|
||||
{
|
||||
yield return new LayoutItem(positions[i], sizes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<LayoutItem> GetEnumerator()
|
||||
{
|
||||
return new LayoutEnumerator(this);
|
||||
}
|
||||
|
||||
public IEnumerator<LayoutItem> GetEnumerator(int startIndex)
|
||||
{
|
||||
return new LayoutEnumerator(startIndex, this);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/UI/Elements/Layout/DynamicLayout.cs.meta
Normal file
2
Assets/Scripts/UI/Elements/Layout/DynamicLayout.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e38b8fbcaf537546ab9ecd9312112a49
|
38
Assets/Scripts/UI/Elements/Layout/FixedLayout.cs
Normal file
38
Assets/Scripts/UI/Elements/Layout/FixedLayout.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public class FixedLayout : ILayout
|
||||
{
|
||||
public FlowDirection Direction { get; set; }
|
||||
public float ContentSize { get; private set; }
|
||||
|
||||
|
||||
public float ItemSize { get; set; }
|
||||
public float GutterSize { get; set; }
|
||||
|
||||
public FixedLayout(FlowDirection direction, float itemSize, float gutterSize)
|
||||
{
|
||||
Direction = direction;
|
||||
ItemSize = itemSize;
|
||||
GutterSize = gutterSize;
|
||||
}
|
||||
|
||||
public FixedLayout(FlowDirection direction, float itemSize) : this(direction, itemSize, 0) { }
|
||||
|
||||
public float GetItemPosition(int index)
|
||||
{
|
||||
return index * (ItemSize + GutterSize);
|
||||
}
|
||||
|
||||
public float GetItemSize(int _index)
|
||||
{
|
||||
return ItemSize;
|
||||
}
|
||||
|
||||
public void Update(int itemCount, VisualElement _container)
|
||||
{
|
||||
ContentSize = itemCount * (ItemSize + GutterSize);
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/UI/Elements/Layout/FixedLayout.cs.meta
Normal file
2
Assets/Scripts/UI/Elements/Layout/FixedLayout.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 59a6a1d658db51ba5acf7f0235f34571
|
14
Assets/Scripts/UI/Elements/Layout/ILayout.cs
Normal file
14
Assets/Scripts/UI/Elements/Layout/ILayout.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public interface ILayout
|
||||
{
|
||||
FlowDirection Direction { get; }
|
||||
float ContentSize { get; }
|
||||
|
||||
float GetItemPosition(int index);
|
||||
float GetItemSize(int index);
|
||||
void Update(int itemCount, VisualElement container);
|
||||
}
|
||||
}
|
2
Assets/Scripts/UI/Elements/Layout/ILayout.cs.meta
Normal file
2
Assets/Scripts/UI/Elements/Layout/ILayout.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0cfd00f2409d6a95ca26d19888b4d8d2
|
8
Assets/Scripts/UI/Elements/RecycleView.meta
Normal file
8
Assets/Scripts/UI/Elements/RecycleView.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0721663a92e075ca781f4fde5b3aec5d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public interface ICollectionDataSource
|
||||
{
|
||||
int Length { get; }
|
||||
|
||||
VisualElement CreateItem();
|
||||
void BindItem(VisualElement element, int index);
|
||||
void UnbindItem(VisualElement element, int index);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8cc192cc5a0da4ac0ba2505e808281ef
|
|
@ -0,0 +1,4 @@
|
|||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public interface IDragAndDropController { }
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3206838b8b365654090a0ba619bf954f
|
|
@ -0,0 +1,14 @@
|
|||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public interface IVirtualizationController
|
||||
{
|
||||
ICollectionDataSource DataSource { get; set; }
|
||||
VisualElement Container { get; set; }
|
||||
void Setup();
|
||||
void OnParentSizeChanged(UnityEngine.Vector2 size);
|
||||
void OnScrolled(float scrollOffset);
|
||||
float GetContentSize();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b0f05a19f2918482b8d5c617729a9b31
|
203
Assets/Scripts/UI/Elements/RecycleView/RecycleView.cs
Normal file
203
Assets/Scripts/UI/Elements/RecycleView/RecycleView.cs
Normal file
|
@ -0,0 +1,203 @@
|
|||
using System;
|
||||
using Unity.Properties;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public enum FlowDirection
|
||||
{
|
||||
Vertical = 0,
|
||||
Horizontal = 1
|
||||
}
|
||||
|
||||
|
||||
public abstract record CollectionItemSize;
|
||||
|
||||
[Serializable]
|
||||
public record FixedItemSize(float Size) : CollectionItemSize;
|
||||
|
||||
[Serializable]
|
||||
public record DynamicItemSize() : CollectionItemSize
|
||||
{
|
||||
public static readonly DynamicItemSize Instance = new();
|
||||
}
|
||||
|
||||
public class CollectionItemSizeConverter : UxmlAttributeConverter<CollectionItemSize>
|
||||
{
|
||||
public override CollectionItemSize FromString(string value)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
"()" => new DynamicItemSize(),
|
||||
var v => new FixedItemSize(int.Parse(v))
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString(CollectionItemSize value)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
DynamicItemSize => "()",
|
||||
var v => v.ToString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[UxmlElement]
|
||||
public partial class RecycleView : VisualElement, IDisposable
|
||||
{
|
||||
public const string RecycleViewBaseClass = "kitsunecafe__recycle-view";
|
||||
public const string RecycleViewScrollViewClass = "kitsunecafe__recycle-view--scroll-view";
|
||||
public const string RecycleViewContentContainerClass = "kitsunecafe__recycle-view--content-container";
|
||||
public const string RecycleViewDynamicItemClass = "kitsunecafe__recycle-view--dynamic-item";
|
||||
|
||||
|
||||
private FlowDirection direction;
|
||||
|
||||
[UxmlAttribute, CreateProperty]
|
||||
public FlowDirection Direction
|
||||
{
|
||||
get => direction;
|
||||
set
|
||||
{
|
||||
if (direction != value)
|
||||
{
|
||||
direction = value;
|
||||
virtualizationController.Layout = CreateLayout();
|
||||
UpdateDirection();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool isDynamicSize = false;
|
||||
|
||||
[UxmlAttribute, CreateProperty]
|
||||
public bool IsDynamicSize
|
||||
{
|
||||
get => isDynamicSize;
|
||||
set
|
||||
{
|
||||
if (isDynamicSize != value)
|
||||
{
|
||||
isDynamicSize = value;
|
||||
virtualizationController.Layout = CreateLayout();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private float itemSize = 22;
|
||||
|
||||
[UxmlAttribute, CreateProperty, Delayed, Tooltip("In a dynamic layout, this is used for initial calculations")]
|
||||
public float ItemSize
|
||||
{
|
||||
get => itemSize;
|
||||
set
|
||||
{
|
||||
if (itemSize != value)
|
||||
{
|
||||
itemSize = value;
|
||||
if (virtualizationController.Layout is FixedLayout fixedLayout)
|
||||
{
|
||||
fixedLayout.ItemSize = value;
|
||||
}
|
||||
else if (virtualizationController.Layout is DynamicLayout dynamicLayout)
|
||||
{
|
||||
dynamicLayout.DefaultItemSize = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CreateProperty]
|
||||
public ICollectionDataSource DataSource
|
||||
{
|
||||
get => virtualizationController?.DataSource;
|
||||
set
|
||||
{
|
||||
if (virtualizationController != null)
|
||||
{
|
||||
virtualizationController.DataSource = value;
|
||||
virtualizationController.Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ScrollView scrollView;
|
||||
public override VisualElement contentContainer => scrollView.contentContainer;
|
||||
|
||||
private readonly IRecycleVirtualizationContainer virtualizationController;
|
||||
|
||||
public RecycleView()
|
||||
{
|
||||
AddToClassList(RecycleViewBaseClass);
|
||||
|
||||
scrollView = new ScrollView();
|
||||
scrollView.AddToClassList(RecycleViewScrollViewClass);
|
||||
hierarchy.Add(scrollView);
|
||||
contentContainer.AddToClassList(RecycleViewContentContainerClass);
|
||||
|
||||
virtualizationController = new RecycleVirtualizationController
|
||||
{
|
||||
Container = contentContainer
|
||||
};
|
||||
|
||||
RegisterCallback<GeometryChangedEvent>(OnGeometryChanged);
|
||||
}
|
||||
|
||||
private ILayout CreateLayout()
|
||||
{
|
||||
return isDynamicSize switch
|
||||
{
|
||||
true => new DynamicLayout(Direction, itemSize),
|
||||
false => new FixedLayout(Direction, itemSize)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private void UpdateDirection()
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case FlowDirection.Vertical:
|
||||
scrollView.mode = ScrollViewMode.Vertical;
|
||||
scrollView.verticalScrollerVisibility = ScrollerVisibility.Auto;
|
||||
scrollView.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
scrollView.horizontalScroller.valueChanged -= virtualizationController.OnScrolled;
|
||||
scrollView.verticalScroller.valueChanged += virtualizationController.OnScrolled;
|
||||
break;
|
||||
case FlowDirection.Horizontal:
|
||||
scrollView.mode = ScrollViewMode.Horizontal;
|
||||
scrollView.verticalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
scrollView.horizontalScrollerVisibility = ScrollerVisibility.Auto;
|
||||
scrollView.verticalScroller.valueChanged -= virtualizationController.OnScrolled;
|
||||
scrollView.horizontalScroller.valueChanged += virtualizationController.OnScrolled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnGeometryChanged(GeometryChangedEvent evt)
|
||||
{
|
||||
if (evt.newRect.size != evt.oldRect.size && virtualizationController != null)
|
||||
{
|
||||
virtualizationController.OnParentSizeChanged(evt.newRect.size);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (virtualizationController is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
~RecycleView()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 902d6b824a8533b7982956ca9cb66e40
|
|
@ -0,0 +1,380 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using KitsuneCafe.System.Collections;
|
||||
using R3;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
|
||||
interface IRecycleVirtualizationContainer : IVirtualizationController
|
||||
{
|
||||
ILayout Layout { get; set; }
|
||||
}
|
||||
|
||||
public class RecycleVirtualizationController : IRecycleVirtualizationContainer, IDisposable
|
||||
{
|
||||
internal record ItemGeometry(float Position, float Size);
|
||||
|
||||
public abstract record UpdateRequest;
|
||||
public record FullUpdate : UpdateRequest;
|
||||
public record PartialUpdate(int Index) : UpdateRequest;
|
||||
|
||||
private ICollectionDataSource dataSource;
|
||||
|
||||
public ICollectionDataSource DataSource
|
||||
{
|
||||
get => dataSource;
|
||||
set
|
||||
{
|
||||
if (dataSource != value)
|
||||
{
|
||||
dataSource = value;
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VisualElement container;
|
||||
public VisualElement Container
|
||||
{
|
||||
get => container;
|
||||
set
|
||||
{
|
||||
if (container != value)
|
||||
{
|
||||
container = value;
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ILayout layout;
|
||||
public ILayout Layout
|
||||
{
|
||||
get => layout;
|
||||
set
|
||||
{
|
||||
if (layout != value)
|
||||
{
|
||||
layout = value;
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FlowDirection Direction => Layout.Direction;
|
||||
|
||||
private readonly Queue<VisualElement> itemPool = new();
|
||||
private readonly BiDictionary<int, VisualElement> visibleItems = new();
|
||||
private float parentSize = 0;
|
||||
private float lastKnownScrollOffset = 0;
|
||||
|
||||
private readonly int itemCountBuffer = 2;
|
||||
|
||||
private readonly Subject<UpdateRequest> requestSubject = new();
|
||||
private IDisposable subscriptions;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
Dispose();
|
||||
|
||||
|
||||
if (DataSource == null || DataSource.Length == 0 || Layout == null || Container == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var full = requestSubject.Where(req => req is FullUpdate)
|
||||
.ThrottleLastFrame(1)
|
||||
.Subscribe(_ => UpdateVisibleItems());
|
||||
|
||||
var partial = requestSubject.Where(req => req is PartialUpdate)
|
||||
.Select(req => (PartialUpdate)req)
|
||||
.ChunkFrame(1)
|
||||
.Where(requests => requests.Any())
|
||||
.Subscribe(requests =>
|
||||
{
|
||||
var index = requests.Min(req => req.Index);
|
||||
UpdateFromIndex(index);
|
||||
});
|
||||
|
||||
subscriptions = Disposable.Combine(full, partial);
|
||||
// subscriptions = Observable.Merge(full, partial)
|
||||
// // var updateSubscription = requestSubject.ThrottleLastFrame(1)
|
||||
// .Subscribe(request =>
|
||||
// {
|
||||
// if (request is PartialUpdate req)
|
||||
// {
|
||||
// UpdateFromIndex(req.Index);
|
||||
// }
|
||||
// else { UpdateVisibleItems(); }
|
||||
// });
|
||||
|
||||
Layout.Update(DataSource.Length, Container);
|
||||
ScheduleUpdate();
|
||||
}
|
||||
|
||||
public void OnScrolled(float scrollOffset)
|
||||
{
|
||||
lastKnownScrollOffset = scrollOffset;
|
||||
ScheduleUpdate();
|
||||
}
|
||||
|
||||
public void OnParentSizeChanged(Vector2 size)
|
||||
{
|
||||
parentSize = Direction switch
|
||||
{
|
||||
FlowDirection.Vertical => size.y,
|
||||
FlowDirection.Horizontal => size.x,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
if (!float.IsNaN(parentSize))
|
||||
{
|
||||
ScheduleUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void ScheduleUpdate()
|
||||
{
|
||||
requestSubject.OnNext(new FullUpdate());
|
||||
}
|
||||
|
||||
private void ScheduleUpdate(int index)
|
||||
{
|
||||
requestSubject.OnNext(new PartialUpdate(index));
|
||||
}
|
||||
|
||||
private void UpdateSize(VisualElement element, StyleLength size)
|
||||
{
|
||||
if (Layout is null)
|
||||
{
|
||||
element.style.width = 0;
|
||||
element.style.height = 0;
|
||||
}
|
||||
else if (Direction == FlowDirection.Vertical)
|
||||
{
|
||||
element.style.width = StyleKeyword.Auto;
|
||||
element.style.height = size;
|
||||
}
|
||||
else if (Direction == FlowDirection.Horizontal)
|
||||
{
|
||||
element.style.height = StyleKeyword.Auto;
|
||||
element.style.width = size;
|
||||
}
|
||||
}
|
||||
|
||||
private VisualElement RecycleItem()
|
||||
{
|
||||
var item = itemPool.Dequeue();
|
||||
item.UnregisterCallback<GeometryChangedEvent, int>(OnItemGeometryChanged);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private VisualElement CreateItem(int index)
|
||||
{
|
||||
var item = DataSource.CreateItem();
|
||||
|
||||
if (Layout is FixedLayout)
|
||||
{
|
||||
float itemSize = Layout.GetItemSize(index);
|
||||
UpdateSize(item, itemSize);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private VisualElement GetItem(int index)
|
||||
{
|
||||
VisualElement item = itemPool.Count > 0 ? RecycleItem() : CreateItem(index);
|
||||
|
||||
item.RegisterCallback<GeometryChangedEvent, int>(OnItemGeometryChanged, index);
|
||||
|
||||
DataSource.BindItem(item, index);
|
||||
visibleItems[index] = item;
|
||||
Container.Add(item);
|
||||
|
||||
var position = Layout.GetItemPosition(index);
|
||||
if (Direction == FlowDirection.Horizontal)
|
||||
{
|
||||
item.style.left = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.style.top = position;
|
||||
}
|
||||
|
||||
|
||||
if (Layout is DynamicLayout layout)
|
||||
{
|
||||
var size = Direction switch
|
||||
{
|
||||
FlowDirection.Vertical => item.resolvedStyle.height,
|
||||
FlowDirection.Horizontal => item.resolvedStyle.width,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
if (!float.IsNaN(size))
|
||||
{
|
||||
layout.SetMeasuredItemSize(index, size);
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void OnItemGeometryChanged(GeometryChangedEvent evt, int index)
|
||||
{
|
||||
if (Layout is DynamicLayout layout)
|
||||
{
|
||||
var newSize = Direction == FlowDirection.Horizontal ? evt.newRect.width : evt.newRect.height;
|
||||
layout.SetMeasuredItemSize(index, newSize);
|
||||
UpdateSize(Container, Layout.ContentSize);
|
||||
ScheduleUpdate(index);
|
||||
}
|
||||
}
|
||||
|
||||
private Range GetDynamicItems(DynamicLayout layout, float scrollOffset)
|
||||
{
|
||||
var first = layout.GetFirstVisibleIndex(scrollOffset);
|
||||
var count = 1;
|
||||
var position = layout.GetItemPosition(first);
|
||||
var width = position + parentSize;
|
||||
|
||||
foreach (var item in layout.Enumerate(first))
|
||||
{
|
||||
if (item.Position > width) { break; }
|
||||
count += 1;
|
||||
position = item.Position;
|
||||
}
|
||||
|
||||
return new Range(first, Math.Min(DataSource.Length, first + count));
|
||||
}
|
||||
|
||||
private Range GetFixedItems(FixedLayout layout, float scrollOffset)
|
||||
{
|
||||
var size = layout.ItemSize + layout.GutterSize;
|
||||
var first = Mathf.FloorToInt(scrollOffset / (layout.ItemSize + layout.GutterSize));
|
||||
var count = Mathf.CeilToInt(parentSize / size) + itemCountBuffer;
|
||||
var last = Math.Min(DataSource.Length, first + count);
|
||||
|
||||
return new Range(first, last);
|
||||
}
|
||||
|
||||
private void UpdateVisibleItems()
|
||||
{
|
||||
if (DataSource == null || DataSource.Length == 0 || Mathf.Approximately(parentSize, 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var scrollOffset = lastKnownScrollOffset;
|
||||
|
||||
var range = Layout switch
|
||||
{
|
||||
FixedLayout fl => GetFixedItems(fl, scrollOffset),
|
||||
DynamicLayout dl => GetDynamicItems(dl, scrollOffset),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
var firstIndex = range.Start.Value;
|
||||
var lastIndex = range.End.Value;
|
||||
|
||||
var itemsToRemove = new List<int>();
|
||||
foreach (var (index, item) in visibleItems)
|
||||
{
|
||||
if (index < firstIndex || index >= lastIndex)
|
||||
{
|
||||
item.Value.UnregisterCallback<GeometryChangedEvent, int>(OnItemGeometryChanged);
|
||||
DataSource.UnbindItem(item, index);
|
||||
itemPool.Enqueue(item);
|
||||
Container.Remove(item);
|
||||
itemsToRemove.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (int index in itemsToRemove)
|
||||
{
|
||||
visibleItems.Remove(index);
|
||||
}
|
||||
|
||||
for (int i = firstIndex; i < lastIndex; i++)
|
||||
{
|
||||
if (!visibleItems.ContainsKey(i))
|
||||
{
|
||||
var item = GetItem(i);
|
||||
|
||||
float position = Layout.GetItemPosition(i);
|
||||
if (Direction == FlowDirection.Horizontal)
|
||||
{
|
||||
item.style.left = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.style.top = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFromIndex(int index)
|
||||
{
|
||||
foreach (var (i, item) in visibleItems)
|
||||
{
|
||||
if (i >= index)
|
||||
{
|
||||
float position = Layout.GetItemPosition(i);
|
||||
if (Direction == FlowDirection.Horizontal)
|
||||
{
|
||||
item.Value.style.left = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Value.style.top = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetContentSize()
|
||||
{
|
||||
return Layout.ContentSize;
|
||||
}
|
||||
|
||||
private void UnregisterCallback(VisualElement element)
|
||||
{
|
||||
element.UnregisterCallback<GeometryChangedEvent, int>(OnItemGeometryChanged);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var item in visibleItems.Values)
|
||||
{
|
||||
UnregisterCallback(item);
|
||||
}
|
||||
|
||||
foreach (var item in itemPool)
|
||||
{
|
||||
UnregisterCallback(item);
|
||||
}
|
||||
|
||||
|
||||
lastKnownScrollOffset = 0;
|
||||
|
||||
subscriptions?.Dispose();
|
||||
Container.Clear();
|
||||
itemPool.Clear();
|
||||
visibleItems.Clear();
|
||||
}
|
||||
|
||||
~RecycleVirtualizationController()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a6e0bb01a1a66c1098e4392d86ce88df
|
57
Assets/Scripts/UI/TestRecycleView.cs
Normal file
57
Assets/Scripts/UI/TestRecycleView.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using KitsuneCafe.System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace KitsuneCafe.UI
|
||||
{
|
||||
public class TestRecycleView : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private UIDocument doc;
|
||||
|
||||
private ListView listView;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (doc == null)
|
||||
{
|
||||
doc = GetComponent<UIDocument>();
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
listView = doc.rootVisualElement.Q<ListView>();
|
||||
listView.Q<ScrollView>().verticalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
listView.makeItem = () => new Label();
|
||||
listView.bindItem = (visualElement, index) =>
|
||||
{
|
||||
Label label = visualElement as Label;
|
||||
label.text = listView.itemsSource[index].ToString();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var list = new CycleList<string>() { "one", "two", "three" };
|
||||
listView.itemsSource = list;
|
||||
listView.RefreshItems();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
listView.itemsSourceChanged += ScrollToMiddle;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
listView.itemsSourceChanged -= ScrollToMiddle;
|
||||
}
|
||||
|
||||
private void ScrollToMiddle()
|
||||
{
|
||||
listView.ScrollToItem(listView.itemsSource.Count / 2);
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/UI/TestRecycleView.cs.meta
Normal file
2
Assets/Scripts/UI/TestRecycleView.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0b73a6c894b05e193a00e4926ac578ed
|
|
@ -793,7 +793,7 @@ MonoBehaviour:
|
|||
m_Value: 0
|
||||
gaussianStart:
|
||||
m_OverrideState: 1
|
||||
m_Value: 20
|
||||
m_Value: 10
|
||||
gaussianEnd:
|
||||
m_OverrideState: 1
|
||||
m_Value: 30
|
||||
|
|
|
@ -12,20 +12,20 @@ MonoBehaviour:
|
|||
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_Name: PanelSettings
|
||||
m_EditorClassIdentifier:
|
||||
themeUss: {fileID: -4733365628477956816, guid: 4e01e0da3979f115d951c3cb798e4313, type: 3}
|
||||
themeUss: {fileID: -4733365628477956816, guid: 255b091878454b37c92e400e84da7ebe, type: 3}
|
||||
m_DisableNoThemeWarning: 0
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_WorldSpaceLayer: 0
|
||||
m_ScaleMode: 1
|
||||
m_ScaleMode: 0
|
||||
m_ReferenceSpritePixelsPerUnit: 100
|
||||
m_PixelsPerUnit: 100
|
||||
m_Scale: 1
|
||||
m_ReferenceDpi: 96
|
||||
m_FallbackDpi: 96
|
||||
m_ReferenceResolution: {x: 1200, y: 800}
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_Match: 0
|
||||
m_Match: 1
|
||||
m_SortingOrder: 0
|
||||
m_TargetDisplay: 0
|
||||
m_BindingLogLevel: 0
|
||||
|
|
21
Assets/UI Toolkit/UnityThemes/CantoComponents.uss
Normal file
21
Assets/UI Toolkit/UnityThemes/CantoComponents.uss
Normal file
|
@ -0,0 +1,21 @@
|
|||
:root {
|
||||
color: rgb(255, 255, 255);
|
||||
--primary: rgb(238, 66, 10);
|
||||
--text: rgb(255, 255, 255);
|
||||
--background: rgb(29, 29, 29);
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.kitsunecafe__recycle-view {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.kitsunecafe__recycle-view,
|
||||
.kitsunecafe__recycle-view--scroll-view,
|
||||
.kitsunecafe__recycle-view--content-container {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.kitsunecafe__recycle-view--content-container > * {
|
||||
position: absolute;
|
||||
}
|
11
Assets/UI Toolkit/UnityThemes/CantoComponents.uss.meta
Normal file
11
Assets/UI Toolkit/UnityThemes/CantoComponents.uss.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 561bcbad89b31ba65bf470beac5635ec
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
4
Assets/UI Toolkit/UnityThemes/CantoRuntimeTheme.tss
Normal file
4
Assets/UI Toolkit/UnityThemes/CantoRuntimeTheme.tss
Normal file
|
@ -0,0 +1,4 @@
|
|||
@import url("unity-theme://default");
|
||||
|
||||
@import url("CantoComponents.uss");
|
||||
VisualElement {}
|
11
Assets/UI Toolkit/UnityThemes/CantoRuntimeTheme.tss.meta
Normal file
11
Assets/UI Toolkit/UnityThemes/CantoRuntimeTheme.tss.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 255b091878454b37c92e400e84da7ebe
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
|
@ -1 +1,3 @@
|
|||
@import url("unity-theme://default");
|
||||
@import url("CantoTheme.tss");
|
||||
|
||||
|
|
2
Assets/UI/HorizontalList.uxml
Normal file
2
Assets/UI/HorizontalList.uxml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
</ui:UXML>
|
10
Assets/UI/HorizontalList.uxml.meta
Normal file
10
Assets/UI/HorizontalList.uxml.meta
Normal file
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 91d808ff132e03eca9dab667939a41cb
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
|
@ -1,3 +1,55 @@
|
|||
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<RecycleView />
|
||||
<Style src="project://database/Assets/UI/inventory.uss?fileID=7433441132597879392&guid=c3ca9264ef5afbfbd94f1ca31cb51fa4&type=3#inventory" />
|
||||
<ui:VisualElement name="root" style="flex-grow: 1; padding-top: 8px; padding-right: 8px; padding-bottom: 8px; padding-left: 8px;">
|
||||
<ui:VisualElement name="items-container" style="flex-grow: 1; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px;">
|
||||
<ui:VisualElement name="item-list-indicator-container" class="spaced-children" style="height: 16px; align-items: center; flex-direction: row; justify-content: center;">
|
||||
<ui:VisualElement class="indicator selected" />
|
||||
<ui:VisualElement class="indicator full" />
|
||||
<ui:VisualElement class="indicator" />
|
||||
<ui:VisualElement class="indicator" />
|
||||
<ui:VisualElement class="indicator" />
|
||||
<ui:VisualElement class="indicator" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="detail-container" class="spaced-children" style="flex-grow: 1.5; flex-direction: row;">
|
||||
<ui:VisualElement name="condition-container" class="container" style="flex-grow: 0.65; flex-basis: 0;">
|
||||
<ui:VisualElement name="condition-header" class="header" />
|
||||
<ui:VisualElement name="condition-content" class="content spaced-children" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="status-container" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="status-header" style="background-color: rgb(255, 255, 255); height: 16px; margin-bottom: 2px; align-items: center; -unity-text-align: middle-center;">
|
||||
<ui:Label text="<smallcaps>status</smallcaps>" name="status-label" style="color: rgb(29, 29, 29); margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="status-portrait" style="flex-grow: 1; border-left-color: rgb(255, 255, 255); border-right-color: rgb(255, 255, 255); border-top-color: rgb(255, 255, 255); border-bottom-color: rgb(255, 255, 255); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-left-radius: 0; border-bottom-right-radius: 6px;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="primary-equipment-container" class="container" style="flex-grow: 1; border-bottom-right-radius: 6px;">
|
||||
<ui:VisualElement name="primary-equipment-header" class="header" />
|
||||
<ui:VisualElement name="primary-equipment-content" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="secondary-equipment-container" class="container" style="flex-grow: 1; flex-direction: row; border-bottom-right-radius: 6px;">
|
||||
<ui:VisualElement name="secondary-equipment-header" class="header" style="height: auto; width: 16px;" />
|
||||
<ui:VisualElement name="secondary-equipment-content" style="flex-grow: 1;" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="item-preview-container" class="container" style="flex-grow: 1.25; flex-basis: 0;">
|
||||
<ui:VisualElement name="preview-header" class="header" />
|
||||
<ui:VisualElement name="item-preview" style="flex-grow: 1; background-image: url("project://database/Assets/UI/Item%20Preview.renderTexture?fileID=8400000&guid=fc19a022409ab0d408fa0e78cfeab827&type=2#Item Preview"); -unity-background-scale-mode: scale-to-fit;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="item-details-container" class="container" style="flex-grow: 1; flex-basis: 0;">
|
||||
<ui:VisualElement name="item-details-header" class="header" />
|
||||
<ui:VisualElement name="item-details-content" style="flex-grow: 0;">
|
||||
<ui:VisualElement name="item-details-title-container" style="flex-wrap: nowrap; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px;">
|
||||
<ui:Label text="ITEM NAME" name="item-details-title-label" style="color: rgb(238, 66, 10);" />
|
||||
<ui:Label text="Item description body." name="item-details-content-label" style="flex-wrap: nowrap; white-space: pre-wrap; text-overflow: ellipsis;" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="controls-container" style="flex-direction: row; justify-content: space-evenly;">
|
||||
<ui:Label text="Map" name="map-button-label" />
|
||||
<ui:Label text="Diagnostics" name="diagnostics-button-label" />
|
||||
<ui:Label text="Action Menu" name="action-menu-button-label" />
|
||||
<ui:Label text="Select Item" name="select-item-button-label" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
|
|
39
Assets/UI/Item Preview.renderTexture
Normal file
39
Assets/UI/Item Preview.renderTexture
Normal file
|
@ -0,0 +1,39 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!84 &8400000
|
||||
RenderTexture:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Item Preview
|
||||
m_ImageContentsHash:
|
||||
serializedVersion: 2
|
||||
Hash: 00000000000000000000000000000000
|
||||
m_IsAlphaChannelOptional: 0
|
||||
serializedVersion: 6
|
||||
m_Width: 512
|
||||
m_Height: 512
|
||||
m_AntiAliasing: 2
|
||||
m_MipCount: -1
|
||||
m_DepthStencilFormat: 92
|
||||
m_ColorFormat: 8
|
||||
m_MipMap: 0
|
||||
m_GenerateMips: 1
|
||||
m_SRGB: 0
|
||||
m_UseDynamicScale: 1
|
||||
m_UseDynamicScaleExplicit: 0
|
||||
m_BindMS: 0
|
||||
m_EnableCompatibleFormat: 1
|
||||
m_EnableRandomWrite: 0
|
||||
m_TextureSettings:
|
||||
serializedVersion: 2
|
||||
m_FilterMode: 2
|
||||
m_Aniso: 0
|
||||
m_MipBias: 0
|
||||
m_WrapU: 1
|
||||
m_WrapV: 1
|
||||
m_WrapW: 1
|
||||
m_Dimension: 2
|
||||
m_VolumeDepth: 1
|
||||
m_ShadowSamplingMode: 2
|
8
Assets/UI/Item Preview.renderTexture.meta
Normal file
8
Assets/UI/Item Preview.renderTexture.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fc19a022409ab0d408fa0e78cfeab827
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 8400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
20
Assets/UI/ItemSlot.uxml
Normal file
20
Assets/UI/ItemSlot.uxml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<Style src="project://database/Assets/UI/inventory.uss?fileID=7433441132597879392&guid=c3ca9264ef5afbfbd94f1ca31cb51fa4&type=3" />
|
||||
<Style src="project://database/Assets/UI/itemslot.uss?fileID=7433441132597879392&guid=ab2fe9f4942517d359babfd8c160725c&type=3#itemslot" />
|
||||
<ui:VisualElement name="container" data-source-type="KitsuneCafe.ItemSystem.InventoryItem, Assembly-CSharp" enabled="true" class="container" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="header" class="header">
|
||||
<ui:Label name="item-name-label" text="Label">
|
||||
<Bindings>
|
||||
<ui:DataBinding property="text" data-source-path="Item.displayName" binding-mode="ToTarget" />
|
||||
</Bindings>
|
||||
</ui:Label>
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="content" style="flex-grow: 1;">
|
||||
<ui:VisualElement name="item-icon" style="flex-grow: 1; -unity-background-scale-mode: scale-to-fit;">
|
||||
<Bindings>
|
||||
<ui:DataBinding property="style.backgroundImage" data-source-path="Item.icon" binding-mode="ToTarget" />
|
||||
</Bindings>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
10
Assets/UI/ItemSlot.uxml.meta
Normal file
10
Assets/UI/ItemSlot.uxml.meta
Normal file
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 01b74a9c8f3685fb2880379892a17e46
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
8
Assets/UI/Test.meta
Normal file
8
Assets/UI/Test.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6be3a53c19fb771fa95c8b22fe8d5778
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
30
Assets/UI/Test/ProfileView.cs
Normal file
30
Assets/UI/Test/ProfileView.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Collections.Generic;
|
||||
using KitsuneCafe.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class MainUIController : MonoBehaviour
|
||||
{
|
||||
public UIDocument uiDocument;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
var rootVisualElement = uiDocument.rootVisualElement;
|
||||
|
||||
// Find the RecycleView in your UXML.
|
||||
var recycleView = rootVisualElement.Q<RecycleView>("recycle-view");
|
||||
|
||||
// Create some dummy data.
|
||||
var profiles = new List<UserProfile>();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
profiles.Add(new UserProfile($"User {i}", $"Status: {Random.Range(0, 100)}", Random.ColorHSV()));
|
||||
}
|
||||
|
||||
// Create our data source with the dummy data.
|
||||
var dataSource = new UserProfileDataSource(profiles);
|
||||
|
||||
// Assign the data source to the RecycleView.
|
||||
recycleView.DataSource = dataSource;
|
||||
}
|
||||
}
|
2
Assets/UI/Test/ProfileView.cs.meta
Normal file
2
Assets/UI/Test/ProfileView.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2a819c4e399f6cc6c84ace2a31f18d56
|
8
Assets/UI/Test/Resources.meta
Normal file
8
Assets/UI/Test/Resources.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 60c39b18b580f6428994e67d5c6c02a8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
6
Assets/UI/Test/Resources/UserProfileItem.uxml
Normal file
6
Assets/UI/Test/Resources/UserProfileItem.uxml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" editor:extensible-by-uxml="false">
|
||||
<ui:VisualElement name="user-profile-item">
|
||||
<ui:Label name="user-name" text="User Name" />
|
||||
<ui:Label name="user-status" text="Online" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
10
Assets/UI/Test/Resources/UserProfileItem.uxml.meta
Normal file
10
Assets/UI/Test/Resources/UserProfileItem.uxml.meta
Normal file
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4dc88e769dfb2756a9085ef5acd1337f
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
3
Assets/UI/Test/Resources/UserProfileList.uxml
Normal file
3
Assets/UI/Test/Resources/UserProfileList.uxml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
|
||||
<KitsuneCafe.UI.RecycleView name="recycle-view" direction="Horizontal" a="Stupid" is-dynamic-size="true" default-item-size="50" fixed-item-size="22" item-size="22" style="flex-grow: 1; flex-direction: row;" />
|
||||
</ui:UXML>
|
10
Assets/UI/Test/Resources/UserProfileList.uxml.meta
Normal file
10
Assets/UI/Test/Resources/UserProfileList.uxml.meta
Normal file
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0c1a0528290b37272b20d94b19311768
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
74
Assets/UI/Test/UserProfile.cs
Normal file
74
Assets/UI/Test/UserProfile.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System.Collections.Generic;
|
||||
using KitsuneCafe.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class UserProfile
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Status { get; set; }
|
||||
public Color StatusColor { get; set; }
|
||||
|
||||
public UserProfile(string name, string status, Color statusColor)
|
||||
{
|
||||
Name = name;
|
||||
Status = status;
|
||||
StatusColor = statusColor;
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserProfileItemBinder
|
||||
{
|
||||
public static void Bind(VisualElement root, UserProfile profile)
|
||||
{
|
||||
var nameLabel = root.Q<Label>("user-name");
|
||||
var statusLabel = root.Q<Label>("user-status");
|
||||
|
||||
if (nameLabel != null)
|
||||
{
|
||||
nameLabel.text = profile.Name;
|
||||
}
|
||||
|
||||
if (statusLabel != null)
|
||||
{
|
||||
statusLabel.text = profile.Status;
|
||||
statusLabel.style.color = new StyleColor(profile.StatusColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UserProfileDataSource : ICollectionDataSource
|
||||
{
|
||||
public int Length => profiles.Count;
|
||||
|
||||
private readonly List<UserProfile> profiles;
|
||||
private readonly VisualTreeAsset itemUxml;
|
||||
|
||||
public UserProfileDataSource(List<UserProfile> profiles)
|
||||
{
|
||||
this.profiles = profiles;
|
||||
|
||||
itemUxml = Resources.Load<VisualTreeAsset>(UserProfileItemVisualElement.UxmlPath);
|
||||
if (itemUxml == null)
|
||||
{
|
||||
Debug.LogError($"Could not find UXML asset at path: {UserProfileItemVisualElement.UxmlPath}");
|
||||
}
|
||||
}
|
||||
|
||||
public VisualElement CreateItem()
|
||||
{
|
||||
var root = itemUxml.Instantiate();
|
||||
var item = new UserProfileItemVisualElement();
|
||||
item.Add(root);
|
||||
return item;
|
||||
}
|
||||
|
||||
public void BindItem(VisualElement element, int index)
|
||||
{
|
||||
UserProfileItemBinder.Bind(element, profiles[index]);
|
||||
}
|
||||
|
||||
public void UnbindItem(VisualElement element, int index)
|
||||
{
|
||||
}
|
||||
}
|
2
Assets/UI/Test/UserProfile.cs.meta
Normal file
2
Assets/UI/Test/UserProfile.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 92cb5063ccf6dde86992d95f55af5048
|
33
Assets/UI/Test/UserProfileItemVisualElement.cs
Normal file
33
Assets/UI/Test/UserProfileItemVisualElement.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using UnityEngine.UIElements;
|
||||
|
||||
public class UserProfileItemVisualElement : VisualElement
|
||||
{
|
||||
// A reference to the UXML template. We will load this in the DataSource.
|
||||
public static readonly string UxmlPath = "UserProfileItem";
|
||||
|
||||
// References to the UI elements inside the template.
|
||||
private readonly Label nameLabel;
|
||||
private readonly Label statusLabel;
|
||||
|
||||
public UserProfileItemVisualElement()
|
||||
{
|
||||
// This is where we find the child elements by their names from the UXML.
|
||||
nameLabel = this.Q<Label>("user-name");
|
||||
statusLabel = this.Q<Label>("user-status");
|
||||
}
|
||||
|
||||
// Public method to bind the data.
|
||||
public void SetData(UserProfile profile)
|
||||
{
|
||||
nameLabel.text = profile.Name;
|
||||
statusLabel.text = profile.Status;
|
||||
statusLabel.style.color = new StyleColor(profile.StatusColor);
|
||||
}
|
||||
|
||||
// Public method to clear data for recycling.
|
||||
public void ClearData()
|
||||
{
|
||||
nameLabel.text = string.Empty;
|
||||
statusLabel.text = string.Empty;
|
||||
}
|
||||
}
|
2
Assets/UI/Test/UserProfileItemVisualElement.cs.meta
Normal file
2
Assets/UI/Test/UserProfileItemVisualElement.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 188f6258dc15a873c8bb7dfcd3f7db85
|
65
Assets/UI/inventory.uss
Normal file
65
Assets/UI/inventory.uss
Normal file
|
@ -0,0 +1,65 @@
|
|||
.container {
|
||||
border-left-color: var(--primary);
|
||||
border-right-color: var(--primary);
|
||||
border-top-color: var(--primary);
|
||||
border-bottom-color: var(--primary);
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.container > .header {
|
||||
background-color: var(--primary);
|
||||
height: 14px;
|
||||
flex-grow: 0;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.spaced-children > * {
|
||||
margin-top: 4px;
|
||||
margin-right: 4px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.container > .content {
|
||||
padding-top: 16px;
|
||||
padding-right: 16px;
|
||||
padding-bottom: 16px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-left-color: rgb(79, 76, 78);
|
||||
border-right-color: rgb(79, 76, 78);
|
||||
border-top-color: rgb(79, 76, 78);
|
||||
border-bottom-color: rgb(79, 76, 78);
|
||||
width: 24px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.indicator.full {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
.indicator.selected {
|
||||
background-color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.container > .header > Label {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
-unity-text-align: middle-left;
|
||||
color: rgb(29, 29, 29);
|
||||
}
|
11
Assets/UI/inventory.uss.meta
Normal file
11
Assets/UI/inventory.uss.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c3ca9264ef5afbfbd94f1ca31cb51fa4
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
3
Assets/UI/itemslot.uss
Normal file
3
Assets/UI/itemslot.uss
Normal file
|
@ -0,0 +1,3 @@
|
|||
:root {
|
||||
|
||||
}
|
11
Assets/UI/itemslot.uss.meta
Normal file
11
Assets/UI/itemslot.uss.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ab2fe9f4942517d359babfd8c160725c
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
|
||||
disableValidation: 0
|
|
@ -75,7 +75,7 @@ QualitySettings:
|
|||
globalTextureMipmapLimit: 0
|
||||
textureMipmapLimitSettings: []
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 0
|
||||
antiAliasing: 2
|
||||
softParticles: 0
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 0
|
||||
|
|
|
@ -13,7 +13,7 @@ TagManager:
|
|||
- UI
|
||||
- Player
|
||||
- Outline
|
||||
-
|
||||
- Preview
|
||||
-
|
||||
-
|
||||
-
|
||||
|
|
Loading…
Add table
Reference in a new issue