commit 01bc67dcff65face9e68418fe3b087fb74b4d04c Author: Aaro Varis Date: Mon Sep 30 13:16:04 2024 +0300 Add new meta files and initial implementations for VRCBoard components and materials diff --git a/!Prefabs & Examples.meta b/!Prefabs & Examples.meta new file mode 100644 index 0000000..2e1356a --- /dev/null +++ b/!Prefabs & Examples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 13a6aae7a108d8345ad289f64ab3ac42 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/!Prefabs & Examples/!VRCBoardManager.prefab b/!Prefabs & Examples/!VRCBoardManager.prefab new file mode 100644 index 0000000..b0bedce --- /dev/null +++ b/!Prefabs & Examples/!VRCBoardManager.prefab @@ -0,0 +1,193 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8491167449487683663 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1162021088411673579} + - component: {fileID: 3756576528260158576} + - component: {fileID: 1195327852248355995} + m_Layer: 0 + m_Name: '!VRCBoardManager' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1162021088411673579 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8491167449487683663} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 11.237934, y: -0.7982679, z: 68.57478} + 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 &3756576528260158576 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8491167449487683663} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a15201eb91eaa134bb21f3335054e187, type: 3} + m_Name: + m_EditorClassIdentifier: + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: [] + _udonSharpBackingUdonBehaviour: {fileID: 1195327852248355995} + vrcBoardDomain: mydomain.vrcboard.app + periodicUpdateInterval: 60 + vrcBoardComponents: [] + atlasUrls: + - url: http://mydomain.vrcboard.app/atlas/0 + - url: http://mydomain.vrcboard.app/atlas/1 + - url: http://mydomain.vrcboard.app/atlas/2 + - url: http://mydomain.vrcboard.app/atlas/3 + - url: http://mydomain.vrcboard.app/atlas/4 + - url: http://mydomain.vrcboard.app/atlas/5 + - url: http://mydomain.vrcboard.app/atlas/6 + - url: http://mydomain.vrcboard.app/atlas/7 + - url: http://mydomain.vrcboard.app/atlas/8 + - url: http://mydomain.vrcboard.app/atlas/9 + - url: http://mydomain.vrcboard.app/atlas/10 + - url: http://mydomain.vrcboard.app/atlas/11 + - url: http://mydomain.vrcboard.app/atlas/12 + - url: http://mydomain.vrcboard.app/atlas/13 + - url: http://mydomain.vrcboard.app/atlas/14 + - url: http://mydomain.vrcboard.app/atlas/15 + - url: http://mydomain.vrcboard.app/atlas/16 + - url: http://mydomain.vrcboard.app/atlas/17 + - url: http://mydomain.vrcboard.app/atlas/18 + - url: http://mydomain.vrcboard.app/atlas/19 + - url: http://mydomain.vrcboard.app/atlas/20 + - url: http://mydomain.vrcboard.app/atlas/21 + - url: http://mydomain.vrcboard.app/atlas/22 + - url: http://mydomain.vrcboard.app/atlas/23 + - url: http://mydomain.vrcboard.app/atlas/24 + - url: http://mydomain.vrcboard.app/atlas/25 + - url: http://mydomain.vrcboard.app/atlas/26 + - url: http://mydomain.vrcboard.app/atlas/27 + - url: http://mydomain.vrcboard.app/atlas/28 + - url: http://mydomain.vrcboard.app/atlas/29 + - url: http://mydomain.vrcboard.app/atlas/30 + - url: http://mydomain.vrcboard.app/atlas/31 + - url: http://mydomain.vrcboard.app/atlas/32 + - url: http://mydomain.vrcboard.app/atlas/33 + - url: http://mydomain.vrcboard.app/atlas/34 + - url: http://mydomain.vrcboard.app/atlas/35 + - url: http://mydomain.vrcboard.app/atlas/36 + - url: http://mydomain.vrcboard.app/atlas/37 + - url: http://mydomain.vrcboard.app/atlas/38 + - url: http://mydomain.vrcboard.app/atlas/39 + - url: http://mydomain.vrcboard.app/atlas/40 + - url: http://mydomain.vrcboard.app/atlas/41 + - url: http://mydomain.vrcboard.app/atlas/42 + - url: http://mydomain.vrcboard.app/atlas/43 + - url: http://mydomain.vrcboard.app/atlas/44 + - url: http://mydomain.vrcboard.app/atlas/45 + - url: http://mydomain.vrcboard.app/atlas/46 + - url: http://mydomain.vrcboard.app/atlas/47 + - url: http://mydomain.vrcboard.app/atlas/48 + - url: http://mydomain.vrcboard.app/atlas/49 + - url: http://mydomain.vrcboard.app/atlas/50 + - url: http://mydomain.vrcboard.app/atlas/51 + - url: http://mydomain.vrcboard.app/atlas/52 + - url: http://mydomain.vrcboard.app/atlas/53 + - url: http://mydomain.vrcboard.app/atlas/54 + - url: http://mydomain.vrcboard.app/atlas/55 + - url: http://mydomain.vrcboard.app/atlas/56 + - url: http://mydomain.vrcboard.app/atlas/57 + - url: http://mydomain.vrcboard.app/atlas/58 + - url: http://mydomain.vrcboard.app/atlas/59 + - url: http://mydomain.vrcboard.app/atlas/60 + - url: http://mydomain.vrcboard.app/atlas/61 + - url: http://mydomain.vrcboard.app/atlas/62 + - url: http://mydomain.vrcboard.app/atlas/63 + - url: http://mydomain.vrcboard.app/atlas/64 + - url: http://mydomain.vrcboard.app/atlas/65 + - url: http://mydomain.vrcboard.app/atlas/66 + - url: http://mydomain.vrcboard.app/atlas/67 + - url: http://mydomain.vrcboard.app/atlas/68 + - url: http://mydomain.vrcboard.app/atlas/69 + - url: http://mydomain.vrcboard.app/atlas/70 + - url: http://mydomain.vrcboard.app/atlas/71 + - url: http://mydomain.vrcboard.app/atlas/72 + - url: http://mydomain.vrcboard.app/atlas/73 + - url: http://mydomain.vrcboard.app/atlas/74 + - url: http://mydomain.vrcboard.app/atlas/75 + - url: http://mydomain.vrcboard.app/atlas/76 + - url: http://mydomain.vrcboard.app/atlas/77 + - url: http://mydomain.vrcboard.app/atlas/78 + - url: http://mydomain.vrcboard.app/atlas/79 + - url: http://mydomain.vrcboard.app/atlas/80 + - url: http://mydomain.vrcboard.app/atlas/81 + - url: http://mydomain.vrcboard.app/atlas/82 + - url: http://mydomain.vrcboard.app/atlas/83 + - url: http://mydomain.vrcboard.app/atlas/84 + - url: http://mydomain.vrcboard.app/atlas/85 + - url: http://mydomain.vrcboard.app/atlas/86 + - url: http://mydomain.vrcboard.app/atlas/87 + - url: http://mydomain.vrcboard.app/atlas/88 + - url: http://mydomain.vrcboard.app/atlas/89 + - url: http://mydomain.vrcboard.app/atlas/90 + - url: http://mydomain.vrcboard.app/atlas/91 + - url: http://mydomain.vrcboard.app/atlas/92 + - url: http://mydomain.vrcboard.app/atlas/93 + - url: http://mydomain.vrcboard.app/atlas/94 + - url: http://mydomain.vrcboard.app/atlas/95 + - url: http://mydomain.vrcboard.app/atlas/96 + - url: http://mydomain.vrcboard.app/atlas/97 + - url: http://mydomain.vrcboard.app/atlas/98 + - url: http://mydomain.vrcboard.app/atlas/99 + customModuleUrls: [] + atlasInfoUrl: + url: http://mydomain.vrcboard.app/api/data/v1/atlas + supporterInfoUrl: + url: http://mydomain.vrcboard.app/api/data/v1/supporters + imageIdDownloadQueue: [] +--- !u!114 &1195327852248355995 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8491167449487683663} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 45115577ef41a5b4ca741ed302693907, type: 3} + m_Name: + m_EditorClassIdentifier: + interactTextPlacement: {fileID: 0} + interactText: Use + interactTextGO: {fileID: 0} + proximity: 2 + SynchronizePosition: 0 + AllowCollisionOwnershipTransfer: 0 + Reliable: 0 + _syncMethod: 0 + serializedProgramAsset: {fileID: 11400000, guid: b0a3201f714d46b4cbdb27ef08a99c58, + type: 2} + programSource: {fileID: 11400000, guid: c4183376def25d24a8d2963d59ac2cd2, type: 2} + serializedPublicVariablesBytesString: Ai8AAAAAATIAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAFQAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AAAAAAAYBAAAAAAAAACcBBAAAAHQAeQBwAGUAAWgAAABTAHkAcwB0AGUAbQAuAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEcAZQBuAGUAcgBpAGMALgBMAGkAcwB0AGAAMQBbAFsAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4ALgBJAG4AdABlAHIAZgBhAGMAZQBzAC4ASQBVAGQAbwBuAFYAYQByAGkAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AXQBdACwAIABtAHMAYwBvAHIAbABpAGIAAQEJAAAAVgBhAHIAaQBhAGIAbABlAHMALwEAAAABaAAAAFMAeQBzAHQAZQBtAC4AQwBvAGwAbABlAGMAdABpAG8AbgBzAC4ARwBlAG4AZQByAGkAYwAuAEwAaQBzAHQAYAAxAFsAWwBWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAEkAbgB0AGUAcgBmAGEAYwBlAHMALgBJAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlACwAIABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgBdAF0ALAAgAG0AcwBjAG8AcgBsAGkAYgABAAAABgEAAAAAAAAAAi8CAAAAAUkAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAGAAMQBbAFsAUwB5AHMAdABlAG0ALgBJAG4AdAAzADIALAAgAG0AcwBjAG8AcgBsAGkAYgBdAF0ALAAgAFYAUgBDAC4AVQBkAG8AbgAuAEMAbwBtAG0AbwBuAAIAAAAGAgAAAAAAAAAnAQQAAAB0AHkAcABlAAEXAAAAUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwAsACAAbQBzAGMAbwByAGwAaQBiACcBCgAAAFMAeQBtAGIAbwBsAE4AYQBtAGUAAR8AAABfAF8AXwBVAGQAbwBuAFMAaABhAHIAcABCAGUAaABhAHYAaQBvAHUAcgBWAGUAcgBzAGkAbwBuAF8AXwBfACcBBAAAAHQAeQBwAGUAARYAAABTAHkAcwB0AGUAbQAuAEkAbgB0ADMAMgAsACAAbQBzAGMAbwByAGwAaQBiABcBBQAAAFYAYQBsAHUAZQACAAAABwUHBQcF + publicVariablesUnityEngineObjects: [] + publicVariablesSerializationDataFormat: 0 diff --git a/!Prefabs & Examples/!VRCBoardManager.prefab.meta b/!Prefabs & Examples/!VRCBoardManager.prefab.meta new file mode 100644 index 0000000..496e09e --- /dev/null +++ b/!Prefabs & Examples/!VRCBoardManager.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d8cf4a9c422718b418c6fd51caaf655f +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/!Prefabs & Examples/ImagePoster.prefab b/!Prefabs & Examples/ImagePoster.prefab new file mode 100644 index 0000000..2d9180b --- /dev/null +++ b/!Prefabs & Examples/ImagePoster.prefab @@ -0,0 +1,140 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3308026792867535421 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8929716667225344615} + - component: {fileID: 2925911129273897591} + - component: {fileID: 2163663917368825931} + - component: {fileID: 8581893138345168617} + - component: {fileID: 9181003179774458621} + m_Layer: 0 + m_Name: ImagePoster + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8929716667225344615 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308026792867535421} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0.7071068, z: -0.7071068, w: 0} + m_LocalPosition: {x: -4.13, y: 4.49, z: 35.1} + m_LocalScale: {x: 4, y: 5, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: -180} +--- !u!114 &2925911129273897591 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308026792867535421} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 63987f0853a8d0d44bd6ea28693af468, type: 3} + m_Name: + m_EditorClassIdentifier: + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: [] + _udonSharpBackingUdonBehaviour: {fileID: 9181003179774458621} + manager: {fileID: 0} + uploaderIdOverride: + AlbedoImageId: 1234 + EmissionImageId: 1234 + NormalImageId: +--- !u!33 &2163663917368825931 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308026792867535421} + m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8581893138345168617 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308026792867535421} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 66b314f6e6cbc5a4a97f18dde3864299, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &9181003179774458621 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308026792867535421} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 45115577ef41a5b4ca741ed302693907, type: 3} + m_Name: + m_EditorClassIdentifier: + interactTextPlacement: {fileID: 0} + interactText: Use + interactTextGO: {fileID: 0} + proximity: 2 + SynchronizePosition: 0 + AllowCollisionOwnershipTransfer: 0 + Reliable: 0 + _syncMethod: 1 + serializedProgramAsset: {fileID: 11400000, guid: f83f88ce349d298438a783df6b33c10f, + type: 2} + programSource: {fileID: 11400000, guid: ac7f998a74898ea4ead01ba49e49e658, type: 2} + serializedPublicVariablesBytesString: Ai8AAAAAATIAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAFQAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AAAAAAAYBAAAAAAAAACcBBAAAAHQAeQBwAGUAAWgAAABTAHkAcwB0AGUAbQAuAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEcAZQBuAGUAcgBpAGMALgBMAGkAcwB0AGAAMQBbAFsAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4ALgBJAG4AdABlAHIAZgBhAGMAZQBzAC4ASQBVAGQAbwBuAFYAYQByAGkAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AXQBdACwAIABtAHMAYwBvAHIAbABpAGIAAQEJAAAAVgBhAHIAaQBhAGIAbABlAHMALwEAAAABaAAAAFMAeQBzAHQAZQBtAC4AQwBvAGwAbABlAGMAdABpAG8AbgBzAC4ARwBlAG4AZQByAGkAYwAuAEwAaQBzAHQAYAAxAFsAWwBWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAEkAbgB0AGUAcgBmAGEAYwBlAHMALgBJAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlACwAIABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgBdAF0ALAAgAG0AcwBjAG8AcgBsAGkAYgABAAAABgEAAAAAAAAAAi8CAAAAAUkAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAGAAMQBbAFsAUwB5AHMAdABlAG0ALgBJAG4AdAAzADIALAAgAG0AcwBjAG8AcgBsAGkAYgBdAF0ALAAgAFYAUgBDAC4AVQBkAG8AbgAuAEMAbwBtAG0AbwBuAAIAAAAGAgAAAAAAAAAnAQQAAAB0AHkAcABlAAEXAAAAUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwAsACAAbQBzAGMAbwByAGwAaQBiACcBCgAAAFMAeQBtAGIAbwBsAE4AYQBtAGUAAR8AAABfAF8AXwBVAGQAbwBuAFMAaABhAHIAcABCAGUAaABhAHYAaQBvAHUAcgBWAGUAcgBzAGkAbwBuAF8AXwBfACcBBAAAAHQAeQBwAGUAARYAAABTAHkAcwB0AGUAbQAuAEkAbgB0ADMAMgAsACAAbQBzAGMAbwByAGwAaQBiABcBBQAAAFYAYQBsAHUAZQACAAAABwUHBQcF + publicVariablesUnityEngineObjects: [] + publicVariablesSerializationDataFormat: 0 diff --git a/!Prefabs & Examples/ImagePoster.prefab.meta b/!Prefabs & Examples/ImagePoster.prefab.meta new file mode 100644 index 0000000..3e620af --- /dev/null +++ b/!Prefabs & Examples/ImagePoster.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1bc0dab61449df0429ef358e98f0e696 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/!Prefabs & Examples/SupporterBoardTMP.prefab b/!Prefabs & Examples/SupporterBoardTMP.prefab new file mode 100644 index 0000000..e6860f4 --- /dev/null +++ b/!Prefabs & Examples/SupporterBoardTMP.prefab @@ -0,0 +1,266 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3673492051547775719 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8528962665691960831} + - component: {fileID: 4850915801468868207} + - component: {fileID: 5484924365637121399} + - component: {fileID: 4423468667012971133} + - component: {fileID: 5921522376555870917} + m_Layer: 0 + m_Name: SupporterBoardTMP + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8528962665691960831 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3673492051547775719} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 17.07} + m_LocalScale: {x: 0.2487, y: 0.2487, z: 0.2487} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 1.49, y: 6.36} + m_SizeDelta: {x: 80, y: 25} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4850915801468868207 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3673492051547775719} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 670e2136f923f894789f2871f5134127, type: 3} + m_Name: + m_EditorClassIdentifier: + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: [] + _udonSharpBackingUdonBehaviour: {fileID: 5921522376555870917} + manager: {fileID: 0} + Separator: \n + ConfigEntries: + - IDType: 0 + id: 1234 + template: %s + separator: ', ' + userMustBeInWorld: 0 + exclusive: 1 + - IDType: 0 + id: 1337 + template: %s + separator: ', ' + userMustBeInWorld: 0 + exclusive: 1 + - IDType: 0 + id: 567 + template: %s + separator: ', ' + userMustBeInWorld: 0 + exclusive: 1 + config: + - Tier + - 1234 + - %s + - ', ' + - 0 + - 1 + - Tier + - 1337 + - %s + - ', ' + - 0 + - 1 + - Tier + - 567 + - %s + - ', ' + - 0 + - 1 + text: + - {fileID: 4423468667012971133} + textUGUI: [] +--- !u!23 &5484924365637121399 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3673492051547775719} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: e73a58f6e2794ae7b1b7e50b7fb811b0, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!114 &4423468667012971133 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3673492051547775719} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Loading... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2100000, guid: e73a58f6e2794ae7b1b7e50b7fb811b0, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 4 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 0 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 1 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + _SortingLayer: 0 + _SortingLayerID: 0 + _SortingOrder: 0 + m_hasFontAssetChanged: 0 + m_renderer: {fileID: 5484924365637121399} + m_maskType: 0 +--- !u!114 &5921522376555870917 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3673492051547775719} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 45115577ef41a5b4ca741ed302693907, type: 3} + m_Name: + m_EditorClassIdentifier: + interactTextPlacement: {fileID: 0} + interactText: Use + interactTextGO: {fileID: 0} + proximity: 2 + SynchronizePosition: 0 + AllowCollisionOwnershipTransfer: 0 + Reliable: 0 + _syncMethod: 1 + serializedProgramAsset: {fileID: 11400000, guid: e758930ddabc47d499d718189a2787b5, + type: 2} + programSource: {fileID: 11400000, guid: 486db5f9f0a8ce345a26bc8587a216a2, type: 2} + serializedPublicVariablesBytesString: Ai8AAAAAATIAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAFQAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AAAAAAAYBAAAAAAAAACcBBAAAAHQAeQBwAGUAAWgAAABTAHkAcwB0AGUAbQAuAEMAbwBsAGwAZQBjAHQAaQBvAG4AcwAuAEcAZQBuAGUAcgBpAGMALgBMAGkAcwB0AGAAMQBbAFsAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4ALgBJAG4AdABlAHIAZgBhAGMAZQBzAC4ASQBVAGQAbwBuAFYAYQByAGkAYQBiAGwAZQAsACAAVgBSAEMALgBVAGQAbwBuAC4AQwBvAG0AbQBvAG4AXQBdACwAIABtAHMAYwBvAHIAbABpAGIAAQEJAAAAVgBhAHIAaQBhAGIAbABlAHMALwEAAAABaAAAAFMAeQBzAHQAZQBtAC4AQwBvAGwAbABlAGMAdABpAG8AbgBzAC4ARwBlAG4AZQByAGkAYwAuAEwAaQBzAHQAYAAxAFsAWwBWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAEkAbgB0AGUAcgBmAGEAYwBlAHMALgBJAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlACwAIABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgBdAF0ALAAgAG0AcwBjAG8AcgBsAGkAYgABAAAABgEAAAAAAAAAAi8CAAAAAUkAAABWAFIAQwAuAFUAZABvAG4ALgBDAG8AbQBtAG8AbgAuAFUAZABvAG4AVgBhAHIAaQBhAGIAbABlAGAAMQBbAFsAUwB5AHMAdABlAG0ALgBJAG4AdAAzADIALAAgAG0AcwBjAG8AcgBsAGkAYgBdAF0ALAAgAFYAUgBDAC4AVQBkAG8AbgAuAEMAbwBtAG0AbwBuAAIAAAAGAgAAAAAAAAAnAQQAAAB0AHkAcABlAAEXAAAAUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwAsACAAbQBzAGMAbwByAGwAaQBiACcBCgAAAFMAeQBtAGIAbwBsAE4AYQBtAGUAAR8AAABfAF8AXwBVAGQAbwBuAFMAaABhAHIAcABCAGUAaABhAHYAaQBvAHUAcgBWAGUAcgBzAGkAbwBuAF8AXwBfACcBBAAAAHQAeQBwAGUAARYAAABTAHkAcwB0AGUAbQAuAEkAbgB0ADMAMgAsACAAbQBzAGMAbwByAGwAaQBiABcBBQAAAFYAYQBsAHUAZQACAAAABwUHBQcF + publicVariablesUnityEngineObjects: [] + publicVariablesSerializationDataFormat: 0 diff --git a/!Prefabs & Examples/SupporterBoardTMP.prefab.meta b/!Prefabs & Examples/SupporterBoardTMP.prefab.meta new file mode 100644 index 0000000..5740369 --- /dev/null +++ b/!Prefabs & Examples/SupporterBoardTMP.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9d561eb9f3068b4892b0100d415cc5b +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components.meta b/Components.meta new file mode 100644 index 0000000..e021e30 --- /dev/null +++ b/Components.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 93ffeb45ad449104f85bfe1b58a09d2a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardBaseComponent.cs b/Components/VRCBoardBaseComponent.cs new file mode 100644 index 0000000..92ccd30 --- /dev/null +++ b/Components/VRCBoardBaseComponent.cs @@ -0,0 +1,116 @@ +using UdonSharp; +using UnityEngine; +using VRC.SDK3.Data; + + +using UnityEditor; + + +namespace VRCBoard.Components +{ + [UdonBehaviourSyncMode(BehaviourSyncMode.None)] + public abstract class VRCBoardBaseComponent : UdonSharpBehaviour + { + [HideInInspector] public VRCBoardManager manager; + + protected abstract void OnRegister(); + protected abstract void OnInitialize(); + protected abstract void OnSupporterDataUpdate(); + protected abstract void OnImageDataUpdate(); + protected abstract void OnImageLoaded(); + + // ReSharper disable once InconsistentNaming + protected internal void _Register(VRCBoardManager _manager) + { + manager = _manager; + OnRegister(); + } + + private bool _imageInitialized; + private bool _dataInitialized; + private bool _initialized; + private void CheckInitialization() + { + if (_imageInitialized && _dataInitialized && !_initialized) + { + _initialized = true; + OnInitialize(); + OnImageDataUpdate(); + OnSupporterDataUpdate(); + } + } + protected internal void _OnImageInfoUpdate() + { + if (_initialized) OnImageDataUpdate(); + else + { + _imageInitialized = true; + CheckInitialization(); + } + + } + protected internal void _OnSupporterDataUpdate() + { + if (_initialized) OnSupporterDataUpdate(); + else + { + _dataInitialized = true; + CheckInitialization(); + } + } + + protected internal void _OnImageLoaded(int atlasIndex = -1) + { + OnImageLoaded(); + } + + private DataDictionary GetImageIdInfo(string imageId) => manager._GetImageIdInfo(imageId); + + internal bool GetImageAtlasTexture(string imageId, string uploader, out Texture2D texture, + out int position, out int size, out string type) { + return manager._GetImageAtlasTexture(imageId, uploader, out int atlasIndex, out texture, out position, out size, + out type); + } + + + internal string GetRandomUploader(string imageId) + { + DataDictionary imageInfo = GetImageIdInfo(imageId); + if (imageInfo == null) return null; + bool uploadsSuccess = imageInfo.TryGetValue("uploads", out DataToken uploadsToken); + if (!uploadsSuccess) return null; + if (uploadsToken.TokenType != TokenType.DataList) return null; + DataList uploads = uploadsToken.DataList; + if (uploads.Count == 0) return null; + int randomIndex = Random.Range(0, uploads.Count); + DataDictionary upload = uploads[randomIndex].DataDictionary; + if (upload == null) return null; + bool uploaderSuccess = upload.TryGetValue("a", out DataToken uploaderToken); + if (!uploaderSuccess) return null; + if (uploaderToken.TokenType != TokenType.String) return null; + return uploaderToken.String; + } + + internal void RequestImageLoad(string imageId, string uploaderId = "") + { + manager._RequestImageLoad(imageId, uploaderId, this); + } + } +#if UNITY_EDITOR && !COMPILER_UDONSHARP + [CustomEditor(typeof(VRCBoardBaseComponent), true)] + public class VRCBoardBaseComponentEditor : Editor + { + public override void OnInspectorGUI() + { + if (Application.isPlaying) + { + EditorGUILayout.LabelField("Cannot edit a VRCBoard component while in play mode"); + return; + } + + base.OnInspectorGUI(); + } + } +#endif +} + diff --git a/Components/VRCBoardBaseComponent.cs.meta b/Components/VRCBoardBaseComponent.cs.meta new file mode 100644 index 0000000..3036b5b --- /dev/null +++ b/Components/VRCBoardBaseComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eeb8a49e78fdf45439cb6d35397f8774 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardImage.asset b/Components/VRCBoardImage.asset new file mode 100644 index 0000000..d404179 --- /dev/null +++ b/Components/VRCBoardImage.asset @@ -0,0 +1,944 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3} + m_Name: VRCBoardImage + m_EditorClassIdentifier: + serializedUdonProgramAsset: {fileID: 11400000, guid: f83f88ce349d298438a783df6b33c10f, + type: 2} + udonAssembly: + assemblyError: + sourceCsScript: {fileID: 11500000, guid: 63987f0853a8d0d44bd6ea28693af468, type: 3} + scriptVersion: 2 + compiledVersion: 2 + behaviourSyncMode: 1 + hasInteractEvent: 0 + scriptID: -7602492438531743077 + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: + - Name: fieldDefinitions + Entry: 7 + Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition, + UdonSharp.Editor]], mscorlib + - Name: comparer + Entry: 7 + Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 16 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: manager + - Name: $v + Entry: 7 + Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: manager + - Name: k__BackingField + Entry: 7 + Data: 3|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRCBoard.VRCBoardManager, Assembly-CSharp + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: 4|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.Udon.UdonBehaviour, VRC.Udon + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 5|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 6|UnityEngine.HideInInspector, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _imageInitialized + - Name: $v + Entry: 7 + Data: 7|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _imageInitialized + - Name: k__BackingField + Entry: 7 + Data: 8|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Boolean, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 9|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _dataInitialized + - Name: $v + Entry: 7 + Data: 10|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _dataInitialized + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _initialized + - Name: $v + Entry: 7 + Data: 12|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _initialized + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 13|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: uploaderIdOverride + - Name: $v + Entry: 7 + Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: uploaderIdOverride + - Name: k__BackingField + Entry: 7 + Data: 15|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 16|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 17|UnityEngine.HeaderAttribute, UnityEngine.CoreModule + - Name: header + Entry: 1 + Data: Uploader ID (only applies to images of 'shared' or 'instance' type) + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: albedoImageId + - Name: $v + Entry: 7 + Data: 18|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: albedoImageId + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 19|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 20|UnityEngine.HeaderAttribute, UnityEngine.CoreModule + - Name: header + Entry: 1 + Data: Image IDs + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: emissionImageId + - Name: $v + Entry: 7 + Data: 21|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: emissionImageId + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 22|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: normalImageId + - Name: $v + Entry: 7 + Data: 23|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: normalImageId + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 24|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: defaultAlbedo + - Name: $v + Entry: 7 + Data: 25|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: defaultAlbedo + - Name: k__BackingField + Entry: 7 + Data: 26|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Texture2D, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 26 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 27|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 28|UnityEngine.HeaderAttribute, UnityEngine.CoreModule + - Name: header + Entry: 1 + Data: Defaults + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: albedoColor + - Name: $v + Entry: 7 + Data: 29|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: albedoColor + - Name: k__BackingField + Entry: 7 + Data: 30|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Color, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 31|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 32|UnityEngine.ColorUsageAttribute, UnityEngine.CoreModule + - Name: showAlpha + Entry: 5 + Data: true + - Name: hdr + Entry: 5 + Data: true + - Name: minBrightness + Entry: 4 + Data: 0 + - Name: maxBrightness + Entry: 4 + Data: 8 + - Name: minExposureValue + Entry: 4 + Data: 0.125 + - Name: maxExposureValue + Entry: 4 + Data: 3 + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: defaultEmission + - Name: $v + Entry: 7 + Data: 33|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: defaultEmission + - Name: k__BackingField + Entry: 9 + Data: 26 + - Name: k__BackingField + Entry: 9 + Data: 26 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 34|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: emissionColor + - Name: $v + Entry: 7 + Data: 35|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: emissionColor + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 36|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 37|UnityEngine.ColorUsageAttribute, UnityEngine.CoreModule + - Name: showAlpha + Entry: 5 + Data: true + - Name: hdr + Entry: 5 + Data: true + - Name: minBrightness + Entry: 4 + Data: 0 + - Name: maxBrightness + Entry: 4 + Data: 8 + - Name: minExposureValue + Entry: 4 + Data: 0.125 + - Name: maxExposureValue + Entry: 4 + Data: 3 + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: defaultNormal + - Name: $v + Entry: 7 + Data: 38|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: defaultNormal + - Name: k__BackingField + Entry: 9 + Data: 26 + - Name: k__BackingField + Entry: 9 + Data: 26 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 39|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: normalIntensity + - Name: $v + Entry: 7 + Data: 40|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: normalIntensity + - Name: k__BackingField + Entry: 7 + Data: 41|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Single, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 41 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 42|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _mainType + - Name: $v + Entry: 7 + Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _mainType + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _uploaderId + - Name: $v + Entry: 7 + Data: 45|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _uploaderId + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 46|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: diff --git a/Components/VRCBoardImage.asset.meta b/Components/VRCBoardImage.asset.meta new file mode 100644 index 0000000..5d40cc8 --- /dev/null +++ b/Components/VRCBoardImage.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ac7f998a74898ea4ead01ba49e49e658 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardImage.cs b/Components/VRCBoardImage.cs new file mode 100644 index 0000000..82b6e9f --- /dev/null +++ b/Components/VRCBoardImage.cs @@ -0,0 +1,179 @@ +using UdonSharp; +using UnityEngine; +using UnityEngine.Serialization; +using VRC.SDK3.Data; + +namespace VRCBoard.Components +{ + [UdonBehaviourSyncMode(BehaviourSyncMode.None)] + public class VRCBoardImage : VRCBoardBaseComponent + { + [Header("Uploader ID (only applies to images of 'shared' or 'instance' type)")] + public string uploaderIdOverride; + + [Header("Image IDs")] + public string albedoImageId; + public string emissionImageId; + public string normalImageId; + + [Header("Defaults")] + public Texture2D defaultAlbedo; + [ColorUsageAttribute(true,true)] public Color albedoColor = Color.white; + public Texture2D defaultEmission; + [ColorUsageAttribute(true,true)] public Color emissionColor = Color.white; + public Texture2D defaultNormal; + public float normalIntensity = 1.0f; + + + private string _mainType = ""; + private string _uploaderId = ""; + + protected override void OnRegister() + { + MaterialPropertyBlock _propertyBlock = new MaterialPropertyBlock(); + Debug.Log("Registering image component"); + if (defaultAlbedo) + _propertyBlock.SetTexture("_MainTexAtlas", defaultAlbedo); + + if (defaultEmission) + _propertyBlock.SetTexture("_EmissionMapAtlas", defaultEmission); + + if (defaultNormal) + _propertyBlock.SetTexture("_NormalMapAtlas", defaultNormal); + + _propertyBlock.SetInteger("_MainTexAtlasIndex", 0); + _propertyBlock.SetInteger("_MainTexAtlasSize", 1); + _propertyBlock.SetInteger("_EmissionMapAtlasIndex", 0); + _propertyBlock.SetInteger("_EmissionMapAtlasSize", 1); + _propertyBlock.SetInteger("_NormalMapAtlasIndex", 0); + _propertyBlock.SetInteger("_NormalMapAtlasSize", 1); + + _propertyBlock.SetColor("_EmissionColor", emissionColor); + _propertyBlock.SetFloat("_NormalMapScale", normalIntensity); + _propertyBlock.SetColor("_MainTexColor", albedoColor); + + GetComponent().SetPropertyBlock(_propertyBlock); + } + + + private string GetUploader() + { + string uploaderId = ""; + if (string.IsNullOrEmpty(uploaderIdOverride)) + { + GetImageAtlasTexture(albedoImageId, null, out Texture2D albedoTexture, out int albedoAtlasPosition, out int albedoAtlasSize, out string albedoType); + if (albedoType == null) + { + Debug.LogError("Failed to get image type for albedo image"); + return ""; + } + _mainType = albedoType; + if (_mainType == "shared") + { + uploaderId = GetRandomUploader(albedoImageId); + } + else + { + DataDictionary ownerInfo = manager.GetSupporterDataFromPlayer(manager.instanceOwner); + if (ownerInfo == null) + { + Debug.LogWarning("Failed to get owner info, user has likely not linked their account."); + return ""; + } + bool ownerSuccess = ownerInfo.TryGetValue("id", out DataToken ownerToken); + if (!ownerSuccess || ownerToken.TokenType != TokenType.String) + { + Debug.LogWarning("Failed to get owner ID from owner info."); + return ""; + } + uploaderId = ownerToken.String; + } + + Debug.Log("image uploader: " + uploaderId); + } else + { + uploaderId = uploaderIdOverride; + } + return uploaderId; + } + + private void TryGetUploader() + { + if (!string.IsNullOrEmpty(_uploaderId)) return; + _uploaderId = GetUploader(); + if (string.IsNullOrEmpty(_uploaderId)) + { + Debug.LogError("Failed to get uploader ID"); + return; + } + RequestImageLoad(albedoImageId, _uploaderId); + RequestImageLoad(emissionImageId, _uploaderId); + RequestImageLoad(normalImageId, _uploaderId); + } + protected override void OnInitialize() + { + TryGetUploader(); + } + protected override void OnImageDataUpdate() + { + TryGetUploader(); + } + + protected override void OnSupporterDataUpdate() + { + TryGetUploader(); + } + + protected override void OnImageLoaded() + { + Debug.Log("Image loaded VRCBoardImage"); + + Texture2D albedoTexture; + int albedoAtlasPosition; + int albedoAtlasSize; + + Texture2D emissionTexture; + int emissionAtlasPosition; + int emissionAtlasSize; + + Texture2D normalTexture; + int normalAtlasPosition; + int normalAtlasSize; + + bool albedoSuccess = GetImageAtlasTexture(albedoImageId, _uploaderId, out albedoTexture, out albedoAtlasPosition, out albedoAtlasSize, out string type1); + bool emissionSuccess = GetImageAtlasTexture(emissionImageId, _uploaderId, out emissionTexture, out emissionAtlasPosition, out emissionAtlasSize, out string type2); + bool normalSuccess = GetImageAtlasTexture(normalImageId, _uploaderId, out normalTexture, out normalAtlasPosition, out normalAtlasSize, out string type3); + + MaterialPropertyBlock _propertyBlock = new MaterialPropertyBlock(); + + if (albedoSuccess && albedoTexture) { + _propertyBlock.SetTexture("_MainTexAtlas", albedoTexture); + _propertyBlock.SetInteger("_MainTexAtlasIndex", albedoAtlasPosition); + _propertyBlock.SetInteger("_MainTexAtlasSize", albedoAtlasSize); + } + else + { + return; + } + + if (emissionSuccess && emissionTexture) { + _propertyBlock.SetTexture("_EmissionMapAtlas", emissionTexture); + _propertyBlock.SetInteger("_EmissionMapAtlasIndex", emissionAtlasPosition); + _propertyBlock.SetInteger("_EmissionMapAtlasSize", emissionAtlasSize); + } + + if (normalSuccess && normalTexture) { + _propertyBlock.SetTexture("_NormalMapAtlas", normalTexture); + _propertyBlock.SetInteger("_NormalMapAtlasIndex", normalAtlasPosition); + _propertyBlock.SetInteger("_NormalMapAtlasSize", normalAtlasSize); + } + + _propertyBlock.SetColor("_EmissionColor", emissionColor); + _propertyBlock.SetFloat("_NormalMapScale", normalIntensity); + _propertyBlock.SetColor("_MainTexColor", albedoColor); + + GetComponent().SetPropertyBlock(_propertyBlock); + } + } +} + diff --git a/Components/VRCBoardImage.cs.meta b/Components/VRCBoardImage.cs.meta new file mode 100644 index 0000000..497f8a2 --- /dev/null +++ b/Components/VRCBoardImage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 63987f0853a8d0d44bd6ea28693af468 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardSupporterBoardBase.cs b/Components/VRCBoardSupporterBoardBase.cs new file mode 100644 index 0000000..92e29c9 --- /dev/null +++ b/Components/VRCBoardSupporterBoardBase.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UdonSharp; +using UnityEngine; +using VRC.SDK3.Data; +using VRCBoard.Components; + +using UnityEditor; + + +namespace VRCBoard.Components +{ + [Serializable] + internal struct BoardEditorConfigEntry + { + public const int length = 6; + [Header("ID")] + public IDType IDType; + [Tooltip("Uses with this tag / tier will be displayed")] + public string id; + + [Header("Styling"), Tooltip("Template to use for this tier, %s will be replaced with the supporter name")] + public string template; + public string separator; + + [Header("Advanced Options")] + public bool userMustBeInWorld; + public bool exclusive; + + + public BoardEditorConfigEntry(string[] data) + { + IDType = (IDType)Enum.Parse(typeof(IDType), data[0]); + id = data[1]; + template = data[2]; + separator = data[3]; + userMustBeInWorld = data[4] == "1"; + exclusive = data[5] == "1"; + } + public string[] ToArray() + { + string[] result = new string[length]; + result[0] = IDType.ToString(); + result[1] = id; + result[2] = template; + result[3] = separator; + result[4] = userMustBeInWorld ? "1" : "0"; + result[5] = exclusive ? "1" : "0"; + return result; + } + } + public abstract class VRCBoardSupporterBoardBase : VRCBoardBaseComponent + { + [SerializeField] internal string Separator = "\\n"; + [SerializeField] internal BoardEditorConfigEntry[] ConfigEntries = new BoardEditorConfigEntry[0]; + internal int configLength => config.Length/BoardEditorConfigEntry.length; + private string GetSeparator(string sep) + { + sep = sep.Replace("\\n", "\n"); + sep = sep.Replace("\\t", "\t"); + return sep; + } + + [HideInInspector] public string[] config = new string[0]; + private string _supporterList = ""; + + + protected abstract void UpdateSupporterBoard(string supporterList); + protected override void OnRegister() { } + + private string RemovePrefix(string node, string prefix) + { + if (node.StartsWith(prefix)) + return node.Substring(prefix.Length); + return node; + } + private string RemoveSuffix(string str, string suffix) + { + if (str.EndsWith(suffix)) + return str.Substring(0, str.Length - suffix.Length); + return str; + } + + private bool GetConfigFromNode(string node, out string[] foundConfig, out int foundIndex) + { + // for each entry in string[] config get every fifth element + // if the first element is equal to the node, return the config + Debug.Log("Getting config from node " + node); + foundConfig = null; + foundIndex = -1; + string[] split = node.Split('.'); + string nodeType = split[0].ToLower(); + string nodeValue = split[1].ToLower(); + + //Debug.Log("Length of config: " + config.Length+ " length of entry: " + BoardEditorConfigEntry.length+" config length: " + configLength); + for (int i = 0; i < configLength; i++) + { + string[] thisConfig = new string[BoardEditorConfigEntry.length]; + for (int j = 0; j < BoardEditorConfigEntry.length; j++) + { + thisConfig[j] = config[i * BoardEditorConfigEntry.length + j]; + } + + string id = thisConfig[1]; + string idType = thisConfig[0]; + + //Debug.Log("Checking " + idType + "." + id + " against " + nodeType + "." + nodeValue); + + if (idType.ToLower() == nodeType && id.ToLower() == nodeValue) + { + foundConfig = thisConfig; + foundIndex = i; + return true; + } + } + + return false; + } + private void GetFormattedSupporter(int index) + { + DataDictionary supporterData = manager.GetSupporterData(index); + DataToken supporterName = supporterData["name"]; + DataToken perkNodes = supporterData["pn"]; + if (supporterName.TokenType != TokenType.String) + return; + if (perkNodes.TokenType != TokenType.DataList) + return; + DataList perkNodeList = perkNodes.DataList; + int perkNodeCount = perkNodeList.Count; + bool reverseSearch = false; + for (int i = 0; i < perkNodeCount; i++) + { + DataToken perkNode = reverseSearch ? perkNodeList[perkNodeCount-1-i] : perkNodeList[i]; + if (perkNode.TokenType != TokenType.String) + continue; + string node = perkNode.String; + if (!GetConfigFromNode(node, out string[] foundConfig, out int foundIndex)) + continue; + + string template = foundConfig[2]; + string separator = GetSeparator(foundConfig[3]); + + string formatted = template.Replace("%s", supporterName.String); + + string result = formatted + separator; + string[] newArray = new string[_supporterListSeperated[foundIndex].Length + 1]; + for (int j = 0; j < _supporterListSeperated[foundIndex].Length; j++) + { + newArray[j] = _supporterListSeperated[foundIndex][j]; + } + newArray[newArray.Length - 1] = result; + _supporterListSeperated[foundIndex] = newArray; + + + bool userMustBeInWorld = foundConfig[4] == "1"; + bool exclusive = foundConfig[5] == "1"; + + if (exclusive) + break; + } + } + private string[][] _supporterListSeperated; + + private void ResetSupporterList() + { + _supporterListSeperated = new string[configLength][]; + for (int i = 0; i < configLength; i++) + { + _supporterListSeperated[i] = new string[0]; + } + } + private void UpdateSupporterList() + { + ResetSupporterList(); + int supporterCount = manager.SupporterCount; + _supporterList = ""; + for (int i = 0; i < supporterCount; i++) + { + GetFormattedSupporter(i); + } + // loop through all the seperated lists and join them with the separator + for (int i = 0; i < _supporterListSeperated.Length; i++) + { + for (int j = 0; j < _supporterListSeperated[i].Length; j++) + { + _supporterList += _supporterListSeperated[i][j]; + } + + string separator = GetSeparator(config[i * BoardEditorConfigEntry.length + 3]); + _supporterList = RemoveSuffix(_supporterList, separator); + + if (i != _supporterListSeperated.Length - 1) + _supporterList += GetSeparator(Separator); + } + + UpdateSupporterBoard(_supporterList); + } + + protected override void OnInitialize() + { + //Debug.Log("Initializing supporter board component"); + } + + protected override void OnImageDataUpdate() { } + protected override void OnImageLoaded() { } + + protected override void OnSupporterDataUpdate() + { + UpdateSupporterList(); + } + } + #if UNITY_EDITOR && !UDONSHARP_COMPILER + + [CustomEditor(typeof(VRCBoardSupporterBoardBase), true)] + public class VRCBoardSupporterBoardBaseEditor : Editor + { + // with methods to serialize and deserialize the config arra + public override void OnInspectorGUI() + { + if (Application.isPlaying) return; + //Debug.Log("EDITORRRR"); + EditorGUILayout.LabelField("Supporter Board Component"); + // apply the editorConfigEntries to config + List configList = new List(); + VRCBoardSupporterBoardBase targetComponent = (VRCBoardSupporterBoardBase)base.target; + BoardEditorConfigEntry[] editorConfigEntries = targetComponent.ConfigEntries; + foreach (BoardEditorConfigEntry entry in editorConfigEntries) + { + configList.AddRange(entry.ToArray()); + } + targetComponent.config = configList.ToArray(); + base.OnInspectorGUI(); + } + } + #endif +} + + diff --git a/Components/VRCBoardSupporterBoardBase.cs.meta b/Components/VRCBoardSupporterBoardBase.cs.meta new file mode 100644 index 0000000..d9536f9 --- /dev/null +++ b/Components/VRCBoardSupporterBoardBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0881a6e6e0907742a8eea495a9c061c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardSupporterBoardTMP.asset b/Components/VRCBoardSupporterBoardTMP.asset new file mode 100644 index 0000000..6752d81 --- /dev/null +++ b/Components/VRCBoardSupporterBoardTMP.asset @@ -0,0 +1,665 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3} + m_Name: VRCBoardSupporterBoardTMP + m_EditorClassIdentifier: + serializedUdonProgramAsset: {fileID: 11400000, guid: e758930ddabc47d499d718189a2787b5, + type: 2} + udonAssembly: + assemblyError: + sourceCsScript: {fileID: 11500000, guid: 670e2136f923f894789f2871f5134127, type: 3} + scriptVersion: 2 + compiledVersion: 2 + behaviourSyncMode: 1 + hasInteractEvent: 0 + scriptID: -834845268903273143 + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: + - Name: fieldDefinitions + Entry: 7 + Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition, + UdonSharp.Editor]], mscorlib + - Name: comparer + Entry: 7 + Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 11 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: manager + - Name: $v + Entry: 7 + Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: manager + - Name: k__BackingField + Entry: 7 + Data: 3|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRCBoard.VRCBoardManager, Assembly-CSharp + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: 4|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.Udon.UdonBehaviour, VRC.Udon + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 5|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 6|UnityEngine.HideInInspector, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _imageInitialized + - Name: $v + Entry: 7 + Data: 7|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _imageInitialized + - Name: k__BackingField + Entry: 7 + Data: 8|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Boolean, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 9|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _dataInitialized + - Name: $v + Entry: 7 + Data: 10|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _dataInitialized + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _initialized + - Name: $v + Entry: 7 + Data: 12|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _initialized + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 9 + Data: 8 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 13|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: Separator + - Name: $v + Entry: 7 + Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: Separator + - Name: k__BackingField + Entry: 7 + Data: 15|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 16|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 17|UnityEngine.SerializeField, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: ConfigEntries + - Name: $v + Entry: 7 + Data: 18|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: ConfigEntries + - Name: k__BackingField + Entry: 7 + Data: 19|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRCBoard.Components.BoardEditorConfigEntry[], Assembly-CSharp + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: 20|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Object[], mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 21|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 22|UnityEngine.SerializeField, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: config + - Name: $v + Entry: 7 + Data: 23|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: config + - Name: k__BackingField + Entry: 7 + Data: 24|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String[], mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 24 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 25|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 1 + - Name: + Entry: 7 + Data: 26|UnityEngine.HideInInspector, UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _supporterList + - Name: $v + Entry: 7 + Data: 27|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _supporterList + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 9 + Data: 15 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 28|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _supporterListSeperated + - Name: $v + Entry: 7 + Data: 29|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _supporterListSeperated + - Name: k__BackingField + Entry: 7 + Data: 30|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String[][], mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 20 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 31|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: text + - Name: $v + Entry: 7 + Data: 32|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: text + - Name: k__BackingField + Entry: 7 + Data: 33|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: TMPro.TextMeshPro[], Unity.TextMeshPro + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 33 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 34|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: textUGUI + - Name: $v + Entry: 7 + Data: 35|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: textUGUI + - Name: k__BackingField + Entry: 7 + Data: 36|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: TMPro.TextMeshProUGUI[], Unity.TextMeshPro + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 36 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 37|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: diff --git a/Components/VRCBoardSupporterBoardTMP.asset.meta b/Components/VRCBoardSupporterBoardTMP.asset.meta new file mode 100644 index 0000000..39d17e8 --- /dev/null +++ b/Components/VRCBoardSupporterBoardTMP.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 486db5f9f0a8ce345a26bc8587a216a2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Components/VRCBoardSupporterBoardTMP.cs b/Components/VRCBoardSupporterBoardTMP.cs new file mode 100644 index 0000000..615e9c0 --- /dev/null +++ b/Components/VRCBoardSupporterBoardTMP.cs @@ -0,0 +1,27 @@ + +using UdonSharp; +using UnityEngine; +using VRC.SDKBase; +using VRC.Udon; + +namespace VRCBoard.Components +{ + public class VRCBoardSupporterBoardTMP : VRCBoardSupporterBoardBase + { + public TMPro.TextMeshPro[] text; + public TMPro.TextMeshProUGUI[] textUGUI; + + protected override void UpdateSupporterBoard(string supporterList) + { + Debug.Log("Updating supporter board"); + for (int i = 0; i < text.Length; i++) + { + text[i].text = supporterList; + } + for (int i = 0; i < textUGUI.Length; i++) + { + textUGUI[i].text = supporterList; + } + } + } +} diff --git a/Components/VRCBoardSupporterBoardTMP.cs.meta b/Components/VRCBoardSupporterBoardTMP.cs.meta new file mode 100644 index 0000000..2122c6a --- /dev/null +++ b/Components/VRCBoardSupporterBoardTMP.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 670e2136f923f894789f2871f5134127 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials.meta b/Materials.meta new file mode 100644 index 0000000..0c65181 --- /dev/null +++ b/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 67d89a5dfafd1aa46aabf1ca1062e6ea +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials/Editor.meta b/Materials/Editor.meta new file mode 100644 index 0000000..aeec0b3 --- /dev/null +++ b/Materials/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: beb1ece4e81f7d54481022aa41ad1214 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials/Editor/VRCBoardShaderEditor.cs b/Materials/Editor/VRCBoardShaderEditor.cs new file mode 100644 index 0000000..bf0647a --- /dev/null +++ b/Materials/Editor/VRCBoardShaderEditor.cs @@ -0,0 +1,20 @@ +using System.Collections; +using System.Collections.Generic; +using UdonSharp; +using UnityEngine; +using UnityEditor; + +namespace VRCBoard +{ + [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] + public class VRCBoardShaderEditor : ShaderGUI + { + // Start is called before the first frame update + public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) + { + EditorGUILayout.LabelField("Please use the VRCBoardImage component to edit the material properties."); + //base.OnGUI(materialEditor, properties); + } + } + +} diff --git a/Materials/Editor/VRCBoardShaderEditor.cs.meta b/Materials/Editor/VRCBoardShaderEditor.cs.meta new file mode 100644 index 0000000..c05fa1c --- /dev/null +++ b/Materials/Editor/VRCBoardShaderEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54050364012eda64b93ac4539faa4a15 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials/VRCBoardImage.mat b/Materials/VRCBoardImage.mat new file mode 100644 index 0000000..d24837d --- /dev/null +++ b/Materials/VRCBoardImage.mat @@ -0,0 +1,103 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: VRCBoardImage + m_Shader: {fileID: 4800000, guid: 8391ead9ad6feee41a7c2f7f6ccd5f81, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 1 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMapAtlas: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTexAtlas: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _NormalMapAtlas: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EmissionMapAtlasIndex: 0 + - _EmissionMapAtlasSize: 1 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _MainTexAtlasIndex: 0 + - _MainTexAtlasSize: 1 + - _Metallic: 0 + - _Mode: 0 + - _NormalMapAtlasIndex: 0 + - _NormalMapAtlasSize: 1 + - _NormalMapScale: 1 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _MainTexColor: {r: 1, g: 1, b: 1, a: 1} + m_BuildTextureStacks: [] diff --git a/Materials/VRCBoardImage.mat.meta b/Materials/VRCBoardImage.mat.meta new file mode 100644 index 0000000..9fa0f57 --- /dev/null +++ b/Materials/VRCBoardImage.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 66b314f6e6cbc5a4a97f18dde3864299 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Materials/VRCBoardImageShader.shader b/Materials/VRCBoardImageShader.shader new file mode 100644 index 0000000..36e1073 --- /dev/null +++ b/Materials/VRCBoardImageShader.shader @@ -0,0 +1,98 @@ +Shader "VRCBoard/VRCBoardAtlasShader" +{ + Properties + { + // _MainTex + _MainTexAtlas("Albedo", 2D) = "white" {} + [HideInInspector] _MainTexAtlasSize("Atlas Size", int) = 1 + [HideInInspector] _MainTexAtlasIndex("Atlas Position", int) = 0 + [HideInInspector] _MainTexColor("Color", Color) = (1,1,1,1) + + // _EmissionMap + _EmissionMapAtlas("Emission", 2D) = "black" {} + [HideInInspector] _EmissionMapAtlasSize("Emission Atlas Size", int) = 1 + [HideInInspector] _EmissionMapAtlasIndex("Emission Atlas Position", int) = 0 + [HideInInspector] _EmissionColor("Emission Color", Color) = (1,1,1,1) + + // _NormalMap + _NormalMapAtlas("Normal", 2D) = "bump" {} + [HideInInspector] _NormalMapAtlasSize("Normal Atlas Size", int) = 1 + [HideInInspector] _NormalMapAtlasIndex("Normal Atlas Position", int) = 0 + [HideInInspector] _NormalMapScale("Normal Scale", float) = 1 + + } + SubShader + { + Tags { "RenderType"="Opaque" } + LOD 200 + + CGPROGRAM + #pragma surface surf Standard fullforwardshadows + + #pragma target 3.0 + + sampler2D _MainTexAtlas; + sampler2D _EmissionMapAtlas; + sampler2D _NormalMapAtlas; + + uint _MainTexAtlasSize; + uint _MainTexAtlasIndex; + float4 _MainTexColor; + + + uint _EmissionMapAtlasSize; + uint _EmissionMapAtlasIndex; + float4 _EmissionColor; + + uint _NormalMapAtlasSize; + uint _NormalMapAtlasIndex; + float _NormalMapScale; + + struct Input + { + float2 uv_MainTexAtlas; + float2 uv_EmissionMapAtlas; + float2 uv_NormalMapAtlas; + }; + + // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. + // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. + // #pragma instancing_options assumeuniformscaling + UNITY_INSTANCING_BUFFER_START(Props) + UNITY_INSTANCING_BUFFER_END(Props) + + void surf (Input IN, inout SurfaceOutputStandard o) + { + _MainTexAtlasIndex = _MainTexAtlasIndex+_MainTexAtlasSize; + _EmissionMapAtlasIndex = _EmissionMapAtlasIndex+_EmissionMapAtlasSize; + _NormalMapAtlasIndex = _NormalMapAtlasIndex+_NormalMapAtlasSize; + + float2 MainTexAtlasUV = float2( + (float(_MainTexAtlasIndex % _MainTexAtlasSize) + IN.uv_MainTexAtlas.x) / _MainTexAtlasSize, + 1.0 - (float(_MainTexAtlasIndex / _MainTexAtlasSize) - IN.uv_MainTexAtlas.y) / _MainTexAtlasSize + ); + + float2 EmissionMapAtlasUV = float2( + (float(_EmissionMapAtlasIndex % _EmissionMapAtlasSize) + IN.uv_EmissionMapAtlas.x) / _EmissionMapAtlasSize, + 1.0 - (float(_EmissionMapAtlasIndex / _EmissionMapAtlasSize) - IN.uv_EmissionMapAtlas.y) / _EmissionMapAtlasSize + ); + + float2 NormalMapAtlasUV = float2( + (float(_NormalMapAtlasIndex % _NormalMapAtlasSize) + IN.uv_NormalMapAtlas.x) / _NormalMapAtlasSize, + 1.0 - (float(_NormalMapAtlasIndex / _NormalMapAtlasSize) - IN.uv_NormalMapAtlas.y) / _NormalMapAtlasSize + ); + + + fixed4 c = tex2D (_MainTexAtlas, MainTexAtlasUV); + fixed4 e = tex2D (_EmissionMapAtlas, EmissionMapAtlasUV); + fixed4 n = tex2D (_NormalMapAtlas, NormalMapAtlasUV); + + o.Albedo = c.rgb * _MainTexColor.rgb; + o.Emission = e.rgb * _EmissionColor.rgb; + o.Normal = UnpackNormal(n); + } + ENDCG + } + FallBack "Diffuse" + CustomEditor "VRCBoard.VRCBoardShaderEditor" +} diff --git a/Materials/VRCBoardImageShader.shader.meta b/Materials/VRCBoardImageShader.shader.meta new file mode 100644 index 0000000..05427c5 --- /dev/null +++ b/Materials/VRCBoardImageShader.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8391ead9ad6feee41a7c2f7f6ccd5f81 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCBoardManager.asset b/VRCBoardManager.asset new file mode 100644 index 0000000..23ec038 --- /dev/null +++ b/VRCBoardManager.asset @@ -0,0 +1,1163 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3} + m_Name: VRCBoardManager + m_EditorClassIdentifier: + serializedUdonProgramAsset: {fileID: 11400000, guid: b0a3201f714d46b4cbdb27ef08a99c58, + type: 2} + udonAssembly: + assemblyError: + sourceCsScript: {fileID: 11500000, guid: a15201eb91eaa134bb21f3335054e187, type: 3} + scriptVersion: 2 + compiledVersion: 2 + behaviourSyncMode: 0 + hasInteractEvent: 0 + scriptID: -2600486769412427948 + serializationData: + SerializedFormat: 2 + SerializedBytes: + ReferencedUnityObjects: [] + SerializedBytesString: + Prefab: {fileID: 0} + PrefabModificationsReferencedUnityObjects: [] + PrefabModifications: [] + SerializationNodes: + - Name: fieldDefinitions + Entry: 7 + Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition, + UdonSharp.Editor]], mscorlib + - Name: comparer + Entry: 7 + Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String, + mscorlib]], mscorlib + - Name: + Entry: 8 + Data: + - Name: + Entry: 12 + Data: 21 + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: vrcBoardDomain + - Name: $v + Entry: 7 + Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: vrcBoardDomain + - Name: k__BackingField + Entry: 7 + Data: 3|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 3 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 4|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: periodicUpdateInterval + - Name: $v + Entry: 7 + Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: periodicUpdateInterval + - Name: k__BackingField + Entry: 7 + Data: 6|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Single, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 6 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 7|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: vrcBoardComponents + - Name: $v + Entry: 7 + Data: 8|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: vrcBoardComponents + - Name: k__BackingField + Entry: 7 + Data: 9|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRCBoard.Components.VRCBoardBaseComponent[], Assembly-CSharp + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: 10|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Component[], UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: atlasUrls + - Name: $v + Entry: 7 + Data: 12|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: atlasUrls + - Name: k__BackingField + Entry: 7 + Data: 13|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.SDKBase.VRCUrl[], VRCSDKBase + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 13 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 14|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _imageDownloaders + - Name: $v + Entry: 7 + Data: 15|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _imageDownloaders + - Name: k__BackingField + Entry: 7 + Data: 16|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.SDK3.Image.VRCImageDownloader[], VRCSDK3 + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 16 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 17|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _downloadedAtlasTextures + - Name: $v + Entry: 7 + Data: 18|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _downloadedAtlasTextures + - Name: k__BackingField + Entry: 7 + Data: 19|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: UnityEngine.Texture2D[], UnityEngine.CoreModule + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 19 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 20|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _atlasDownloadTimes + - Name: $v + Entry: 7 + Data: 21|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _atlasDownloadTimes + - Name: k__BackingField + Entry: 7 + Data: 22|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Single[], mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 22 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 23|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: customModuleUrls + - Name: $v + Entry: 7 + Data: 24|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: customModuleUrls + - Name: k__BackingField + Entry: 9 + Data: 13 + - Name: k__BackingField + Entry: 9 + Data: 13 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 25|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: atlasInfoUrl + - Name: $v + Entry: 7 + Data: 26|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: atlasInfoUrl + - Name: k__BackingField + Entry: 7 + Data: 27|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.SDKBase.VRCUrl, VRCSDKBase + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 27 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 28|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _atlasInfo + - Name: $v + Entry: 7 + Data: 29|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _atlasInfo + - Name: k__BackingField + Entry: 7 + Data: 30|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.SDK3.Data.DataDictionary, VRCSDK3 + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 31|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: supporterInfoUrl + - Name: $v + Entry: 7 + Data: 32|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: supporterInfoUrl + - Name: k__BackingField + Entry: 9 + Data: 27 + - Name: k__BackingField + Entry: 9 + Data: 27 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 33|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _supporterInfo + - Name: $v + Entry: 7 + Data: 34|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _supporterInfo + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 35|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _supporterInfoVrcLookup + - Name: $v + Entry: 7 + Data: 36|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _supporterInfoVrcLookup + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 9 + Data: 30 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 37|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _supporterList + - Name: $v + Entry: 7 + Data: 38|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _supporterList + - Name: k__BackingField + Entry: 7 + Data: 39|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: VRC.SDK3.Data.DataList, VRCSDK3 + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 39 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 40|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _perkNodes + - Name: $v + Entry: 7 + Data: 41|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _perkNodes + - Name: k__BackingField + Entry: 9 + Data: 39 + - Name: k__BackingField + Entry: 9 + Data: 39 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 42|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _instanceOwnerOverride + - Name: $v + Entry: 7 + Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _instanceOwnerOverride + - Name: k__BackingField + Entry: 9 + Data: 3 + - Name: k__BackingField + Entry: 9 + Data: 3 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 3 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 2 + - Name: + Entry: 7 + Data: 45|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: 46|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _instanceOwner + - Name: $v + Entry: 7 + Data: 47|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _instanceOwner + - Name: k__BackingField + Entry: 9 + Data: 3 + - Name: k__BackingField + Entry: 9 + Data: 3 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 3 + Data: 1 + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 48|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 2 + - Name: + Entry: 7 + Data: 49|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: 50|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: imageIdDownloadQueue + - Name: $v + Entry: 7 + Data: 51|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: imageIdDownloadQueue + - Name: k__BackingField + Entry: 7 + Data: 52|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.String[], mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 52 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: true + - Name: _fieldAttributes + Entry: 7 + Data: 53|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _shouldUpdateAtlasInfo + - Name: $v + Entry: 7 + Data: 54|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _shouldUpdateAtlasInfo + - Name: k__BackingField + Entry: 7 + Data: 55|System.RuntimeType, mscorlib + - Name: + Entry: 1 + Data: System.Boolean, mscorlib + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 9 + Data: 55 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 56|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _shouldUpdateSupporterInfo + - Name: $v + Entry: 7 + Data: 57|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _shouldUpdateSupporterInfo + - Name: k__BackingField + Entry: 9 + Data: 55 + - Name: k__BackingField + Entry: 9 + Data: 55 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 58|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 7 + Data: + - Name: $k + Entry: 1 + Data: _currentlyDownloadingUrls + - Name: $v + Entry: 7 + Data: 59|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor + - Name: k__BackingField + Entry: 1 + Data: _currentlyDownloadingUrls + - Name: k__BackingField + Entry: 9 + Data: 13 + - Name: k__BackingField + Entry: 9 + Data: 13 + - Name: k__BackingField + Entry: 7 + Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib + - Name: + Entry: 6 + Data: + - Name: + Entry: 8 + Data: + - Name: k__BackingField + Entry: 5 + Data: false + - Name: _fieldAttributes + Entry: 7 + Data: 60|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib + - Name: + Entry: 12 + Data: 0 + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 8 + Data: + - Name: + Entry: 13 + Data: + - Name: + Entry: 8 + Data: diff --git a/VRCBoardManager.asset.meta b/VRCBoardManager.asset.meta new file mode 100644 index 0000000..61b9c96 --- /dev/null +++ b/VRCBoardManager.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c4183376def25d24a8d2963d59ac2cd2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VRCBoardManager.cs b/VRCBoardManager.cs new file mode 100644 index 0000000..990a0c5 --- /dev/null +++ b/VRCBoardManager.cs @@ -0,0 +1,662 @@ +using System; +using JetBrains.Annotations; +using UdonSharp; +using UnityEngine; +using UnityEngine.Serialization; +using VRC.SDK3.Data; +using VRC.SDK3.Image; +using VRC.SDK3.StringLoading; +using VRC.SDKBase; +using VRC.Udon.Common.Interfaces; +using VRCBoard; +using VRCBoard.Components; +using Object = UnityEngine.Object; + + +using UnityEditor; + + +namespace VRCBoard +{ + + public enum IDType + { + Tier, + Tag, + Image + } + public class VRCBoardManager : UdonSharpBehaviour + { + public string vrcBoardDomain = "mydomain.vrcboard.app"; + public float periodicUpdateInterval = 60f; + public string VrcBoardBaseUrl => "https://" + vrcBoardDomain + "/"; + + public VRCBoardBaseComponent[] vrcBoardComponents; + + public VRCUrl[] atlasUrls; + private VRCImageDownloader[] _imageDownloaders; + private Texture2D[] _downloadedAtlasTextures; + private float[] _atlasDownloadTimes; + + public VRCUrl[] customModuleUrls; + + public VRCUrl atlasInfoUrl; + private DataDictionary _atlasInfo; + + public VRCUrl supporterInfoUrl; + private DataDictionary _supporterInfo; + private DataDictionary _supporterInfoVrcLookup; + private DataList _supporterList; + private DataList _perkNodes; + + + [UdonSynced, FieldChangeCallback(nameof(instanceOwnerOverride))] + private string _instanceOwnerOverride = ""; + + public string instanceOwnerOverride + { + get => _instanceOwnerOverride; + set + { + _instanceOwnerOverride = value; + Networking.SetOwner(Networking.LocalPlayer, gameObject); + RequestSerialization(); + Debug.Log("Instance owner override set to " + value); + } + } + + [UdonSynced, FieldChangeCallback(nameof(instanceOwner))] private string _instanceOwner; + public string[] imageIdDownloadQueue = new string[0]; + + public string instanceOwner + { + get { + if (!string.IsNullOrWhiteSpace(instanceOwnerOverride)) return instanceOwnerOverride; + return _instanceOwner; + } + set + { + _instanceOwner = value; + Networking.SetOwner(Networking.LocalPlayer, gameObject); + RequestSerialization(); + Debug.Log("Instance owner set to " + value); + } + } + + private void RemoveNullComponents() + { + int nullCount = 0; + for (int i = 0; i < vrcBoardComponents.Length; i++) + { + if (vrcBoardComponents[i] == null) + { + nullCount++; + } + } + + if (nullCount == 0) return; + VRCBoardBaseComponent[] newComponents = new VRCBoardBaseComponent[vrcBoardComponents.Length - nullCount]; + int newIndex = 0; + for (int i = 0; i < vrcBoardComponents.Length; i++) + { + if (vrcBoardComponents[i] == null) continue; + newComponents[newIndex] = vrcBoardComponents[i]; + newIndex++; + } + + vrcBoardComponents = newComponents; + } + private void Start() + { + int urlCount = atlasUrls.Length; + _imageDownloaders = new VRCImageDownloader[urlCount]; + _downloadedAtlasTextures = new Texture2D[urlCount]; + _atlasDownloadTimes = new float[urlCount]; + for (int i = 0; i < atlasUrls.Length; i++) + { + _imageDownloaders[i] = new VRCImageDownloader(); + } + + RemoveNullComponents(); + + foreach (var component in vrcBoardComponents) + component._Register(this); + _PeriodicUpdate(); + _TaskLoop(); + Debug.Log("VRCBoardManager started"); + } + + public void _PeriodicUpdate() + { + //Debug.Log("Periodic update"); + if (Networking.LocalPlayer.isInstanceOwner) { instanceOwner = Networking.LocalPlayer.displayName; } + _RequestAtlasInfoUpdate(); + _RequestSupporterInfoUpdate(); + SendCustomEventDelayedSeconds(nameof(_PeriodicUpdate), periodicUpdateInterval); + } + public void _TaskLoop() + { + //Debug.Log("Task loop"); + _TryUpdateAtlasInfo(); + _TryUpdateSupporterInfo(); + SendCustomEventDelayedSeconds(nameof(_TaskLoop), 1f); + } + + + private bool _shouldUpdateAtlasInfo = true; + private bool _shouldUpdateSupporterInfo = true; + private void _TryUpdateAtlasInfo() + { + if (!_shouldUpdateAtlasInfo) return; + Debug.Log("Trying to update atlas info !"); + RequestUrlLoad(atlasInfoUrl); + _shouldUpdateAtlasInfo = false; + } + private void _TryUpdateSupporterInfo() + { + if (!_shouldUpdateSupporterInfo) return; + Debug.Log("Trying to update supporter info !"); + RequestUrlLoad(supporterInfoUrl); + _shouldUpdateSupporterInfo = false; + } + + [PublicAPI] public void _RequestAtlasInfoUpdate() + { + _shouldUpdateAtlasInfo = true; + } + [PublicAPI] public void _RequestSupporterInfoUpdate() + { + _shouldUpdateSupporterInfo = true; + } + + + private VRCUrl[] _currentlyDownloadingUrls = new VRCUrl[0]; + private void RequestUrlLoad(VRCUrl url) + { + string urlStr = url.Get(); + for (int i = 0; i < _currentlyDownloadingUrls.Length; i++) + { + if (_currentlyDownloadingUrls[i].Get() == urlStr) + { + return; + } + } + + VRCStringDownloader.LoadUrl(url, (IUdonEventReceiver)this); + VRCUrl[] newUrls = new VRCUrl[_currentlyDownloadingUrls.Length + 1]; + for (int i = 0; i < _currentlyDownloadingUrls.Length; i++) + { + newUrls[i] = _currentlyDownloadingUrls[i]; + } + newUrls[_currentlyDownloadingUrls.Length] = url; + _currentlyDownloadingUrls = newUrls; + } + + + public override void OnStringLoadSuccess(IVRCStringDownload download) + { + string url = download.Url.Get(); + + VRCUrl[] newUrls = new VRCUrl[_currentlyDownloadingUrls.Length - 1]; + int newIndex = 0; + for (int i = 0; i < _currentlyDownloadingUrls.Length; i++) + { + if (_currentlyDownloadingUrls[i].Get() == url) + { + continue; + } + + newUrls[newIndex] = _currentlyDownloadingUrls[i]; + newIndex++; + } + _currentlyDownloadingUrls = newUrls; + + //Debug.Log("String load success " + url); + if (url == atlasInfoUrl.Get()) + { + OnAtlasInfoDownload(download.Result); + } else if (url == supporterInfoUrl.Get()) + { + OnSupporterInfoDownload(download.Result); + } + } + public override void OnStringLoadError(IVRCStringDownload result) + { + base.OnStringLoadError(result); + Debug.LogWarning(result.Url.Get() + " : " + result.Error.ToString()); + } + public DataDictionary _GetImageIdInfo(string imageId) + { + if (_atlasInfo == null) return null; + if (!_atlasInfo.ContainsKey(imageId)) return null; + DataToken token = _atlasInfo[imageId]; + if (token.TokenType != TokenType.DataDictionary) return null; + return token.DataDictionary; + } + public bool _GetImageAtlasTexture(string imageId, string uploader, out int atlasIndex, out Texture2D texture, out int position, out int size, out string type) + { + texture = null; + position = -1; + size = -1; + atlasIndex = -1; + type = null; + DataDictionary imageInfo = _GetImageIdInfo(imageId); + if (imageInfo == null) + { + return false; + } + + bool imageTypeSuccess = imageInfo.TryGetValue("type", out DataToken typeToken); + bool uploadsSuccess = imageInfo.TryGetValue("uploads", out DataToken uploadsToken); + bool atlasSizeSuccess = imageInfo.TryGetValue("size", out DataToken sizeToken); + //Debug.Log("Get image atlas texture " + imageId + " success: " + imageTypeSuccess + " " + uploadsSuccess + " " + atlasSizeSuccess); + if ((!imageTypeSuccess || !uploadsSuccess || !atlasSizeSuccess) || + (typeToken.TokenType != TokenType.String || uploadsToken.TokenType != TokenType.DataList || sizeToken.TokenType != TokenType.Double)) + { + return false; + } + + type = typeToken.String; + size = (int)sizeToken.Double; + + bool isGlobal = type == "global"; + + DataList uploads = uploadsToken.DataList; + int uploadCount = uploads.Count; + if (uploadCount == 0) + { + return false; + } + // find index of the uploader + int uploaderIndex = 0; + if (!isGlobal) + { + uploaderIndex = -1; + if (uploader == null) return false; + for (int i = 0; i < uploadCount; i++) + { + DataDictionary upload = uploads[i].DataDictionary; + if (upload == null) continue; + bool uploaderSuccess = upload.TryGetValue("a", out DataToken uploaderToken); + //Debug.Log("Uploader success: " + uploaderSuccess); + if (!uploaderSuccess) continue; + if (uploaderToken.TokenType != TokenType.String) continue; + string uploadUploader = uploaderToken.String; + //Debug.Log("Comparing uploader " + uploadUploader + " to " + uploader); + if (uploadUploader == uploader) + { + //Debug.Log("Match"); + uploaderIndex = i; + break; + } + } + } + //Debug.Log("Uploader index: " + uploaderIndex); + if (uploaderIndex == -1) + { + return false; + } + DataDictionary uploadInfo = uploads[uploaderIndex].DataDictionary; + if (uploadInfo == null) + { + return false; + } + bool atlasIndexSuccess = uploadInfo.TryGetValue("i", out DataToken atlasIndexToken); + if (!atlasIndexSuccess || atlasIndexToken.TokenType != TokenType.Double) + { + return false; + } + + atlasIndex = (int)atlasIndexToken.Double; + texture = _downloadedAtlasTextures[atlasIndex]; + bool positionSuccess = uploadInfo.TryGetValue("p", out DataToken positionToken); + if (!positionSuccess || positionToken.TokenType != TokenType.Double) + { + return false; + } + position = (int)positionToken.Double; + return true; + } + public void _RequestImageLoad(string imageId, string uploader, VRCBoardBaseComponent component) + { + //Debug.Log("Requesting image load " + imageId); + if (string.IsNullOrEmpty(imageId)) return; + string combinedId = $"{imageId}:{uploader}"; + if (HasImageInQueue(combinedId)) return; + AddImageToQueue(combinedId); + } + private void TryDownloadImageId(string combinedImageId) + { + string[] split = combinedImageId.Split(':'); + if (split.Length != 2) return; + string imageId = split[0]; + string uploader = split[1]; + bool success = _GetImageAtlasTexture(imageId, uploader, out int atlasIndex, out Texture2D texture, + out int position, out int size, out string type); + //Debug.Log("Try download image " + combinedImageId + " success: " + success); + if (!success) return; + DownloadAtlas(atlasIndex); + + } + + private void OnSupporterInfoDownload(string data) + { + Debug.Log("Supporter info download success"); + if (VRCJson.TryDeserializeFromJson(data, out DataToken result)) + { + if (result.TokenType != TokenType.DataDictionary) return; + SetSupporterInfo(result.DataDictionary); + OnSupporterInfoUpdate(); + + } + else + { + Debug.LogError("Failed to deserialize supporter info"); + } + } + private void SetSupporterInfo(DataDictionary value) + { + _supporterInfo = value; + if (_supporterInfo == null) return; + bool vrcsuccess = _supporterInfo.TryGetValue("vrclookup", out DataToken vrcToken); + bool supporterSuccess = _supporterInfo.TryGetValue("supporters", out DataToken supporterToken); + bool perkSuccess = _supporterInfo.TryGetValue("perkNodes", out DataToken perkToken); + if (vrcsuccess && vrcToken.TokenType == TokenType.DataDictionary) + { + _supporterInfoVrcLookup = vrcToken.DataDictionary; + } + if (supporterSuccess && supporterToken.TokenType == TokenType.DataList) + { + _supporterList = supporterToken.DataList; + } + if (perkSuccess && perkToken.TokenType == TokenType.DataList) + { + _perkNodes = perkToken.DataList; + } + Debug.Log("Set supporter info "+vrcsuccess+" "+supporterSuccess+" "+perkSuccess); + } + + [PublicAPI] + public bool PlayerHasTag(VRCPlayerApi player, string tag) + { + return PlayerHasTag(player.displayName, tag); + } + + [PublicAPI] + public bool PlayerHasTag(string displayName, string tag) + { + DataDictionary supporterData = GetSupporterDataFromPlayer(displayName); + if (supporterData == null) return false; + bool perkNodesSuccess = supporterData.TryGetValue("pn", out DataToken perkNodesToken); + if (!perkNodesSuccess || perkNodesToken.TokenType != TokenType.DataList) return false; + DataList perkNodes = perkNodesToken.DataList; + for (int i = 0; i < perkNodes.Count; i++) + { + DataToken perkNode = perkNodes[i]; + if (perkNode.TokenType != TokenType.String) continue; + if (perkNode.String == tag) return true; + } + return false; + } + + [PublicAPI] + public int SupporterCount => _supporterList.Count; + [PublicAPI] + public DataDictionary GetSupporterData(int index) + { + DataToken token = _supporterList[index]; + if (token.TokenType != TokenType.DataDictionary) return null; + DataDictionary supporterData = token.DataDictionary; + string perkNodesKey = "pn"; + bool perkNodesSuccess = supporterData.TryGetValue(perkNodesKey, out DataToken pnToken); + if (!perkNodesSuccess || pnToken.TokenType != TokenType.DataList) return supporterData; + DataList perkNodes = pnToken.DataList; + for (int i = 0; i < perkNodes.Count; i++) + { + DataToken perkNodeToken = perkNodes[i]; + if (perkNodeToken.TokenType != TokenType.Double) continue; + int perkIndex = (int)perkNodeToken.Double; + if (perkIndex < 0 || perkIndex >= _perkNodes.Count) continue; + DataToken perkNode = _perkNodes[perkIndex]; + if (perkNode.TokenType != TokenType.DataDictionary) continue; + bool perkNameSuccess = perkNode.DataDictionary.TryGetValue("id", out DataToken perkNameToken); + if (!perkNameSuccess || perkNameToken.TokenType != TokenType.String) continue; + perkNodes[i] = perkNameToken; + } + supporterData[perkNodesKey] = perkNodes; + return supporterData; + } + + [PublicAPI] + public DataDictionary GetSupporterDataFromPlayer(string vrcName) + { + if (_supporterInfoVrcLookup == null) return null; + if (!_supporterInfoVrcLookup.ContainsKey(vrcName)) return null; + DataToken token = _supporterInfoVrcLookup[vrcName]; + if (token.TokenType != TokenType.Double) return null; + int index = (int)token.Double; + return GetSupporterData(index); + } + + [PublicAPI] + public DataDictionary GetSupporterDataFromPlayer(VRCPlayerApi player) + { + return GetSupporterDataFromPlayer(player.displayName); + } + + private void OnSupporterInfoUpdate() + { + Debug.Log("Supporter info updated"); + foreach (var component in vrcBoardComponents) + component._OnSupporterDataUpdate(); + } + + private void OnAtlasInfoDownload(string data) + { + //Debug.Log("Atlas info download success"); + if (VRCJson.TryDeserializeFromJson(data, out DataToken result)) + { + if (result.TokenType != TokenType.DataDictionary) return; + _atlasInfo = result.DataDictionary; + OnAtlasInfoUpdate(); + } + else + { + Debug.LogError("Failed to deserialize atlas info"); + } + } + + + + private void OnAtlasInfoUpdate() + { + //Debug.Log("Atlas info updated"); + if (_atlasInfo == null) return; + while (true) + { + string combinedImageId = GetNextImageInQueue(); + if (combinedImageId == null) break; + TryDownloadImageId(combinedImageId); + } + + foreach (var component in vrcBoardComponents) + component._OnImageInfoUpdate(); + } + + + + private void DownloadAtlas(int index) + { + //Debug.Log("Downloading atlas " + index); + if (index < 0 || index >= atlasUrls.Length) return; + VRCUrl url = GetAtlasUrlFromIndex(index); + VRCImageDownloader imageDownloader = _imageDownloaders[index]; + imageDownloader.Dispose(); + + if (url == null) return; + TextureInfo textureInfo = new TextureInfo(); + textureInfo.FilterMode = FilterMode.Bilinear; + textureInfo.WrapModeU = TextureWrapMode.Clamp; + textureInfo.WrapModeV = TextureWrapMode.Clamp; + textureInfo.WrapModeW = TextureWrapMode.Clamp; + IVRCImageDownload download = + imageDownloader.DownloadImage(url, null, (IUdonEventReceiver)this, textureInfo); + } + + public override void OnImageLoadSuccess(IVRCImageDownload result) + { + string url = result.Url.Get(); + Debug.Log("Image load success " + url); + Texture2D texture = result.Result; + int index = GetAtlasIndexFromUrl(url); + if (index == -1) return; + _downloadedAtlasTextures[index] = result.Result; + _atlasDownloadTimes[index] = Time.time; + Debug.Log("Downloaded atlas texture " + index); + foreach (var component in vrcBoardComponents) + component._OnImageLoaded(index); + } + + public override void OnImageLoadError(IVRCImageDownload result) + { + base.OnImageLoadError(result); + Debug.LogWarning(result.Url.Get() + " : " + result.Error.ToString()); + } + private int GetAtlasIndexFromUrl(string url) + { + for (int i = 0; i < atlasUrls.Length; i++) + { + if (atlasUrls[i].Get() == url) return i; + } + + return -1; + } + [PublicAPI] public VRCUrl GetAtlasUrlFromIndex(int index) + { + if (index < 0 || index >= atlasUrls.Length || atlasUrls[index] == null) + { + return null; + } + + return atlasUrls[index]; + } + + #region Queue Functions + + private void AddImageToQueue(string imageId) + { + string[] newQueue = new string[imageIdDownloadQueue.Length + 1]; + for (int i = 0; i < imageIdDownloadQueue.Length; i++) + { + newQueue[i] = imageIdDownloadQueue[i]; + } + + newQueue[imageIdDownloadQueue.Length] = imageId; + imageIdDownloadQueue = newQueue; + _RequestAtlasInfoUpdate(); + } + + private bool HasImageInQueue(string imageId) + { + for (int i = 0; i < imageIdDownloadQueue.Length; i++) + { + if (imageIdDownloadQueue[i] == imageId) + { + return true; + } + } + + return false; + } + + private string GetNextImageInQueue() + { + if (imageIdDownloadQueue.Length == 0) return null; + string imageId = imageIdDownloadQueue[0]; + string[] newQueue = new string[imageIdDownloadQueue.Length - 1]; + for (int i = 1; i < imageIdDownloadQueue.Length; i++) + { + newQueue[i - 1] = imageIdDownloadQueue[i]; + } + + imageIdDownloadQueue = newQueue; + return imageId; + } + + #endregion + } +} +#if UNITY_EDITOR && !UDONSHARP_COMPILER +namespace VRCBoard +{ + [CustomEditor(typeof(VRCBoardManager))] + public class VrcBoardManagerEditor : Editor + { + public override void OnInspectorGUI() + { + //base.OnInspectorGUI(); + VRCBoardManager manager = target as VRCBoardManager; + if (manager == null) + { + EditorGUILayout.HelpBox("This script is not attached to a VRCBoardManager object", MessageType.Error); + return; + } + + + + // draw a header + EditorGUILayout.HelpBox("VRCBoard Manager", MessageType.Info); + string domainInput = EditorGUILayout.TextField("Your VRCBoard Domain", manager.vrcBoardDomain); + bool changed = domainInput != manager.vrcBoardDomain; + if (changed) + { + domainInput = domainInput.Trim(); + domainInput = domainInput.Replace("http://", ""); + domainInput = domainInput.Replace("https://", ""); + domainInput = domainInput.Replace("/", ""); + manager.vrcBoardDomain = domainInput; + + string baseUrl = manager.VrcBoardBaseUrl; + // update the urls + const int urlCount = 100; + manager.atlasUrls = new VRCUrl[urlCount]; + for (int i = 0; i < urlCount; i++) + { + manager.atlasUrls[i] = new VRCUrl(baseUrl + "atlas/" + i); + } + + const string apiPath = "api/data/v1/"; + + manager.atlasInfoUrl = new VRCUrl(baseUrl + apiPath + "atlas"); + manager.supporterInfoUrl = new VRCUrl(baseUrl + apiPath + "supporters"); + EditorUtility.SetDirty(manager); + } + + + float selectedInterval = EditorGUILayout.FloatField("Periodic Update Interval", manager.periodicUpdateInterval); + manager.periodicUpdateInterval = Mathf.Clamp(selectedInterval, 5f, 600f); + EditorGUILayout.Space(); + + SerializedProperty vrcBoardComponents = serializedObject.FindProperty("vrcBoardComponents"); + EditorGUILayout.PropertyField(vrcBoardComponents); + + if (GUILayout.Button("Link all VRCBoard components")) + { + VRCBoardBaseComponent[] components = FindObjectsOfType(); + manager.vrcBoardComponents = components; + // mark the object as dirty + EditorUtility.SetDirty(manager); + } + + + serializedObject.ApplyModifiedProperties(); + + //DrawDefaultInspector(); + + + + } + } +} + +#endif diff --git a/VRCBoardManager.cs.meta b/VRCBoardManager.cs.meta new file mode 100644 index 0000000..626a82f --- /dev/null +++ b/VRCBoardManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a15201eb91eaa134bb21f3335054e187 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: