Inuninu
Inuninu2w ago

ModelDataReader and ModelDataWriter are not recognized.RealtimeModel does not expect WriteLength or

i always get this errors , am i missing something?
29 Replies
kapa.ai
kapa.ai2w ago
Hi @Inuninu. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It seems you're encountering issues with ModelDataReader, ModelDataWriter, and RealtimeModel in NormalVR. Based on the knowledge sources provided, I don't have specific information about these exact classes or methods. However, I can provide some insights that might help: 1. The error suggests you might be using outdated or incorrect syntax. NormalVR's documentation doesn't mention ModelDataReader or ModelDataWriter. 2. For serialization in NormalVR, the correct interfaces appear to be IStreamWriter and WriteStream. According to the IStreamWriter documentation, the correct methods are WriteLength and Write. 3. RealtimeModel is a core concept in NormalVR, but it doesn't directly implement WriteLength. Instead, it uses the [RealtimeModel] attribute and [RealtimeProperty] attributes on fields. 4. If you're using an older version of NormalVR, you might need to upgrade. The Upgrading from Normcore 1 to Normcore 2 guide mentions significant changes between versions. 5. Make sure your model is defined correctly. Here's an example of how a RealtimeModel should be structured:
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true, true)]
private Color _color;
}
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true, true)]
private Color _color;
}
6. After defining your model, you need to compile it. In Unity 2021+, this happens automatically. For older Unity versions, you need to manually compile the model in the Unity editor. If you're still encountering issues, it might be helpful to review the RealtimeModel documentation and ensure you're following the correct steps for your Unity version. If these suggestions don't resolve your issue, you might want to check if you have the latest version of NormalVR installed, or reach out to their support for more specific assistance. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant i am using normcore 2.12.0
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Thank you for providing that information. Since you're using Normcore 2.12.0, which is a recent version, the issues you're experiencing shouldn't be related to using an outdated version. Based on the knowledge sources provided, I don't have specific information about version 2.12.0 or the exact errors you're encountering. However, I can offer some general advice based on how Normcore 2 works: 1. In Normcore 2, you shouldn't need to manually implement ModelDataReader, ModelDataWriter, or WriteLength. These might be remnants from an older version or a different system. 2. For Normcore 2, the correct way to create a model is to use the [RealtimeModel] and [RealtimeProperty] attributes. Here's an example of how your model should look:
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true, true)]
private Color _color;
}
[RealtimeModel]
public partial class MyModel {
[RealtimeProperty(1, true, true)]
private Color _color;
}
3. Make sure your model is a partial class, as shown in the example above. This is important for Normcore to generate the necessary code. 4. If you're using Unity 2021 or newer, Normcore should automatically generate the remaining code needed to use your model. You don't need to manually implement serialization methods like WriteLength. 5. If you're still seeing references to ModelDataReader and ModelDataWriter in your code, you might want to remove them as they're not part of the current Normcore API. If you're still encountering issues after checking these points, I recommend reaching out to the Normcore community on their Discord for further assistance. They might be able to provide more specific help based on your exact implementation and the full error messages you're seeing. Common Questions ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
can i post my full code here? @Normcore Assistant is it okay if i post my full code here
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Certainly! While I'd be happy to look at your code, I want to make you aware that this chat doesn't have a way for you to directly upload or paste large code snippets. However, if you have a specific part of your code that you think is causing the issue, you can share that shorter snippet here. If you need to share a larger amount of code, I'd recommend using a code sharing service like GitHub Gist or Pastebin, and then sharing the link here. That way, we can look at your full implementation without overwhelming the chat. Alternatively, for more comprehensive support and code review, you might want to consider reaching out to the Normcore community on their Discord. The community there is likely to be very familiar with common issues and can provide more interactive support. Remember, when sharing code, it's always a good idea to remove any sensitive information like API keys or personal data. Let me know how you'd like to proceed! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant is ths conversation public or private
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize, but I'm specifically designed to answer questions about NormalVR and its related technologies. This question about the privacy of our conversation is not directly related to NormalVR. If you have any questions about NormalVR, its features, implementation, or usage, I'd be happy to assist you with those. Is there anything specific about NormalVR you'd like to know? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant public class TreeChopperModel : RealtimeModel { public delegate void SliceHandler(int targetID); public event SliceHandler sliceEvent; private int _targetID; protected override void WriteLength(WriteStream stream, StreamContext context) { stream.WriteInt32(sizeof(int)); } protected override void Write(WriteStream stream, StreamContext context) { stream.WriteInt32(_targetID); } protected override void Read(ReadStream stream, StreamContext context) { _targetID = stream.ReadInt32(); sliceEvent?.Invoke(_targetID); } public void RequestSlice(int targetID) { _targetID = targetID; Dirty(); sliceEvent?.Invoke(_targetID); } Assets\TreeChopper.cs(143,29): error CS0115: 'TreeChopperModel.WriteLength(WriteStream, StreamContext)': no suitable method found to overrideAssets\TreeChopper.cs(136,14): error CS0534: 'TreeChopperModel' does not implement inherited abstract member 'RealtimeModel.WriteLength(StreamContext)'
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Thank you for sharing your code and the error messages. It appears you're encountering issues with implementing a RealtimeModel in Normcore 2.12.0. Let's address the problems based on the information provided in the knowledge sources: 1. The main issue is that you're trying to override methods that don't exist in the current version of Normcore. In Normcore 2, the serialization process is handled differently. 2. The RealtimeModel class doesn't expect you to manually implement WriteLength, Write, or Read methods. Instead, it uses attributes to generate the necessary serialization code. Here's how you should structure your TreeChopperModel class:
[RealtimeModel]
public partial class TreeChopperModel : RealtimeModel
{
public delegate void SliceHandler(int targetID);
public event SliceHandler sliceEvent;

[RealtimeProperty(1, true)]
private int _targetID;

public void RequestSlice(int targetID)
{
_targetID = targetID;
sliceEvent?.Invoke(_targetID);
}
}
[RealtimeModel]
public partial class TreeChopperModel : RealtimeModel
{
public delegate void SliceHandler(int targetID);
public event SliceHandler sliceEvent;

[RealtimeProperty(1, true)]
private int _targetID;

public void RequestSlice(int targetID)
{
_targetID = targetID;
sliceEvent?.Invoke(_targetID);
}
}
Key changes: 1. Add the [RealtimeModel] attribute to the class. 2. Make the class partial. This allows Normcore to generate additional code for your model. 3. Use the [RealtimeProperty] attribute for the _targetID field. The 1 is the property ID, and true indicates it should sync reliably. 4. Remove the WriteLength, Write, and Read methods. Normcore will generate these for you. 5. Remove the Dirty() call in RequestSlice. The setter generated by Normcore will handle this automatically. After making these changes, you need to let Normcore generate the model code: - If you're using Unity 2021 or newer, this should happen automatically. - For older Unity versions, you need to manually compile the model in the Unity editor. These changes should resolve the errors you're seeing. The RealtimeModel base class doesn't have WriteLength, Write, or Read methods for you to override in Normcore 2. For more information on creating and using Realtime Models, you can refer to the RealtimeModel documentation. If you're still encountering issues after making these changes, please let me know, and we can troubleshoot further. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant [RealtimeModel] public partial class TreeChopperModel : RealtimeModel { public delegate void SliceHandler(int targetID); public event SliceHandler sliceEvent; [RealtimeProperty(1, true)] private int _targetID; public void RequestSlice(int targetID) { _targetID = targetID; sliceEvent?.Invoke(_targetID); } // Auto-generated by Normcore, but we can add partial methods to handle changes partial void OnTargetIDChanged() { sliceEvent?.Invoke(_targetID); }error CS0759: No defining declaration found for implementing declaration of partial method 'TreeChopperModel.OnTargetIDChanged()'TreeChopperModel' does not implement inherited abstract member 'RealtimeModel.Read(ReadStream, StreamContext)' error CS0534: 'TreeChopperModel' does not implement inherited abstract member 'RealtimeModel.Write(WriteStream, StreamContext)' error CS0534: 'TreeChopperModel' does not implement inherited abstract member 'RealtimeModel.WriteLength(StreamContext)'
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Thank you for sharing your updated code and the new error messages. It seems you're still encountering some issues with your TreeChopperModel implementation in Normcore. Let's address these errors one by one: 1. The error about the partial method OnTargetIDChanged() suggests that Normcore isn't generating the expected code for your model. This could be due to a few reasons: - Make sure you've saved your script and allowed Unity to recompile after making changes. - If you're using Unity 2021 or newer, Normcore should automatically generate the model code. For older Unity versions, you need to manually compile the model in the Unity editor. 2. The errors about not implementing abstract members Read(), Write(), and WriteLength() indicate that your RealtimeModel base class is not being recognized correctly. This could be because: - The Normcore package might not be properly imported or referenced in your project. - There might be a version mismatch or conflict in your project. To resolve these issues, try the following steps: 1. Ensure that your Normcore package is up to date and properly imported. You can check this in the Unity Package Manager. 2. Remove the partial method OnTargetIDChanged() for now. While Normcore does generate these methods, manually declaring them can sometimes cause issues if the code generation isn't working correctly. 3. Make sure your class definition looks exactly like this:
[RealtimeModel]
public partial class TreeChopperModel : RealtimeModel
{
public delegate void SliceHandler(int targetID);
public event SliceHandler sliceEvent;

[RealtimeProperty(1, true)]
private int _targetID;

public void RequestSlice(int targetID)
{
_targetID = targetID;
sliceEvent?.Invoke(_targetID);
}
}
[RealtimeModel]
public partial class TreeChopperModel : RealtimeModel
{
public delegate void SliceHandler(int targetID);
public event SliceHandler sliceEvent;

[RealtimeProperty(1, true)]
private int _targetID;

public void RequestSlice(int targetID)
{
_targetID = targetID;
sliceEvent?.Invoke(_targetID);
}
}
4. If you're using Unity 2021 or newer, try closing and reopening your project to trigger a full recompile. 5. If you're using an older version of Unity, manually compile the model by selecting the script in the Unity editor and clicking the "Compile Model" button (if available). 6. If the issues persist, try creating a new script with just this model definition and see if it compiles correctly. This can help isolate whether the problem is with this specific model or a broader issue with your Normcore setup. If you're still encountering problems after trying these steps, it might be helpful to check your Normcore and Unity versions, and ensure they are compatible. You may also want to consider reaching out to the Normcore community on their Discord for more specific troubleshooting, as they might be aware of any recent issues or have more detailed debugging steps for your particular setup. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant i want to sync the slices of the mesh such that every one can see the same slices,how do i do that using normcode
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To synchronize mesh slices across all clients using Normcore, you'll need to create a custom RealtimeComponent that manages the state of your mesh slices. Here's a general approach to achieve this: 1. Create a RealtimeModel to store the slice data:
[RealtimeModel]
public partial class MeshSliceModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3> _slicePositions;

[RealtimeProperty(2, true)]
private RealtimeArray<Quaternion> _sliceRotations;
}
[RealtimeModel]
public partial class MeshSliceModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3> _slicePositions;

[RealtimeProperty(2, true)]
private RealtimeArray<Quaternion> _sliceRotations;
}
2. Create a RealtimeComponent to manage the synchronization:
public class MeshSlicer : RealtimeComponent<MeshSliceModel>
{
private Mesh _mesh;

private void Awake()
{
_mesh = GetComponent<MeshFilter>().mesh;
}

protected override void OnRealtimeModelReplaced(MeshSliceModel previousModel, MeshSliceModel currentModel)
{
if (previousModel != null)
{
// Unregister from events
previousModel.slicePositions.didInsert -= OnSliceInserted;
}

if (currentModel != null)
{
if (currentModel.isFreshModel)
{
// Initialize with empty arrays
currentModel.slicePositions = new RealtimeArray<Vector3>();
currentModel.sliceRotations = new RealtimeArray<Quaternion>();
}

// Register for events
currentModel.slicePositions.didInsert += OnSliceInserted;

// Apply existing slices
ApplySlices();
}
}

private void OnSliceInserted(RealtimeArray<Vector3> array, int index, Vector3 value)
{
// Apply the new slice
ApplySlice(model.slicePositions[index], model.sliceRotations[index]);
}
private void ApplySlices()
{
for (int i = 0; i < model.slicePositions.Count; i++)
{
ApplySlice(model.slicePositions[i], model.sliceRotations[i]);
}
}

private void ApplySlice(Vector3 position, Quaternion rotation)
{
// Implement your mesh slicing logic here
// This will depend on how you're actually slicing the mesh
}

public void AddSlice(Vector3 position, Quaternion rotation)
{
model.slicePositions.Add(position);
model.sliceRotations.Add(rotation);

// The slice will be applied via the OnSliceInserted event
}
}
public class MeshSlicer : RealtimeComponent<MeshSliceModel>
{
private Mesh _mesh;

private void Awake()
{
_mesh = GetComponent<MeshFilter>().mesh;
}

protected override void OnRealtimeModelReplaced(MeshSliceModel previousModel, MeshSliceModel currentModel)
{
if (previousModel != null)
{
// Unregister from events
previousModel.slicePositions.didInsert -= OnSliceInserted;
}

if (currentModel != null)
{
if (currentModel.isFreshModel)
{
// Initialize with empty arrays
currentModel.slicePositions = new RealtimeArray<Vector3>();
currentModel.sliceRotations = new RealtimeArray<Quaternion>();
}

// Register for events
currentModel.slicePositions.didInsert += OnSliceInserted;

// Apply existing slices
ApplySlices();
}
}

private void OnSliceInserted(RealtimeArray<Vector3> array, int index, Vector3 value)
{
// Apply the new slice
ApplySlice(model.slicePositions[index], model.sliceRotations[index]);
}
private void ApplySlices()
{
for (int i = 0; i < model.slicePositions.Count; i++)
{
ApplySlice(model.slicePositions[i], model.sliceRotations[i]);
}
}

private void ApplySlice(Vector3 position, Quaternion rotation)
{
// Implement your mesh slicing logic here
// This will depend on how you're actually slicing the mesh
}

public void AddSlice(Vector3 position, Quaternion rotation)
{
model.slicePositions.Add(position);
model.sliceRotations.Add(rotation);

// The slice will be applied via the OnSliceInserted event
}
}
3. Add the MeshSlicer component to your mesh object in the scene. 4. To add a new slice, call the AddSlice method:
meshSlicer.AddSlice(slicePosition, sliceRotation);
meshSlicer.AddSlice(slicePosition, sliceRotation);
This approach uses Normcore's RealtimeArray to synchronize an array of slice positions and rotations. When a new slice is added, it's synchronized across all clients, and each client applies the slice to their local mesh. A few important points: 1. The actual mesh slicing logic isn't included here, as it depends on how you're implementing the slicing. You'll need to implement the ApplySlice method based on your specific slicing algorithm. 2. This example assumes that slices are only added, not removed or modified. If you need more complex operations, you might need to adjust the model and component accordingly. 3. Make sure your mesh object has a RealtimeView component in addition to the MeshSlicer component. 4. The synchronization of the actual modified mesh data isn't included here. If your slices significantly alter the mesh data, you might need to synchronize that as well, which would require a more complex approach. For more detailed information on using RealtimeComponents and synchronizing custom data, you can refer to the Synchronizing Custom Data guide. Remember to test thoroughly in a multiplayer setting to ensure that the slices are correctly synchronized across all clients. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant private void HandleSliceAdded(RealtimeArray<uint> slicedObjectIDs, int index, uint realtimeID) { Vector3 position = model.slicePositions[index]; Vector3 normal = model.sliceNormals[index]; ApplySlice(realtimeID, position, normal); } Assets\TreeChopper.cs(66,55): error CS0315: The type 'uint' cannot be used as type parameter 'TValue' in the generic type or method 'RealtimeArray<TValue>'. There is no boxing conversion from 'uint' to 'Normal.Realtime.Serialization.IModel'.
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Thank you for sharing your code and the error message. It seems you're encountering an issue with the RealtimeArray<uint> in your Normcore implementation. Let's address this based on the information from the knowledge sources: The error suggests that uint cannot be used directly as a type parameter for RealtimeArray. This is because RealtimeArray is designed to work with RealtimeModel types, not primitive types like uint. To resolve this issue, you have a couple of options: 1. Use RealtimeArray<int> instead of RealtimeArray<uint>. Normcore supports int as a primitive type for RealtimeArray. Here's how you can modify your code:
private void HandleSliceAdded(RealtimeArray<int> slicedObjectIDs, int index, int realtimeID)
{
Vector3 position = model.slicePositions[index];
Vector3 normal = model.sliceNormals[index];
ApplySlice((uint)realtimeID, position, normal);
}
private void HandleSliceAdded(RealtimeArray<int> slicedObjectIDs, int index, int realtimeID)
{
Vector3 position = model.slicePositions[index];
Vector3 normal = model.sliceNormals[index];
ApplySlice((uint)realtimeID, position, normal);
}
2. If you absolutely need to use uint, you can create a custom RealtimeModel to wrap the uint value:
[RealtimeModel]
public partial class UIntWrapper
{
[RealtimeProperty(1, true)]
private uint _value;

public uint Value
{
get => _value;
set => _value = value;
}
}
[RealtimeModel]
public partial class UIntWrapper
{
[RealtimeProperty(1, true)]
private uint _value;

public uint Value
{
get => _value;
set => _value = value;
}
}
Then use RealtimeArray<UIntWrapper> instead:
private void HandleSliceAdded(RealtimeArray<UIntWrapper> slicedObjectIDs, int index, UIntWrapper realtimeID)
{
Vector3 position = model.slicePositions[index];
Vector3 normal = model.sliceNormals[index];
ApplySlice(realtimeID.Value, position, normal);
}
private void HandleSliceAdded(RealtimeArray<UIntWrapper> slicedObjectIDs, int index, UIntWrapper realtimeID)
{
Vector3 position = model.slicePositions[index];
Vector3 normal = model.sliceNormals[index];
ApplySlice(realtimeID.Value, position, normal);
}
The first option is simpler and likely sufficient for most use cases. The second option provides more flexibility but adds complexity. Remember to update your model definition accordingly:
[RealtimeModel]
public partial class YourModel : RealtimeModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<int> _slicedObjectIDs; // Or RealtimeArray<UIntWrapper> if using option 2

