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;
 }
Esempio n. 2
0
        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");
        }
Esempio n. 3
0
        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");
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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();
        }