Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(SyncDictionary): Add individual Actions for operations #3791

Merged
merged 2 commits into from
Mar 23, 2024

Conversation

MrGadget1024
Copy link
Collaborator

@MrGadget1024 MrGadget1024 commented Mar 22, 2024

  • Set and Remove Actions pass OLD item
  • Deprecates Callback Action

With the new Set and Remove Actions, users will be able to do work with the previous values, while accessing the new values by the dictionary key.

Below is an example that would be applicable for a card game or inventory:

using UnityEngine;
using Mirror;
using System;

public class SyncDictTest : NetworkBehaviour
{
    public struct ItemData
    {
        public byte prefabIndex;
        public Vector3 position;
        public Quaternion rotation;

        // this is not networked or serialized, it's only used on the client
        // to hold reference to the instantiated object for a dictionary item.
        [NonSerialized]
        public GameObject clientObject;

        public void CreateClientObject(GameObject prefab, Vector3 pos, Quaternion rot)
        {
            clientObject = Instantiate(prefab, pos, rot);
        }
    }

    public GameObject[] prefabs;

    public readonly SyncDictionary<ushort, ItemData> dict = new SyncDictionary<ushort, ItemData>();

    ushort nextIndex = 0;

    void Awake()
    {
        dict.OnAdd = OnAdd;
        dict.OnSet = OnSet;
        dict.OnRemove = OnRemove;
        dict.OnClear = OnClear;
    }

    public override void OnStartClient()
    {
        // Handlers not setup when spawned...call OnAdd for each.
        foreach (ushort key in dict.Keys)
            dict.OnAdd?.Invoke(key);
    }

    void OnAdd(ushort key)
    {
        dict[key].CreateClientObject(prefabs[dict[key].prefabIndex], dict[key].position, dict[key].rotation);
    }

    void OnSet(ushort key, ItemData oldItem)
    {
        if (dict[key].prefabIndex != oldItem.prefabIndex)
        {
            if (oldItem.clientObject != null)
                Destroy(oldItem.clientObject);

            dict[key].CreateClientObject(prefabs[dict[key].prefabIndex], dict[key].position, dict[key].rotation);
        }
        else
        {
            oldItem.clientObject.transform.position = dict[key].position;
            oldItem.clientObject.transform.rotation = dict[key].rotation;
        }
    }

    void OnRemove(ushort key, ItemData oldItem)
    {
        if (oldItem.clientObject != null)
            Destroy(oldItem.clientObject);
    }

    void OnClear()
    {
        foreach (ItemData itemData in dict.Values)
            if (itemData.clientObject != null)
                Destroy(itemData.clientObject);
    }

    [Command]
    public void CmdAddItem(byte prefabIndex, Vector3 position, Quaternion rotation)
    {
        dict[nextIndex] = new ItemData
        {
            prefabIndex = prefabIndex,
            position = position,
            rotation = rotation
        };

        nextIndex++;
    }

    [Command]
    public void CmdSetItem(ushort key, byte prefabIndex, Vector3 position, Quaternion rotation)
    {
        if (dict.TryGetValue(key, out ItemData item))
        {
            item.prefabIndex = prefabIndex;
            item.position = position;
            item.rotation = rotation;
            dict[key] = item;
        }
    }

    [Command]
    public void CmdReplaceItem(ushort key, byte prefabIndex)
    {
        if (dict.TryGetValue(key, out ItemData item))
        {
            item.prefabIndex = prefabIndex;
            dict[key] = item;
        }
    }

    [Command]
    public void CmdMoveItem(ushort key, Vector3 position)
    {
        if (dict.TryGetValue(key, out ItemData item))
        {
            item.position = position;
            dict[key] = item;
        }
    }

    [Command]
    public void CmdRotateItem(ushort key, Quaternion rotation)
    {
        if (dict.TryGetValue(key, out ItemData item))
        {
            item.rotation = rotation;
            dict[key] = item;
        }
    }

    [Command]
    public void CmdRemoveItem(ushort key)
    {
        dict.Remove(key);
    }

    [Command]
    public void CmdClearItems()
    {
        dict.Clear();
    }
}

- Set and Remove Actions pass **OLD** item
- Deprecates Callback Action

With the new Set and Remove Actions, users will be able to do work with the previous values, while accessing the new values by the dictionary key.
@miwarnec miwarnec merged commit 81238b6 into master Mar 23, 2024
7 checks passed
@miwarnec miwarnec deleted the SyncDictActions branch March 23, 2024 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants