recycle view

This commit is contained in:
Rowan 2025-08-06 12:51:11 -04:00
parent 232e5d4ef2
commit 9e6e3ccdee
76 changed files with 2963 additions and 40 deletions

View file

@ -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

Binary file not shown.

View 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

Binary file not shown.

View file

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

View file

@ -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}

View file

@ -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

View 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}

View file

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

View file

@ -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
View 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}

View file

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

View file

@ -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)

View file

@ -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;
}
}
}

View file

@ -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;
@ -147,4 +145,4 @@ namespace KitsuneCafe.Player
return current;
}
}
}
}

View 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)
{
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cbcedbac951b59685ac98946b7c71e51

View file

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

View 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();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ee096968879dadffa8fd3597a0ec0b12

View 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;
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 254c0563f8601e998a3d4eacff1833c6

View file

@ -0,0 +1,6 @@
using System.ComponentModel;
namespace System.Runtime.CompilerServices
{
[EditorBrowsable(EditorBrowsableState.Never)]
internal class IsExternalInit { }
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ea4ec4bcaf729ed14ba315e9a9923ceb

View file

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

View 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();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e38b8fbcaf537546ab9ecd9312112a49

View 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);
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 59a6a1d658db51ba5acf7f0235f34571

View 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);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0cfd00f2409d6a95ca26d19888b4d8d2

View file

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

View file

@ -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);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8cc192cc5a0da4ac0ba2505e808281ef

View file

@ -0,0 +1,4 @@
namespace KitsuneCafe.UI
{
public interface IDragAndDropController { }
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3206838b8b365654090a0ba619bf954f

View file

@ -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();
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b0f05a19f2918482b8d5c617729a9b31

View 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();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 902d6b824a8533b7982956ca9cb66e40

View file

@ -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();
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a6e0bb01a1a66c1098e4392d86ce88df

View 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);
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0b73a6c894b05e193a00e4926ac578ed

View file

@ -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

View file

@ -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

View 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;
}

View 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

View file

@ -0,0 +1,4 @@
@import url("unity-theme://default");
@import url("CantoComponents.uss");
VisualElement {}

View 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

View file

@ -1 +1,3 @@
@import url("unity-theme://default");
@import url("unity-theme://default");
@import url("CantoTheme.tss");

View 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>

View file

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

View file

@ -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&amp;guid=c3ca9264ef5afbfbd94f1ca31cb51fa4&amp;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="&lt;smallcaps&gt;status&lt;/smallcaps&gt;" 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(&quot;project://database/Assets/UI/Item%20Preview.renderTexture?fileID=8400000&amp;guid=fc19a022409ab0d408fa0e78cfeab827&amp;type=2#Item Preview&quot;); -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>

View 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

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fc19a022409ab0d408fa0e78cfeab827
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 8400000
userData:
assetBundleName:
assetBundleVariant:

20
Assets/UI/ItemSlot.uxml Normal file
View 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&amp;guid=c3ca9264ef5afbfbd94f1ca31cb51fa4&amp;type=3" />
<Style src="project://database/Assets/UI/itemslot.uss?fileID=7433441132597879392&amp;guid=ab2fe9f4942517d359babfd8c160725c&amp;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>

View 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
View file

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

View 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;
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2a819c4e399f6cc6c84ace2a31f18d56

View file

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

View 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>

View file

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

View 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>

View file

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

View 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)
{
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 92cb5063ccf6dde86992d95f55af5048

View 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;
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 188f6258dc15a873c8bb7dfcd3f7db85

65
Assets/UI/inventory.uss Normal file
View 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);
}

View 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
View file

@ -0,0 +1,3 @@
:root {
}

View 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

View file

@ -75,7 +75,7 @@ QualitySettings:
globalTextureMipmapLimit: 0
textureMipmapLimitSettings: []
anisotropicTextures: 2
antiAliasing: 0
antiAliasing: 2
softParticles: 0
softVegetation: 1
realtimeReflectionProbes: 0

View file

@ -13,7 +13,7 @@ TagManager:
- UI
- Player
- Outline
-
- Preview
-
-
-