Browse Source

rebuilt project using vrc3 not tested yet

vrchat
Ixandria 3 years ago
parent
commit
a3f2fad49c
100 changed files with 8478 additions and 51 deletions
  1. 29
    3
      Assets/Interior Asset/Source/Table/Table.fbx.meta
  2. 0
    11
      Assets/MultiXR/MultiXRMasterControl.cs.meta
  3. 0
    11
      Assets/MultiXR/MultiXRSpawnPoint.cs.meta
  4. BIN
      Assets/New Terrain.asset
  5. 0
    8
      Assets/Plugins.meta
  6. 0
    9
      Assets/Plugins/VRCSDK.meta
  7. 0
    9
      Assets/Plugins/VRCSDK/x86_64.meta
  8. 8
    0
      Assets/SerializedUdonPrograms.meta
  9. 17
    0
      Assets/SerializedUdonPrograms/18a8a73823b22934e929c67357a4e2d7.asset
  10. 8
    0
      Assets/SerializedUdonPrograms/18a8a73823b22934e929c67357a4e2d7.asset.meta
  11. 17
    0
      Assets/SerializedUdonPrograms/6657daa4973ee1249aae293810e8bccd.asset
  12. 8
    0
      Assets/SerializedUdonPrograms/6657daa4973ee1249aae293810e8bccd.asset.meta
  13. 17
    0
      Assets/SerializedUdonPrograms/980a7697571ae1540827c8b930f79790.asset
  14. 8
    0
      Assets/SerializedUdonPrograms/980a7697571ae1540827c8b930f79790.asset.meta
  15. 17
    0
      Assets/SerializedUdonPrograms/a7250c474046ad245ac64456f76800ca.asset
  16. 8
    0
      Assets/SerializedUdonPrograms/a7250c474046ad245ac64456f76800ca.asset.meta
  17. 17
    0
      Assets/SerializedUdonPrograms/acd8738ca64f5a9448dfb040d1f2e4d5.asset
  18. 8
    0
      Assets/SerializedUdonPrograms/acd8738ca64f5a9448dfb040d1f2e4d5.asset.meta
  19. 17
    0
      Assets/SerializedUdonPrograms/c8df303ceb45ae84f85a11591f741734.asset
  20. 8
    0
      Assets/SerializedUdonPrograms/c8df303ceb45ae84f85a11591f741734.asset.meta
  21. 17
    0
      Assets/SerializedUdonPrograms/d5d0346a3148a584da4572e44316e658.asset
  22. 8
    0
      Assets/SerializedUdonPrograms/d5d0346a3148a584da4572e44316e658.asset.meta
  23. 8
    0
      Assets/Udon.meta
  24. 8
    0
      Assets/Udon/Editor.meta
  25. 8
    0
      Assets/Udon/Editor/External.meta
  26. BIN
      Assets/Udon/Editor/External/VRC.Udon.Compiler.dll
  27. 102
    0
      Assets/Udon/Editor/External/VRC.Udon.Compiler.dll.meta
  28. 7
    0
      Assets/Udon/Editor/External/VRC.Udon.Compiler.pdb.meta
  29. BIN
      Assets/Udon/Editor/External/VRC.Udon.EditorBindings.dll
  30. 46
    0
      Assets/Udon/Editor/External/VRC.Udon.EditorBindings.dll.meta
  31. 7
    0
      Assets/Udon/Editor/External/VRC.Udon.EditorBindings.pdb.meta
  32. BIN
      Assets/Udon/Editor/External/VRC.Udon.Graph.dll
  33. 46
    0
      Assets/Udon/Editor/External/VRC.Udon.Graph.dll.meta
  34. 7
    0
      Assets/Udon/Editor/External/VRC.Udon.Graph.pdb.meta
  35. BIN
      Assets/Udon/Editor/External/VRC.Udon.UAssembly.dll
  36. 46
    0
      Assets/Udon/Editor/External/VRC.Udon.UAssembly.dll.meta
  37. 7
    0
      Assets/Udon/Editor/External/VRC.Udon.UAssembly.pdb.meta
  38. 8
    0
      Assets/Udon/Editor/ProgramSources.meta
  39. 8
    0
      Assets/Udon/Editor/ProgramSources/Attributes.meta
  40. 18
    0
      Assets/Udon/Editor/ProgramSources/Attributes/UdonProgramSourceNewMenuAttribute.cs
  41. 11
    0
      Assets/Udon/Editor/ProgramSources/Attributes/UdonProgramSourceNewMenuAttribute.cs.meta
  42. 57
    0
      Assets/Udon/Editor/ProgramSources/SerializedUdonProgramAssetEditor.cs
  43. 11
    0
      Assets/Udon/Editor/ProgramSources/SerializedUdonProgramAssetEditor.cs.meta
  44. 8
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram.meta
  45. 90
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAsset.cs
  46. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAsset.cs.meta
  47. 9
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetEditor.cs
  48. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetEditor.cs.meta
  49. 27
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetImporter.cs
  50. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetImporter.cs.meta
  51. 8
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph.meta
  52. 35
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/SearchComparer.cs
  53. 3
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/SearchComparer.cs.meta
  54. 483
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonEdgeGUI.cs
  55. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonEdgeGUI.cs.meta
  56. 693
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraph.cs
  57. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraph.cs.meta
  58. 224
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphExtensions.cs
  59. 3
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphExtensions.cs.meta
  60. 2498
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphGUI.cs
  61. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphGUI.cs.meta
  62. 194
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAsset.cs
  63. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAsset.cs.meta
  64. 9
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAssetEditor.cs
  65. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAssetEditor.cs.meta
  66. 253
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphWindow.cs
  67. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphWindow.cs.meta
  68. 169
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNode.cs
  69. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNode.cs.meta
  70. 817
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNodeSearchMenu.cs
  71. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNodeSearchMenu.cs.meta
  72. 19
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonSubGraphAsset.cs
  73. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonGraph/UdonSubGraphAsset.cs.meta
  74. 8
    0
      Assets/Udon/Editor/ProgramSources/UdonProgram.meta
  75. 1173
    0
      Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAsset.cs
  76. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAsset.cs.meta
  77. 19
    0
      Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAssetEditor.cs
  78. 11
    0
      Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAssetEditor.cs.meta
  79. 8
    0
      Assets/Udon/Editor/Resources.meta
  80. BIN
      Assets/Udon/Editor/Resources/UdonFlowSlot.png
  81. 96
    0
      Assets/Udon/Editor/Resources/UdonFlowSlot.png.meta
  82. BIN
      Assets/Udon/Editor/Resources/UdonFlowSlotFilled.png
  83. 96
    0
      Assets/Udon/Editor/Resources/UdonFlowSlotFilled.png.meta
  84. BIN
      Assets/Udon/Editor/Resources/UdonFlowSlotFilledLight.png
  85. 96
    0
      Assets/Udon/Editor/Resources/UdonFlowSlotFilledLight.png.meta
  86. BIN
      Assets/Udon/Editor/Resources/UdonFlowSlotLight.png
  87. 96
    0
      Assets/Udon/Editor/Resources/UdonFlowSlotLight.png.meta
  88. BIN
      Assets/Udon/Editor/Resources/UdonLogo.png
  89. 76
    0
      Assets/Udon/Editor/Resources/UdonLogo.png.meta
  90. BIN
      Assets/Udon/Editor/Resources/UdonLogoAlpha.png
  91. 121
    0
      Assets/Udon/Editor/Resources/UdonLogoAlpha.png.meta
  92. BIN
      Assets/Udon/Editor/Resources/UdonLogoAlphaWhite.png
  93. 88
    0
      Assets/Udon/Editor/Resources/UdonLogoAlphaWhite.png.meta
  94. BIN
      Assets/Udon/Editor/Resources/UdonNodeAccent.png
  95. 96
    0
      Assets/Udon/Editor/Resources/UdonNodeAccent.png.meta
  96. BIN
      Assets/Udon/Editor/Resources/UdonNodeActiveBackground.png
  97. 96
    0
      Assets/Udon/Editor/Resources/UdonNodeActiveBackground.png.meta
  98. BIN
      Assets/Udon/Editor/Resources/UdonNodeActiveBackgroundLight.png
  99. 96
    0
      Assets/Udon/Editor/Resources/UdonNodeActiveBackgroundLight.png.meta
  100. 0
    0
      Assets/Udon/Editor/Resources/UdonNodeBackground.png

+ 29
- 3
Assets/Interior Asset/Source/Table/Table.fbx.meta View File

@@ -1,35 +1,46 @@
fileFormatVersion: 2
guid: e274dd71b041d6e408c83336cc82256b
timeCreated: 1490201715
licenseType: Store
ModelImporter:
serializedVersion: 19
serializedVersion: 23
fileIDToRecycleName:
100000: //RootNode
400000: //RootNode
2300000: //RootNode
3300000: //RootNode
4300000: "\u041A\u0443\u0431.003"
2186277476908879412: ImportLogs
externalObjects:
- first:
type: UnityEngine:Material
assembly: UnityEngine.CoreModule
name: No Name
second: {fileID: 2100000, guid: b3faac127ca512e418f5512a49b9e0f1, type: 2}
materials:
importMaterials: 1
materialName: 0
materialSearch: 1
materialLocation: 0
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 1
meshes:
@@ -37,25 +48,38 @@ ModelImporter:
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
importVisibility: 0
importBlendShapes: 1
importCameras: 0
importLights: 0
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
keepQuads: 0
weldVertices: 1
preserveHierarchy: 0
indexFormat: 1
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
previousCalculatedGlobalScale: 1
hasPreviousCalculatedGlobalScale: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 0
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 1
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
importAnimation: 1
copyAvatar: 0
humanDescription:
serializedVersion: 2
human: []
skeleton: []
armTwist: 0.5
@@ -67,6 +91,8 @@ ModelImporter:
feetSpacing: 0
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 0
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 0
humanoidOversampling: 1

+ 0
- 11
Assets/MultiXR/MultiXRMasterControl.cs.meta View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f1c08f05ea962fc428f6ce7e953cb1c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 11
Assets/MultiXR/MultiXRSpawnPoint.cs.meta View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 019f01580ed7a3346ac2d164ecbd612e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/New Terrain.asset View File


+ 0
- 8
Assets/Plugins.meta View File

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

+ 0
- 9
Assets/Plugins/VRCSDK.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 9ceea87507dde1e4e9f4d2f9b3218898
folderAsset: yes
timeCreated: 1521506758
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 9
Assets/Plugins/VRCSDK/x86_64.meta View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: c3215fde7fc71504fb3b192b10dbf263
folderAsset: yes
timeCreated: 1521506802
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/SerializedUdonPrograms.meta View File

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

+ 17
- 0
Assets/SerializedUdonPrograms/18a8a73823b22934e929c67357a4e2d7.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/18a8a73823b22934e929c67357a4e2d7.asset.meta View File

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

+ 17
- 0
Assets/SerializedUdonPrograms/6657daa4973ee1249aae293810e8bccd.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/6657daa4973ee1249aae293810e8bccd.asset.meta View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6a4d431d0263ec14e809f337be489069
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

+ 17
- 0
Assets/SerializedUdonPrograms/980a7697571ae1540827c8b930f79790.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/980a7697571ae1540827c8b930f79790.asset.meta View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 53b01afe807b1db44932e99813167910
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

+ 17
- 0
Assets/SerializedUdonPrograms/a7250c474046ad245ac64456f76800ca.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/a7250c474046ad245ac64456f76800ca.asset.meta View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49962594cb127494dbaf43127eb2bfc7
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

+ 17
- 0
Assets/SerializedUdonPrograms/acd8738ca64f5a9448dfb040d1f2e4d5.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/acd8738ca64f5a9448dfb040d1f2e4d5.asset.meta View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 71095558784d7d34a9a1e2d0b8d037f8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

+ 17
- 0
Assets/SerializedUdonPrograms/c8df303ceb45ae84f85a11591f741734.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/c8df303ceb45ae84f85a11591f741734.asset.meta View File

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

+ 17
- 0
Assets/SerializedUdonPrograms/d5d0346a3148a584da4572e44316e658.asset
File diff suppressed because it is too large
View File


+ 8
- 0
Assets/SerializedUdonPrograms/d5d0346a3148a584da4572e44316e658.asset.meta View File

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

+ 8
- 0
Assets/Udon.meta View File

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

+ 8
- 0
Assets/Udon/Editor.meta View File

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

+ 8
- 0
Assets/Udon/Editor/External.meta View File

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

BIN
Assets/Udon/Editor/External/VRC.Udon.Compiler.dll View File


+ 102
- 0
Assets/Udon/Editor/External/VRC.Udon.Compiler.dll.meta View File

@@ -0,0 +1,102 @@
fileFormatVersion: 2
guid: 8b6535096cfa29340897276abbdd015f
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

+ 7
- 0
Assets/Udon/Editor/External/VRC.Udon.Compiler.pdb.meta View File

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

BIN
Assets/Udon/Editor/External/VRC.Udon.EditorBindings.dll View File


+ 46
- 0
Assets/Udon/Editor/External/VRC.Udon.EditorBindings.dll.meta View File

@@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 585dd63e377866248b16bdba915820ed
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

+ 7
- 0
Assets/Udon/Editor/External/VRC.Udon.EditorBindings.pdb.meta View File

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

BIN
Assets/Udon/Editor/External/VRC.Udon.Graph.dll View File


+ 46
- 0
Assets/Udon/Editor/External/VRC.Udon.Graph.dll.meta View File

@@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: b335798a4f28bec40ba9b3d4a15acee7
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

+ 7
- 0
Assets/Udon/Editor/External/VRC.Udon.Graph.pdb.meta View File

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

BIN
Assets/Udon/Editor/External/VRC.Udon.UAssembly.dll View File


+ 46
- 0
Assets/Udon/Editor/External/VRC.Udon.UAssembly.dll.meta View File

@@ -0,0 +1,46 @@
fileFormatVersion: 2
guid: 21dcba1a47cc8c84381629950b692129
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

+ 7
- 0
Assets/Udon/Editor/External/VRC.Udon.UAssembly.pdb.meta View File

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

+ 8
- 0
Assets/Udon/Editor/ProgramSources.meta View File

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

+ 8
- 0
Assets/Udon/Editor/ProgramSources/Attributes.meta View File

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

+ 18
- 0
Assets/Udon/Editor/ProgramSources/Attributes/UdonProgramSourceNewMenuAttribute.cs View File

@@ -0,0 +1,18 @@
using System;

namespace VRC.Udon.Editor.ProgramSources.Attributes
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class UdonProgramSourceNewMenuAttribute : Attribute
{
public Type Type { get; }
public string DisplayName { get; }

public UdonProgramSourceNewMenuAttribute(Type type, string displayName)
{
Type = type;
DisplayName = displayName;
}
}
}


+ 11
- 0
Assets/Udon/Editor/ProgramSources/Attributes/UdonProgramSourceNewMenuAttribute.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0e5ced9511d591140b191bbd9e948e61
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 57
- 0
Assets/Udon/Editor/ProgramSources/SerializedUdonProgramAssetEditor.cs View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEditor;
using VRC.Udon.Common.Interfaces;
using VRC.Udon.ProgramSources;
using VRC.Udon.Serialization.OdinSerializer;

