diff --git a/Assets/Mirror/Core/SyncList.cs b/Assets/Mirror/Core/SyncList.cs
index 20775ad91..6f4952e4e 100644
--- a/Assets/Mirror/Core/SyncList.cs
+++ b/Assets/Mirror/Core/SyncList.cs
@@ -27,6 +27,14 @@ public enum Operation : byte
/// This is called after the item is removed with index and OLD Value
public Action OnRemove;
+ ///
+ /// This is called for all changes to the List.
+ /// For OP_ADD and OP_INSERT, T is the NEW value of the entry.
+ /// For OP_SET and OP_REMOVE, T is the OLD value of the entry.
+ /// For OP_CLEAR, T is default.
+ ///
+ public Action OnChange;
+
/// This is called before the list is cleared so the list can be iterated
public Action OnClear;
@@ -106,18 +114,23 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA
{
case Operation.OP_ADD:
OnAdd?.Invoke(itemIndex);
+ OnChange?.Invoke(op, itemIndex, newItem);
break;
case Operation.OP_INSERT:
OnInsert?.Invoke(itemIndex);
+ OnChange?.Invoke(op, itemIndex, newItem);
break;
case Operation.OP_SET:
OnSet?.Invoke(itemIndex, oldItem);
+ OnChange?.Invoke(op, itemIndex, oldItem);
break;
case Operation.OP_REMOVEAT:
OnRemove?.Invoke(itemIndex, oldItem);
+ OnChange?.Invoke(op, itemIndex, oldItem);
break;
case Operation.OP_CLEAR:
OnClear?.Invoke();
+ OnChange?.Invoke(op, itemIndex, default);
break;
}
diff --git a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs
index 752237979..c87da8cc4 100644
--- a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs
+++ b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs
@@ -463,10 +463,20 @@ public void CallbackTest()
Assert.That(clientSyncList[index], Is.EqualTo("yay"));
};
+ bool changeActionCalled = false;
+ clientSyncList.OnChange = (op, index, oldItem) =>
+ {
+ changeActionCalled = true;
+ Assert.That(op, Is.EqualTo(SyncList.Operation.OP_ADD));
+ Assert.That(index, Is.EqualTo(3));
+ Assert.That(oldItem, Is.EqualTo("yay"));
+ };
+
serverSyncList.Add("yay");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
+ Assert.That(changeActionCalled, Is.True);
}
[Test]
@@ -492,10 +502,20 @@ public void CallbackRemoveTest()
Assert.That(oldItem, Is.EqualTo("World"));
};
+ bool changeActionCalled = false;
+ clientSyncList.OnChange = (op, index, oldItem) =>
+ {
+ changeActionCalled = true;
+ Assert.That(op, Is.EqualTo(SyncList.Operation.OP_REMOVEAT));
+ Assert.That(index, Is.EqualTo(1));
+ Assert.That(oldItem, Is.EqualTo("World"));
+ };
+
serverSyncList.Remove("World");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
+ Assert.That(changeActionCalled, Is.True);
}
[Test]
@@ -522,10 +542,20 @@ public void CallbackRemoveAtTest()
Assert.That(oldItem, Is.EqualTo("World"));
};
+ bool changeActionCalled = false;
+ clientSyncList.OnChange = (op, index, oldItem) =>
+ {
+ changeActionCalled = true;
+ Assert.That(op, Is.EqualTo(SyncList.Operation.OP_REMOVEAT));
+ Assert.That(index, Is.EqualTo(1));
+ Assert.That(oldItem, Is.EqualTo("World"));
+ };
+
serverSyncList.RemoveAt(1);
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
+ Assert.That(changeActionCalled, Is.True);
}
[Test]