public SpawnedAvatar SpawnAvatar(LoadedAvatar avatar, IAvatarInput input, Transform parent = null) { if (avatar == null) { throw new ArgumentNullException(nameof(avatar)); } if (input == null) { throw new ArgumentNullException(nameof(input)); } if (parent) { _logger.Info($"Spawning avatar '{avatar.descriptor.name}' into '{parent.name}'"); } else { _logger.Info($"Spawning avatar '{avatar.descriptor.name}'"); } DiContainer subContainer = new DiContainer(_container); subContainer.Bind <LoadedAvatar>().FromInstance(avatar); subContainer.Bind <IAvatarInput>().FromInstance(input); GameObject avatarInstance = subContainer.InstantiatePrefab(avatar.prefab, parent); return(subContainer.InstantiateComponent <SpawnedAvatar>(avatarInstance)); }
public SpawnedAvatar(LoadedAvatar avatar, AvatarInput input) { customAvatar = avatar ?? throw new ArgumentNullException(nameof(avatar)); _gameObject = Object.Instantiate(customAvatar.gameObject); _firstPersonExclusions = _gameObject.GetComponentsInChildren <FirstPersonExclusion>(); eventsPlayer = _gameObject.AddComponent <AvatarEventsPlayer>(); tracking = _gameObject.AddComponent <AvatarTracking>(); tracking.customAvatar = customAvatar; tracking.input = input; if (customAvatar.isIKAvatar) { AvatarIK ik = _gameObject.AddComponent <AvatarIK>(); ik.input = input; } if (customAvatar.supportsFingerTracking) { _gameObject.AddComponent <AvatarFingerTracking>(); } Object.DontDestroyOnLoad(_gameObject); }
public void Inject(ILoggerProvider loggerProvider, LoadedAvatar avatar, ScoreController scoreController, BeatmapObjectCallbackController beatmapObjectCallbackController, ILevelEndActions levelEndActions) { _logger = loggerProvider.CreateLogger <AvatarGameplayEventsPlayer>(avatar.descriptor.name); _scoreController = scoreController; _levelEndActions = levelEndActions; _beatmapObjectCallbackController = beatmapObjectCallbackController; }
public void Inject(ILoggerProvider loggerProvider, LoadedAvatar avatar, ScoreController scoreController, BeatmapObjectCallbackController beatmapObjectCallbackController, ILevelEndActions levelEndActions) { _logger = loggerProvider.CreateLogger <AvatarGameplayEventsPlayer>(avatar.descriptor.name); _scoreController = scoreController; _levelEndActions = levelEndActions; _beatmapObjectCallbackController = beatmapObjectCallbackController; // unfortunately this is not bound through Zenject _sparkleEffectManager = FindObjectOfType <ObstacleSaberSparkleEffectManager>(); }
private void HandleSuccess(string fullPath, LoadedAvatar loadedAvatar) { _logger.Info($"Successfully loaded avatar '{loadedAvatar.descriptor.name}' by '{loadedAvatar.descriptor.author}' from '{fullPath}'"); foreach (LoadHandlers handler in _handlers[fullPath]) { handler.InvokeSuccess(loadedAvatar); } _handlers.Remove(fullPath); }
public AvatarInfo(LoadedAvatar avatar) { name = avatar.descriptor.name; author = avatar.descriptor.author; icon = avatar.descriptor.cover ? avatar.descriptor.cover.texture : null; var fileInfo = new FileInfo(avatar.fullPath); fileName = fileInfo.Name; fileSize = fileInfo.Length; created = fileInfo.CreationTimeUtc; lastModified = fileInfo.LastWriteTimeUtc; timestamp = DateTime.Now; }
private void SwitchToAvatar(LoadedAvatar avatar) { if (currentlySpawnedAvatar && currentlySpawnedAvatar.avatar == avatar) { return; } if (avatar?.fullPath != _switchingToPath) { return; } if (avatar == null) { _logger.Info("No avatar selected"); avatarChanged?.Invoke(null); _settings.previousAvatarPath = null; return; } var avatarInfo = new AvatarInfo(avatar); _settings.previousAvatarPath = avatarInfo.fileName; // cache avatar info since loading asset bundles is expensive if (_avatarInfos.ContainsKey(avatarInfo.fileName)) { _avatarInfos[avatarInfo.fileName] = avatarInfo; } else { _avatarInfos.Add(avatarInfo.fileName, avatarInfo); } currentlySpawnedAvatar = _spawner.SpawnAvatar(avatar, _container.Instantiate <VRPlayerInput>(new object[] { avatar })); _currentAvatarSettings = _settings.GetAvatarSettings(avatar.fileName); ResizeCurrentAvatar(); UpdateFirstPersonVisibility(); UpdateLocomotionEnabled(); avatarChanged?.Invoke(currentlySpawnedAvatar); }
public void InvokeSuccess(LoadedAvatar value) { success?.Invoke(value); complete?.Invoke(); }
internal void Construct(string fullPath, ILogger <AvatarPrefab> logger, IKHelper ikHelper, DiContainer container) { this.fullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath)); descriptor = GetComponent <AvatarDescriptor>() ?? throw new AvatarLoadException($"Avatar at '{fullPath}' does not have an AvatarDescriptor"); fileName = Path.GetFileName(fullPath); _logger = logger; _logger.name = descriptor.name; #pragma warning disable CS0618 VRIKManager vrikManager = GetComponentInChildren <VRIKManager>(); IKManager ikManager = GetComponentInChildren <IKManager>(); #pragma warning restore CS0618 // migrate IKManager/IKManagerAdvanced to VRIKManager if (ikManager) { if (!vrikManager) { vrikManager = container.InstantiateComponent <VRIKManager>(gameObject); } _logger.Warning("IKManager and IKManagerAdvanced are deprecated; please migrate to VRIKManager"); ApplyIKManagerFields(vrikManager, ikManager); 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 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); } Destroy(existingVrik); } if (vrikManager) { ikHelper.CreateOffsetTargetsIfMissing(vrikManager, transform); } head = transform.Find("Head"); leftHand = transform.Find("LeftHand"); rightHand = transform.Find("RightHand"); pelvis = transform.Find("Pelvis"); leftLeg = transform.Find("LeftLeg"); rightLeg = transform.Find("RightLeg"); if (vrikManager) { if (vrikManager.references_root != vrikManager.transform) { _logger.Warning("VRIKManager is not on the root reference transform; this may cause unexpected issues"); } CheckTargetWeight("Left Arm", leftHand, vrikManager.solver_leftArm_positionWeight, vrikManager.solver_leftArm_rotationWeight); CheckTargetWeight("Right Arm", rightHand, vrikManager.solver_rightArm_positionWeight, vrikManager.solver_rightArm_rotationWeight); CheckTargetWeight("Pelvis", pelvis, vrikManager.solver_spine_pelvisPositionWeight, vrikManager.solver_spine_pelvisRotationWeight); CheckTargetWeight("Left Leg", leftLeg, vrikManager.solver_leftLeg_positionWeight, vrikManager.solver_leftLeg_rotationWeight); CheckTargetWeight("Right Leg", rightLeg, vrikManager.solver_rightLeg_positionWeight, vrikManager.solver_rightLeg_rotationWeight); FixTrackingReferences(vrikManager); } if (transform.localPosition.sqrMagnitude > 0) { _logger.Warning("Avatar root position is not at origin; this may cause unexpected issues"); } var poseManager = GetComponentInChildren <PoseManager>(); isIKAvatar = vrikManager; supportsFingerTracking = poseManager && poseManager.isValid; eyeHeight = GetEyeHeight(); armSpan = GetArmSpan(vrikManager); #pragma warning disable CS0612, CS0618 loadedAvatar = new LoadedAvatar(this); #pragma warning restore CS0612, CS0618 }
// TODO from stream/memory /// <summary> /// Load an avatar from a file. /// </summary> /// <param name="path">Path to the .avatar file</param> /// <param name="success">Action to call if the avatar is loaded successfully</param> /// <param name="error">Action to call if the avatar isn't loaded successfully</param> /// <returns><see cref="IEnumerator{AsyncOperation}"/></returns> public IEnumerator <AsyncOperation> FromFileCoroutine(string path, Action <LoadedAvatar> success = null, Action <Exception> error = null) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } string fullPath = Path.GetFullPath(path); if (!File.Exists(fullPath)) { throw new IOException($"File '{fullPath}' does not exist"); } // already loading, just add handlers if (_handlers.ContainsKey(fullPath)) { _handlers[fullPath].Add(new LoadHandlers(success, error)); yield break; } _handlers.Add(fullPath, new List <LoadHandlers> { new LoadHandlers(success, error) }); _logger.Info($"Loading avatar from '{fullPath}'"); AssetBundleCreateRequest assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(fullPath); yield return(assetBundleCreateRequest); if (!assetBundleCreateRequest.isDone || !assetBundleCreateRequest.assetBundle) { var exception = new AvatarLoadException("Could not load asset bundle"); _logger.Error($"Failed to load avatar at '{fullPath}'"); _logger.Error(exception); foreach (LoadHandlers handler in _handlers[fullPath]) { handler.error?.Invoke(exception); } _handlers.Remove(fullPath); yield break; } AssetBundleRequest assetBundleRequest = assetBundleCreateRequest.assetBundle.LoadAssetWithSubAssetsAsync <GameObject>(kGameObjectName); yield return(assetBundleRequest); if (!assetBundleRequest.isDone || assetBundleRequest.asset == null) { assetBundleCreateRequest.assetBundle.Unload(true); var exception = new AvatarLoadException("Could not load asset from asset bundle"); _logger.Error($"Failed to load avatar at '{fullPath}'"); _logger.Error(exception); foreach (LoadHandlers handler in _handlers[fullPath]) { handler.error?.Invoke(exception); } _handlers.Remove(fullPath); yield break; } assetBundleCreateRequest.assetBundle.Unload(false); try { var loadedAvatar = new LoadedAvatar(fullPath, (GameObject)assetBundleRequest.asset, _container.Resolve <ILoggerProvider>()); _logger.Info($"Successfully loaded avatar '{loadedAvatar.descriptor.name}' from '{fullPath}'"); foreach (LoadHandlers handler in _handlers[fullPath]) { handler.success?.Invoke(loadedAvatar); } } catch (Exception ex) { _logger.Error($"Failed to load avatar at '{fullPath}'"); _logger.Error(ex); foreach (LoadHandlers handler in _handlers[fullPath]) { handler.error?.Invoke(new AvatarLoadException("Failed to load avatar", ex)); } } _handlers.Remove(fullPath); }