khoi
khoi3d ago

failed to set model on component - when does this happen?

ERROR: Failed to set model on component (1:ArenaPvE (ArenaPveSync)). UnityEngine.Debug:LogError (object) Normal.Realtime.RealtimeView:BindModelsToComponentMap (Normal.Realtime.ImmutableModelCollection,Normal.Realtime.RealtimeComponentMap) Normal.Realtime.RealtimeView:Normal.Realtime.IConfigurableComponent.SetModel (Normal.Realtime.RealtimeModel) Normal.Realtime.Realtime:ReplaceSceneViewModelWithFreshModel (Normal.Realtime.RealtimeView) Normal.Realtime.Realtime:RegisterSceneRealtimeView (Normal.Realtime.RealtimeView) Normal.Realtime.RealtimeView:Start () REALTIME COMPONENT: (attached) REALTIME MODEL: using Normal.Realtime; using Normal.Realtime.Serialization; [RealtimeModel] public partial class ArenaPveSyncModel { [RealtimeProperty(1, true, true)] private int _waveIndex; [RealtimeProperty(2, true, true)] private int _enemyCount; [RealtimeProperty(3, true, true)] private int _enemySetIndex; [RealtimeProperty(4, true, true)] private double _waveStartTime; [RealtimeProperty(5, true, true)] private RealtimeDictionary<EnemyIdModel> _spawnedEnemyIds; }
12 Replies
kapa.ai
kapa.ai3d ago
Hi @khoi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The error "Failed to set model on component" in Normcore typically occurs when there is a mismatch or issue connecting your custom RealtimeComponent (e.g., ArenaPveSync) to its corresponding RealtimeModel (e.g., ArenaPveSyncModel). According to the documentation, this can happen for several reasons: 1. Component Added Before Subclassing: If you added your custom component to a GameObject before it was converted to a RealtimeComponent subclass, Unity may not properly register it with the RealtimeView. To fix this, remove the component from the GameObject and re-add it. This ensures that the RealtimeView recognizes your component and includes it in its list of components. If your component does not appear in the RealtimeView's list, this is likely the issue [Synchronizing Custom Data FAQ]. 2. Prefab or Scene Setup Issues: If the prefab or scene object is not set up correctly, such as missing the RealtimeView or having a corrupt prefab, the model may not be set on the component. The documentation notes that the model is set by Realtime when you connect to the room, and this process can fail if the RealtimeComponent is not properly referenced by the RealtimeView [Common Questions]. 3. Incorrect Instantiation: If you instantiate your object using Unity’s Instantiate() instead of Normcore’s Realtime.Instantiate(), the Realtime system will not properly set up the model and component connections. Always use Realtime.Instantiate() for networked objects [Common Questions]. 4. Model Compilation Issues: If your model class has not been compiled correctly (e.g., due to compile errors or missing the [RealtimeModel] and [RealtimeProperty] attributes), the auto-generated code required for synchronization will not be present, and the model cannot be set on the component [Compiling a model]. What to check: - Ensure your ArenaPveSync component is a subclass of RealtimeComponent<ArenaPveSyncModel>. - Remove and re-add the component to the GameObject to refresh the RealtimeView’s component list. - Confirm that your prefab or scene object has a valid RealtimeView and that your component appears in its list. - Use Realtime.Instantiate() for networked objects. - Make sure your model compiles without errors and has the correct attributes. If you follow these steps and the error persists, double-check the setup in the Unity Editor and ensure there are no compilation errors in your project. If the component still fails to receive its model, it is likely due to one of the issues above [Synchronizing Custom Data FAQ]. If you need more specific troubleshooting, please provide details about how the component and model are attached and instantiated in your scene or prefab. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel3d ago
There should be more to the error than that. It should tell you what failed exactly. (ie null model, etc) Do you have any other errors logged with that one?
khoi
khoiOP3d ago
NullReferenceException: Object reference not set to an instance of an object ArenaPveSync.SetEnemySetIndex (System.Int32 enemySetIndex) (at Assets/_Scripts/RealtimeComponents/ArenaPveSync.cs:186) ArenaPveManager.OnWaveStartTimeChanged (System.Double waveStartTime) (at Assets/_Scripts/ArenaPveManager.cs:378) ArenaPveSync.UpdateWaveStartTimeFromModel () (at Assets/_Scripts/RealtimeComponents/ArenaPveSync.cs:71) ArenaPveSync.UpdateFromModel () (at Assets/_Scripts/RealtimeComponents/ArenaPveSync.cs:65) ArenaPveSync.OnRealtimeModelReplaced (ArenaPveSyncModel previousModel, ArenaPveSyncModel currentModel) (at Assets/_Scripts/RealtimeComponents/ArenaPveSync.cs:50) Normal.Realtime.RealtimeComponent`1[TModel].Normal.Realtime.IConfigurableComponent.SetModel (Normal.Realtime.RealtimeModel model) (at <36464fac2b844b89b252d65a2d4b5f20>:0) Normal.Realtime.RealtimeView.BindModelsToComponentMap (Normal.Realtime.ImmutableModelCollection models, Normal.Realtime.RealtimeComponentMap components) (at <36464fac2b844b89b252d65a2d4b5f20>:0) UnityEngine.Debug:LogException(Exception) Normal.Realtime.RealtimeView:BindModelsToComponentMap(ImmutableModelCollection, RealtimeComponentMap) Normal.Realtime.RealtimeView:Normal.Realtime.IConfigurableComponent.SetModel(RealtimeModel) Normal.Realtime.Realtime:ReplaceSceneViewModelWithFreshModel(RealtimeView) Normal.Realtime.Realtime:RegisterSceneRealtimeView(RealtimeView) Normal.Realtime.RealtimeView:Start() basically i have it so that when WaveStartTime is changed, my other script calls SetWaveIndex. My guess is that when it is a fresh model, it's calling this on fresh before there is a model, so model is null?
khoi
khoiOP3d ago
if i add this check for waveStartTime > 0 (eg not a fresh model) it works
No description
maxweisel
maxweisel3d ago
It looks like you have code inside of OnRealtimeModelReplaced that hits an exception and it bubbles up to Normcore which says it failed to set the model in general don’t change other game objects or models from inside OnRealtimeModelReplaced it’s a good place to set up the model being set, not a good place to perform game logic
khoi
khoiOP3d ago
protected override void OnRealtimeModelReplaced( ArenaPveSyncModel previousModel, ArenaPveSyncModel currentModel ) { if (previousModel != null) { currentModel.waveIndexDidChange -= WaveIndexDidChange; currentModel.enemyCountDidChange -= EnemyCountDidChange; currentModel.enemySetIndexDidChange -= EnemySetIndexDidChange; currentModel.waveStartTimeDidChange -= WaveStartTimeDidChange; currentModel.spawnedEnemyIds.modelAdded -= SpawnedEnemyIdsDidAdd; currentModel.spawnedEnemyIds.modelRemoved -= SpawnedEnemyIdsDidRemove; } if (currentModel != null) { if (currentModel.isFreshModel) { currentModel.waveIndex = WaveIndex; currentModel.enemyCount = EnemyCount; currentModel.enemySetIndex = EnemySetIndex; currentModel.waveStartTime = WaveStartTime; } UpdateFromModel(); currentModel.waveIndexDidChange += WaveIndexDidChange; currentModel.enemyCountDidChange += EnemyCountDidChange; currentModel.enemySetIndexDidChange += EnemySetIndexDidChange; currentModel.waveStartTimeDidChange += WaveStartTimeDidChange; currentModel.spawnedEnemyIds.modelAdded += SpawnedEnemyIdsDidAdd; currentModel.spawnedEnemyIds.modelRemoved += SpawnedEnemyIdsDidRemove; } }
maxweisel
maxweisel3d ago
it’s just there so you can subscribe / unsubscribe from model events. your stack trace shows your trying to perform actions on other state in the game
khoi
khoiOP3d ago
ok so dont bind game logic to WaveStartTimeDidChange hmmm my code in onrealtimemodelreplaced doesnt do anything to other game objects, but UpdateFromModel() does? Isn't that the correct pattern?
maxweisel
maxweisel3d ago
Or don’t call it from OnRealtimeModelReplaced Normcore explicitly doesn’t fire change events when models are set for this reason. If you need that, UpdateFromModel should signal that it didn’t change but instead this is the initial value being set and save game related logic for later on in the frame when all models are updated
khoi
khoiOP3d ago
Okay, so like. In here, I should check if they are fresh values (eg == 0 or == -1). And don't do anything unless they are not fresh values.
No description
khoi
khoiOP3d ago
since these can be called initally when they are set from a fresh model

Did you find this page helpful?