initial upload

This commit is contained in:
tom.hempel
2025-09-21 22:42:26 +02:00
commit d03bcd4ba5
6231 changed files with 351582 additions and 0 deletions

View File

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

View File

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

View File

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

View File

@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: efefb40b1e45b0e4ab53ed241bdfb797
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior

View File

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

View File

@ -0,0 +1 @@
{"BodyType":"fullbodyxr","OutfitGender":1,"UpdatedAt":"2025-06-07T17:25:40.959Z","SkinTone":"#d6957b"}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 77e676c752b18604e868fee31889e0da
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1 @@
{"BodyType":"fullbodyxr","OutfitGender":1,"UpdatedAt":"2025-06-05T12:03:31.724Z","SkinTone":"#b16243"}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9652d213cb4bfd848a0d62a3140a8bf0
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,36 @@
fileFormatVersion: 2
guid: 273cb6bd2ee5c094e945c35bc6505a7a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
texturesReadable: 0
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior
- type: 2
code: 20
messages:
- KHR_materials_specular

View File

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

View File

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

View File

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

View File

@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: 818f2787fdeb3cb428484a7e5b968f63
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 814140de63339f14598654b99e920313
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
{"BodyType":"fullbodyxr","OutfitGender":1,"UpdatedAt":"2025-07-06T17:56:12.232Z","SkinTone":"#d6957b"}

View File

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

View File

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

View File

@ -0,0 +1,36 @@
fileFormatVersion: 2
guid: dae291a3f624bde4da0cfa5eca52f24e
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
texturesReadable: 0
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior
- type: 2
code: 20
messages:
- KHR_materials_specular

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 47ae63c8fffc48d4ba481a109e0c7bae
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1 @@
{"BodyType":"fullbodyxr","OutfitGender":1,"UpdatedAt":"2025-06-20T16:24:51.344Z","SkinTone":"#b76c4e"}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 00ca93cccf41e8f43a3857586add9b19
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,31 @@
fileFormatVersion: 2
guid: a22c29a9c3e63704ebf37e4a24aa00a9
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior

View File

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

View File

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

View File

@ -0,0 +1 @@
{"BodyType":"fullbodyxr","OutfitGender":2,"UpdatedAt":"2025-07-06T17:48:44.268Z","SkinTone":"#b7653e"}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 49c81d17316e0cc4cb5a684c384d3705
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,36 @@
fileFormatVersion: 2
guid: ef28ecd5c4ba32941ab56eb94c74be54
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 715df9372183c47e389bb6e19fbc3b52, type: 3}
editorImportSettings:
generateSecondaryUVSet: 0
importSettings:
nodeNameMethod: 1
animationMethod: 2
generateMipMaps: 1
texturesReadable: 0
defaultMinFilterMode: 9729
defaultMagFilterMode: 9729
anisotropicFilterLevel: 1
instantiationSettings:
mask: -1
layer: 0
skinUpdateWhenOffscreen: 1
lightIntensityFactor: 1
sceneObjectCreation: 2
assetDependencies: []
reportItems:
- type: 2
code: 20
messages:
- KHR_materials_ior
- type: 2
code: 20
messages:
- KHR_materials_specular

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 36a5a50a7e7673647837e7992aa26808
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,472 @@
# Changelog
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [7.3.1] - 2024.10.30
## Updated
- Re-exporting package for asset store with updated dependencies
## [7.3.0] - 2024.10.22
## Updated
- auth-related requests now use auth-service endpoints [#317](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/317)
- updated shader variants to fix issues various material issues
## Fixed
- Fixed an issue causing Out of Bounds exception in WebGL voice handler [#322](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/322)
## Added
- DestroyMesh class can be used to destroy manually destroy mesh, materials and textures to prevent memory leaks
## [7.2.0] - 2024.09.06
## Updated
- Updated handling of response data to reduce garbage allocation [#314](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/314)
## Fixed
- Preserve AssetId property in IAssetData [#313](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/313)
## [7.1.1] - 2024.07.25
## Fixed
- Fixed an issue causing json parsing to fail on iFrame events [#311](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/311/)
## [7.1.0] - 2024.07.16
## Updated
- Reworked shader overrides to support mapping of other property types [#306](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/306)
## Fixed
- Fixed an issue caused by missing bones on avatar template prefabs [#310](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/310/)
## [7.0.0] - 2024.07.01
## Updated
- Loading circle animation now using MMecanim animation [#302](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/302)
- Removed unnecessary assets from Resources folder [#303](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/303)
- Updated Template avatar assets [#300](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/300)
- Avatar Body type now moved to CoreSettings [#290](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/290)
### Added
- Added support for hero customization assets (costumes) [#301](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/301)
- Templates can now be filtered by Bodytype [#296](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/296)
### Fixed
- Fixed an issue causing invalid load settings in Avatar Loader window [#298](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/298)
## [6.3.1] - 2024.06.18
### Fixed
- Allow cache to be loaded from previous versions, where bodyType was stored as an integer [#293](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/293)
## [6.3.0] - 2024.06.11
### Updated
- XR animation avatars now have DOF enabled by default [#288](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/288)
- Updated InCreatorAvatarLoader to use avatar config [#286](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/286)
- Avatar Creator Icon categories updated [#272](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/272)
### Fixed
- Fixed an issue preventing LOD's from updating [#277](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/277)
- An issue causing multiple signup requests [#275](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/275)
### Added
- Avatar template type filter [#270](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/270)
- Handle failed body shape requests [#281](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/281)
- Option to filter Templates by gender [#273](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/273)
## [6.2.4] - 2024.05.03
### Fixed
- Updated XR template prefab meshes to prevent missing bone references to fix mesh transfer [#266](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/266)
## [6.2.3] - 2024.04.29
### Fixed
- Reverted update to GetMeshRenderer method [#264](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/264)
## [6.2.2] - 2024.04.29
### Updated
- Updated XR template avatar to have separated head mesh [#261](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/261)
- Improved GetMeshRenderer() method to exclude invalid mesh renderers [#261](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/261)
### Fixed
- Fixed issue with XR animation avatars
## [6.2.1] - 2024.04.23
### Fixed
- An issue with gender and avatarID not to be set in AvatarManager [#260](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/260)
## [6.2.0] - 2024.04.22
### Added
- XR template avatar added to the Resources folder [#258](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/258)
- Avatar Creator now supports body shapes [#252](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/252)
- support for unknown exceptions [#251](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/251)
- Simple PanelManager script
- Optional define symbol to remove camera permissions from the Android manifest [#259](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/259)
## Updated
- Removed use of tuples and deprecated old methods [#257](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/257)
## [6.1.2] - 2024.04.03
### Updated
- XR animation avatars updated to support with latest xr avatar updates
## [6.1.1] - 2024.04.03
### Updated
- Avatars done with a photo are now added as a draft avatars [#254](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/254)
## [6.1.0] - 2024.03.04
### Updated
- AvatarMeshHelper now supports multiple mesh and material transfer. [#241](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/241)
### Added
- GetHeadMeshes method to AvatarMeshHelper to get head related meshes from an avatar. [#242](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/242)
- Template avatar with all possible meshes is added to the Resources folder.
## [6.0.1] - 2024.02.26
### Updated
- Updated default render settings to fix an issue causing incorrect halfbody avatar renders [#238](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/238)
## [6.0.0] - 2024.02.19
### Updated
- **BREAKING: Renamed Avatar Create Samples** [#210](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/210) _This change
may require updates to existing references in your projects._
- Small fix for button icon resizing [#215](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/215)
- LoginWithCode can now merge avatars into RPM account [#219](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/219)
- Recover hair when headwear is removed [#224](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/224)
- Added extra check to prevent settings override [#226](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/226)
### Added
- Logout Element for Avatar Creator [#216](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/216)
- New iFrame Events to WebFrameHandler [#212](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/212)
- Added support for XR Avatar skeleton [#217](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/217)
- Added Avatar List element [#218](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/218)
- Account creation and login elements in Avatar Creator sample [#230](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/230)
### Removed
- Quickstart Parameter from UrlConfig [#221](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/221)
- Selfie to Avatar Element* [#220](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/220)
- Removed WebView auto installation [#208](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/208)
## [5.0.0] - 2024.01.12
### Updated
- Refactor and extracted shared logic from network
packages [#148](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/148)
- Replaced api urls in samples with models urls [#152](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/152)
- Added com.unity.cloud.gltfast as a dependency and removed auto install of gltfast from git
url [#155](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/155)
- Updated to GLTFast 6.0.1 [#157](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/157)
- Replaced use of ienumerator coroutines with
async/await [#172](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/172)
- Request class names updated to be more uniform [#173](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/173)
- Endpoint classes removed and refactored [#174](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/174)
- Added avatar creator POC sample using new
elements [#182](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/182)
- Removed "I don't have an account" checkbox from setup
guide [#184](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/184)
- Restructure of avatar creator samples [#185](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/185)
- Class and folder restructure to match Unity package
standards [#190](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/190)
- Namespaces added to some scripts to meet asset store
requirements [#195](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/195)
- Ready Player Me top toolbar menu is under `Tools/Ready Player Me` to comply with Asset Store
requirements [#195](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/195)
- Samples renamed for Asset Store version of package and paths updated
accordingly [#198](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/198)
- Quick start sample animations updated [#200](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/200)
- Draco compression package version updated [#202](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/202)
### Added
- Add gender select element for Avatar Creator [#159](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/159)
- Basic login element for Avatar Creator [#160](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/160)
- Photo capture element for Avatar Creator [#162](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/162)
- Avatar template element for Avatar Creator [#164](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/164)
- Selfie element for Avatar Creator [#166](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/166)
- Asset panel element for Avatar Creator [#175](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/175)
- Account creation element for Avatar Creator [#178](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/178)
- Avatar preview element for Avatar Creator [#181](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/181)
- Fixed some issues related to paths like in the Graphics Setting
Utility [#195](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/195)
- Shader override property added to avatar config [#199](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/199)
### Fixed
- Fix for handling pasted url text in subdomain
field [#183](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/183)
- Added permission and orientation fix to photo capture
element [#192](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/192)
- Added Panel Switcher clear functionality to fix issues related to relaunching the
Creator [#194](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/194)
- Namespaces added to some scripts to meet asset store
requirements [#195](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/195)
## [4.1.2] - 2023.12.20
### Fixed
- Add preserve attribute to CategoryConverter in
AvatarCreator [#193](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/193)
## [4.1.1] - 2023.11.29
### Fixed
- Fixed json converters in AvatarCreator getting stripped on android or webgl
builds [#188](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/188)
## [4.1.0] - 2023.11.29
### Updated
- Replaced API URLs with model URLs for shortcodes [#152](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/152)
- Updated render api and samples [#147](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/147)
### Added
- Added app id to setup guide [#145](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/145)
## [4.0.1] - 2023.11.14
### Fixed
- Fixed an issue causing avatars to be stored locally even if caching was
disabled [#150](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/150)
## [4.0.0] - 2023.11.01
### Breaking Changes
- Merge avatar creator into core [#135](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/135).
- AvatarProcessor no longer searches and replaces existing
avatar [#138](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/138)
### Added
- Show Avatar Creator sample button in guide [#141](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/141)
### Updated
- Merged related samples into single folders [#139](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/139)
## [3.4.0] - 2023.10.24
### Added
- Breaking change popup [#136](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/136)
### Updated
- Disable use demo toggle in setup guide [#131](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/131)
- Refactor define symbol add and remove logic [#133](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/133)
## [3.3.0] - 2023.10.05
### Added
- Moved core iframe and url logic from WebView
package [#125](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/125)
### Updated
- Refactored core settings handler [#124](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/124)
- Centred all editor window content [#122](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/122)
## [3.2.4] - 2023.09.28
### Fixed
- An issue causing WebView to be auto imported if
removed [#126](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/126)
## [3.2.3] - 2023.09.11
### Fixed
- An issue causing settings to be recreated when not
needed [#123](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/123)
## [3.2.2] - 2023.09.07
### Fixed
- An issue with module installer causing errors when importing on some Windows
machines [#117](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/117)
## [3.2.1] - 2023.08.28
### Fixed
-Issue of missing mesh references when prefabs were created by avatar loader
window [#109](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/109)
## [3.2.0] - 2023.08.24
### Added
- App Id is added to header of all web requests
### Fixed
- GLTF scripting define symbol not getting assigned
## [3.1.1] - 2023.08.11
### Fixed
- Fixed an issue causing analytics events being sent to development
environment [#102](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/102)
- Re-added RPM define symbol required for supporting
packages [#102](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/102)
## [3.1.0] - 2023.08.08
### Added
* Personal avatar loading in quick start https://github.com/readyplayerme/rpm-unity-sdk-core/pull/97
* Runtime analytics to quick start https://github.com/readyplayerme/rpm-unity-sdk-core/pull/98
## [3.0.0] - 2023.07.31
### Added
- **BREAKING: All scripts and assets from Avatar
Loader** [#87](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/87)
- Module installer now automatically removes Avatar Loader after
update [#89](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/89)
- New Integration guide editor window [#91](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/91)
### Removed
- **BREAKING: all references to ReadyPlayerMe.AvatarLoader namespace** [#87](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/87)
### Updated
- Moved GltFast dependent code behind scripting define
symbol [#87](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/87)
- Avatar config processor now uses new mesh LOD
parameter [#90](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/90)
- Setup guide window improvements [#91](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/91)
## [1.3.0] - 2023.05.29
### Added
- Import timeout to module installer [#70](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/70)
- Add new setup guide window [#71](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/71)
- Added function for folder size in MB [#72](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/72)
### Fixed
- Various editor window layout fixes [#73](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/73)
## [1.2.0] - 2023.04.18
### Added
- Support for response codes [#62](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/62)
### Updated
- Refactor of WebRequestDispatcher [#59](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/59)
### Fixed
- Fixed an issue with the popup don't ask again pref was not updating
correctly [#58](https://github.com/readyplayerme/rpm-unity-sdk-core/pull/58)
## [1.1.0] - 2023.03.21
### Added
- Quick start sample popup
- Added operation completed event
- Discussion link to README.md
### Updated
- OpenUPM installation added to README.md
## [1.0.0] - 2023.02.20
### Added
- Optional sdk logging
- Don't ask again option for update check
### Updated
- PartnerSubdomainSettings refactored to a CoreSettings scriptable object
### Fixed
- Core settings asset now automatically created if it is missing
- Various bug fixes and improvements
## [0.2.0] - 2023.02.08
### Added
- Optional sdk logging
### Updated
- PartnerSubdomainSettings refactored to a CoreSettings scriptable object
### Fixed
- Various bug fixes and improvements
## [0.1.0] - 2023.01.22
### Updated
- Repository names in module list + version numbers
## [0.1.0] - 2023.01.12
### Added
- Inline code documentation
- Contribution guide and code of conduct
- Module installer and updater for handling package installation
### Updated
- A big refactor of code and classes
### Fixed
- Various bug fixes and improvements

View File

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

View File

@ -0,0 +1,80 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address, without their explicit permission
* Contacting individual members, contributors, or leaders privately, outside designated community mechanisms, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at support@readyplayer.me. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at <https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at <https://www.contributor-covenant.org/faq>. Translations are available at <https://www.contributor-covenant.org/translations>.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7879103106cd18d47b36fbbd7faf0b2c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,136 @@
# Welcome to the Ready Player Me Unity SDK (Core) contributing guide
Thank you for investing your time in contributing to our project! Any contribution you make will be reflected on [https://github.com/readyplayerme/Unity-Core](https://github.com/readyplayerme/Unity-Core) :sparkles:.
Read our [Code of Conduct](./CODE_OF_CONDUCT.md) to keep our community approachable and respectable.
In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
Use the table of contents icon on the top left corner of this document to get to a specific section of this guide quickly.
## New contributor guide
To get an overview of the project, read the [README](README.md). Here are some resources to help you get started with open source contributions:
- [FAQ](#faq)
- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
- [Code style guide](https://github.com/readyplayerme/rpm-unity-sdk-core/blob/main/style-guidelines.md)
## FAQ
#### **Did you find a bug?**
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/readyplayerme/Unity-core/issues).
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/readyplayerme/Unity-core/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
* If possible, use the relevant bug report templates to create the issue. Simply copy the content of the appropriate template into a .rb file, make the necessary changes to demonstrate the issue, and **paste the content into the issue description**:
* [**Generic template** for other issues](https://github.com/readyplayerme/Unity-Core/blob/develop/.github/pull_request_template.md)
* If you would like to contact us directly to report an issue or for general support requests contact our Ready Player Me Support email [support@readyplayer.me](mailto:support@readyplayer.me).
#### **Did you write a patch that fixes a bug?**
* Open a new GitHub pull request with the patch.
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
* Before submitting, please read the [Contributing to Ready Player Me Unity SDK](#) guide to know more about our coding conventions and best practices.
#### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability will generally not be accepted.
#### **Do you intend to add a new feature or change an existing one?**
* Suggest your change to the Ready Player Me support email [support@readyplayer.me](mailto:support@readyplayer.me) and start writing code.
* **Do not open an issue on GitHub** until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
#### **Do you have questions about the source code?**
* Ask any question about how to use the Ready Player Me Unity SDK in the [Ready Player Me support email](mailto:support@readyplayer.me).
## Issues
#### Create a new issue
If you spot a problem with the docs, [search if an issue already exists](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments). If a related issue doesn't exist, you can open a new issue using a relevant [issue form](https://github.com/github/docs/issues/new/choose).
#### Solve an issue
Scan through our [existing issues](https://github.com/github/docs/issues) to find one that interests you. You can narrow down the search using `labels` as filters. See [Labels](/contributing/how-to-use-labels.md) for more information. As a general rule, we dont assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix.
### Make Changes
#### Make changes locally
1. [Install Git LFS](https://docs.github.com/en/github/managing-large-files/versioning-large-files/installing-git-large-file-storage).
2. Fork the repository.
- Using GitHub Desktop:
- [Getting started with GitHub Desktop](https://docs.github.com/en/desktop/installing-and-configuring-github-desktop/getting-started-with-github-desktop) will guide you through setting up Desktop.
- Once Desktop is set up, you can use it to [fork the repo](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop)!
- Using the command line:
- [Fork the repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until you're ready to merge them.
4. Create a working branch and start with your changes!
### Commit your update
We encourage following the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format when it comes to writing commit messages. Our package repositories come with a .githooks folder that has a commit-msg file that can enforce this.
To set this up you just need to configure git's hookspath folder to point there.
You can do this by
1. Open the terminal
2. Navigate to the root folder of this repository
3. Run the following command
`git config core.hooksPath .githooks`
Commit the changes once you are happy with them. Don't forget to [self-review](#self-review) to speed up the review process:zap:.
### Self review
You should always review your own PR first.
For content changes, make sure that you:
- [ ] Confirm that the changes meet the user experience and goals outlined in the content design plan (if there is one).
- [ ] Compare your pull request's source changes to staging to confirm that the output matches the source and that everything is rendering as expected. This helps spot issues like typos, content that doesn't follow the [style guide](https://github.com/readyplayerme/rpm-unity-sdk-core/blob/main/style-guidelines.md), or content that isn't rendering due to versioning problems. Remember that lists and tables can be tricky.
- [ ] Review the content for technical accuracy.
- [ ] Review the entire pull request using the [translations guide for writers](./translations/for-writers.md).
- [ ] Copy-edit the changes for grammar, spelling, and adherence to the [style guide](https://github.com/readyplayerme/rpm-unity-sdk-core/blob/main/style-guidelines.md).
- [ ] Check new or updated Liquid statements to confirm that versioning is correct.
- [ ] If there are any failing checks in your PR, troubleshoot them until they're all passing.
### Pull Request
When you're finished with the changes, create a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests).
- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
Once you submit your PR, a team member will review your proposal. We may ask questions or request additional information.
- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues.
### Your PR is merged!
Congratulations :tada::tada: The GitHub team thanks you :sparkles:.
Once your PR is merged, your contributions will be publicly visible on the [GitHub docs](https://docs.github.com/en).
Now that you are part of the GitHub docs community, see how else you can [contribute to the docs](/contributing/types-of-contributions.md).
Thanks! :heart: :heart: :heart:
Ready Player Me Team

View File

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

View File

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

View File

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

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace ReadyPlayerMe.AvatarCreator.Editor
{
[CustomPropertyDrawer(typeof(AssetTypeFilterAttribute))]
public class AssetTypeFilterDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var assetTypeAttribute = attribute as AssetTypeFilterAttribute;
if (property.propertyType == SerializedPropertyType.Enum)
{
EditorGUI.BeginProperty(position, label, property);
EditorGUI.BeginChangeCheck();
// Get the current enum value
var currentEnumValue = (AssetType) property.enumValueIndex;
var filteredEnumNames = new List<string>();
foreach (var enumName in Enum.GetNames(typeof(AssetType)))
{
var enumFieldInfo = typeof(AssetType).GetField(enumName);
var enumAttribute = (AssetTypeFilterAttribute) Attribute.GetCustomAttribute(enumFieldInfo, typeof(AssetTypeFilterAttribute));
if (enumAttribute == null) continue;
var filter = (AssetFilter) Enum.Parse(typeof(AssetFilter), enumAttribute.filter.ToString());
if (filter == assetTypeAttribute?.filter)
{
filteredEnumNames.Add(enumName);
}
}
// Display the dropdown with filtered enum values
var newIndex = EditorGUI.Popup(position, label.text, Array.IndexOf(filteredEnumNames.ToArray(), currentEnumValue.ToString()), filteredEnumNames.ToArray());
// Set the new enum value if it has changed
if (EditorGUI.EndChangeCheck())
{
property.enumValueIndex = (int) Enum.Parse(typeof(AssetType), filteredEnumNames[newIndex]);
}
EditorGUI.EndProperty();
}
else
{
EditorGUI.LabelField(position, label.text, "Use AssetType with Enum.");
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6add29e0a6c64d6786c6742dfbd87acf
timeCreated: 1702392584

View File

@ -0,0 +1,19 @@
{
"name": "ReadyPlayerMe.AvatarCreator.Editor",
"rootNamespace": "",
"references": [
"ReadyPlayerMe.Core",
"ReadyPlayerMe.AvatarCreator"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

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

View File

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

Binary file not shown.

View File

@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: 97cb8e496ac634f4ba4c0a1bb899c8da
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
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
vTOnly: 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: 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: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,132 @@
fileFormatVersion: 2
guid: 38a8827f446904c4c802c5b7850e3ff0
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
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
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
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: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 32
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ac1c518000284e8ea25dfdd1284e0f16
timeCreated: 1657013631

View File

@ -0,0 +1,301 @@
using System;
using System.Collections.Generic;
using ReadyPlayerMe.Core.Editor;
using UnityEditor;
using UnityEngine;
using static ReadyPlayerMe.Core.Analytics.Constants;
namespace ReadyPlayerMe.Core.Analytics
{
public class AmplitudeEditorLogger : IAnalyticsEditorLogger
{
private const string SDK_TARGET = "Unity";
private readonly Dictionary<HelpSubject, string> helpDataMap = new()
{
{ HelpSubject.AvatarCaching, "avatar caching" },
{ HelpSubject.Subdomain, "subdomain" },
{ HelpSubject.AvatarConfig, "avatar config" },
{ HelpSubject.GltfDeferAgent, "gltf defer agent" },
{ HelpSubject.LoadingAvatars, "download avatar into scene" },
{
HelpSubject.Avatars, "avatars body type"
}
};
private bool isEnabled;
private readonly AppData appData;
public AmplitudeEditorLogger(bool isEnabled)
{
this.isEnabled = isEnabled;
appData = ApplicationData.GetData();
}
public void Enable()
{
isEnabled = true;
if (!AmplitudeEventLogger.IsSessionIdSet())
{
GenerateSessionId();
}
ToggleAnalytics(true);
}
public void Disable()
{
ToggleAnalytics(false);
isEnabled = false;
AmplitudeEventLogger.SetSessionId(0);
}
public void IdentifyUser()
{
if (!isEnabled) return;
if (!AmplitudeEventLogger.IsSessionIdSet())
{
GenerateSessionId();
}
SetUserProperties();
}
public void LogOpenProject()
{
if (!isEnabled) return;
GenerateSessionId();
AmplitudeEventLogger.LogEvent(EventName.OPEN_PROJECT);
}
public void LogCloseProject()
{
LogEvent(EventName.CLOSE_PROJECT);
}
public void LogOpenDocumentation(string target)
{
LogEvent(EventName.OPEN_DOCUMENTATION, new Dictionary<string, object>
{
{ Properties.TARGET, target }
});
}
public void LogOpenFaq(string target)
{
LogEvent(EventName.OPEN_FAQ, new Dictionary<string, object>
{
{ Properties.TARGET, target }
});
}
public void LogOpenDiscord(string target)
{
LogEvent(EventName.OPEN_DISCORD, new Dictionary<string, object>
{
{ Properties.TARGET, target }
});
}
public void LogLoadAvatarFromDialog(string avatarUrl, bool eyeAnimation, bool voiceHandler)
{
LogEvent(EventName.LOAD_AVATAR_FROM_DIALOG, new Dictionary<string, object>
{
{ Properties.AVATAR_URL, avatarUrl },
{ Properties.EYE_ANIMATION, eyeAnimation },
{ Properties.VOICE_HANDLER, voiceHandler }
});
}
public void LogUpdatePartnerURL(string previousSubdomain, string newSubdomain)
{
LogEvent(EventName.UPDATED_PARTNER_URL, new Dictionary<string, object>
{
{ Properties.PREVIOUS_SUBDOMAIN, previousSubdomain },
{ Properties.NEW_SUBDOMAIN, newSubdomain }
}, new Dictionary<string, object>
{
{ Properties.SUBDOMAIN, newSubdomain }
});
}
public void LogOpenDialog(string dialog)
{
LogEvent(EventName.OPEN_DIALOG, new Dictionary<string, object>
{
{ Properties.DIALOG, dialog }
});
}
public void LogBuildApplication(string target, string appName, bool productionBuild)
{
LogEvent(EventName.BUILD_APPLICATION, new Dictionary<string, object>
{
{ Properties.TARGET, target },
{ Properties.APP_NAME, appName },
{ Properties.PRODUCTION_BUILD, productionBuild },
{ Properties.APP_IDENTIFIER, Application.identifier }
});
}
public void LogMetadataDownloaded(double duration)
{
LogEvent(EventName.METADATA_DOWNLOADED, new Dictionary<string, object>
{
{ Properties.DURATION, duration }
});
}
public void LogAvatarLoaded(double duration)
{
LogEvent(EventName.AVATAR_LOADED, new Dictionary<string, object>
{
{ Properties.DURATION, duration }
});
}
public void LogCheckForUpdates()
{
LogEvent(EventName.CHECK_FOR_UPDATES);
}
public void LogSetLoggingEnabled(bool isLoggingEnabled)
{
LogEvent(EventName.SET_LOGGING_ENABLED, new Dictionary<string, object>
{
{ Properties.LOGGING_ENABLED, isLoggingEnabled }
});
}
public void LogSetCachingEnabled(bool isCachingEnabled)
{
LogEvent(EventName.SET_CACHING_ENABLED, new Dictionary<string, object>
{
{ Properties.CACHING_ENABLED, isCachingEnabled }
});
}
public void LogClearLocalCache()
{
LogEvent(EventName.CLEAR_LOCAL_CACHE);
}
public void LogViewPrivacyPolicy()
{
LogEvent(EventName.PRIVACY_POLICY);
}
public void LogShowInExplorer()
{
LogEvent(EventName.SHOW_IN_EXPLORER);
}
public void LogFindOutMore(HelpSubject subject)
{
LogEvent(EventName.FIND_OUT_MORE, new Dictionary<string, object>
{
{ Properties.CONTEXT, helpDataMap[subject] }
});
}
public void LogOpenSetupGuide()
{
LogEvent(EventName.OPEN_SETUP_GUIDE);
}
public void LogOpenIntegrationGuide()
{
LogEvent(EventName.OPEN_INTEGRATION_GUIDE);
}
public void LogLoadQuickStartScene()
{
LogEvent(EventName.LOAD_QUICK_START_SCENE);
}
public void LogOpenAvatarDocumentation()
{
LogEvent(EventName.OPEN_AVATAR_DOCUMENTATION);
}
public void LogOpenAnimationDocumentation()
{
LogEvent(EventName.OPEN_ANIMATION_DOCUMENTATION);
}
public void LogOpenAvatarCreatorDocumentation()
{
LogEvent(EventName.OPEN_AVATAR_CREATOR_DOCUMENTATION);
}
public void LogOpenOptimizationDocumentation()
{
LogEvent(EventName.OPEN_OPTIMIZATION_DOCUMENTATION);
}
public void LogAvatarCreatorSampleImported()
{
LogEvent(EventName.AVATAR_CREATOR_SAMPLE_IMPORTED);
}
public void LogPackageInstalled(string id, string name)
{
LogEvent(EventName.INSTALL_PACKAGE, new Dictionary<string, object>
{
{ "id", id },
{ "name", name }
});
}
private void SetUserProperties()
{
var userProperties = new Dictionary<string, object>
{
{ Properties.SDK_SOURCE_URL, PackageManagerHelper.GetSdkPackageSourceUrl() },
{ Properties.ENGINE_VERSION, appData.UnityVersion },
{ Properties.RENDER_PIPELINE, appData.RenderPipeline },
{ Properties.SUBDOMAIN, appData.PartnerName },
{ Properties.APP_NAME, PlayerSettings.productName },
{ Properties.SDK_TARGET, SDK_TARGET },
{ Properties.APP_IDENTIFIER, Application.identifier },
{ Properties.ALLOW_ANALYTICS, true }
};
var modules = ModuleList.GetInstalledModuleVersionDictionary();
foreach (var module in modules)
{
userProperties.Add(module.Key, module.Value);
}
LogEvent(EventName.SET_USER_PROPERTIES, null, userProperties);
}
private void GenerateSessionId()
{
AmplitudeEventLogger.SetSessionId(DateTimeOffset.Now.ToUnixTimeMilliseconds());
}
private void ToggleAnalytics(bool allow)
{
LogEvent(EventName.ALLOW_ANALYTICS, new Dictionary<string, object>
{
{ Properties.ALLOW, allow }
}, new Dictionary<string, object>
{
{ Properties.ENGINE_VERSION, appData.UnityVersion },
{ Properties.RENDER_PIPELINE, appData.RenderPipeline },
{ Properties.SUBDOMAIN, appData.PartnerName },
{ Properties.APP_NAME, PlayerSettings.productName },
{ Properties.SDK_TARGET, "Unity" },
{ Properties.APP_IDENTIFIER, Application.identifier },
{ Properties.ALLOW_ANALYTICS, allow }
});
}
private void LogEvent(string eventName, Dictionary<string, object> eventProperties = null, Dictionary<string, object> userProperties = null)
{
if (!isEnabled) return;
AmplitudeEventLogger.LogEvent(eventName, eventProperties, userProperties);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ed6804cd2c9d4b9bb873a4c1cd6af062
timeCreated: 1657032252

View File

@ -0,0 +1,31 @@
using ReadyPlayerMe.Core.Editor;
namespace ReadyPlayerMe.Core.Analytics
{
public static class AnalyticsEditorLogger
{
public static readonly IAnalyticsEditorLogger EventLogger;
static AnalyticsEditorLogger()
{
IsEnabled = CoreSettingsHandler.CoreSettings.EnableAnalytics;
EventLogger = new AmplitudeEditorLogger(IsEnabled);
}
public static bool IsEnabled { get; private set; }
public static void Enable()
{
IsEnabled = true;
EventLogger.Enable();
CoreSettingsSetter.SetEnableAnalytics(true);
}
public static void Disable()
{
EventLogger.Disable();
IsEnabled = false;
CoreSettingsSetter.SetEnableAnalytics(false);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fc2862cbf129461eaa91ca136d9d045d
timeCreated: 1658921992

View File

@ -0,0 +1,74 @@
namespace ReadyPlayerMe.Core.Analytics
{
public static class Constants
{
public static class EventName
{
public const string OPEN_PROJECT = "open project";
public const string OPEN_DOCUMENTATION = "open documentation";
public const string OPEN_FAQ = "open faq";
public const string OPEN_DISCORD = "open discord";
public const string LOAD_AVATAR_FROM_DIALOG = "load avatar from dialog";
public const string UPDATED_PARTNER_URL = "updated partner url";
public const string ALLOW_ANALYTICS = "allow analytics";
public const string OPEN_DIALOG = "open dialog";
public const string BUILD_APPLICATION = "build application";
public const string CLOSE_PROJECT = "close project";
public const string METADATA_DOWNLOADED = "metadata downloaded";
public const string AVATAR_LOADED = "avatar loaded";
public const string SET_USER_PROPERTIES = "set user properties";
public const string CLEAR_LOCAL_CACHE = "clear local cache";
public const string SHOW_IN_EXPLORER = "show in explorer";
public const string SET_LOGGING_ENABLED = "set logging enabled";
public const string SET_CACHING_ENABLED = "set caching enabled";
public const string CHECK_FOR_UPDATES = "check for updates";
public const string PRIVACY_POLICY = "view privacy policy";
public const string FIND_OUT_MORE = "find out more";
public const string OPEN_SETUP_GUIDE = "open setup guide";
public const string OPEN_INTEGRATION_GUIDE = "open integration guide";
public const string LOAD_QUICK_START_SCENE = "load quick start scene";
public const string OPEN_AVATAR_DOCUMENTATION = "open avatar documentation";
public const string OPEN_ANIMATION_DOCUMENTATION = "open animation documentation";
public const string OPEN_AVATAR_CREATOR_DOCUMENTATION = "open avatar creator documentation";
public const string OPEN_OPTIMIZATION_DOCUMENTATION = "open optimization documentation";
public const string AVATAR_CREATOR_SAMPLE_IMPORTED = "Avatar creator sample imported";
public const string INSTALL_PACKAGE = "install unity package";
}
public static class Properties
{
public const string SDK_SOURCE_URL = "sdk source url";
public const string ENGINE_VERSION = "engine version";
public const string RENDER_PIPELINE = "render pipeline";
public const string SUBDOMAIN = "subdomain";
public const string APP_NAME = "app name";
public const string SDK_TARGET = "sdk target";
public const string TARGET = "target";
public const string EYE_ANIMATION = "eye animation";
public const string VOICE_HANDLER = "voice handler";
public const string PREVIOUS_SUBDOMAIN = "previous subdomain";
public const string NEW_SUBDOMAIN = "new subdomain";
public const string ALLOW = "allow";
public const string DIALOG = "dialog";
public const string PRODUCTION_BUILD = "production build";
public const string AVATAR_URL = "avatar url";
public const string APP_IDENTIFIER = "app identifier";
public const string ALLOW_ANALYTICS = "allow analytics";
public const string DURATION = "duration";
public const string LOGGING_ENABLED = "logging enabled";
public const string CACHING_ENABLED = "caching enabled";
public const string CONTEXT = "context";
}
public static class Links
{
public const string DOCS_PARTNERS_LINK = "https://docs.readyplayer.me/ready-player-me/what-is-ready-player-me#url";
public const string DOCS_DEFER_AGENT_LINK = "https://docs.readyplayer.me/ready-player-me/integration-guides/unity/optimize/defer-agents";
public const string DOCS_AVATAR_LOADER_WINDOW = "https://docs.readyplayer.me/ready-player-me/integration-guides/unity/avatar-loader-window";
public const string DOCS_AVATAR_CONFIG_LINK = "https://docs.readyplayer.me/ready-player-me/integration-guides/unity/optimize/avatar-configuration";
public const string DOCS_AVATAR_CACHING = "https://docs.readyplayer.me/ready-player-me/integration-guides/unity/optimize/avatar-caching";
public const string AVATARS = "https://docs.readyplayer.me/ready-player-me/api-reference/avatars";
public const string APP_ID = "https://docs.readyplayer.me/ready-player-me/integration-guides/unity/avatar-creator/custom-avatar-creator#prerequisites";
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e7e6b1c7b30a462e971d46dd09b38bdf
timeCreated: 1657013679

View File

@ -0,0 +1,12 @@
namespace ReadyPlayerMe.Core.Analytics
{
public enum HelpSubject
{
AvatarCaching,
Subdomain,
AvatarConfig,
GltfDeferAgent,
LoadingAvatars,
Avatars
}
}

View File

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

View File

@ -0,0 +1,36 @@
namespace ReadyPlayerMe.Core.Analytics
{
public interface IAnalyticsEditorLogger
{
void Enable();
void Disable();
void IdentifyUser();
void LogOpenProject();
void LogCloseProject();
void LogOpenDocumentation(string target);
void LogOpenFaq(string target);
void LogOpenDiscord(string target);
void LogLoadAvatarFromDialog(string avatarUrl, bool eyeAnimation, bool voiceHandler);
void LogUpdatePartnerURL(string previousSubdomain, string newSubdomain);
void LogOpenDialog(string dialog);
void LogBuildApplication(string target, string appName, bool productionBuild);
void LogMetadataDownloaded(double duration);
void LogAvatarLoaded(double duration);
void LogCheckForUpdates();
void LogSetLoggingEnabled(bool isLoggingEnabled);
void LogSetCachingEnabled(bool isCachingEnabled);
void LogClearLocalCache();
void LogViewPrivacyPolicy();
void LogShowInExplorer();
void LogFindOutMore(HelpSubject subject);
void LogOpenSetupGuide();
void LogOpenIntegrationGuide();
void LogLoadQuickStartScene();
void LogOpenAvatarDocumentation();
void LogOpenAnimationDocumentation();
void LogOpenAvatarCreatorDocumentation();
void LogOpenOptimizationDocumentation();
void LogAvatarCreatorSampleImported();
void LogPackageInstalled(string id, string name);
}
}

View File

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

View File

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

View File

@ -0,0 +1,16 @@
using System;
using System.Text.RegularExpressions;
namespace ReadyPlayerMe.Core.Editor
{
public static class StringExtensions
{
private const string SHORT_CODE_REGEX = "^[A-Z0-9]{6}$";
public static bool IsUrlShortcodeValid(this string urlString)
{
return !string.IsNullOrEmpty(urlString) &&
(Regex.Match(urlString, SHORT_CODE_REGEX).Length > 0 || Uri.IsWellFormedUriString(urlString, UriKind.Absolute) && urlString.EndsWith(".glb"));
}
}
}

View File

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

View File

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

View File

@ -0,0 +1,48 @@
using System;
using ReadyPlayerMe.Core.Analytics;
using UnityEditor;
namespace ReadyPlayerMe.Core.Editor
{
/// <summary>
/// This class serves as a way of tracking when the Unity project (editor) is initially opened so that functions can be run at this point.
/// </summary>
[InitializeOnLoad]
public static class EntryPoint
{
private const string SESSION_STARTED_KEY = "SessionStarted";
/// Event for when package is imported or when project with package is opened.
public static Action Startup;
/// <summary>
/// This constructor is used to subscribe to the <see cref="EditorApplication.update"/> event.
/// </summary>
static EntryPoint()
{
if (!SessionState.GetBool(SESSION_STARTED_KEY, false))
{
SessionState.SetBool(SESSION_STARTED_KEY, true);
EditorApplication.update += Update;
}
}
/// <summary>
/// This function is called on every Editor <see cref="EditorApplication.update"/>.
/// It is used to trigger moduleUpdater to check for updates when the Unity Project launches.
/// </summary>
private static void Update()
{
EditorApplication.update -= Update;
AnalyticsEditorLogger.EventLogger.LogOpenProject();
AnalyticsEditorLogger.EventLogger.IdentifyUser();
Startup?.Invoke();
EditorApplication.quitting += OnQuit;
}
private static void OnQuit()
{
AnalyticsEditorLogger.EventLogger.LogCloseProject();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71bde74e39624415805f1552261fd75e
timeCreated: 1657016805

View File

@ -0,0 +1,37 @@
using System;
namespace ReadyPlayerMe.Core.Editor
{
/// <summary>
/// Structure <c>ModuleInfo</c> describes a Ready Player Me Module or Unity package.
/// </summary>
[Serializable]
public struct ModuleInfo
{
public string name;
public string gitUrl;
public string branch;
public string version;
/// <summary>
/// Get the Unity package identifier.
/// </summary>
/// <returns>
/// A <c>string</c> representing the Unity packages Git Url including branch if specified. Returns module name if
/// gitUrl is not set.
/// </returns>
public string Identifier
{
get
{
if (gitUrl == string.Empty)
{
return name;
}
// if branch not set, default to the version in ModuleList
return gitUrl + (string.IsNullOrEmpty(branch) ? $"#v{version}" : $"#{branch}");
}
}
}
}

View File

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

View File

@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
namespace ReadyPlayerMe.Core.Editor
{
/// <summary>
/// Class <c>ModuleInstaller</c> is responsible for checking and installing all modules (Unity packages) required for
/// the Ready Player Me Unity SDK from their Git URL's.
/// </summary>
[InitializeOnLoad]
public static class ModuleInstaller
{
private const string TAG = nameof(ModuleInstaller);
private const int THREAD_SLEEP_TIME = 100;
private const float TIMEOUT_FOR_MODULE_INSTALLATION = 20f;
static ModuleInstaller()
{
Events.registeringPackages -= OnRegisteringPackages;
Events.registeringPackages += OnRegisteringPackages;
#if !READY_PLAYER_ME
EditorApplication.delayCall += DelayCreateCoreSettings;
DefineSymbolHelper.AddSymbols();
#endif
}
/// <summary>
/// Called when a package is about to be added, removed or changed.
/// </summary>
/// <param name="args">Describes the <c>PackageInfo</c> entries of packages currently registering.</param>
private static void OnRegisteringPackages(PackageRegistrationEventArgs args)
{
// Core module uninstalled
if (args.removed != null && args.removed.Any(p => p.name == ModuleList.Core.name))
{
DefineSymbolHelper.RemoveSymbols();
ProjectPrefs.SetBool(ProjectPrefs.FIRST_TIME_SETUP_DONE, false);
}
}
private static void DelayCreateCoreSettings()
{
EditorApplication.delayCall -= DelayCreateCoreSettings;
CoreSettingsLoader.EnsureSettingsExist();
}
/// <summary>
/// Request UPM to install the given module with the identifier.
/// </summary>
/// <param name="identifier">The Unity package identifier of the module to be installed.</param>
public static void AddModuleRequest(string identifier)
{
var startTime = Time.realtimeSinceStartup;
AddRequest addRequest = Client.Add(identifier);
while (!addRequest.IsCompleted && Time.realtimeSinceStartup - startTime < TIMEOUT_FOR_MODULE_INSTALLATION)
Thread.Sleep(THREAD_SLEEP_TIME);
if (Time.realtimeSinceStartup - startTime >= TIMEOUT_FOR_MODULE_INSTALLATION)
{
Debug.LogError($"Package installation timed out for {identifier}. Please try again.");
}
if (addRequest.Error != null)
{
Debug.LogError("Error: " + addRequest.Error.message);
}
}
/// <summary>
/// Check if the given module with the name is currently installed.
/// </summary>
/// <param name="name">Name of the module.</param>
/// <returns>A boolean <c>true</c> if the module is installed.</returns>
public static bool IsModuleInstalled(string name)
{
return GetPackageList().Any(info => info.name == name);
}
/// <summary>
/// Get the list of unity packages installed in the current project.
/// </summary>
/// <returns>An array of <c>PackageInfo</c>.</returns>
public static PackageInfo[] GetPackageList()
{
ListRequest listRequest = Client.List(true);
while (!listRequest.IsCompleted)
Thread.Sleep(THREAD_SLEEP_TIME);
if (listRequest.Error != null)
{
SDKLogger.Log(TAG, "Error: " + listRequest.Error.message);
return Array.Empty<PackageInfo>();
}
return listRequest.Result.ToArray();
}
}
}

View File

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

View File

@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor.PackageManager;
namespace ReadyPlayerMe.Core.Editor
{
/// <summary>
/// Class <c>ModuleList</c> is a static class that can be referenced to get the latest module version.
/// </summary>
public static class ModuleList
{
public static ModuleInfo Core = new ModuleInfo
{
name = "com.readyplayerme.core",
gitUrl = "https://github.com/readyplayerme/rpm-unity-sdk-core.git",
branch = "",
version = "5.0.0"
};
/// <summary>
/// A static list of all the required modules represented in an array of <c>ModuleInfo</c>.
/// </summary>
public static readonly ModuleInfo[] Modules =
{
new ModuleInfo
{
name = "com.readyplayerme.webview",
gitUrl = "https://github.com/readyplayerme/rpm-unity-sdk-webview.git",
branch = "",
version = "2.1.3"
}
};
/// <summary>
/// Unity Module that adds support for gltf files that use DracoCompression.
/// </summary>
public static ModuleInfo DracoCompression = new ModuleInfo
{
name = "com.atteneder.draco",
gitUrl = "https://github.com/atteneder/DracoUnity.git",
branch = "",
version = "4.1.0"
};
/// <summary>
/// Get installed modules from Modules list.
/// </summary>
/// <returns>A <see cref="Dictionary"/> of installed Unity Module information in the format of <c>Dictionary&lt;string: name, string: version&gt;</c>. </returns>
public static Dictionary<string, string> GetInstalledModuleVersionDictionary()
{
PackageInfo[] packageList = ModuleInstaller.GetPackageList();
var installedModules = new Dictionary<string, string>();
installedModules.Add(Core.name, Core.version);
foreach (ModuleInfo module in Modules)
{
if (packageList.Any(x => x.name == module.name))
{
installedModules.Add(module.name, module.version);
}
}
if (packageList.Any(x => x.name == DracoCompression.name))
{
installedModules.Add(DracoCompression.name, DracoCompression.version);
}
return installedModules;
}
}
}

View File

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

View File

@ -0,0 +1,211 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using ReadyPlayerMe.Core.Analytics;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;
using UnityEngine.Networking;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
namespace ReadyPlayerMe.Core.Editor
{
/// <summary>
/// It is responsible for checking and updating the Ready Player Me SDK modules.
/// </summary>
[InitializeOnLoad]
public class ModuleUpdater
{
private class Release
{
[JsonProperty("tag_name")]
public string Tag;
}
private const string PACKAGE_JSON = "package.json";
private const string PACKAGE_DOMAIN = "com.readyplayerme";
private const string GITHUB_WEBSITE = "https://github.com";
private const string GITHUB_API_URL = "https://api.github.com/repos";
private const int MILLISECONDS_TIMEOUT = 20;
private const string ASSET_FILTER = "package";
private const string DONT_ASK = "Dont Ask";
private const string UPDATE_PACKAGES_WINDOW_TITLE = "Update Packages";
private const string UPDATE_BUTTON_TEXT = "Update";
private const string CANCEL_BUTTON_TEXT = "Cancel";
private const string DONT_ASK_TEXT = "Don't ask";
private const string AVATAR_LOADER_PACKAGE = "com.readyplayerme.avatarloader";
static ModuleUpdater()
{
EntryPoint.Startup += () => Check(true);
}
/// <summary>
/// Check for Ready Player Me package updates.
/// </summary>
[MenuItem("Tools/Ready Player Me/Check For Updates", priority = 23)]
public static void CheckForUpdates()
{
AnalyticsEditorLogger.EventLogger.LogCheckForUpdates();
Check();
}
private static void Check(bool isStartup = false)
{
// Get PackageInfo array from RPM Module package.json files
PackageInfo[] packages = AssetDatabase.FindAssets(ASSET_FILTER)
.Select(AssetDatabase.GUIDToAssetPath)
.Where(x => x.Contains(PACKAGE_JSON) && x.Contains(PACKAGE_DOMAIN))
.Select(PackageInfo.FindForAssetPath)
.ToArray();
if (packages.Length == 0)
{
Debug.Log("No rpm package found");
}
// Turn package_name@repo_url#branch_name into https://api.github.com/repos/readyplayerme/repo_name/releases
foreach (PackageInfo package in packages)
{
var repoUrl = package.packageId.Split('@')[1];
var releasesUrl = repoUrl
.Split(new[] { ".git" }, StringSplitOptions.None)[0]
.Replace(GITHUB_WEBSITE, GITHUB_API_URL) + "/releases";
var packageUrl = repoUrl.Split('#')[0];
// Experimental or prerelease packages might look like 0.1.0-exp.1, remove after dash to parse with Version
var version = package.version.Split('-')[0];
if (isStartup && EditorPrefs.GetBool(DONT_ASK + "-" + package.name))
{
continue;
}
FetchReleases(package.name, packageUrl, releasesUrl, new Version(version));
}
}
/// <summary>
/// Fetch latest release for each module and prompt for update if available.
/// </summary>
/// <param name="packageName">The name of the Unity package.</param>
/// <param name="packageUrl">The Git URL of the Unity package.</param>
/// <param name="releasesUrl">The Git URL of the Unity package.</param>
/// <param name="currentVersion">The current version of the package.</param>
private static async void FetchReleases(string packageName, string packageUrl, string releasesUrl,
Version currentVersion)
{
UnityWebRequest request = UnityWebRequest.Get(releasesUrl);
UnityWebRequestAsyncOperation op = request.SendWebRequest();
while (!op.isDone) await Task.Yield();
if (request.result == UnityWebRequest.Result.Success)
{
var response = request.downloadHandler.text;
Release[] releases = JsonConvert.DeserializeObject<Release[]>(response);
Version[] versions = releases!.Select(r => new Version(r.Tag.Substring(1).Split('-')[0])).ToArray();
Version latestVersion = versions.Max();
if (latestVersion > currentVersion)
{
DisplayUpdateDialog(packageName, currentVersion, latestVersion, packageUrl);
}
}
else
{
Debug.Log($"Failed to fetch {packageName} releases. Error: {request.error} ");
}
}
/// <summary>
/// Display a Unity popup with notification about available package updates with buttons to update or skip.
/// </summary>
/// <param name="packageName">The name of the Unity package.</param>
/// <param name="currentVersion">The current version of the package.</param>
/// <param name="latestVersion">The new version of the package.</param>
/// <param name="packageUrl">The Git URL of the Unity package.</param>
private static void DisplayUpdateDialog(string packageName, Version currentVersion, Version latestVersion,
string packageUrl)
{
var shouldUpdate = EditorUtility.DisplayDialogComplex(UPDATE_PACKAGES_WINDOW_TITLE,
$"New update available for {packageName}\nCurrent version: {currentVersion}\nLatest version: {latestVersion}",
UPDATE_BUTTON_TEXT,
CANCEL_BUTTON_TEXT,
DONT_ASK_TEXT);
switch (shouldUpdate)
{
// Update
case 0:
CheckIfMajorRelease(packageName, currentVersion, latestVersion, packageUrl);
break;
// Cancel
case 1:
// Do nothing
break;
// Don't ask
case 2:
EditorPrefs.SetBool(DONT_ASK + "-" + packageName, true);
break;
}
}
private static void CheckIfMajorRelease(string packageName, Version currentVersion, Version latestVersion,
string packageUrl)
{
if (latestVersion.Major > currentVersion.Major)
{
BreakingChangeDialog.ShowDialog(() =>
{
UpdateModule(packageName, packageUrl, currentVersion, latestVersion);
});
}
else
{
UpdateModule(packageName, packageUrl, currentVersion, latestVersion);
}
}
/// <summary>
/// Update the specified module by removing the current version and then adding the specified version.
/// </summary>
/// <param name="name">The name of the Unity package.</param>
/// <param name="url">The Git URL of the Unity package.</param>
/// <param name="current">The current version of the package.</param>
/// <param name="latest">The new version of the package.</param>
private static void UpdateModule(string name, string url, Version current, Version latest)
{
url += "#v" + latest;
CleanRedundantAvatarLoader();
RemoveRequest removeRequest = Client.Remove(name);
while (!removeRequest.IsCompleted) Thread.Sleep(MILLISECONDS_TIMEOUT);
AddRequest addRequest = Client.Add(url);
while (!addRequest.IsCompleted) Thread.Sleep(MILLISECONDS_TIMEOUT);
Debug.Log($"Updated {name} from v{current} to v{latest}");
}
private static void CleanRedundantAvatarLoader()
{
if (!ModuleInstaller.IsModuleInstalled(AVATAR_LOADER_PACKAGE))
{
return;
}
RemoveRequest removeRequest = Client.Remove(AVATAR_LOADER_PACKAGE);
while (!removeRequest.IsCompleted) Thread.Sleep(MILLISECONDS_TIMEOUT);
}
}
}

View File

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

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2ac2b39cc7ef4a5988d6ac77077db307
timeCreated: 1699344120

View File

@ -0,0 +1,35 @@
using System;
using System.Linq;
using ReadyPlayerMe.Core.Analytics;
using UnityEditor;
using UnityEditor.PackageManager;
namespace ReadyPlayerMe.Core.Editor
{
public abstract class PackageManagerEventListener
{
public static event Action<string> OnPackageImported;
[InitializeOnLoadMethod]
static void Initialize()
{
Events.registeredPackages += OnPackagesInstalled;
}
~PackageManagerEventListener()
{
Events.registeredPackages -= OnPackagesInstalled;
}
static void OnPackagesInstalled(PackageRegistrationEventArgs packageRegistrationEventArgs)
{
packageRegistrationEventArgs.added
.ToList()
.ForEach(packageInfo =>
{
OnPackageImported?.Invoke(packageInfo.name);
AnalyticsEditorLogger.EventLogger.LogPackageInstalled(packageInfo.name, packageInfo.packageId);
});
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a08c3f9ac3c142dc9ea5d854a1bc3af1
timeCreated: 1699344135

View File

@ -0,0 +1,68 @@
using System;
using System.Linq;
using System.Threading;
using UnityEditor.PackageManager;
using UnityEngine;
namespace ReadyPlayerMe.Core.Editor
{
public abstract class PackageManagerHelper
{
private const string TAG = nameof(PackageManagerHelper);
private const int THREAD_SLEEP_TIME = 100;
private const float TIMEOUT_FOR_PACKAGE_INSTALLATION = 20f;
private const string READY_PLAYER_ME_PACKAGE_PATH = "Packages/com.readyplayerme.core";
public static bool IsPackageInstalled(string name)
{
return GetPackageList().Any(info => info.name == name);
}
/// <summary>
/// Get the list of unity packages installed in the current project.
/// </summary>
/// <returns>An array of <c>PackageInfo</c>.</returns>
public static PackageInfo[] GetPackageList()
{
var listRequest = Client.List(true);
while (!listRequest.IsCompleted)
Thread.Sleep(THREAD_SLEEP_TIME);
if (listRequest.Error == null)
{
return listRequest.Result.ToArray();
}
SDKLogger.Log(TAG, "Error: " + listRequest.Error.message);
return Array.Empty<PackageInfo>();
}
public static string GetSdkPackageSourceUrl()
{
var sdkPackageInfo = PackageInfo.FindForAssetPath(READY_PLAYER_ME_PACKAGE_PATH);
return sdkPackageInfo?.packageId
.Split(new[] { '@' }, StringSplitOptions.RemoveEmptyEntries)
.LastOrDefault();
}
public static void AddPackage(string identifier)
{
var startTime = Time.realtimeSinceStartup;
var addRequest = Client.Add(identifier);
while (!addRequest.IsCompleted && Time.realtimeSinceStartup - startTime < TIMEOUT_FOR_PACKAGE_INSTALLATION)
Thread.Sleep(THREAD_SLEEP_TIME);
if (Time.realtimeSinceStartup - startTime >= TIMEOUT_FOR_PACKAGE_INSTALLATION)
{
Debug.LogError($"Package installation timed out for {identifier}. Please try again.");
}
if (addRequest.Error != null)
{
Debug.LogError("Error: " + addRequest.Error.message);
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1c12b21e35214e19a1c3dfe7148a3fda
timeCreated: 1698851420

View File

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

View File

@ -0,0 +1,19 @@
using ReadyPlayerMe.Core.Analytics;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
namespace ReadyPlayerMe.Core.Editor
{
public static class BuildPostProcessor
{
[PostProcessBuild(1)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
// create asset if it has been deleted
CoreSettingsLoader.EnsureSettingsExist();
AppData appData = ApplicationData.GetData();
AnalyticsEditorLogger.EventLogger.LogBuildApplication(appData.BuildTarget, PlayerSettings.productName, !Debug.isDebugBuild);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9efa9adc0c4948579b226dac039a2e85
timeCreated: 1657013212

View File

@ -0,0 +1,40 @@
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace ReadyPlayerMe.Core.Editor
{
public class BuildPreprocessor : IPreprocessBuildWithReport
{
private const string TAG = nameof(BuildPreprocessor);
private const string ADD_SHADER_VARIANTS = "Add and Build";
private const string BUILD_WARNING = "Build Warning";
private const string SUBDOMAIN_WARNING =
@"It looks like the glTFast Shader Variants are missing from the Graphics Settings/Preloaded Shader list list. This can cause errors when loading Ready Player Me avatars at runtime. Would you like to add them now before building?";
private const string CONTINUE_WITH_DEMO = "Build without Variants";
private const string WARNING_BUILD_WITHOUT_VARIANTS = "Building without adding glTFast Shader Variants";
public int callbackOrder { get; }
public void OnPreprocessBuild(BuildReport report)
{
if (!Application.isBatchMode && GraphicsSettingsUtility.IsMissingVariants())
{
var addShaderVariants = EditorUtility.DisplayDialog(BUILD_WARNING,
SUBDOMAIN_WARNING,
ADD_SHADER_VARIANTS,
CONTINUE_WITH_DEMO);
if (addShaderVariants)
{
GraphicsSettingsUtility.AddPreloadShaderVariants();
}
else
{
SDKLogger.LogWarning(TAG, WARNING_BUILD_WITHOUT_VARIANTS);
}
}
}
}
}

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