1099 Posted May 15 Share Posted May 15 Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) Cannot set the parent of the GameObject 'VIUModelViveController(Clone)' while activating or deactivating the parent GameObject 'Model'. Have anyone encountered this error? I have multiple scenes in Unity, and each scene has a player. The player contains ViveCameraRig, and I am getting those errors above. It will still run throughout the game, but I want to resolve these errors if possible. Any suggestions for resolving this? Link to comment Share on other sites More sharing options...
VIVE_chengnay Posted May 16 Share Posted May 16 Hi @1099, Could you provide a sample code or project that can reproduce the errors? Link to comment Share on other sites More sharing options...
1099 Posted July 22 Author Share Posted July 22 (edited) //========= Copyright 2016-2022, HTC Corporation. All rights reserved. =========== using HTC.UnityPlugin.Utility; using HTC.UnityPlugin.VRModuleManagement; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; namespace HTC.UnityPlugin.Vive { // This script creates and handles SteamVR_RenderModel using viveRole property or device index [DisallowMultipleComponent] [AddComponentMenu("VIU/Hooks/Render Model Hook", 10)] public class RenderModelHook : MonoBehaviour, IViveRoleComponent { public interface ICustomModel { void OnAfterModelCreated(RenderModelHook hook); /// <summary> /// If from all components return true, hook will perform SetActive(true) on this model after this message /// </summary> bool OnBeforeModelActivated(RenderModelHook hook); /// <summary> /// If from all components return true, hook will perform SetActive(false) on this model after this message /// </summary> bool OnBeforeModelDeactivated(RenderModelHook hook); } [AttributeUsage(AttributeTargets.Class)] public class CreatorPriorityAttirbute : Attribute { public int priority { get; set; } public CreatorPriorityAttirbute(int priority = 0) { this.priority = priority; } } public abstract class RenderModelCreator { public abstract bool shouldActive { get; } protected RenderModelHook hook { get; private set; } public void Initialize(RenderModelHook hook) { this.hook = hook; } public abstract void UpdateRenderModel(); public abstract void CleanUpRenderModel(); } public class DefaultRenderModelCreator : RenderModelCreator { private struct DefaultModelData { public bool isLoaded; public GameObject model; } private static EnumArray<VRModuleDeviceModel, DefaultModelData> s_defaultModels = new EnumArray<VRModuleDeviceModel, DefaultModelData>(); private bool m_isModelActivated; private EnumArray<VRModuleDeviceModel, GameObject> m_modelObjs = new EnumArray<VRModuleDeviceModel, GameObject>(); private VRModuleDeviceModel m_activeModel; [Obsolete] protected GameObject m_model; public override bool shouldActive { get { return true; } } protected VRModuleDeviceModel activeDefaultModel { get { return m_activeModel; } } protected bool isDefaultModelActive { get { return m_isModelActivated; } } public static GameObject GetDefaultDeviceModelPrefab(VRModuleDeviceModel modelNum) { if (modelNum < s_defaultModels.Min || modelNum > s_defaultModels.Max) { return null; } var modelData = s_defaultModels[modelNum]; if (!modelData.isLoaded) { GameObject modelPrefab = null; int modelNameIndex; var info = EnumUtils.GetDisplayInfo(typeof(VRModuleDeviceModel)); if (info.value2displayedIndex.TryGetValue((int)modelNum, out modelNameIndex)) { modelPrefab = Resources.Load<GameObject>("Models/VIUModel" + info.displayedNames[modelNameIndex]); } s_defaultModels[modelNum] = modelData = new DefaultModelData() { isLoaded = true, model = modelPrefab, }; } return modelData.model; } public override void UpdateRenderModel() { UpdateDefaultRenderModel(true); } protected void UpdateDefaultRenderModel(bool shouldActive) { var deviceState = VRModule.GetDeviceState(hook.GetModelDeviceIndex()); var lastModelActivated = m_isModelActivated; var lastActivatedModel = m_activeModel; var shouldActiveModelNum = hook.overrideModel == OverrideModelEnum.DontOverride ? deviceState.deviceModel : (VRModuleDeviceModel)hook.overrideModel; var shouldActiveModelPrefab = shouldActive ? GetDefaultDeviceModelPrefab(shouldActiveModelNum) : null; var shouldActiveModel = shouldActive && deviceState.isConnected && shouldActiveModelPrefab != null; if (lastModelActivated) { if (!shouldActiveModel || lastActivatedModel != shouldActiveModelNum) { // deactivate custom override model var lastActiveModelObj = m_modelObjs[m_activeModel]; if (lastActiveModelObj != null && SendBeforeModelDeactivatedMessage(lastActiveModelObj, hook)) { lastActiveModelObj.gameObject.SetActive(false); } m_isModelActivated = false; } } if (shouldActiveModel) { if (!lastModelActivated || lastActivatedModel != shouldActiveModelNum) { var shouldActiveModelObj = m_modelObjs[shouldActiveModelNum]; if (shouldActiveModelObj == null) { // instantiate custom override model shouldActiveModelObj = Instantiate(shouldActiveModelPrefab); shouldActiveModelObj.transform.position = Vector3.zero; shouldActiveModelObj.transform.rotation = Quaternion.identity; if (hook.m_overrideMaterial != null) { var renderer = shouldActiveModelObj.GetComponentInChildren<Renderer>(); if (renderer != null) { renderer.material = hook.m_overrideMaterial; } } if (hook.m_overrideShader != null) { var renderer = shouldActiveModelObj.GetComponentInChildren<Renderer>(); if (renderer != null) { renderer.material.shader = hook.m_overrideShader; } } shouldActiveModelObj.transform.SetParent(hook.transform, false); m_modelObjs[shouldActiveModelNum] = shouldActiveModelObj; SendAfterModelCreatedMessage(shouldActiveModelObj, hook); } // active custom override model if (SendBeforeModelActivatedMessage(shouldActiveModelObj, hook)) { shouldActiveModelObj.gameObject.SetActive(true); } m_activeModel = shouldActiveModelNum; m_isModelActivated = true; } } } public override void CleanUpRenderModel() { if (m_isModelActivated) { // deactivate custom override model var lastActiveModelObj = m_modelObjs[m_activeModel]; if (lastActiveModelObj != null && SendBeforeModelDeactivatedMessage(lastActiveModelObj, hook)) { lastActiveModelObj.gameObject.SetActive(false); } m_isModelActivated = false; } } } public enum Mode { Disable, ViveRole, DeivceIndex, } public enum Index { None = -1, Hmd, Device1, Device2, Device3, Device4, Device5, Device6, Device7, Device8, Device9, Device10, Device11, Device12, Device13, Device14, Device15, } public enum OverrideModelEnum { DontOverride = VRModuleDeviceModel.Unknown, ViveController = VRModuleDeviceModel.ViveController, ViveTracker = VRModuleDeviceModel.ViveTracker, ViveBaseStation = VRModuleDeviceModel.ViveBaseStation, OculusTouchLeft = VRModuleDeviceModel.OculusTouchLeft, OculusTouchRight = VRModuleDeviceModel.OculusTouchRight, OculusSensor = VRModuleDeviceModel.OculusSensor, KnucklesLeft = VRModuleDeviceModel.KnucklesLeft, KnucklesRight = VRModuleDeviceModel.KnucklesRight, DaydreamController = VRModuleDeviceModel.DaydreamController, ViveFocusFinch = VRModuleDeviceModel.ViveFocusFinch, OculusGoController = VRModuleDeviceModel.OculusGoController, OculusGearVrController = VRModuleDeviceModel.OculusGearVrController, WMRControllerLeft = VRModuleDeviceModel.WMRControllerLeft, WMRControllerRight = VRModuleDeviceModel.WMRControllerRight, ViveCosmosControllerLeft = VRModuleDeviceModel.ViveCosmosControllerLeft, ViveCosmosControllerRight = VRModuleDeviceModel.ViveCosmosControllerRight, OculusQuestControllerLeft = VRModuleDeviceModel.OculusQuestControllerLeft, OculusQuestControllerRight = VRModuleDeviceModel.OculusQuestControllerRight, IndexHMD = VRModuleDeviceModel.IndexHMD, // no model IndexControllerLeft = VRModuleDeviceModel.IndexControllerLeft, IndexControllerRight = VRModuleDeviceModel.IndexControllerRight, MagicLeapHMD = VRModuleDeviceModel.MagicLeapHMD, // no model MagicLeapController = VRModuleDeviceModel.MagicLeapController, // no model ViveHandTrackingTrackedHandLeft = VRModuleDeviceModel.ViveHandTrackingTrackedHandLeft, ViveHandTrackingTrackedHandRight = VRModuleDeviceModel.ViveHandTrackingTrackedHandRight, WaveLegacyTrackedHandLeft = VRModuleDeviceModel.WaveLegacyTrackedHandLeft, WaveLegacyTrackedHandRight = VRModuleDeviceModel.WaveLegacyTrackedHandRight, WaveTrackedHandLeft = VRModuleDeviceModel.WaveTrackedHandLeft, WaveTrackedHandRight = VRModuleDeviceModel.WaveTrackedHandRight, OculusTrackedHandLeft = VRModuleDeviceModel.OculusTrackedHandLeft, OculusTrackedHandRight = VRModuleDeviceModel.OculusTrackedHandRight, ViveFocus3ControllerLeft = VRModuleDeviceModel.ViveFocus3ControllerLeft, ViveFocus3ControllerRight = VRModuleDeviceModel.ViveFocus3ControllerRight, ViveFocusChirp = VRModuleDeviceModel.ViveFocusChirp, ViveTracker3 = VRModuleDeviceModel.ViveTracker3, ViveFlowPhoneController = VRModuleDeviceModel.ViveFlowPhoneController, OculusQuest2ControllerLeft = VRModuleDeviceModel.OculusQuest2ControllerLeft, OculusQuest2ControllerRight = VRModuleDeviceModel.OculusQuest2ControllerRight, ViveWristTracker = VRModuleDeviceModel.ViveWristTracker, } [SerializeField] private Mode m_mode = Mode.ViveRole; [SerializeField] private ViveRoleProperty m_viveRole = ViveRoleProperty.New(HandRole.RightHand); [SerializeField] private Index m_deviceIndex = Index.Hmd; [SerializeField] private OverrideModelEnum m_overrideModel = OverrideModelEnum.DontOverride; [SerializeField] private Shader m_overrideShader = null; [SerializeField] private Material m_overrideMaterial = null; [SerializeField] private VIUSettings.DeviceModelArray m_customModels = new VIUSettings.DeviceModelArray(); private static Type[] s_creatorTypes; private RenderModelCreator[] m_creators; private int m_activeCreatorIndex = -1; private int m_defaultCreatorIndex = -1; private bool m_isQuiting; private bool m_updateModelLock; public ViveRoleProperty viveRole { get { return m_viveRole; } } [Obsolete] public Transform origin { get; set; } [Obsolete] public bool applyTracking { get; set; } public OverrideModelEnum overrideModel { get { return m_overrideModel; } set { m_overrideModel = value; } } public Shader overrideShader { get { return m_overrideShader; } set { m_overrideShader = value; } } public Material overrideMaterial { get { return m_overrideMaterial; } set { m_overrideMaterial = value; } } public VIUSettings.DeviceModelArray customModels { get { return m_customModels; } } private static void FindAllRenderModelCreatorTypes() { if (s_creatorTypes != null) { return; } var defaultCreatorType = typeof(DefaultRenderModelCreator); try { var creatorBaseType = typeof(RenderModelCreator); var creatorTypes = new List<Type>(); var currentAsm = creatorBaseType.Assembly; var currentAsmName = currentAsm.GetName().Name; foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { var referencingCurrentAsm = false; if (asm == currentAsm) { referencingCurrentAsm = true; } else { foreach (var asmref in asm.GetReferencedAssemblies()) { if (asmref.Name == currentAsmName) { referencingCurrentAsm = true; break; } } } if (referencingCurrentAsm) { foreach (var type in asm.GetTypes().Where(t => t.IsSubclassOf(creatorBaseType) && !t.IsAbstract && t != defaultCreatorType)) { creatorTypes.Add(type); } } } creatorTypes.Sort((x, y) => GetCreatorPriority(x) - GetCreatorPriority(y)); creatorTypes.Add(defaultCreatorType); s_creatorTypes = creatorTypes.ToArray(); } catch (Exception e) { s_creatorTypes = new Type[] { defaultCreatorType }; Debug.LogError(e); } } private static int GetCreatorPriority(Type t, int defaultValue = 0) { foreach (var at in t.GetCustomAttributes(typeof(CreatorPriorityAttirbute), true)) { return ((CreatorPriorityAttirbute)at).priority; } return defaultValue; } private void Awake() { FindAllRenderModelCreatorTypes(); m_creators = new RenderModelCreator[s_creatorTypes.Length]; for (int i = s_creatorTypes.Length - 1; i >= 0; --i) { m_creators[i] = (RenderModelCreator)Activator.CreateInstance(s_creatorTypes[i]); m_creators[i].Initialize(this); if (s_creatorTypes[i] == typeof(DefaultRenderModelCreator)) { m_defaultCreatorIndex = i; } } } protected virtual void OnEnable() { UpdateModel(); VRModule.onActiveModuleChanged += OnActiveModuleChanged; VRModule.onControllerRoleChanged += UpdateModel; m_viveRole.onDeviceIndexChanged += OnDeviceIndexChanged; m_viveRole.onRoleChanged += UpdateModel; } protected virtual void OnDisable() { VRModule.onActiveModuleChanged -= OnActiveModuleChanged; VRModule.onControllerRoleChanged -= UpdateModel; m_viveRole.onDeviceIndexChanged -= OnDeviceIndexChanged; m_viveRole.onRoleChanged -= UpdateModel; UpdateModel(); } private void OnDeviceIndexChanged(uint deviceIndex) { UpdateModel(); } private void OnActiveModuleChanged(VRModuleActiveEnum module) { UpdateModel(); } private void OnApplicationQuit() { m_isQuiting = true; } public uint GetModelDeviceIndex() { if (!enabled) { return VRModule.INVALID_DEVICE_INDEX; } uint result; switch (m_mode) { case Mode.ViveRole: result = m_viveRole.GetDeviceIndex(); break; case Mode.DeivceIndex: result = (uint)m_deviceIndex; break; case Mode.Disable: default: return VRModule.INVALID_DEVICE_INDEX; } return result; } private bool m_isCustomModelActivated; private EnumArray<VRModuleDeviceModel, GameObject> m_customModelObjs = new EnumArray<VRModuleDeviceModel, GameObject>(); private VRModuleDeviceModel m_activeCustomModel; public EnumArray<VRModuleDeviceModel, GameObject>.IReadOnly loadedCuustomModels { get { return m_customModelObjs.ReadOnly; } } private static void SendAfterModelCreatedMessage(GameObject rootObj, RenderModelHook hook) { var iList = ListPool<ICustomModel>.Get(); try { rootObj.GetComponentsInChildren(true, iList); for (int i = 0, imax = iList.Count; i < imax; ++i) { iList[i].OnAfterModelCreated(hook); } } finally { ListPool<ICustomModel>.Release(iList); } } private static bool SendBeforeModelActivatedMessage(GameObject rootObj, RenderModelHook hook) { var result = true; var iList = ListPool<ICustomModel>.Get(); try { rootObj.GetComponentsInChildren(true, iList); for (int i = 0, imax = iList.Count; i < imax; ++i) { result &= iList[i].OnBeforeModelActivated(hook); } } finally { ListPool<ICustomModel>.Release(iList); } return result; } private static bool SendBeforeModelDeactivatedMessage(GameObject rootObj, RenderModelHook hook) { var result = true; var iList = ListPool<ICustomModel>.Get(); try { rootObj.GetComponentsInChildren(true, iList); for (int i = 0, imax = iList.Count; i < imax; ++i) { result &= iList[i].OnBeforeModelDeactivated(hook); } } finally { ListPool<ICustomModel>.Release(iList); } return result; } [ContextMenu("Update Model")] public void UpdateModel() { if (m_isQuiting) { return; } if (m_updateModelLock) { Debug.LogWarning("Recursive UpdateModel call is not supported"); return; } m_updateModelLock = true; var deviceState = VRModule.GetDeviceState(GetModelDeviceIndex()); var lastActiveCustomModelNum = m_activeCustomModel; var lastActiveCustomModelObj = m_customModelObjs[m_activeCustomModel]; var lastCustomModelActive = m_isCustomModelActivated; var shouldActiveCustomModelNum = deviceState.deviceModel; var shouldActiveCustomModelPrefab = m_customModels[shouldActiveCustomModelNum]; if (shouldActiveCustomModelPrefab == null) { shouldActiveCustomModelPrefab = VIUSettings.GetOverrideDeviceModel(shouldActiveCustomModelNum); } var shouldActiveCustomModel = enabled && deviceState.isConnected && shouldActiveCustomModelPrefab != null; var lastCreatorActive = m_activeCreatorIndex >= 0; var shouldActiveCreator = enabled && !shouldActiveCustomModel; var shouldActiveCreatorIndex = -1; if (shouldActiveCreator) { // determin which creator should be activated shouldActiveCreatorIndex = m_defaultCreatorIndex; if (m_overrideModel == OverrideModelEnum.DontOverride) { for (int i = 0, imax = m_creators.Length; i < imax; ++i) { if (m_creators[i].shouldActive) { shouldActiveCreatorIndex = i; break; } } } } if (lastCustomModelActive) { if (!shouldActiveCustomModel || lastActiveCustomModelNum != shouldActiveCustomModelNum) { // deactivate custom override model if (lastActiveCustomModelObj != null && SendBeforeModelDeactivatedMessage(lastActiveCustomModelObj, this)) { lastActiveCustomModelObj.gameObject.SetActive(false); } m_isCustomModelActivated = false; } } if (lastCreatorActive) { if (!shouldActiveCreator || m_activeCreatorIndex != shouldActiveCreatorIndex) { // clean up old creator m_creators[m_activeCreatorIndex].CleanUpRenderModel(); m_activeCreatorIndex = -1; } } if (shouldActiveCustomModel) { if (!lastCustomModelActive || lastActiveCustomModelNum != shouldActiveCustomModelNum) { var shouldActiveCustomModelObj = m_customModelObjs[shouldActiveCustomModelNum]; if (shouldActiveCustomModelObj == null) { // instantiate custom override model shouldActiveCustomModelObj = Instantiate(shouldActiveCustomModelPrefab); shouldActiveCustomModelObj.transform.position = Vector3.zero; shouldActiveCustomModelObj.transform.rotation = Quaternion.identity; shouldActiveCustomModelObj.transform.SetParent(transform, false); m_customModelObjs[shouldActiveCustomModelNum] = shouldActiveCustomModelObj; SendAfterModelCreatedMessage(shouldActiveCustomModelObj, this); } // active custom override model if (SendBeforeModelActivatedMessage(shouldActiveCustomModelObj, this)) { shouldActiveCustomModelObj.gameObject.SetActive(true); } m_activeCustomModel = shouldActiveCustomModelNum; m_isCustomModelActivated = true; } } if (shouldActiveCreator) { m_activeCreatorIndex = shouldActiveCreatorIndex; // update active creator m_creators[m_activeCreatorIndex].UpdateRenderModel(); } m_updateModelLock = false; } } } @chengnay Hi, sorry for the late reply. I am getting the error on line 151. HTC.UnityPlugin.Vive.RenderModelHook/DefaultRenderModelCreator:UpdateDefaultRenderModel (bool) (at Assets/HTC.UnityPlugin/ViveInputUtility/Scripts/Misc/RenderModelHook.cs:151 Edited July 22 by 1099 Link to comment Share on other sites More sharing options...
VIVE_chengnay Posted July 24 Share Posted July 24 Hi @1099, Not sure if the error occurrs because of multiple scenes and each scene has a player. How did you load each scene, by additive? Could you explain what is the purpose of the player for each scene? Link to comment Share on other sites More sharing options...
1099 Posted July 27 Author Share Posted July 27 I am not loading scenes by the additive. There are multiple custom player prefabs, so I have many player prefabs, and each scene has a different player prefab. One thing I realized that, I get VIUModelViveController object (I attached the image) under the Hand Model but some of player prefabs won't have these. Do you know why sometime I get this prefab and sometime not? Link to comment Share on other sites More sharing options...
VIVE_chengnay Posted July 27 Share Posted July 27 Hi @1099, Are you able to provide sample project for further investigation? It is hard to get full picture from some screenshots. From my understanding as follows, You have multiple scenes, and each scene has player prefab(what is in the prefab? ViveCameraRig includes camera and left/right hand?). Your app will switch scene by reloading each scene? The issue comes after unloading from A scene to B scene? Link to comment Share on other sites More sharing options...
1099 Posted July 27 Author Share Posted July 27 I can't share the project because this is not my personal project. I wish I could share. You have multiple scenes, and each scene has player prefab(what is in the prefab? ViveCameraRig includes camera and left/right hand?). The player prefab contains many game objects, including ViveCameraRig. All player prefab contain ViveCameraRig and has camera and left/right hand. Your app will switch scene by reloading each scene? This app will switch scenes by AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName); The issue comes after unloading from A scene to B scene? The issue comes when loading Scene A to Scene B. I don't get the error message while I am Scene A but I get this error message when I am in scene B. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now