[RealtimeProperty(2, true)]
private RealtimeArray<Vector3> _slicePositions;

[RealtimeProperty(3, true)]
private RealtimeArray<Vector3> _sliceNormals;
}
[RealtimeModel]
public partial class YourModel : RealtimeModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<int> _slicedObjectIDs; // Or RealtimeArray<UIntWrapper> if using option 2

[RealtimeProperty(2, true)]
private RealtimeArray<Vector3> _slicePositions;

[RealtimeProperty(3, true)]
private RealtimeArray<Vector3> _sliceNormals;
}
For more information on supported types and collections in Normcore, you can refer to the Supported Primitives and Collections documentation. If you're still encountering issues after making these changes, please let me know, and we can troubleshoot further. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Inuninu
InuninuOP2w ago
@Normcore Assistant how can i fix these issue Normal.Realtime.SourceGenerators\Normal.Realtime.SourceGenerators.RealtimeModelSourceGenerator\TreeChopperSyncModel.g.cs(28,93): error CS0315: The type 'UnityEngine.Vector3' cannot be used as type parameter 'TValue' in the generic type or method 'RealtimeArray<TValue>'. There is no boxing conversion from 'UnityEngine.Vector3' to 'Normal.Realtime.Serialization.IModel'.
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Thank you for sharing the error message. This issue is related to how Normcore handles certain types in RealtimeArray. Let's address this based on the information from the knowledge sources: The error suggests that Vector3 cannot be used directly as a type parameter for RealtimeArray. This is because RealtimeArray is designed to work with RealtimeModel types or specific supported primitives. To resolve this issue, you have a couple of options: 1. Use a supported collection type for Vector3. According to the Supported Primitives documentation, Vector3 is a supported Unity primitive, but it needs to be used with the correct collection type. Instead of RealtimeArray<Vector3>, you should use RealtimeArray<Vector3Serializer>. Here's how you can modify your model:
[RealtimeModel]
public partial class TreeChopperSyncModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3Serializer> _slicePositions;

// ... other properties
}
[RealtimeModel]
public partial class TreeChopperSyncModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3Serializer> _slicePositions;

// ... other properties
}
2. If you prefer to keep using Vector3 directly, you can create a custom RealtimeModel to wrap the Vector3 value:
[RealtimeModel]
public partial class Vector3Wrapper
{
[RealtimeProperty(1, true)]
private Vector3 _value;

public Vector3 Value
{
get => _value;
set => _value = value;
}
}
[RealtimeModel]
public partial class Vector3Wrapper
{
[RealtimeProperty(1, true)]
private Vector3 _value;

public Vector3 Value
{
get => _value;
set => _value = value;
}
}
Then use RealtimeArray<Vector3Wrapper> in your TreeChopperSyncModel:
[RealtimeModel]
public partial class TreeChopperSyncModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3Wrapper> _slicePositions;

// ... other properties
}
[RealtimeModel]
public partial class TreeChopperSyncModel
{
[RealtimeProperty(1, true)]
private RealtimeArray<Vector3Wrapper> _slicePositions;

// ... other properties
}
The first option is simpler and directly supported by Normcore. The second option provides more flexibility but adds complexity. After making these changes, make sure to save your scripts and let Unity recompile. If you're using Unity 2021 or newer, Normcore should automatically regenerate the model code. For older Unity versions, you may need to manually compile the model in the Unity editor. If you're still encountering issues after making these changes, please let me know, and we can troubleshoot further. Remember, when working with Normcore, it's important to use the supported types and collections as outlined in their documentation. Supported Primitives Collections ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@354846683693187082> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
maxweisel
maxweisel2w ago
@NormalMark @Scott will you take a look at this one?
NormalMark
NormalMark2w ago
@Inuninu Hey, here's how your original code would look in current Normcore. Note that change events can now be automatically generated (it's now an argument inside the RealtimeProperty attribute).
c#
[RealtimeModel]
public partial class TreeChopperModel
{
[RealtimeProperty(1, true, true)]
private int _targetID;
}

