protected override void OnThreadUnSafeEventFired(object source, ContentPrefabCompletedDownloadEventArgs args) { //We really should only get this for players, so we should just assume this will work. OnContentPrefabRecieved?.Invoke(); OnContentPrefabRecieved = null; GameObject avatar = GameObject.Instantiate(args.DownloadedPrefabObject, new Vector3(1, 0, -2.4f), Quaternion.Euler(0, 90, 0)); avatar.transform.localScale = Vector3.one; avatar.layer = 5; Animator animator = avatar.GetComponent <Animator>(); if (animator != null) { animator.runtimeAnimatorController = Resources.Load <RuntimeAnimatorController>("IdleCharacterScreenAnimationController"); } else { animator = avatar.GetComponentInChildren <Animator>(); if (animator != null) { animator.runtimeAnimatorController = Resources.Load <RuntimeAnimatorController>("IdleCharacterScreenAnimationController"); } } //He'll drift across the screen if we don't do this. //Slowly but surely. if (animator != null) { animator.applyRootMotion = false; } //This is for custom complex avatars that may need initialization after downloading. IAvatarInitializable avatarInitializable = avatar.GetComponentInChildren <IAvatarInitializable>(); if (avatarInitializable != null) { avatarInitializable.InitializeAvatar(args.EntityGuid, NameQueryable.RetrieveAsync(args.EntityGuid)); } OnContentPrefabRecieved += () => { GameObject.Destroy(avatar); args.PrefabHandle.Release(); }; }
protected override void OnEventFired(object source, ContentPrefabCompletedDownloadEventArgs args) { //Only interested in players. if (args.EntityGuid.EntityType != EntityType.Player) { return; } if (Logger.IsInfoEnabled) { Logger.Info($"About to create new Avatar for Entity: {args.EntityGuid}"); } try { //Now we've assigned the handle, we need to actually handle the spawning/loading of the avatar. GameObject ikRootGameObject = GameObjectDirectoryMappable.RetrieveEntity(args.EntityGuid).GetGameObject(EntityGameObjectDirectory.Type.IKRoot); GameObject currentAvatarRootGameObject = ikRootGameObject.transform.GetChild(0).gameObject; GameObject newlySpawnedAvatar = InstantiateNewFromPrefab(args.DownloadedPrefabObject, currentAvatarRootGameObject); //Try to get AvatarBoneSDKData from root spawned model AvatarBoneSDKData boneSdkData = newlySpawnedAvatar.GetComponent <AvatarBoneSDKData>(); //TODO: Head height. //We can set relative camera height for VR users or first person users. //Don't do it for desktop. if (boneSdkData != null) { GameObject nameRoot = GameObjectDirectoryMappable.RetrieveEntity(args.EntityGuid).GetGameObject(EntityGameObjectDirectory.Type.NameRoot); nameRoot.transform.localPosition = new Vector3(nameRoot.transform.localPosition.x, boneSdkData.FloatingNameHeight, nameRoot.transform.localPosition.z); //Don't use 0 or super small head heights. They're probably wrong, especially negative ones. if (boneSdkData.HeadHeight > 0.1f) { GameObject headRoot = GameObjectDirectoryMappable.RetrieveEntity(args.EntityGuid).GetGameObject(EntityGameObjectDirectory.Type.HeadRoot); headRoot.transform.localPosition = new Vector3(headRoot.transform.localPosition.x, boneSdkData.HeadHeight, headRoot.transform.localPosition.z); } } GameObject.DestroyImmediate(currentAvatarRootGameObject, false); IMovementDirectionChangedListener movementChangeListener = newlySpawnedAvatar.GetComponentInChildren <IMovementDirectionChangedListener>(); if (movementChangeListener != null) { if (MovementDirectionListenerMappable.ContainsKey(args.EntityGuid)) { MovementDirectionListenerMappable.ReplaceObject(args.EntityGuid, movementChangeListener); } else { MovementDirectionListenerMappable.AddObject(args.EntityGuid, movementChangeListener); } } else { MovementDirectionListenerMappable.RemoveEntityEntry(args.EntityGuid); //if it's null jsut remove one if it exists. } //This is for custom complex avatars that may need initialization after downloading. IAvatarInitializable avatarInitializable = newlySpawnedAvatar.GetComponentInChildren <IAvatarInitializable>(); if (avatarInitializable != null) { avatarInitializable.InitializeAvatar(args.EntityGuid, NameQueryable.RetrieveAsync(args.EntityGuid)); } //This will actually re-initialize the IK for the new avatar, since the old one is now gone. ikRootGameObject.GetComponent <IIKReinitializable>().ReInitialize(); } catch (Exception e) { if (Logger.IsErrorEnabled) { Logger.Error($"Failed to create Avatar for Entity: {args.EntityGuid}. Error: {e.Message}\n\nStack: {e.StackTrace}"); } throw; } }