internal LoadedAvatar(AvatarPrefab prefab) { this.prefab = prefab.gameObject; fileName = prefab.fileName; fullPath = prefab.fullPath; descriptor = prefab.descriptor; isIKAvatar = prefab.isIKAvatar; supportsFingerTracking = prefab.supportsFingerTracking; eyeHeight = prefab.eyeHeight; armSpan = prefab.armSpan; }
private void SaveAvatar(AvatarDescriptor avatar) { string destinationPath = EditorUtility.SaveFilePanel("Save avatar file", null, avatar.name + ".avatar", "avatar"); if (string.IsNullOrEmpty(destinationPath)) { return; } string destinationFileName = Path.GetFileName(destinationPath); string tempFolder = Application.temporaryCachePath; string tempAssetBundlePath = Path.Combine(Application.temporaryCachePath, destinationFileName); string prefabPath = Path.Combine("Assets", "_CustomAvatar.prefab"); PrefabUtility.SaveAsPrefabAsset(avatar.gameObject, prefabPath); AssetBundleBuild assetBundleBuild = new AssetBundleBuild { assetBundleName = destinationFileName, assetNames = new[] { prefabPath } }; assetBundleBuild.assetBundleName = destinationFileName; BuildTargetGroup selectedBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; BuildTarget activeBuildTarget = EditorUserBuildSettings.activeBuildTarget; AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(tempFolder, new[] { assetBundleBuild }, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget); // switch back to what it was before creating the asset bundle EditorUserBuildSettings.SwitchActiveBuildTarget(selectedBuildTargetGroup, activeBuildTarget); if (manifest == null) { EditorUtility.DisplayDialog("Export Failed", "Failed to create asset bundle! Please check the Unity console for more information.", "OK"); return; } File.Copy(tempAssetBundlePath, destinationPath, true); AssetDatabase.DeleteAsset(prefabPath); AssetDatabase.Refresh(); EditorUtility.DisplayDialog("Export Successful!", $"{avatar.name} was exported successfully!", "OK"); }
private void SaveAvatar(AvatarDescriptor avatar) { string destinationPath = EditorUtility.SaveFilePanel("Save avatar file", null, avatar.name + ".avatar", "avatar"); if (string.IsNullOrEmpty(destinationPath)) { return; } string destinationFileName = Path.GetFileName(destinationPath); string tempFolder = Application.temporaryCachePath; string tempAssetBundlePath = Path.Combine(Application.temporaryCachePath, destinationFileName); string prefabPath = Path.Combine("Assets", "_CustomAvatar.prefab"); PrefabUtility.SaveAsPrefabAsset(avatar.gameObject, prefabPath); AssetBundleBuild assetBundleBuild = new AssetBundleBuild { assetBundleName = destinationFileName, assetNames = new[] { prefabPath } }; assetBundleBuild.assetBundleName = destinationFileName; BuildTargetGroup selectedBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; BuildTarget activeBuildTarget = EditorUserBuildSettings.activeBuildTarget; BuildPipeline.BuildAssetBundles(tempFolder, new[] { assetBundleBuild }, 0, EditorUserBuildSettings.activeBuildTarget); EditorUserBuildSettings.SwitchActiveBuildTarget(selectedBuildTargetGroup, activeBuildTarget); File.Copy(tempAssetBundlePath, destinationPath, true); AssetDatabase.DeleteAsset(prefabPath); AssetDatabase.Refresh(); EditorUtility.DisplayDialog("Export Successful!", $"{avatar.name} was exported successfully!", "OK"); }
internal LoadedAvatar(string fullPath, GameObject avatarGameObject, ILoggerProvider loggerProvider, DiContainer container) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath)); prefab = avatarGameObject ? avatarGameObject : throw new ArgumentNullException(nameof(avatarGameObject)); descriptor = avatarGameObject.GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); prefab.name = $"LoadedAvatar({descriptor.name})"; _logger = loggerProvider.CreateLogger <LoadedAvatar>(descriptor.name); head = prefab.transform.Find("Head"); leftHand = prefab.transform.Find("LeftHand"); rightHand = prefab.transform.Find("RightHand"); pelvis = prefab.transform.Find("Pelvis"); leftLeg = prefab.transform.Find("LeftLeg"); rightLeg = prefab.transform.Find("RightLeg"); #pragma warning disable CS0618 VRIKManager vrikManager = prefab.GetComponentInChildren <VRIKManager>(); IKManager ikManager = prefab.GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = container.InstantiateComponent <VRIKManager>(prefab); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); Object.Destroy(ikManager); } if (vrikManager) { if (!vrikManager.areReferencesFilled) { _logger.Warning($"References are not filled on '{vrikManager.name}'; detecting references automatically"); vrikManager.AutoDetectReferences(); } } // remove any existing VRIK instances foreach (VRIK existingVrik in prefab.GetComponentsInChildren <VRIK>()) { _logger.Warning($"Found VRIK on '{existingVrik.name}'; manually adding VRIK to an avatar is no longer needed, please remove it"); if (existingVrik && vrikManager && existingVrik.references.isFilled && !vrikManager.areReferencesFilled) { _logger.Warning($"Copying references from VRIK on '{existingVrik.name}'; this is deprecated behaviour and will be removed in a future release"); CopyReferencesFromExistingVrik(vrikManager, existingVrik.references); } Object.Destroy(existingVrik); } if (vrikManager) { if (vrikManager.references_root != vrikManager.transform) { _logger.Warning("VRIKManager is not on the root reference transform; this may cause unexpected issues"); } FixTrackingReferences(vrikManager); } if (prefab.transform.localPosition.sqrMagnitude > 0) { _logger.Warning("Avatar root position is not at origin; this may cause unexpected issues"); } var poseManager = prefab.GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFullBodyTracking = pelvis || leftLeg || rightLeg; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(vrikManager); }
internal LoadedAvatar(string fullPath, GameObject avatarGameObject, ILoggerProvider loggerProvider) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(avatarGameObject)); prefab = avatarGameObject ? avatarGameObject : throw new ArgumentNullException(nameof(avatarGameObject)); descriptor = avatarGameObject.GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); _logger = loggerProvider.CreateLogger <LoadedAvatar>(descriptor.name); VRIKManager vrikManager = prefab.GetComponentInChildren <VRIKManager>(); #pragma warning disable CS0618 IKManager ikManager = prefab.GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = prefab.AddComponent <VRIKManager>(); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); Object.Destroy(ikManager); } // remove any existing VRIK instances foreach (VRIK existingVrik in prefab.GetComponentsInChildren <VRIK>()) { _logger.Warning($"Found VRIK on '{existingVrik.name}'; manually adding VRIK to an avatar is no longer needed, please remove it"); if (existingVrik && vrikManager && existingVrik.references.isFilled && !vrikManager.areReferencesFilled) { _logger.Warning($"Copying references from VRIK on '{existingVrik.name}'; this is deprecated behaviour and will be removed in a future release"); CopyReferencesFromExistingVrik(vrikManager, existingVrik.references); } Object.Destroy(existingVrik); } _head = prefab.transform.Find("Head"); _leftHand = prefab.transform.Find("LeftHand"); _rightHand = prefab.transform.Find("RightHand"); _pelvis = prefab.transform.Find("Pelvis"); _leftLeg = prefab.transform.Find("LeftLeg"); _rightLeg = prefab.transform.Find("RightLeg"); if (vrikManager) { if (!vrikManager.areReferencesFilled) { vrikManager.AutoDetectReferences(); } FixTrackingReferences(vrikManager); } var poseManager = prefab.GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFullBodyTracking = _pelvis || _leftLeg || _rightLeg; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(); }
#pragma warning restore IDE0051 #endregion private void SaveAvatar(AvatarDescriptor avatar) { string destinationPath = EditorUtility.SaveFilePanel("Save avatar file", null, avatar.name + ".avatar", "avatar"); if (string.IsNullOrEmpty(destinationPath)) { return; } string destinationFileName = Path.GetFileName(destinationPath); string tempFolder = Application.temporaryCachePath; string prefabPath = Path.Combine("Assets", "_CustomAvatar.prefab"); PrefabUtility.SaveAsPrefabAsset(avatar.gameObject, prefabPath); AssetBundleBuild assetBundleBuild = new AssetBundleBuild { assetBundleName = destinationFileName, assetNames = new[] { prefabPath } }; assetBundleBuild.assetBundleName = destinationFileName; BuildTargetGroup selectedBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; BuildTarget activeBuildTarget = EditorUserBuildSettings.activeBuildTarget; AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(tempFolder, new[] { assetBundleBuild }, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); // switch back to what it was before creating the asset bundle EditorUserBuildSettings.SwitchActiveBuildTarget(selectedBuildTargetGroup, activeBuildTarget); if (manifest != null) { string tempAssetBundlePath = Path.Combine(tempFolder, destinationFileName); if (!File.Exists(tempAssetBundlePath)) { // Unity on Linux saves to a lowercase file name for some reason tempAssetBundlePath = Path.Combine(tempFolder, destinationFileName.ToLower()); } try { File.Copy(tempAssetBundlePath, destinationPath, true); EditorUtility.DisplayDialog("Export Successful!", $"{avatar.name} was exported successfully!", "OK"); } catch (IOException ex) { Debug.LogError(ex); EditorUtility.DisplayDialog("Export Failed", $"Could not copy avatar to selected folder. Please check the Unity console for more information.", "OK"); } } else { EditorUtility.DisplayDialog("Export Failed", "Failed to create asset bundle! Please check the Unity console for more information.", "OK"); } AssetDatabase.DeleteAsset(prefabPath); AssetDatabase.Refresh(); }