public class TreeChopper : RealtimeComponent<TreeChopperModel>
{
protected override void OnRealtimeModelReplaced(TreeChopperModel previousModel, TreeChopperModel currentModel)
{
if (previousModel != null)
{
previousModel.targetIDDidChange -= OnTargetIDChanged;
}

if (currentModel != null)
{
currentModel.targetIDDidChange += OnTargetIDChanged;
}
}

private void OnTargetIDChanged(TreeChopperModel currentModel, int value)
{
// Example
Debug.Log(value);
}
}
c#
[RealtimeModel]
public partial class TreeChopperModel
{
[RealtimeProperty(1, true, true)]
private int _targetID;
}

public class TreeChopper : RealtimeComponent<TreeChopperModel>
{
protected override void OnRealtimeModelReplaced(TreeChopperModel previousModel, TreeChopperModel currentModel)
{
if (previousModel != null)
{
previousModel.targetIDDidChange -= OnTargetIDChanged;
}

if (currentModel != null)
{
currentModel.targetIDDidChange += OnTargetIDChanged;
}
}

private void OnTargetIDChanged(TreeChopperModel currentModel, int value)
{
// Example
Debug.Log(value);
}
}
This is for a single slice Are you looking for a version for multiple targetIDs?
Inuninu
InuninuOP2w ago
yes,and thanks

Did you find this page helpful?