namespace VRC.Udon.Editor.ProgramSources
{
[CustomEditor(typeof(SerializedUdonProgramAsset))]
public class SerializedUdonProgramAssetEditor : UnityEditor.Editor
{
private SerializedProperty _serializedProgramBytesStringSerializedProperty;
private SerializedProperty _serializationDataFormatSerializedProperty;

private void OnEnable()
{
_serializedProgramBytesStringSerializedProperty = serializedObject.FindProperty("serializedProgramBytesString");
_serializationDataFormatSerializedProperty = serializedObject.FindProperty("serializationDataFormat");
}

public override void OnInspectorGUI()
{
DrawSerializationDebug();
}

[Conditional("UDON_DEBUG")]
private void DrawSerializationDebug()
{
EditorGUILayout.LabelField($"DataFormat: {(DataFormat)_serializationDataFormatSerializedProperty.enumValueIndex}");
if(string.IsNullOrEmpty(_serializedProgramBytesStringSerializedProperty.stringValue))
{
return;
}

if(_serializationDataFormatSerializedProperty.enumValueIndex == (int)DataFormat.JSON)
{
using(new EditorGUI.DisabledScope(true))
{
EditorGUILayout.TextArea(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(_serializedProgramBytesStringSerializedProperty.stringValue)));
}
}
else
{
using(new EditorGUI.DisabledScope(true))
{
SerializedUdonProgramAsset serializedUdonProgramAsset = (SerializedUdonProgramAsset)target;
IUdonProgram udonProgram = serializedUdonProgramAsset.RetrieveProgram();
byte[] serializedBytes = SerializationUtility.SerializeValue(udonProgram, DataFormat.JSON, out List<UnityEngine.Object> _);
EditorGUILayout.TextArea(System.Text.Encoding.UTF8.GetString(serializedBytes));
}
}
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/SerializedUdonProgramAssetEditor.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1b5b45f24b268b42826fc5c5497dc15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram.meta View File

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

+ 90
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAsset.cs View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using VRC.Udon.Editor;
using VRC.Udon.Editor.ProgramSources;
using VRC.Udon.Editor.ProgramSources.Attributes;

[assembly: UdonProgramSourceNewMenu(typeof(UdonAssemblyProgramAsset), "Udon Assembly Program Asset")]

namespace VRC.Udon.Editor.ProgramSources
{
[CreateAssetMenu(menuName = "VRChat/Udon/Udon Assembly Program Asset", fileName = "New Udon Assembly Program Asset")]
public class UdonAssemblyProgramAsset : UdonProgramAsset
{
[SerializeField]
protected string udonAssembly = "";

[SerializeField]
private string assemblyError = null;

protected override void DrawProgramSourceGUI(UdonBehaviour udonBehaviour, ref bool dirty)
{
DrawAssemblyTextArea(!Application.isPlaying, ref dirty);
DrawAssemblyErrorTextArea();

base.DrawProgramSourceGUI(udonBehaviour, ref dirty);
}

protected override void RefreshProgramImpl()
{
AssembleProgram();
}

[PublicAPI]
protected virtual void DrawAssemblyTextArea(bool allowEditing, ref bool dirty)
{
EditorGUILayout.LabelField("Assembly Code", EditorStyles.boldLabel);
if(GUILayout.Button("Copy Assembly To Clipboard"))
{
EditorGUIUtility.systemCopyBuffer = udonAssembly;
}

EditorGUI.BeginChangeCheck();
using(new EditorGUI.DisabledScope(!allowEditing))
{
string newAssembly = EditorGUILayout.TextArea(udonAssembly);
if(EditorGUI.EndChangeCheck())
{
dirty = true;
Undo.RecordObject(this, "Edit Assembly Program Code");
udonAssembly = newAssembly;
UdonEditorManager.Instance.QueueProgramSourceRefresh(this);
}
}
}

[PublicAPI]
protected void DrawAssemblyErrorTextArea()
{
if(string.IsNullOrEmpty(assemblyError))
{
return;
}

EditorGUILayout.LabelField("Assembly Error", EditorStyles.boldLabel);
using(new EditorGUI.DisabledScope(true))
{
EditorGUILayout.TextArea(assemblyError);
}
}

[PublicAPI]
protected void AssembleProgram()
{
try
{
program = UdonEditorManager.Instance.Assemble(udonAssembly);
assemblyError = null;
}
catch(Exception e)
{
program = null;
assemblyError = e.Message;
Debug.LogException(e);
}
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAsset.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22203902d63dec94194fefc3e155c43b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 9
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetEditor.cs View File

@@ -0,0 +1,9 @@
using UnityEditor;

namespace VRC.Udon.Editor.ProgramSources
{
[CustomEditor(typeof(UdonAssemblyProgramAsset))]
public class UdonAssemblyProgramAssetEditor : UdonProgramAssetEditor
{
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetEditor.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3df823f3ab561fc43bcb81286e14b91d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 27
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetImporter.cs View File

@@ -0,0 +1,27 @@
using System.IO;
using JetBrains.Annotations;
using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
using UnityEngine;

namespace VRC.Udon.Editor.ProgramSources
{
[ScriptedImporter(1, "uasm")]
[UsedImplicitly]
public class UdonAssemblyProgramAssetImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
UdonAssemblyProgramAsset udonAssemblyProgramAsset = ScriptableObject.CreateInstance<UdonAssemblyProgramAsset>();
SerializedObject serializedUdonAssemblyProgramAsset = new SerializedObject(udonAssemblyProgramAsset);
SerializedProperty udonAssemblyProperty = serializedUdonAssemblyProgramAsset.FindProperty("udonAssembly");
udonAssemblyProperty.stringValue = File.ReadAllText(ctx.assetPath);
serializedUdonAssemblyProgramAsset.ApplyModifiedProperties();

udonAssemblyProgramAsset.RefreshProgram();

ctx.AddObjectToAsset("Imported Udon Assembly Program", udonAssemblyProgramAsset);
ctx.SetMainObject(udonAssemblyProgramAsset);
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAssetImporter.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c0638314c289c24193b47d1c53c9fca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph.meta View File

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

+ 35
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/SearchComparer.cs View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace VRC.Udon.Editor.ProgramSources
{
internal class SearchComparer : IComparer<string>
{
public SearchComparer(string searchString)
{
_searchString = searchString;
}
private readonly string _searchString;
public int Compare(string x, string y)
{
if (x == null || y == null)
{
return 0;
}
//-1 is they're out of order, 0 is order doesn't matter, 1 is they're in order

x = x.ReplaceFirst("const ", "");
y = y.ReplaceFirst("const ", "");
int xIndex = x.IndexOf(_searchString, StringComparison.InvariantCultureIgnoreCase);
int yIndex = y.IndexOf(_searchString, StringComparison.InvariantCultureIgnoreCase);
int compareIndex = xIndex.CompareTo(yIndex);
if (compareIndex != 0) return compareIndex;
string xDiff = x.ReplaceFirst(_searchString, "");
string yDiff = y.ReplaceFirst(_searchString, "");
return string.Compare(xDiff, yDiff, StringComparison.InvariantCultureIgnoreCase);
}
}
}

+ 3
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/SearchComparer.cs.meta View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d12298313646456a8070307238fedf48
timeCreated: 1575758808

+ 483
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonEdgeGUI.cs View File

@@ -0,0 +1,483 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using UnityEditor.Graphs;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InvertIf
// ReSharper disable EnforceIfStatementBraces
// ReSharper disable UnusedMember.Local
// ReSharper disable Unity.InefficientMultiplicationOrder
// ReSharper disable PossibleNullReferenceException
// ReSharper disable RedundantExplicitArrayCreation
// ReSharper disable RedundantExplicitParamsArrayCreation
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable ConvertToConstant.Global
// ReSharper disable RedundantNameQualifier
// ReSharper disable ArrangeThisQualifier


namespace VRC.Udon.Editor.ProgramSources
{
public class UdonEdgeGUI : IEdgeGUI
{
public EdgeGUI.EdgeStyle edgeStyle = EdgeGUI.EdgeStyle.Curvy;

private static Slot _sDragSourceSlot;
private static Slot _sDropTarget;

public List<int> edgeSelection { get; set; }

public GraphGUI host { get; set; }

private Edge DontDrawEdge { get; set; }

private Edge MoveEdge { get; set; }

public UdonEdgeGUI()
{
edgeSelection = new List<int>();
}

public void BeginSlotDragging(Slot slot, bool allowStartDrag, bool allowEndDrag)
{
if(allowStartDrag)
{
_sDragSourceSlot = slot;
Event.current.Use();
}

if(allowEndDrag && slot.edges.Count > 0)
{
MoveEdge = slot.edges[slot.edges.Count - 1];
_sDragSourceSlot = MoveEdge.fromSlot;
_sDropTarget = slot;
Event.current.Use();
}
}

public void DoDraggedEdge()
{
if(_sDragSourceSlot != null)
{
EventType typeForControl = Event.current.GetTypeForControl(0);
if(typeForControl != EventType.Repaint)
{
if(typeForControl == EventType.MouseDrag)
{
_sDropTarget = null;
DontDrawEdge = null;
Event.current.Use();
}
}
else
{
Assembly unityEngineAssembly = Assembly.GetAssembly(typeof(UnityEngine.GUI));
Type guiClipType = unityEngineAssembly.GetType("UnityEngine.GUIClip", true);

FieldInfo propInfo = typeof(Slot).GetField(
"m_Position",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

if(propInfo == null) Debug.LogError("PropInfo m_Position is null!");
Rect position = (Rect)propInfo.GetValue(_sDragSourceSlot);

Vector2 end = Event.current.mousePosition;

if(_sDropTarget != null)
{
Rect position2 = (Rect)propInfo.GetValue(_sDropTarget);

object[] endArgs = {new Vector2(position2.x, position2.y + 9f)};
ParameterModifier endP = new ParameterModifier(1);
endP[0] = true;
ParameterModifier[] endMods = {endP};
MethodInfo endClipRect = guiClipType.GetMethod(
"Clip",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy,
Type.DefaultBinder,
new Type[] {typeof(Vector2)},
endMods);

end = (Vector2)endClipRect.Invoke(null, endArgs);
}

object[] startArgs = {new Vector2(position.xMax, position.y + 9f)};
ParameterModifier startP = new ParameterModifier(1);
startP[0] = true;
ParameterModifier[] startMods = {startP};
MethodInfo startClipRect = guiClipType.GetMethod(
"Clip",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy,
Type.DefaultBinder,
new Type[] {typeof(Vector2)},
startMods);

Vector2 start = (Vector2)startClipRect.Invoke(null, startArgs);

Color edgeColor = Color.white;
if (_sDragSourceSlot.dataType != null)
edgeColor = UdonGraphGUI.MapTypeToColor(_sDragSourceSlot.dataType);

DrawEdge(start, end, (Texture2D)Styles.selectedConnectionTexture.image, edgeColor, edgeStyle);
}
}
}

public void DoEdges()
{
int num = 0;
int num2 = 0;
if(Event.current.type == EventType.Repaint)
{
foreach(Edge current in host.graph.edges)
{
if(current == DontDrawEdge || current == MoveEdge) continue;

Texture2D tex = (Texture2D)Styles.connectionTexture.image;
if(num < edgeSelection.Count && edgeSelection[num] == num2)
{
num++;
tex = (Texture2D)Styles.selectedConnectionTexture.image;
}

// TODO: CLEAN-UP
Color color;
if(!current.toSlot.isFlowSlot && current.toSlot.dataType != null &&
current.toSlot.dataType.IsSubclassOf(typeof(UnityEngine.Object)))
{
color = EdgeGUI.kObjectTypeEdgeColor;
}
Color niceGrey = new Color(.85f, .85f, .85f);
color = current.fromSlot.dataType != null ? UdonGraphGUI.MapTypeToColor(current.fromSlot.dataType) : niceGrey;
Color endColor = new Color(.85f, .85f, .85f);
if (current.toSlot.dataType != null)
{
endColor = UdonGraphGUI.MapTypeToColor(current.toSlot.dataType);
}

DrawEdge(current, tex, color != endColor ? Color.Lerp(color, endColor, .5f) : color, edgeStyle);
num2++;
}
}

if(_sDragSourceSlot == null) return;
if(Event.current.type != EventType.MouseUp) return;

if(MoveEdge != null)
{
host.graph.RemoveEdge(MoveEdge);
MoveEdge = null;
}

if(_sDropTarget != null) return;

EndDragging();
Event.current.Use();
}

private static void DrawEdge(Edge e, Texture2D tex, Color color, EdgeGUI.EdgeStyle style)
{
Vector2 start;
Vector2 end;
GetEdgeEndPoints(e, out start, out end);
DrawEdge(start, end, tex, color, style);
}

private static void DrawEdge(Edge e, Texture2D tex, Color color, Color endColor, EdgeGUI.EdgeStyle style)
{
Vector2 start;
Vector2 end;
GetEdgeEndPoints(e, out start, out end);
DrawEdge(start, end, tex, color, endColor, style);
}

private static void DrawEdge(Vector2 start, Vector2 end, Texture2D tex, Color color, EdgeGUI.EdgeStyle style)
{
if(style != EdgeGUI.EdgeStyle.Angular)
{
if(style != EdgeGUI.EdgeStyle.Curvy) return;

Vector3[] array;
Vector3[] array2;
GetCurvyConnectorValues(start, end, out array, out array2);
Handles.DrawBezier(array[0], array[1], array2[0], array2[1], color, tex, 8f);
}
else
{
Vector3[] array;
Vector3[] array2;
GetAngularConnectorValues(start, end, out array, out array2);
DrawRoundedPolyLine(array, array2, tex, color);
}
}

private static void DrawEdge(Vector2 start, Vector2 end, Texture2D tex, Color color, Color endColor,
EdgeGUI.EdgeStyle style)
{
if(style != EdgeGUI.EdgeStyle.Angular)
{
if(style != EdgeGUI.EdgeStyle.Curvy) return;

Vector3[] array;
Vector3[] array2;

Vector3[] array3;
Vector3[] array4;

Vector3[] array5;
Vector3[] array6;
GetCurvyConnectorValues(start, end, out array5, out array6);
GetCurvyConnectorValues(start, (start + end) / 2f, out array, out array2);
GetCurvyConnectorValues((start + end) / 2f, end, out array3, out array4);

Handles.DrawBezier(array[0], array[1], array6[0], array2[1], color, tex, 8f);
Handles.DrawBezier(array3[0], array3[1], array4[0], array6[1], endColor, tex, 8f);
}
else
{
Vector3[] array;
Vector3[] array2;
GetAngularConnectorValues(start, end, out array, out array2);
DrawRoundedPolyLine(array, array2, tex, color);
}
}

private static void GetCurvyConnectorValues(Vector2 start, Vector2 end, out Vector3[] points,
out Vector3[] tangents)
{
points = new Vector3[]
{
start,
end
};

tangents = new Vector3[2];

float num = 0.5f;
float num2 = 1f - num;
float num3 = 0f;
if(start.x > end.x)
{
num = (num2 = -0.25f);
float f = (start.x - end.x) / (start.y - end.y);
if(Mathf.Abs(f) > 0.5f)
{
float num4 = (Mathf.Abs(f) - 0.5f) / 8f;
num4 = Mathf.Sqrt(num4);
num3 = Mathf.Min(num4 * 80f, 80f);
if(start.y > end.y)
{
num3 = -num3;
}
}
}

float d = Mathf.Clamp01(((start - end).magnitude - 10f) / 50f);
tangents[0] = start + new Vector2((end.x - start.x) * num + 30f, num3) * d;
tangents[1] = end + new Vector2((end.x - start.x) * -num2 - 30f, -num3) * d;
}

private static void GetAngularConnectorValues(Vector2 start, Vector2 end, out Vector3[] points,
out Vector3[] tangents)
{
Vector2 a = start - end;
Vector2 vector = a / 2f + end;
Vector2 vector2 = new Vector2(Mathf.Sign(a.x), Mathf.Sign(a.y));
Vector2 vector3 = new Vector2(Mathf.Min(Mathf.Abs(a.x / 2f), 5f), Mathf.Min(Mathf.Abs(a.y / 2f), 5f));
points = new Vector3[]
{
start,
new Vector3(vector.x + vector3.x * vector2.x, start.y),
new Vector3(vector.x, start.y - vector3.y * vector2.y),
new Vector3(vector.x, end.y + vector3.y * vector2.y),
new Vector3(vector.x - vector3.x * vector2.x, end.y),
end
};

tangents = new Vector3[]
{
(points[1] - points[0]).normalized * vector3.x * 0.6f + points[1],
(points[2] - points[3]).normalized * vector3.y * 0.6f + points[2],
(points[3] - points[2]).normalized * vector3.y * 0.6f + points[3],
(points[4] - points[5]).normalized * vector3.x * 0.6f + points[4]
};
}

private static void DrawRoundedPolyLine(Vector3[] points, Vector3[] tangents, Texture2D tex, Color color)
{
Handles.color = color;
for(int i = 0; i < points.Length; i += 2)
{
Handles.DrawAAPolyLine(
tex,
3f,
new Vector3[]
{
points[i],
points[i + 1]
});
}

for(int j = 0; j < tangents.Length; j += 2)
{
Handles.DrawBezier(points[j + 1], points[j + 2], tangents[j], tangents[j + 1], color, tex, 3f);
}
}

private static void GetEdgeEndPoints(Edge e, out Vector2 start, out Vector2 end)
{
FieldInfo propInfo = typeof(Slot).GetField(
"m_Position",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

if(propInfo == null) Debug.LogError("PropInfo m_Position is null!");
Rect fromSlotPosition = (Rect)propInfo.GetValue(e.fromSlot);
Rect toSlotPosition = (Rect)propInfo.GetValue(e.toSlot);

Assembly unityEngineAssembly = Assembly.GetAssembly(typeof(UnityEngine.GUI));
Type guiClipType = unityEngineAssembly.GetType("UnityEngine.GUIClip", true);

object[] startArgs = {new Vector2(fromSlotPosition.xMax, fromSlotPosition.y + 9f)};
object[] endArgs = {new Vector2(toSlotPosition.x, toSlotPosition.y + 9f)};

ParameterModifier startP = new ParameterModifier(1);
startP[0] = true;
ParameterModifier[] startMods = {startP};

ParameterModifier endP = new ParameterModifier(1);
endP[0] = true;
ParameterModifier[] endMods = {endP};

MethodInfo startClipRect = guiClipType.GetMethod(
"Clip",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy,
Type.DefaultBinder,
new Type[] {typeof(Vector2)},
startMods);

MethodInfo endClipRect = guiClipType.GetMethod(
"Clip",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy,
Type.DefaultBinder,
new Type[] {typeof(Vector2)},
endMods);

start = (Vector2)startClipRect.Invoke(null, startArgs);
end = (Vector2)endClipRect.Invoke(null, endArgs);
}

public void EndDragging()
{
_sDragSourceSlot = (_sDropTarget = null);
MoveEdge = null;
DontDrawEdge = null;
}

public void EndSlotDragging(Slot slot, bool allowMultiple)
{
if(slot.isInputSlot && slot.isFlowSlot)
allowMultiple = true;

if(_sDropTarget != slot) return;

if(MoveEdge != null)
{
slot.node.graph.RemoveEdge(MoveEdge);
}

while(_sDropTarget.edges.Count > 0)
{
if(allowMultiple)
{
break;
}

slot.node.graph.RemoveEdge(_sDropTarget.edges[0]);
}

try
{
slot.node.graph.Connect(_sDragSourceSlot, slot);
}
finally
{
EndDragging();
slot.node.graph.Dirty();
Event.current.Use();
}

GUIUtility.ExitGUI();
}


public Edge FindClosestEdge()
{
Vector2 mousePosition = Event.current.mousePosition;
float num = float.PositiveInfinity;
Edge result = null;
foreach(Edge current in host.graph.edges)
{
Vector2 start;
Vector2 end;
GetEdgeEndPoints(current, out start, out end);
Vector3[] array;
if(this.edgeStyle == EdgeGUI.EdgeStyle.Angular)
{
Vector3[] array2;
GetAngularConnectorValues(start, end, out array, out array2);
}
else
{
Vector3[] array2;
GetCurvyConnectorValues(start, end, out array, out array2);
}

for(int i = 0; i < array.Length; i += 2)
{
float num2 = HandleUtility.DistancePointLine(mousePosition, array[i], array[i + 1]);
if(!(num2 < num)) continue;

num = num2;
result = current;
}
}

if(num > 10f)
{
result = null;
}

return result;
}

public void SlotDragging(Slot slot, bool allowEndDrag, bool allowMultiple)
{
if(slot.isInputSlot && slot.isFlowSlot)
allowMultiple = true;

if(!allowEndDrag || _sDragSourceSlot == null || _sDragSourceSlot == slot) return;

if(_sDropTarget != slot && slot.node.graph.CanConnect(_sDragSourceSlot, slot) &&
!slot.node.graph.Connected(_sDragSourceSlot, slot))
{
if((slot.node).inputDataEdges.All(e => e != MoveEdge))
{
_sDropTarget = slot;
if(slot.edges.Count > 0 && !allowMultiple)
{
DontDrawEdge = slot.edges[slot.edges.Count - 1];
}
}
}

Event.current.Use();
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonEdgeGUI.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2af90dfd0a2ecde49bd14418e221009c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 693
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraph.cs View File

@@ -0,0 +1,693 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.CSharp;
using UnityEngine;
using UnityEditor;
using UnityEditor.Graphs;
using VRC.Udon.Common;
using VRC.Udon.Common.Interfaces;
using VRC.Udon.Common.Utils;
using VRC.Udon.Compiler;
using VRC.Udon.EditorBindings;
using VRC.Udon.EditorBindings.Interfaces;
using VRC.Udon.Graph;
using VRC.Udon.Graph.Interfaces;
using VRC.Udon.Serialization;
using VRC.Udon.UAssembly.Assembler;

namespace VRC.Udon.Editor.ProgramSources
{
public class UdonGraph : UnityEditor.Graphs.Graph
{
public IUdonGraphDataProvider graphProgramAsset;
public UdonGraphData data;

private readonly string[] _specialFlows =
{
"Block",
"Branch",
"For",
"Foreach",
"While",
};

public bool Reloading { get; set; } = false;

internal static string FriendlyTypeName(Type t)
{
if (t == null)
{
return "null";
}

if (!t.IsPrimitive)
{
if(t == typeof(UnityEngine.Object))
{
return "Unity Object";
}
return t.Name;
}
using (CSharpCodeProvider provider = new CSharpCodeProvider())
{
CodeTypeReference typeRef = new CodeTypeReference(t);
return provider.GetTypeOutput(typeRef);
}
}

public UdonNode CreateNode(UdonNodeData nodeData)
{
UdonNodeDefinition udonNodeDefinition;
try
{
udonNodeDefinition = UdonEditorManager.Instance.GetNodeDefinition(nodeData.fullName);
}
catch
{
Debug.LogError($"Skipping missing node: {nodeData.fullName}");
return null;
}
if (!TrySetupNode(udonNodeDefinition, nodeData.position, out UdonNode node, ref nodeData)) return null;
int connectedFlowCount = nodeData.flowUIDs.Count(f => !string.IsNullOrEmpty(f));
ValidateNodeData();
LayoutSlots(udonNodeDefinition, node, connectedFlowCount);
AddNode(node);
return node;
void ValidateNodeData()
{
bool modifiedData = false;
for (int i = 0; i < nodeData.nodeValues.Length; i++)
{
if (udonNodeDefinition.Inputs.Count <= i)
{
continue;
}

Type expectedType = udonNodeDefinition.Inputs[i].type;

if (nodeData.nodeValues[i] == null)
{
continue;
}

object value = nodeData.nodeValues[i].Deserialize();
if (value == null)
{
continue;
}

if (!expectedType.IsInstanceOfType(value))
{
nodeData.nodeValues[i] = SerializableObjectContainer.Serialize(null, expectedType);
modifiedData = true;
}
}

if (modifiedData)
{
ReSerializeData();
}
}
}
public void CreateNode(UdonNodeDefinition udonNodeDefinition, Vector2? position = null)
{
UdonNodeData nodeData = null;
if (!TrySetupNode(udonNodeDefinition, position, out UdonNode node, ref nodeData)) return;
PopulateDefaultValues();
LayoutSlots(udonNodeDefinition, node, 0);
ReSerializeData();
AddNode(node);
void PopulateDefaultValues()
{
if (udonNodeDefinition.defaultValues == null) return;
nodeData.nodeValues = new SerializableObjectContainer[udonNodeDefinition.defaultValues.Count];
nodeData.nodeUIDs = new string[udonNodeDefinition.defaultValues.Count];
for (int i = 0; i < udonNodeDefinition.defaultValues.Count; i++)
{
object defaultValue = udonNodeDefinition.defaultValues[i];
if (defaultValue != null)
{
nodeData.nodeValues[i] = SerializableObjectContainer.Serialize(defaultValue);
}
}
}
}

private bool TrySetupNode(UdonNodeDefinition udonNodeDefinition, Vector2? position, out UdonNode node,
ref UdonNodeData nodeData)
{
DoPropHack();
if (!TryCreateNodeInstance(out node)) return false;
if (nodeData == null)
{
nodeData = data.AddNode(udonNodeDefinition.fullName);
}
node.uid = nodeData.uid;
return true;
void DoPropHack()
{
//Awful hack to fix regression in unity graph property type conversion
{
FieldInfo prop = typeof(TypeConverter).GetField(
"useCompatibleTypeConversion",
BindingFlags.NonPublic | BindingFlags.Static
);
if (prop != null) prop.SetValue(this, true);
}
}
bool TryCreateNodeInstance(out UdonNode outNode)
{
outNode = CreateInstance<UdonNode>();

outNode.name = udonNodeDefinition.fullName;
outNode.title = PrettyString(udonNodeDefinition.name).FriendlyNameify();
outNode.position = position == null ? new Rect(Vector2.zero, Vector2.zero) : new Rect(position.Value, Vector2.zero);
string nodeName = outNode.name;
if (nodeName.StartsWith("Event_") &&
(nodeName != "Event_Custom" || graphProgramAsset.GetType() == typeof(UdonSubGraphAsset)))
{
if (nodes.Any(n => n.name == nodeName))
{
Debug.LogWarning(
$"Can't create more than one {nodeName} node, try managing your flow with a Block node instead!");
return false;
}
}

if (nodeName.StartsWith("Event_") &&
(nodeName != "Event_Custom" && graphProgramAsset.GetType() == typeof(UdonSubGraphAsset)))
{
Debug.LogWarning($"SubGraphs can't use built-in events, pipe in your event from the parent graph instead!");
return false;
}

if (outNode.title == "Const_VRCUdonCommonInterfacesIUdonEventReceiver")
{
outNode.title = "UdonBehaviour";
}

return true;
}
}


private void LayoutSlots(UdonNodeDefinition udonNodeDefinition, UdonNode node, int connectedFlowCount)
{
//Layout Flow Slots
if (udonNodeDefinition.flow)
{
if (!udonNodeDefinition.fullName.StartsWith("Event_"))
{
node.AddInputSlot("");
}

node.AddOutputSlot("");
if (_specialFlows.Contains(udonNodeDefinition.fullName))
{
node.AddOutputSlot("");
}

if (udonNodeDefinition.fullName == "Block")
{
int connectedFlows = connectedFlowCount;
if (connectedFlows > 1)
{
for (int i = 0; i < connectedFlows - 1; i++)
{
node.AddOutputSlot("");
}
}
}
}

//Layout InOut Slots
for (int index = 0; index < udonNodeDefinition.Inputs.Count; index++)
{
UdonNodeParameter input = udonNodeDefinition.Inputs[index];
string label = "";
if (udonNodeDefinition.Inputs.Count > index && index >= 0)
{
label = udonNodeDefinition.Inputs[index].name;
}

if (label == "IUdonEventReceiver")
{
label = "UdonBehaviour";
}

label = label.FriendlyNameify();

Slot slot = node.AddInputSlot(FriendlyTypeName(input.type),
SlotTypeConverter(input.type, udonNodeDefinition.fullName));
slot.title = label;
}

foreach (UdonNodeParameter output in udonNodeDefinition.Outputs)
{
node.AddOutputSlot(FriendlyTypeName(output.type), SlotTypeConverter(output.type, udonNodeDefinition.fullName));
}
}

private static Type SlotTypeConverter(Type type, string fullName)
{
if(type == null)
{
return typeof(object);
}

if (fullName.Contains("IUdonEventReceiver") && type == typeof(UnityEngine.Object))
{
return typeof(UdonBehaviour);
}

return type;
}

public void DeleteNode(string nodeID)
{
UdonNodeData node = data.FindNode(nodeID);
if (node == null)
{
return;
}
data.RemoveNode(node);
ReSerializeData();
}

public override Edge Connect(Slot fromSlot, Slot toSlot)
{
int index = 0;
int indexOther = 0;
if (fromSlot.isFlowSlot)
{
foreach(Slot outputSlot in fromSlot.node.outputFlowSlots)
{
if(outputSlot == fromSlot)
{
break;
}

index++;
}
}
else
{
foreach(Slot inputSlot in toSlot.node.inputDataSlots)
{
if(inputSlot == toSlot)
{
break;
}

index++;
}
foreach(Slot outputSlot in fromSlot.node.outputDataSlots)
{
if(outputSlot == fromSlot)
{
break;
}

indexOther++;
}
}

UdonNodeData fromNode = data.FindNode(((UdonNode)fromSlot.node).uid);
UdonNodeData toNode = data.FindNode(((UdonNode)toSlot.node).uid);
if(fromSlot.isFlowSlot)
{
fromNode.AddFlowNode(toNode, index);
}
else
{
toNode.AddNode(fromNode, index, indexOther);
}
if (fromNode.fullName == "Block")
{
int connectedFlows = fromNode.flowUIDs.Count(f => !string.IsNullOrEmpty(f));
if (connectedFlows >= fromSlot.node.outputFlowSlots.Count())
{
fromSlot.node.AddOutputSlot("");
}
}

ReSerializeData();
return base.Connect(fromSlot, toSlot);
}

public override void RemoveEdge(Edge e)
{
int index = 0;
if (e.fromSlot.isFlowSlot)
{
foreach(Slot outputSlot in e.fromSlot.node.outputFlowSlots)
{
if(outputSlot == e.fromSlot)
{
break;
}

index++;
}
}
else
{
foreach(Slot inputSlot in e.toSlot.node.inputDataSlots)
{
if(inputSlot == e.toSlot)
{
break;
}

index++;
}
}

UdonNodeData toNode = data.FindNode(((UdonNode)e.toSlot.node).uid);
UdonNodeData fromNode = data.FindNode(((UdonNode)e.fromSlot.node).uid);
if(e.fromSlot.isFlowSlot)
{
fromNode.RemoveFlowNode(index);
}
else
{
toNode.RemoveNode(index);
}

ReSerializeData();

base.RemoveEdge(e);
}

public override bool CanConnect(Slot fromSlot, Slot toSlot)
{
if(fromSlot.node == toSlot.node)
{
return false;
}

if(fromSlot.isFlowSlot && toSlot.isFlowSlot)
{
return FindRecursiveFlow(fromSlot, toSlot);
//return fromSlot.edges.Count <= 0 && toSlot.edges.Count <= 0 && FindRecursiveFlow(fromSlot, toSlot);
}

if(fromSlot.isFlowSlot && !toSlot.isFlowSlot)
{
return false;
}

if(!fromSlot.isFlowSlot && toSlot.isFlowSlot)
{
return false;
}

if (toSlot.dataType.IsAssignableFrom(fromSlot.dataType) ||
fromSlot.dataType.IsAssignableFrom(toSlot.dataType))
{
return true;
}
if (fromSlot.node.name.Contains("__T") || fromSlot.node.name.Contains("__TArray"))
{
return true;
}
return false;
}

private static bool FindRecursiveFlow(Slot fromSlot, Slot toSlot)
{
foreach(Edge edge in toSlot.node.outputFlowEdges)
{
if(edge.toSlot.node == fromSlot.node)
{
return false;
}

if(!FindRecursiveFlow(fromSlot, edge.toSlot))
{
return false;
}
}

return true;
}

public void Reload()
{

if (this == null)
{
DestroyImmediate(this);
return;
}
Reloading = true;
// ReSharper disable once DelegateSubtraction
Undo.undoRedoPerformed -= OnUndoRedo; //Remove old handler if present to prevent duplicates, doesn't cause errors if not present
Undo.undoRedoPerformed += OnUndoRedo;

nodes.Clear();
edges.Clear();

IEnumerable<UdonNodeDefinition> definitions = UdonEditorManager.Instance.GetNodeDefinitions();
if (definitions == null || definitions.Count() < 100)
{
throw new NullReferenceException("Udon NodeDefinitions have failed to load, aborting graph load.");
}
for (int i = data.nodes.Count - 1; i >= 0; i--)
{
UdonNodeData node = data.nodes[i];
UdonNode udonNode = CreateNode(node);
if (udonNode != null) continue;
Debug.Log($"Removing null node '{node.fullName}'");
data.nodes.RemoveAt(i);
}

foreach(Node node in nodes)
{
UdonNode udonNode = (UdonNode)node;
udonNode.PopulateEdges();
}

Reloading = false;
ReSerializeData();
}

private void OnUndoRedo()
{
data = new UdonGraphData(graphProgramAsset.GetGraphData());
Reload();
}

public override void RemoveNode(Node node, bool destroyNode = false)
{
if (node == null)
{
return;
}
base.RemoveNode(node, destroyNode);
}

public void ReSerializeData()
{
if (Reloading)
{
return;
}

SerializedObject serializedGraphProgramAsset;
if (graphProgramAsset.GetType() == typeof(UdonGraphProgramAsset))
{
serializedGraphProgramAsset = new SerializedObject((UdonGraphProgramAsset)graphProgramAsset);
}
else
{
serializedGraphProgramAsset = new SerializedObject((UdonSubGraphAsset)graphProgramAsset);
}
SerializedProperty graphDataProperty = serializedGraphProgramAsset.FindProperty("graphData");
SerializedProperty nodesProperty = graphDataProperty.FindPropertyRelative("nodes");

if(nodesProperty.arraySize > data.nodes.Count)
{
nodesProperty.ClearArray();
}

for(int i = 0; i < data.nodes.Count; i++)
{
if(nodesProperty.arraySize < data.nodes.Count)
{
nodesProperty.InsertArrayElementAtIndex(i);
}

SerializedProperty nodeProperty = nodesProperty.GetArrayElementAtIndex(i);

SerializedProperty fullNameProperty = nodeProperty.FindPropertyRelative("fullName");
fullNameProperty.stringValue = data.nodes[i].fullName;

SerializedProperty uidProperty = nodeProperty.FindPropertyRelative("uid");
uidProperty.stringValue = data.nodes[i].uid;

SerializedProperty positionProperty = nodeProperty.FindPropertyRelative("position");
positionProperty.vector2Value = data.nodes[i].position;

SerializedProperty nodeUIDsProperty = nodeProperty.FindPropertyRelative("nodeUIDs");
while(nodeUIDsProperty.arraySize > data.nodes[i].nodeUIDs.Length)
{
nodeUIDsProperty.DeleteArrayElementAtIndex(nodeUIDsProperty.arraySize - 1);
}

for(int j = 0; j < data.nodes[i].nodeUIDs.Length; j++)
{
if(nodeUIDsProperty.arraySize < data.nodes[i].nodeUIDs.Length)
{
nodeUIDsProperty.InsertArrayElementAtIndex(j);
nodeUIDsProperty.GetArrayElementAtIndex(j).stringValue = "";
}

SerializedProperty nodeUIDProperty = nodeUIDsProperty.GetArrayElementAtIndex(j);
nodeUIDProperty.stringValue = data.nodes[i].nodeUIDs[j];
}

SerializedProperty flowUIDsProperty = nodeProperty.FindPropertyRelative("flowUIDs");
while(flowUIDsProperty.arraySize > data.nodes[i].flowUIDs.Length)
{
flowUIDsProperty.DeleteArrayElementAtIndex(flowUIDsProperty.arraySize - 1);
}

for(int j = 0; j < data.nodes[i].flowUIDs.Length; j++)
{
if(flowUIDsProperty.arraySize < data.nodes[i].flowUIDs.Length)
{
flowUIDsProperty.InsertArrayElementAtIndex(j);
flowUIDsProperty.GetArrayElementAtIndex(j).stringValue = "";
}

SerializedProperty flowUIDProperty = flowUIDsProperty.GetArrayElementAtIndex(j);
flowUIDProperty.stringValue = data.nodes[i].flowUIDs[j];
}

SerializedProperty nodeValuesProperty = nodeProperty.FindPropertyRelative("nodeValues");
while(nodeValuesProperty.arraySize > data.nodes[i].nodeValues.Length)
{
nodeValuesProperty.DeleteArrayElementAtIndex(nodeValuesProperty.arraySize - 1);
}

for(int j = 0; j < data.nodes[i].nodeValues.Length; j++)
{
if(nodeValuesProperty.arraySize < data.nodes[i].nodeValues.Length)
{
nodeValuesProperty.InsertArrayElementAtIndex(j);
nodeValuesProperty.GetArrayElementAtIndex(j).FindPropertyRelative("unityObjectValue").objectReferenceValue = null;
nodeValuesProperty.GetArrayElementAtIndex(j).FindPropertyRelative("stringValue").stringValue = "";
}

SerializedProperty nodeValueProperty = nodeValuesProperty.GetArrayElementAtIndex(j);

if (data.nodes[i].nodeValues[j] == null)
{
continue;
}
object nodeValue = data.nodes[i].nodeValues[j].Deserialize();
if (nodeValue != null)
{
if (nodeValue is UnityEngine.Object value)
{
if (value != null)
{
nodeValueProperty.FindPropertyRelative("unityObjectValue").objectReferenceValue =
data.nodes[i].nodeValues[j].unityObjectValue;
}
}
}
nodeValueProperty.FindPropertyRelative("stringValue").stringValue =
data.nodes[i].nodeValues[j].stringValue;
}
}

serializedGraphProgramAsset.ApplyModifiedProperties();

if (graphProgramAsset is AbstractUdonProgramSource udonProgramSource)
{
UdonEditorManager.Instance.QueueProgramSourceRefresh(udonProgramSource);
}
}

public void UpdateNodePosition(UdonNode node)
{
data.FindNode(node.uid).position = node.position.position;
ReSerializeData();
}

private static string PrettyString(string s)
{
switch(s)
{
case "op_Equality":
s = "==";
break;

case "op_Inequality":
s = "!=";
break;

case "op_Addition":
s = "+";
break;
case "VRCUdonCommonInterfacesIUdonEventReceiver":
s = "UdonBehaviour";
break;
// ReSharper disable once RedundantEmptySwitchSection
default:
break;
}

s = s.Replace("_", " ");
s = ParseByCase(s);
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
return textInfo.ToTitleCase(s);
}

private static string ParseByCase(string strInput)
{
string strOutput = "";
int intCurrentCharPos = 0;
int intLastCharPos = strInput.Length - 1;
for(intCurrentCharPos = 0; intCurrentCharPos <= intLastCharPos; intCurrentCharPos++)
{
char chrCurrentInputChar = strInput[intCurrentCharPos];
char chrPreviousInputChar = chrCurrentInputChar;
if(intCurrentCharPos > 0)
{
chrPreviousInputChar = strInput[intCurrentCharPos - 1];
}

if(char.IsUpper(chrCurrentInputChar) && char.IsLower(chrPreviousInputChar))
{
strOutput += " ";
}

strOutput += chrCurrentInputChar;
}

return strOutput;
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraph.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30dac15540ec41545a204d3558107018
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 224
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphExtensions.cs View File

@@ -0,0 +1,224 @@
using System;
using System.Collections.Generic;
using System.Linq;
using VRC.Udon.Graph;
using VRC.Udon.Graph.Interfaces;

namespace VRC.Udon.Editor.ProgramSources
{
internal static class UdonGraphExtensions
{
private static readonly Dictionary<string, string> FriendlyNameCache;

static UdonGraphExtensions()
{
FriendlyNameCache = new Dictionary<string, string>();
StartsWithCache = new Dictionary<(string s, string prefix), bool>();
}

public static string FriendlyNameify(this string typeString)
{
if (typeString == null)
{
return null;
}
if (FriendlyNameCache.ContainsKey(typeString))
{
return FriendlyNameCache[typeString];
}
string originalString = typeString;
typeString = typeString.Replace("Single", "float");
typeString = typeString.Replace("Int32", "int");
typeString = typeString.Replace("String", "string");
typeString = typeString.Replace("VRCUdonCommonInterfacesIUdonEventReceiver", "UdonBehaviour");
typeString = typeString.Replace("IUdonEventReceiver", "UdonBehaviour");
typeString = typeString.Replace("Const_VRCUdonCommonInterfacesIUdonEventReceiver", "UdonBehaviour");
typeString = typeString.Replace("Array", "[]");
// ReSharper disable once StringLiteralTypo
if (typeString.Replace("ector", "").Contains("ctor")) //Handle "Vector/vector"
{
typeString = typeString.ReplaceLast("ctor", "constructor");
}

if (typeString == "IUdonEventReceiver")
{
typeString = "UdonBehaviour";
}
FriendlyNameCache.Add(originalString, typeString);
return typeString;
}

private static readonly Dictionary<(string s, string prefix), bool> StartsWithCache;
public static bool StartsWithCached(this string s, string prefix)
{
if (StartsWithCache.ContainsKey((s, prefix)))
{
return StartsWithCache[(s, prefix)];
}
bool doesStartWith = s.StartsWith(prefix);
StartsWithCache.Add((s, prefix), doesStartWith);
return doesStartWith;
}
static string UppercaseFirst(this string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
public static string ReplaceFirst(this string text, string search, string replace)
{
int pos = text.IndexOf(search, StringComparison.Ordinal);
if (pos < 0)
{
return text;
}
return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}
public static string ReplaceLast(this string source, string find, string replace)
{
int place = source.LastIndexOf(find, StringComparison.Ordinal);

if(place == -1)
return source;

string result = source.Remove(place, find.Length).Insert(place, replace);
return result;
}
public static UdonNodeSearchMenu.NodeMenuLayer FindLayer(this UdonNodeSearchMenu.NodeMenuLayer layer, string activePath)
{
if (string.IsNullOrEmpty(activePath) || activePath == "/")
return layer;
return layer.MenuName == activePath
? layer
: layer.SubNodes.First(n => n.MenuName == activePath.Split('/')[0])
.FindLayer(string.Join("/", activePath.Split('/').Skip(1).ToArray()));
}
public static void PopulateNodeMenu(this UdonNodeSearchMenu.NodeMenuLayer nodeLayers)
{
List<(string path, UdonNodeDefinition nodeDefinition)> nodePaths = new List<(string path, UdonNodeDefinition nodeDefinition)>();

foreach (KeyValuePair<string, INodeRegistry> topRegistry in UdonEditorManager.Instance.GetNodeRegistries())
{
string topName = topRegistry.Key.Replace("NodeRegistry", "");
foreach (KeyValuePair<string, INodeRegistry> registry in topRegistry.Value.GetNodeRegistries().OrderBy(s => s.Key))
{
string baseRegistryName = registry.Key.Replace("NodeRegistry", "").FriendlyNameify().ReplaceFirst(topName, "");
string registryName = baseRegistryName.UppercaseFirst();
if (topName == "Udon" && (registryName == "Event" || registryName == "Type"))
{
registryName = $"{registryName}s";
}
if (registryName.EndsWith("[]"))
{
registryName = $"{registryName.Substring(0, registryName.Length - 2)}/{registryName}";
}
Dictionary<string, UdonNodeDefinition> baseNodeDefinition = new Dictionary<string, UdonNodeDefinition>();
foreach (UdonNodeDefinition nodeDefinition in registry.Value.GetNodeDefinitions().OrderBy(s => UdonNodeSearchMenu.PrettyFullName(s)))
{
string baseIdentifier = nodeDefinition.fullName;
string[] splitBaseIdentifier = baseIdentifier.Split(new[] {"__"}, StringSplitOptions.None);
if (splitBaseIdentifier.Length >= 2)
{
baseIdentifier = $"{splitBaseIdentifier[0]}__{splitBaseIdentifier[1]}";
}
if (baseNodeDefinition.ContainsKey(baseIdentifier))
{
continue;
}
baseNodeDefinition.Add(baseIdentifier, nodeDefinition);
}

foreach (KeyValuePair<string, UdonNodeDefinition> nodeDefinitionsEntry in baseNodeDefinition)
{
string nodeName = PrettyBaseName(nodeDefinitionsEntry.Key).ReplaceFirst(baseRegistryName, "");
if (nodeName.Contains("."))
{
nodeName = nodeName.Split('.')[1];
}
nodeName = nodeName.UppercaseFirst();
if(topName == "Udon")
{
nodePaths.Add((
$"{registryName}/{nodeName}", nodeDefinitionsEntry.Value));
}
else
{
nodePaths.Add((
$"{topName}/{registryName}/{nodeName}", nodeDefinitionsEntry.Value));
}
}
}
}

foreach ((string path, UdonNodeDefinition nodeDefinition) item in nodePaths)
{
NodeMenuBuilder(item.path, item.nodeDefinition, nodeLayers);
}
nodeLayers.MenuName = "";
void NodeMenuBuilder(string path, UdonNodeDefinition nodeDefinition, UdonNodeSearchMenu.NodeMenuLayer container)
{
string[] segments = path.Split('/');
string head = segments[0];
string[] tail = segments.Skip(1).ToArray();
if (tail.Length == 0)
{
if (container.SubNodes.Any(n => n.MenuName == head))
{
container.SubNodes.First(n => n.MenuName == head).NodeDefinition = nodeDefinition;
}
else
{
UdonNodeSearchMenu.NodeMenuLayer nLayer = new UdonNodeSearchMenu.NodeMenuLayer();
nLayer.MenuName = head;
nLayer.NodeDefinition = nodeDefinition;
container.SubNodes.Add(nLayer);
}
}
else
{
string head1 = head;
if (container.SubNodes.All(n => n.MenuName != head1))
{
UdonNodeSearchMenu.NodeMenuLayer nLayer = new UdonNodeSearchMenu.NodeMenuLayer();
nLayer.MenuName = head;
container.SubNodes.Add(nLayer);
}

foreach (UdonNodeSearchMenu.NodeMenuLayer layer in container.SubNodes)
{
if (layer.MenuName == head)
NodeMenuBuilder(string.Join("/", tail), nodeDefinition, layer);
}
}
}
string PrettyBaseName(string baseIdentifier)
{
string result = baseIdentifier.Replace("UnityEngine", "").Replace("System", "");
string[] resultSplit = result.Split(new[] {"__"}, StringSplitOptions.None);
if (resultSplit.Length >= 2)
{
result = $"{resultSplit[0]}{resultSplit[1]}";
}
result = result.FriendlyNameify();
result = result.Replace("op_", "");
result = result.Replace("_", " ");
return result;
}
}
}
}

+ 3
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphExtensions.cs.meta View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 83886f1f93224cfb97ea7f32df366c57
timeCreated: 1575758808

+ 2498
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphGUI.cs
File diff suppressed because it is too large
View File


+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphGUI.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f90c33ba12f0134683370bde48be7f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 194
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAsset.cs View File

@@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using VRC.Udon.Common.Interfaces;
using VRC.Udon.Editor.ProgramSources;
using VRC.Udon.Editor.ProgramSources.Attributes;
using VRC.Udon.Graph;
using VRC.Udon.Graph.Interfaces;
using VRC.Udon.Serialization.OdinSerializer;

[assembly: UdonProgramSourceNewMenu(typeof(UdonGraphProgramAsset), "Udon Graph Program Asset")]

namespace VRC.Udon.Editor.ProgramSources
{
[CreateAssetMenu(menuName = "VRChat/Udon/Udon Graph Program Asset", fileName = "New Udon Graph Program Asset")]
public class UdonGraphProgramAsset : UdonAssemblyProgramAsset, IUdonGraphDataProvider
{
[SerializeField]
public UdonGraphData graphData = new UdonGraphData();

[SerializeField]
private bool showAssembly = false;

[NonSerialized, OdinSerialize]
private Dictionary<string, (object value, Type type)> heapDefaultValues = new Dictionary<string, (object value, Type type)>();

protected override void DrawProgramSourceGUI(UdonBehaviour udonBehaviour, ref bool dirty)
{
if(GUILayout.Button("Open Udon Graph", "LargeButton"))
{
var window = EditorWindow.GetWindow<UdonGraphWindow>("Udon Graph", true, typeof(SceneView));
window.lastClickedProgramSource = this;
}

DrawPublicVariables(udonBehaviour, ref dirty);
DrawAssemblyErrorTextArea();
DrawAssemblyTextArea(false, ref dirty);
}

protected override void RefreshProgramImpl()
{
if(graphData == null)
{
return;
}

CompileGraph();
base.RefreshProgramImpl();
ApplyDefaultValuesToHeap();
}

protected override void DrawAssemblyTextArea(bool allowEditing, ref bool dirty)
{
EditorGUI.BeginChangeCheck();
bool newShowAssembly = EditorGUILayout.Foldout(showAssembly, "Compiled Graph Assembly");
if(EditorGUI.EndChangeCheck())
{
Undo.RecordObject(this, "Toggle Assembly Foldout");
showAssembly = newShowAssembly;
}

if(!showAssembly)
{
return;
}

EditorGUI.indentLevel++;
base.DrawAssemblyTextArea(allowEditing, ref dirty);
EditorGUI.indentLevel--;
}

[PublicAPI]
protected void CompileGraph()
{
udonAssembly = UdonEditorManager.Instance.CompileGraph(graphData, null, out Dictionary<string, (string uid, string fullName, int index)> _, out heapDefaultValues);
}

[PublicAPI]
protected void ApplyDefaultValuesToHeap()
{
IUdonSymbolTable symbolTable = program?.SymbolTable;
IUdonHeap heap = program?.Heap;
if(symbolTable == null || heap == null)
{
return;
}

foreach(KeyValuePair<string, (object value, Type type)> defaultValue in heapDefaultValues)
{
if(!symbolTable.HasAddressForSymbol(defaultValue.Key))
{
continue;
}

uint symbolAddress = symbolTable.GetAddressFromSymbol(defaultValue.Key);
(object value, Type declaredType) = defaultValue.Value;
if(typeof(UnityEngine.Object).IsAssignableFrom(declaredType))
{
if(value != null && !declaredType.IsInstanceOfType(value))
{
heap.SetHeapVariable(symbolAddress, null, declaredType);
continue;
}

if((UnityEngine.Object)value == null)
{
heap.SetHeapVariable(symbolAddress, null, declaredType);
continue;
}
}

if(value != null)
{
if(!declaredType.IsInstanceOfType(value))
{
value = declaredType.IsValueType ? Activator.CreateInstance(declaredType) : null;
}
}

heap.SetHeapVariable(symbolAddress, value, declaredType);
}
}

protected override object GetPublicVariableDefaultValue(string symbol, Type type)
{
IUdonSymbolTable symbolTable = program?.SymbolTable;
IUdonHeap heap = program?.Heap;
if(symbolTable == null || heap == null)
{
return null;
}

if(!heapDefaultValues.ContainsKey(symbol))
{
return null;
}

(object value, Type declaredType) = heapDefaultValues[symbol];
if(!typeof(UnityEngine.Object).IsAssignableFrom(declaredType))
{
return value;
}

return (UnityEngine.Object)value == null ? null : value;
}

protected override object DrawPublicVariableField(string symbol, object variableValue, Type variableType, ref bool dirty,
bool enabled)
{
EditorGUILayout.BeginHorizontal();
variableValue = base.DrawPublicVariableField(symbol, variableValue, variableType, ref dirty, enabled);
object defaultValue = null;
if(heapDefaultValues.ContainsKey(symbol))
{
defaultValue = heapDefaultValues[symbol].value;
}

if(variableValue == null || !variableValue.Equals(defaultValue))
{
if(defaultValue != null || variableValue != null)
{
if(GUILayout.Button("Reset to Default Value"))
{
variableValue = defaultValue;
dirty = true;
}
}
}

EditorGUILayout.EndHorizontal();

return variableValue;
}

#region Serialization Methods

protected override void OnAfterDeserialize()
{
foreach(UdonNodeData node in graphData.nodes)
{
node.SetGraph(graphData);
}
}

#endregion

public UdonGraphData GetGraphData()
{
return graphData;
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAsset.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f11136daadff0b44ac2278a314682ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 9
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAssetEditor.cs View File

@@ -0,0 +1,9 @@
using UnityEditor;

namespace VRC.Udon.Editor.ProgramSources
{
[CustomEditor(typeof(UdonGraphProgramAsset))]
public class UdonGraphProgramAssetEditor : UdonAssemblyProgramAssetEditor
{
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphProgramAssetEditor.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31d6811854f59254aa1a263a8d566eb2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 253
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphWindow.cs View File

@@ -0,0 +1,253 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using VRC.Udon.Graph;
using VRC.Udon.Graph.Interfaces;

namespace VRC.Udon.Editor.ProgramSources
{
public class UdonGraphWindow : EditorWindow
{
private const int TOOLBAR_HEIGHT = 17;
private const float CONTENT_LOGO_SCALE = .75f;

[SerializeField]
private UdonGraph graph;

[SerializeField]
private UdonGraphGUI graphGUI;

private static GUIStyle _udonLogo;

public AbstractUdonProgramSource lastClickedProgramSource { private get; set; }

[MenuItem("VRChat SDK/Udon Graph")]
private static void Init()
{
GetWindow(typeof(UdonGraphWindow));
}

private void OnEnable()
{
titleContent = new GUIContent("Udon Graph");

graph = CreateInstance<UdonGraph>();
graphGUI = CreateInstance<UdonGraphGUI>();
graphGUI.graph = graph;
Texture2D logoTexture = Resources.Load<Texture2D>(EditorGUIUtility.isProSkin ? "UdonLogoAlphaWhite" : "UdonLogoAlpha");
_udonLogo = new GUIStyle
{
normal =
{
background = logoTexture,
textColor = Color.white
},
fixedHeight = (int)(logoTexture.height * CONTENT_LOGO_SCALE),
fixedWidth = (int)(logoTexture.width * CONTENT_LOGO_SCALE)
};

// ReSharper disable once DelegateSubtraction
Undo.undoRedoPerformed -= OnUndoRedo; //Remove old handler if present to prevent duplicates, doesn't cause errors if not present
Undo.undoRedoPerformed += OnUndoRedo;
}

private void OnUndoRedo()
{
Repaint();
}

private bool _drawGraph;
private string _displayText = "";

private void OnGUILogic()
{
_drawGraph = true;

if(Selection.gameObjects.Count(g => g.GetComponent<UdonBehaviour>()) > 1)
{
_displayText = "Multi-object editing not supported";
_drawGraph = false;
}
else if(Selection.objects.Count(o => o != null && o is IUdonGraphDataProvider) > 1) // == typeof(UdonGraphProgramAsset)
{
_displayText = "Multi-object editing not supported";
_drawGraph = false;
}

IUdonGraphDataProvider udonGraphProgramAsset = (IUdonGraphDataProvider)Selection.objects.FirstOrDefault(g => g != null && g is IUdonGraphDataProvider);
if(udonGraphProgramAsset == null)
{
GameObject behaviourObject = Selection.gameObjects.FirstOrDefault(g => g.GetComponent<UdonBehaviour>());
if(behaviourObject != null)
{
UdonBehaviour udonBehaviour;
var udonBehaviours = behaviourObject.GetComponents<UdonBehaviour>();
if (udonBehaviours.Length == 1 || lastClickedProgramSource == null)
{
udonBehaviour = udonBehaviours[0];
}
else
{
udonBehaviour = udonBehaviours.FirstOrDefault(u => u.programSource == lastClickedProgramSource);
if(udonBehaviour == null)
{
// the last clicked graph is not available on this object, reset it
lastClickedProgramSource = null;
udonBehaviour = udonBehaviours[0];
}
}
AbstractUdonProgramSource programSource = udonBehaviour.programSource;
if(programSource is IUdonGraphDataProvider asUdonGraphProgramAsset)
{
udonGraphProgramAsset = asUdonGraphProgramAsset;
}
}
}
if (graph == null)
{
graph = CreateInstance<UdonGraph>();
}

if(udonGraphProgramAsset != null)
{
if (graphGUI == null)
{
graphGUI = CreateInstance<UdonGraphGUI>();
graphGUI.graph = graph;
}
if (graph == null)
{
graph = CreateInstance<UdonGraph>();
graphGUI.graph = graph;
}
if(graph.graphProgramAsset == udonGraphProgramAsset)
{
if (graph.data != null)
{
return;
}
}

titleContent = new GUIContent($"Udon - {udonGraphProgramAsset}");
graph.data = new UdonGraphData(udonGraphProgramAsset.GetGraphData());
graph.graphProgramAsset = udonGraphProgramAsset;
graph.Reload();
graphGUI.CenterGraph();
}
else
{
if(graph.graphProgramAsset != null)
{
return;
}

_displayText = "Create an Udon Graph Asset to begin.";
_drawGraph = false;
}
}

public void OnGUI()
{
OnGUILogic();
DrawToolbar();
if (!_drawGraph)
{
DrawCenteredText(_displayText);
}
else
{
DrawGraph();
}
}

private void DrawNodeSearchBox()
{
UdonNodeSearchMenu.DrawWindow(graph, graphGUI);
}

private static void DrawCenteredText(string text)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Box("", _udonLogo);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.Space(100);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(text);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
}

private void DrawGraph()
{
GUI.SetNextControlName("Default");
graphGUI.BeginGraphGUI(this, new Rect(0, TOOLBAR_HEIGHT, position.width, position.height));
graphGUI.OnGraphGUI();
graphGUI.EndGraphGUI();
}

private void DrawToolbar()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);

GUILayout.FlexibleSpace();
if (_drawGraph)
{
using(new EditorGUI.DisabledScope(Application.isPlaying))
{
if (graph.graphProgramAsset is AbstractUdonProgramSource udonProgramSource)
{
bool triggerRefresh;
if (UdonEditorManager.Instance.IsProgramSourceRefreshQueued(udonProgramSource))
{
triggerRefresh =
GUILayout.Button(
$"Auto Compile in {UdonEditorManager.Instance.ProgramRefreshDelayRemaining:F0}s.",
EditorStyles.toolbarButton);
Repaint();
}
else
{
triggerRefresh = GUILayout.Button("Manual Compile", EditorStyles.toolbarButton);
}

if (triggerRefresh)
{
UdonEditorManager.Instance.RefreshQueuedProgramSources();
}
}

DrawNodeSearchBox();
}

if (GUILayout.Button(" Recenter ", EditorStyles.toolbarButton))
{
graphGUI.CenterGraph();
}

using(new EditorGUI.DisabledScope(Application.isPlaying))
{
if(GUILayout.Button(" Reload Graph ", EditorStyles.toolbarButton))
{
graph.data = new UdonGraphData(graph.graphProgramAsset.GetGraphData()); //just do this in reload always
graph.Reload();
graphGUI.CenterGraph();
}
}
}
EditorGUILayout.EndHorizontal();
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonGraphWindow.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8353c90dd1eff01458c55d0bd5290a1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 169
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNode.cs View File

@@ -0,0 +1,169 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor.Graphs;
using UnityEngine.Serialization;
using VRC.Udon.Graph;

namespace VRC.Udon.Editor.ProgramSources
{
public class UdonNode : Node
{
public string uid;

public override void EndDrag()
{
base.EndDrag();

((UdonGraph)graph).UpdateNodePosition(this);
}

public override void RemovingFromGraph()
{
((UdonGraph)graph).DeleteNode(uid);
foreach(Edge edge in inputEdges)
{
graph.RemoveEdge(edge);
}

foreach(Edge edge in outputEdges)
{
graph.RemoveEdge(edge);
}

base.RemovingFromGraph();
}
private static readonly Dictionary<string, UdonNodeDefinition> NodeDefinitionCache =
new Dictionary<string, UdonNodeDefinition>();

internal void PopulateEdges()
{
UdonNodeData data = ((UdonGraph)graph).data.FindNode(uid);
//UdonNodeDefinition nodeDefinition = ((UdonGraph)graph).data.
UdonNodeDefinition udonNodeDefinition;
if (NodeDefinitionCache.ContainsKey(data.fullName))
{
udonNodeDefinition = NodeDefinitionCache[data.fullName];
}
else
{
udonNodeDefinition = UdonEditorManager.Instance.GetNodeDefinition(data.fullName);
NodeDefinitionCache.Add(data.fullName, udonNodeDefinition);
}

for (int i = 0; i < inputDataSlots.Count(); i++) // udonNodeDefinition.Inputs.Count
{
if (data.nodeUIDs.Length <= i)
{
continue;
}
if (string.IsNullOrEmpty(data.nodeUIDs[i]))
{
continue;
}

string[] splitUID = data.nodeUIDs[i].Split('|');
string nodeUID = splitUID[0];
int otherIndex = 0;
if (splitUID.Length > 1)
{
otherIndex = int.Parse(splitUID[1]);
}

if (string.IsNullOrEmpty(nodeUID))
{
continue;
}

Node connectedNode = graph.nodes.FirstOrDefault(n => ((UdonNode) n).uid == nodeUID);
if (connectedNode == null)
{
Debug.LogError("Failed to connect node " + nodeUID);
data.nodeUIDs[i] = "";
((UdonGraph) graph).ReSerializeData();
continue;
}

List<Slot> slots = inputDataSlots.ToList();
if (slots.Count <= i)
{
Debug.LogError($"Failed to find input data slot (index {i}) for node {uid} {data.fullName}");
continue;
}

Slot destSlot = slots[i];

if (destSlot == null)
{
Debug.LogError("Failed to find input data slot for node " + uid);
continue;
}

if (otherIndex < 0)
{
otherIndex = 0;
}

if (connectedNode.outputDataSlots.Count() <= otherIndex)
{
otherIndex = 0;
}
Slot sourceSlot = connectedNode.outputDataSlots.ToList()[otherIndex]; //.FirstOrDefault();
//
// catch
// {
// Debug.LogError($"failed to connect node {uid} {data.fullName} to node {((UdonNode)connectedNode).uid} | otherindex is {otherIndex}");
// }


if(sourceSlot == null)
{
Debug.LogError("Failed to find output data slot for node " + nodeUID);
continue;
}

graph.Connect(sourceSlot, destSlot);
}

for (int i = 0; i < data.flowUIDs.Length; i++)
{
string nodeUID = data.flowUIDs[i];
if (string.IsNullOrEmpty(nodeUID))
{
continue;
}

Node connectedNode = graph.nodes.FirstOrDefault(n => ((UdonNode) n).uid == nodeUID);
if (connectedNode == null)
{
Debug.LogError("Failed to connect flow node " + nodeUID);
continue;
}

if (uid == "4e2c7cdc-8134-4616-bc83-783dc495759f")
{
int count = 0;
foreach (Slot slot in outputFlowSlots) count++;
Debug.Log(count);
}

Slot sourceSlot = outputFlowSlots.Count() > 1 ? outputFlowSlots.ToArray()[i] : outputFlowSlots.FirstOrDefault();
if (sourceSlot == null)
{
Debug.LogError("Failed to find output flow slot for node " + uid);
continue;
}

Slot destSlot = connectedNode.inputFlowSlots.FirstOrDefault();
if (destSlot == null)
{
Debug.LogError("Failed to find input flow slot for node " + nodeUID);
continue;
}

graph.Connect(sourceSlot, destSlot);
}
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNode.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c132ff7be49726341a7eace42312fa93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 817
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNodeSearchMenu.cs View File

@@ -0,0 +1,817 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using UnityEditor;
using UnityEngine;
using VRC.Udon.EditorBindings;
using VRC.Udon.EditorBindings.Interfaces;
using VRC.Udon.Graph;

namespace VRC.Udon.Editor.ProgramSources
{
public class UdonNodeSearchMenu : EditorWindow
{
private static UdonNodeSearchMenu _instance;

private string _searchString = string.Empty;
private UdonGraph _graph;
private UdonGraphGUI _graphGUI;
private Styles _styles;
private Vector2 _scrollPosition = Vector2.zero;
private IEnumerable<UdonNodeDefinition> _filteredNodeDefinitions;
private IEnumerable<UdonNodeDefinition> _unfilteredNodeDefinitions;
private Dictionary<string, UdonNodeDefinition> _searchDefinitions;

private long _lastTime;
private float _animValue;
private float _animGoal = 1;
private bool _isAnimating;

private string _currentActivePath = "";
private string _currentActiveNode = "";
private int _currentActiveIndex;

private string _nextActivePath = "";
private string _nextActiveNode = "";
private int _nextActiveIndex;

private const int LIST_BUTTON_HEIGHT = 20;
private const float DROPDOWN_HEIGHT = 320f;
private float _dropDownWidth;
private Rect _dropDownRect;

private static readonly NodeMenuLayer NodeMenu = new NodeMenuLayer();

private void Awake()
{
//_unfilteredNodeDefinitions = _udonEditorInterface.GetNodeDefinitions();
Dictionary<string, UdonNodeDefinition> baseNodeDefinitions = new Dictionary<string, UdonNodeDefinition>();
foreach (UdonNodeDefinition nodeDefinition in UdonEditorManager.Instance.GetNodeDefinitions().OrderBy(s => PrettyFullName(s)))
{
string baseIdentifier = nodeDefinition.fullName;
string[] splitBaseIdentifier = baseIdentifier.Split(new[] {"__"}, StringSplitOptions.None);
if (splitBaseIdentifier.Length >= 2)
{
baseIdentifier = $"{splitBaseIdentifier[0]}__{splitBaseIdentifier[1]}";
}
if (baseNodeDefinitions.ContainsKey(baseIdentifier))
{
continue;
}
baseNodeDefinitions.Add(baseIdentifier, nodeDefinition);
}

_unfilteredNodeDefinitions = baseNodeDefinitions.Values;
_searchDefinitions = _unfilteredNodeDefinitions.ToDictionary(nodeDefinition => SanitizedSearchString(nodeDefinition.fullName));
_filteredNodeDefinitions = _unfilteredNodeDefinitions;

string SanitizedSearchString(string s)
{
s = s.FriendlyNameify()
.ToLowerInvariant()
.Replace(".__", ".");
if (s.StartsWith("variable_"))
{
s = s.Replace("variable_", "");
}
s = s.Replace("_", " ")
.ReplaceFirst("unityengine", "");
//.ReplaceFirst("system", "");
return s;
}
}

public static void DrawWindow(UdonGraph graph, UdonGraphGUI graphGUI)
{
if(_instance == null)
{
_instance = CreateInstance<UdonNodeSearchMenu>();
}

Rect rect = GUILayoutUtility.GetLastRect();
bool goodState = graphGUI.selection.Count == 0;
if(goodState)
{
goodState = GUI.GetNameOfFocusedControl() != "NodeField";
}

if(goodState && KeyUpEvent(KeyCode.Space) && !Event.current.shift)
{
GUI.UnfocusWindow();
}

if(!GUILayout.Button("Add Node", EditorStyles.toolbarButton, GUILayout.Width(120)) && !(KeyUpEvent(KeyCode.Space) && goodState))
{
return;
}
rect = RemapRectForPopup(rect);
_instance.InitWindow(graph, graphGUI, rect);
_instance.Repaint();
}

private void InitWindow(UdonGraph graph, UdonGraphGUI graphGUI, Rect rect)
{
_dropDownRect = rect;
_graph = graph;
_graphGUI = graphGUI;
_styles = new Styles();
wantsMouseMove = true;

if (NodeMenu.MenuName == null)
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
NodeMenu.PopulateNodeMenu();
}).Start();
}

_dropDownWidth = rect.width;
ShowAsDropDown(rect, new Vector2(rect.width, DROPDOWN_HEIGHT));
Focus();
}

private void OnGUI()
{
GUI.Label(new Rect(0.0f, 0.0f, position.width, position.height), GUIContent.none, _styles.Background);
if(_filteredNodeDefinitions == null)
{
_filteredNodeDefinitions = _unfilteredNodeDefinitions;
}
DrawSearchBox();
if(_isAnimating && Event.current.type == EventType.Repaint)
{
long ms = DateTime.Now.Millisecond;
float maxDelta = -(ms - _lastTime) * .01f;
_lastTime = ms;
_animValue = Mathf.MoveTowards(_animValue, _animGoal, maxDelta);
Repaint();
}
if ((_animValue >= 1 || _animValue <= -1) && Event.current.type != EventType.Repaint)
{
_isAnimating = false;
_animValue = 0;
_currentActivePath = _nextActivePath;
_currentActiveNode = _nextActiveNode;
_currentActiveIndex = _nextActiveIndex;
_nextActivePath = "";
_nextActiveNode = "";
_nextActiveIndex = 0;
while (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
}

while (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
}
}
DrawListGUI(false, _animValue);
if (_isAnimating)
{
//if(animGoal == 1)
DrawListGUI( true, _animValue - 1);
//else
DrawListGUI( true, _animValue + 1);
}

if(KeyUpEvent(KeyCode.Escape))
{
Close();
}
}
private void DrawSearchBox()
{
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();

GUI.SetNextControlName("nodeSearch");
EditorGUI.BeginChangeCheck();
_searchString = EditorGUILayout.TextField(_searchString, _styles.SearchTextField);
if(EditorGUI.EndChangeCheck())
{
ApplySearchFilter();
}

EditorGUI.FocusTextInControl("nodeSearch");
GUIStyle searchButtonStyle =
_searchString == string.Empty ? _styles.SearchCancelButtonEmpty : _styles.SearchCancelButton;

if(GUILayout.Button(string.Empty, searchButtonStyle))
{
_searchString = string.Empty;
GUI.FocusControl(null);
}

EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}

private void ApplySearchFilter()
{
string lowerSearchString = _searchString.ToLowerInvariant();
string unSpacedSearchString = lowerSearchString.Replace(" ", string.Empty);
string[] lowerSearchStringArray = lowerSearchString.Split(' ');
if(unSpacedSearchString.Length < 3)
{
_filteredNodeDefinitions = new List<UdonNodeDefinition>();
return;
}

_filteredNodeDefinitions = _searchDefinitions
.Where(s => s.Key.Contains(lowerSearchString))
.OrderBy(s => s.Key, new SearchComparer(lowerSearchString))
.Concat(_searchDefinitions
.Where(s => s.Key.Contains(unSpacedSearchString))
.OrderBy(s => s.Key, new SearchComparer(unSpacedSearchString))
.Concat(_searchDefinitions
.Where(s => lowerSearchStringArray.All(w => s.Key.Contains(w.ToLowerInvariant())))
.OrderBy(s => s.Key, new SearchComparer(lowerSearchStringArray.First().Replace(" ", string.Empty)))
.Where(s => s.Key.IndexOf(lowerSearchStringArray.First().Replace(" ", string.Empty), StringComparison.InvariantCultureIgnoreCase) != -1)
)
)
.Select(d => d.Value).Distinct().Take(200).ToArray();

//if(_filteredNodeDefinitions.Count() > 1000)
//{
// _filteredNodeDefinitions = _filteredNodeDefinitions.Take(1000).ToArray();
//}
}

public static string PrettyFullName(UdonNodeDefinition nodeDefinition, bool keepLong = false)
{
string fullName = nodeDefinition.fullName;
string result;
if(keepLong)
{
result = fullName.Replace("UnityEngine", "UnityEngine.").Replace("System", "System.");
}
else
{
result = fullName.Replace("UnityEngine", "").Replace("System", "");
}

string[] resultSplit = result.Split(new[] {"__"}, StringSplitOptions.None);
if(resultSplit.Length >= 3)
{
string outName = "";
if (nodeDefinition.type != typeof(void))
{
if (nodeDefinition.Outputs.Count > 0)
{
outName = string.Join(", ", nodeDefinition.Outputs.Select(o => o.name));
}
}
result = nodeDefinition.Inputs.Count > 0
? $"{resultSplit[0]}{resultSplit[1]}({string.Join(", ", nodeDefinition.Inputs.Select(s => s.name))}{outName})"
: $"{resultSplit[0]}{resultSplit[1]}({resultSplit[2].Replace("_", ", ")}{outName})";
}
else if(resultSplit.Length >= 2)
{
result = $"{resultSplit[0]}{resultSplit[1]}()";
}

if(!keepLong)
{
result = result.FriendlyNameify();
result = result.Replace("op_", "");
result = result.Replace("_", " ");
}

return result;
}
//TODO: oof ouch my reflection
private static object GetInstanceField(Type type, object instance, string fieldName)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Static;
FieldInfo field = type.GetField(fieldName, bindFlags);
if (field != null) return field.GetValue(instance);
throw new NullReferenceException($"Failed to get private field named: {fieldName} on object: {instance} of type: {type}");
}

private Rect _headerRect;
private void DrawListGUI( bool isNext = false, float anim = 0)
{
Rect rect = position;
rect.x = +1f;
rect.x -= 230*anim;
rect.y = 30f;
rect.height -= 30f;
rect.width -= 2f;
GUILayout.BeginArea(rect);
rect = GUILayoutUtility.GetRect(10f, 25f);

if (string.IsNullOrEmpty(_currentActivePath) || _currentActivePath == "/")
GUI.Label(rect, _searchString == string.Empty ? "Nodes" : "Search", _styles.Header);
else
{
string nestedTitle = _currentActivePath.Substring(0, _currentActivePath.Length - 1);
if (GUI.Button(rect, _searchString == string.Empty ? nestedTitle : "Search", _styles.Header))
{
if (!isNext && !string.IsNullOrEmpty(_currentActivePath))
{
List<string> tmp = _currentActivePath.Split('/').ToList();
if (tmp.Count - 2 >= 0)
{
_nextActiveNode = tmp[tmp.Count - 2];
_nextActiveIndex = 0;
tmp.RemoveAt(_currentActivePath.Split('/').Length - 2);
}
_nextActivePath = string.Join("/", tmp.ToArray());
_isAnimating = true;
_animGoal = 1;
_lastTime = DateTime.Now.Millisecond;
}
}
if (string.IsNullOrEmpty(_searchString))
GUI.Label(new Rect((float)(rect.x + 6.0), rect.y + 6f, 13f, 13f), "", _styles.LeftArrow);
}

_headerRect = rect;
//TODO: don't be lazy, figure out the math for this so you don't have to loop :P
bool repaint = false;
while (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
repaint = true;
}

while (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
repaint = true;
}

if (repaint)
{
Repaint();
}

float oldScrollPosition = _scrollPosition.y;
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);

if (string.IsNullOrEmpty(_searchString))
{
DrawNodeEntries(NodeMenu, isNext);
}
else
{
for(int i = 0; i < (_filteredNodeDefinitions.Count() > 100 ? 100 : _filteredNodeDefinitions.Count()); i++)
{
UdonNodeDefinition udonNodeDefinition = _filteredNodeDefinitions.ElementAt(i);
string aB = _currentActiveNode;
if(_filteredNodeDefinitions.All(f => f.fullName != aB))
{
_currentActiveNode = udonNodeDefinition.fullName;
}

GUIStyle buttonStyle = _currentActiveNode == udonNodeDefinition.fullName
? _styles.ActiveComponentButton
: _styles.ComponentButton;

rect = GUILayoutUtility.GetRect(10f, LIST_BUTTON_HEIGHT);
bool pressedButton = GUI.Button(rect, NodeContentWithIcon(udonNodeDefinition, PrettyFullName(udonNodeDefinition), PrettyFullName(udonNodeDefinition, true)), buttonStyle);
if(pressedButton ||
(_currentActiveNode == udonNodeDefinition.fullName && (KeyUpEvent(KeyCode.Return) || KeyUpEvent(KeyCode.RightArrow))))
{
Rect graphExtents = (Rect)GetInstanceField(typeof(UdonGraph), _graph, "graphExtents");
graphExtents = new Rect(new Vector2(_graphGUI.scrollPosition.x + (graphExtents.x + (_graphGUI.Host.position.width / 2)) - 125, _graphGUI.scrollPosition.y + (graphExtents.y + (_graphGUI.Host.position.height / 2)) - 24), new Vector2(10, 10));
_graph.CreateNode(udonNodeDefinition, graphExtents.position);
Close();
}
if (rect.Contains(Event.current.mousePosition) &&
Event.current.mousePosition.y <= _dropDownRect.yMin + DROPDOWN_HEIGHT + _scrollPosition.y &&
Event.current.mousePosition.y > _headerRect.yMax + _scrollPosition.y - LIST_BUTTON_HEIGHT)
{
_currentActiveNode = udonNodeDefinition.fullName;
_currentActiveIndex = i;
}

if(Event.current.type != EventType.MouseMove)
{
continue;
}
if(mouseOverWindow != null)
{
mouseOverWindow.Repaint();
}
}
}

GUILayout.EndScrollView();
if ((int)_scrollPosition.y != (int)oldScrollPosition)
{
{
Repaint();
}
}
GUILayout.EndArea();

if (!string.IsNullOrEmpty(_searchString))
{
if (KeyUsedEvent(KeyCode.DownArrow))
{
OffsetActiveButton(1);
}
else if (KeyUsedEvent(KeyCode.UpArrow))
{
OffsetActiveButton(-1);
}
}
}

private string _loadingText = "Loading Nodes";
private void DrawNodeEntries(NodeMenuLayer layer, bool isNext)
{
if (NodeMenu.MenuName == null)
{
Rect buttonRect = GUILayoutUtility.GetRect(10f, LIST_BUTTON_HEIGHT, GUILayout.ExpandWidth(true));
GUI.Label(buttonRect, _loadingText, _styles.ComponentButton);
_loadingText = $"{_loadingText}.";
if (_loadingText.Contains("......"))
{
_loadingText = "Loading Nodes";
}
Repaint();
return;
}
NodeMenuLayer foundLayer = layer.FindLayer(_currentActivePath);
string aN = _currentActiveNode;

if (foundLayer.SubNodes.Count == 0)
{
return;
}
if (foundLayer.SubNodes.All(n => n.MenuName != aN))
{
if (!isNext)
{
_currentActiveNode = foundLayer.SubNodes.First().MenuName;
_currentActiveIndex = 0;
_scrollPosition.y = 0;
aN = _currentActiveNode;
}
}

if (Event.current.type == EventType.Used && Event.current.keyCode == KeyCode.DownArrow)
{
int idx = foundLayer.SubNodes.Select((value, index) => new { value, index }).Where(pair => pair.value.MenuName == aN).Select(pair => pair.index).FirstOrDefault();
if (idx + 1 < foundLayer.SubNodes.Count)
{
if (!isNext)
{
_currentActiveNode = foundLayer.SubNodes[idx + 1].MenuName;
_currentActiveIndex = idx + 1;
if (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
}
}
}
}
if (Event.current.type == EventType.Used && Event.current.keyCode == KeyCode.UpArrow)
{
int idx = foundLayer.SubNodes.Select((value, index) => new { value, index }).Where(pair => pair.value.MenuName == aN).Select(pair => pair.index).FirstOrDefault();
if (idx - 1 >= 0)
{
if (!isNext)
{
_currentActiveNode = foundLayer.SubNodes[idx - 1].MenuName;
_currentActiveIndex = idx - 1;
if (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
}
}
}
}
if (Event.current.type == EventType.Used && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.RightArrow))
{
if (!isNext)
{
if (foundLayer.SubNodes.First(n => n.MenuName == aN).SubNodes.Count == 0)
{
Rect graphExtents = (Rect)GetInstanceField(typeof(UdonGraph), _graph, "graphExtents");
graphExtents = new Rect(new Vector2(_graphGUI.scrollPosition.x + (graphExtents.x + (_graphGUI.Host.position.width / 2)) - 125, _graphGUI.scrollPosition.y + (graphExtents.y + (_graphGUI.Host.position.height / 2)) - 24), new Vector2(10, 10));
_graph.CreateNode(foundLayer.SubNodes.First(n => n.MenuName == aN).NodeDefinition, graphExtents.position);
Close();
}
else
{
_nextActivePath = _currentActivePath + _currentActiveNode + "/";
_isAnimating = true;
_animGoal = -1;
_lastTime = DateTime.Now.Millisecond;
}
}
}
if (Event.current.type == EventType.Used && (Event.current.keyCode == KeyCode.Backspace || Event.current.keyCode == KeyCode.LeftArrow))
{
if (!isNext && !string.IsNullOrEmpty(_currentActivePath))
{
List<string> tmp = _currentActivePath.Split('/').ToList();
if (tmp.Count - 2 >= 0)
{
_nextActiveNode = tmp[tmp.Count - 2];
_nextActiveIndex = 0;
tmp.RemoveAt(_currentActivePath.Split('/').Length - 2);
}
_nextActivePath = string.Join("/", tmp.ToArray());
_isAnimating = true;
_animGoal = 1;
_lastTime = DateTime.Now.Millisecond;
}
}

int nodeIndex = 0;
foreach (NodeMenuLayer item in foundLayer.SubNodes)
{
Rect buttonRect = GUILayoutUtility.GetRect(10f, LIST_BUTTON_HEIGHT, GUILayout.ExpandWidth(true));
if (!isNext)
{
if (string.IsNullOrEmpty(_currentActiveNode))
{
_currentActiveNode = item.MenuName;
_currentActiveIndex = nodeIndex;
while (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
}

while (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
}
}
}

GUIStyle buttonStyle = _styles.ComponentButton;
if (_currentActiveNode == item.MenuName)
{
buttonStyle = _styles.ActiveComponentButton;
}

if (GUI.Button(buttonRect,
NodeContentWithIcon(item.NodeDefinition, item.MenuName,
item.NodeDefinition != null ? PrettyFullName(item.NodeDefinition, true) : item.MenuName),
buttonStyle))
{
if (item.SubNodes.Count == 0)
{
Rect graphExtents = (Rect)GetInstanceField(typeof(UdonGraph), _graph, "graphExtents");
graphExtents = new Rect(new Vector2(_graphGUI.scrollPosition.x + (graphExtents.x + (_graphGUI.Host.position.width / 2)) - 125, _graphGUI.scrollPosition.y + (graphExtents.y + (_graphGUI.Host.position.height / 2)) - 24), new Vector2(10, 10));
_graph.CreateNode(foundLayer.SubNodes.First(n => n.MenuName == aN).NodeDefinition, graphExtents.position);
Close();
}
if (!isNext)
{
_nextActivePath = $"{_currentActivePath}{item.MenuName}/";
_isAnimating = true;
_animGoal = -1;
_lastTime = DateTime.Now.Millisecond;
}
}

if (buttonRect.Contains(Event.current.mousePosition) &&
Event.current.mousePosition.y <= _dropDownRect.yMin + DROPDOWN_HEIGHT + _scrollPosition.y &&
Event.current.mousePosition.y > _headerRect.yMax + _scrollPosition.y - LIST_BUTTON_HEIGHT)
{
if (!isNext)
{
_currentActiveNode = item.MenuName;
_currentActiveIndex = nodeIndex;
while (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
}

while (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
}
}
}

if (buttonRect.Contains(Event.current.mousePosition))
{
if (!isNext)
{
if (Event.current.type == EventType.MouseMove)
{
if (mouseOverWindow != null)
{
mouseOverWindow.Repaint();
}
}
}
else
{
_nextActiveNode = item.MenuName;
_nextActiveIndex = nodeIndex;
}
}

if (item.SubNodes.Count > 0)
{
GUI.Label(
new Rect((float) ((double) buttonRect.x + buttonRect.width - 13.0), buttonRect.y + 4f, 13f,
13f), "", _styles.RightArrow);
}

nodeIndex++;
}

}

private void OffsetActiveButton(int offset)
{
_currentActiveIndex += offset;
_currentActiveIndex = Mathf.Clamp(_currentActiveIndex, 0, _filteredNodeDefinitions.Count() - 1);
_currentActiveNode = _filteredNodeDefinitions.ElementAt(_currentActiveIndex).fullName;
while (_currentActiveIndex * LIST_BUTTON_HEIGHT >=
_scrollPosition.y + DROPDOWN_HEIGHT - (LIST_BUTTON_HEIGHT * 3) - 5)
{
_scrollPosition.y += LIST_BUTTON_HEIGHT;
}

while (_currentActiveIndex * LIST_BUTTON_HEIGHT < _scrollPosition.y)
{
_scrollPosition.y -= LIST_BUTTON_HEIGHT;
}
}

private static Rect RemapRectForPopup(Rect rect)
{
rect.y += 26f;
rect.x += rect.width;
rect.width = 500;
rect.x -= rect.width / 2;
Vector2 v2 = GUIUtility.GUIToScreenPoint(new Vector2(rect.x, rect.y));
rect.x = v2.x;
rect.y = v2.y;
return rect;
}

private static bool KeyUpEvent(KeyCode keyCode)
{
return Event.current.type == EventType.KeyUp && Event.current.keyCode == keyCode;
}

private static bool KeyUsedEvent(KeyCode keyCode)
{
return Event.current.type == EventType.Used && Event.current.keyCode == keyCode;
}

private static Dictionary<Type, Texture2D> typeThumbCache = new Dictionary<Type, Texture2D>();
private GUIContent NodeContentWithIcon(UdonNodeDefinition nodeDefinition, string menuName, string tooltip)
{
GUIContent content;
if (nodeDefinition != null)
{
Type thumbType = nodeDefinition.type;
if (thumbType != null)
{
if (thumbType.IsArray)
{
thumbType = thumbType.GetElementType();
}
}
Texture2D thumb = GetCachedTypeThumbnail(thumbType);

//TODO: This is real gross and hacky, figure out how to just let the name clip naturally without clipping the icon in the process
int maxLength = (int)(_dropDownWidth / 7);
menuName = menuName.Substring(0, menuName.Length <= maxLength ? menuName.Length : maxLength);
while (GUI.skin.label.CalcSize(new GUIContent(menuName)).x > _dropDownWidth - 35)
{
menuName = menuName.Substring(0, menuName.Length - 1);
}
content = thumb != null
? new GUIContent($"{menuName}", thumb, tooltip)
: new GUIContent($" {menuName}", tooltip);
}
else
{
content = new GUIContent($" {menuName}", tooltip);
}
return content;
}

public static Texture2D GetCachedTypeThumbnail(Type thumbType)
{
Texture2D thumb;
if (thumbType == null)
{
thumb = null;
}
else
{
if (typeThumbCache.ContainsKey(thumbType))
{
thumb = typeThumbCache[thumbType];
}
else
{
thumb = AssetPreview.GetMiniTypeThumbnail(thumbType);
typeThumbCache.Add(thumbType, thumb);
}
}

return thumb;
}

private class Styles
{
public readonly GUIStyle ComponentButton = new GUIStyle("PR Label");
public readonly GUIStyle ActiveComponentButton;
public readonly GUIStyle Header = new GUIStyle("In BigTitle");
public readonly GUIStyle SearchTextField;
public readonly GUIStyle SearchCancelButton;
public readonly GUIStyle SearchCancelButtonEmpty;
public readonly GUIStyle Background = "grey_border";
//public readonly GUIStyle PreviewBackground = "PopupCurveSwatchBackground";
//public readonly GUIStyle PreviewHeader = new GUIStyle(EditorStyles.label);
//public readonly GUIStyle PreviewText = new GUIStyle(EditorStyles.wordWrappedLabel);
public readonly GUIStyle RightArrow = "AC RightArrow";
public readonly GUIStyle LeftArrow = "AC LeftArrow";
//public readonly GUIStyle GroupButton;

public Styles()
{
ComponentButton.active = ComponentButton.onActive;
ComponentButton.hover = ComponentButton.onHover;
ComponentButton.padding.left -= 15;
ComponentButton.fixedHeight = 20f;
//ComponentButton.stretchWidth = true;
ComponentButton.alignment = TextAnchor.MiddleLeft;//.MiddleLeft;
ActiveComponentButton = new GUIStyle(ComponentButton);
ActiveComponentButton.normal = ActiveComponentButton.onHover;

Header.font = EditorStyles.boldLabel.font;

SearchTextField = GUI.skin.FindStyle("SearchTextField");
SearchCancelButton = GUI.skin.FindStyle("SearchCancelButton");
SearchCancelButtonEmpty = GUI.skin.FindStyle("SearchCancelButtonEmpty");
Header.font = EditorStyles.boldLabel.font;
//GroupButton = new GUIStyle(ComponentButton);
//GroupButton.padding.left += 17;
//PreviewText.padding.left += 3;
//PreviewText.padding.right += 3;
//++PreviewHeader.padding.left;
//PreviewHeader.padding.right += 3;
//PreviewHeader.padding.top += 3;
//PreviewHeader.padding.bottom += 2;

}
}
public class NodeMenuLayer
{
public string MenuName;
public UdonNodeDefinition NodeDefinition;
public readonly List<NodeMenuLayer> SubNodes = new List<NodeMenuLayer>();
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonNodeSearchMenu.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9702ef19e1c2a0641a7c87ce25cfd1cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 19
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonSubGraphAsset.cs View File

@@ -0,0 +1,19 @@
using UnityEngine;
using VRC.Udon.Graph;
using VRC.Udon.Graph.Interfaces;

namespace VRC.Udon.Editor.ProgramSources
{
//[CreateAssetMenu(menuName = "VRChat/Udon/Udon Sub Graph Asset", fileName = "New Udon Sub Graph Asset")]
public class UdonSubGraphAsset : ScriptableObject, IUdonGraphDataProvider
{
[SerializeField]
private UdonGraphData graphData = new UdonGraphData();

public UdonGraphData GetGraphData()
{
return graphData;
}
}
}


+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonGraph/UdonSubGraphAsset.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d0a5a452d53dea41823b928cf8e3961
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Udon/Editor/ProgramSources/UdonProgram.meta View File

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

+ 1173
- 0
Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAsset.cs
File diff suppressed because it is too large
View File


+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAsset.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 264ec3c8a1d423f42a144da0df6c5ebe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 19
- 0
Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAssetEditor.cs View File

@@ -0,0 +1,19 @@
using UnityEditor;

namespace VRC.Udon.Editor.ProgramSources
{
[CustomEditor(typeof(UdonProgramAsset))]
public class UdonProgramAssetEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
bool dirty = false;
UdonProgramAsset programAsset = (UdonProgramAsset)target;
programAsset.RunEditorUpdate(null, ref dirty);
if(dirty)
{
EditorUtility.SetDirty(target);
}
}
}
}

+ 11
- 0
Assets/Udon/Editor/ProgramSources/UdonProgram/UdonProgramAssetEditor.cs.meta View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41d70977fa7936441afe41442f1862b2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

+ 8
- 0
Assets/Udon/Editor/Resources.meta View File

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

BIN
Assets/Udon/Editor/Resources/UdonFlowSlot.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonFlowSlot.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 927841c571a405846b3442bc0aa56220
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonFlowSlotFilled.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonFlowSlotFilled.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 3803fec4c7b065042891595e749524cc
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonFlowSlotFilledLight.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonFlowSlotFilledLight.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 7c75c00422f12124faed19bfb8dd96df
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonFlowSlotLight.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonFlowSlotLight.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 610088fc92e5fc64b8c7f9e9c51f2939
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonLogo.png View File


+ 76
- 0
Assets/Udon/Editor/Resources/UdonLogo.png.meta View File

@@ -0,0 +1,76 @@
fileFormatVersion: 2
guid: 0e2cfcbd717e75441b108d3ad9de2d29
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonLogoAlpha.png View File


+ 121
- 0
Assets/Udon/Editor/Resources/UdonLogoAlpha.png.meta View File

@@ -0,0 +1,121 @@
fileFormatVersion: 2
guid: 8cf68553c5a4bb140a6341072891aa88
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonLogoAlphaWhite.png View File


+ 88
- 0
Assets/Udon/Editor/Resources/UdonLogoAlphaWhite.png.meta View File

@@ -0,0 +1,88 @@
fileFormatVersion: 2
guid: d0608d33a4043b2499adb1fee18f2a64
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonNodeAccent.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonNodeAccent.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 17102758d03099542afc7a1808745eaf
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonNodeActiveBackground.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonNodeActiveBackground.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: c0230adfeb2abe242b8d64c7e3bd2adc
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Udon/Editor/Resources/UdonNodeActiveBackgroundLight.png View File


+ 96
- 0
Assets/Udon/Editor/Resources/UdonNodeActiveBackgroundLight.png.meta View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 8289cc16393cd3040a9920e71bfe10bc
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

+ 0
- 0
Assets/Udon/Editor/Resources/UdonNodeBackground.png View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save