I am a noob in programming and a complete noob in mirror. And here's my question. I want that when pressed by any player, an item is added to the chest that is visible to all players and all the contents of the chest are displayed correctly for everyone. The text "text1" works completely correctly for everyone, it does not need to be changed. But the display of items in slots (quantity, name, icon) does not work correctly. It displays correctly only for the player who is the host (server). Even when another player adds an item to the chest, the server player displays everything correctly, but the others do not! They do not see the number, name, or icons of objects. Why is that? How to fix it? Although ordinary players have the text "text1" displayed correctly, but the contents of the slots are not. How to fix it? If you need additional information, ask.
Scripts:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Mirror;
public class ChestSlotController : NetworkBehaviour
{
[SerializeField] private Image _image;
[SerializeField] public Text _nameText;
[SerializeField] private Text _countText;
[SerializeField] private Text _descriptionText;
[SerializeField] Sprite _emptyIcon;
[SerializeField] private int _count;
[SerializeField] private string _id;
[SerializeField] private List<Item> _items = new List<Item>();
[SerializeField] private List<string> _idList = new List<string>();
public Item _item;
public void SetItem(string _id, int _count)
{
this._id = _id;
this._item = FindItem(this._id);
this._count = _count;
SetInfo(this._item);
}
private Item FindItem(string _id)
{
for (int i = 0; i <= _idList.Count-1; i++)
{
if (_idList[i] == _id)
{
return _items[i];
}
}
return null;
}
public void AddItem(int _count)
{
this._count += _count;
_countText.text = this._count.ToString();
}
public void RemoveItem()
{
_item = null;
_count = 0;
_nameText.text = "";
_image.sprite = _emptyIcon;
_countText.text = this._count.ToString();
}
private void SetInfo(Item _item)
{
_countText.text = this._count.ToString();
_nameText.text = _item.Name;
_image.sprite = _item.Icon;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Mirror;
using System.Linq;
using System;
public class ChestController : NetworkBehaviour
{
private static ChestController _instance;
public static ChestController Instance { get => _instance; }
[SerializeField] Text text1;
[SerializeField] private List<ChestSlotController> _slots = new List<ChestSlotController>();
[SerializeField] private GameObject _chestUI;
private SyncDictionary<string, int> _content = new SyncDictionary<string, int>();
public Dictionary<string, int> Content = new Dictionary<string, int>();
private void Start()
{
_instance = this;
_content.Callback += OnChestUpdated;
Content = new Dictionary<string, int>(_content.Count);
foreach (KeyValuePair<string, int> kvp in _content)
OnChestUpdated(SyncDictionary<string, int>.Operation.OP_ADD, kvp.Key, kvp.Value);
}
private void FixedUpdate()
{
UpdateUI();
}
[Server]
public void AddItem(string _idItem, int _count)
{
if (_content.ContainsKey(_idItem))
{
_content[_idItem] += _count;
}
else
{
_content.Add(_idItem, _count);
}
Sorting();
}
[Command(requiresAuthority = false)]
public void CmdAddItem(string _idItem, int _count)
{
AddItem(_idItem, _count);
}
private void Sorting()
{
for (int i = 0; i <= _content.Count - 1; i++)
{
_slots[i].SetItem(_content.ElementAt(i).Key, _content.ElementAt(i).Value);
}
}
private void OnChestUpdated(SyncDictionary<string, int>.Operation op, string _idItem, int _count)
{
switch (op)
{
case SyncIDictionary<string, int>.Operation.OP_ADD:
Content.Add(_idItem, _count);
UpdateUI();
break;
case SyncIDictionary<string, int>.Operation.OP_SET:
// entry changed
break;
case SyncIDictionary<string, int>.Operation.OP_REMOVE:
// entry removed
break;
case SyncIDictionary<string, int>.Operation.OP_CLEAR:
// Dictionary was cleared
break;
}
}
private void OnMouseDown()
{
_chestUI.SetActive(!_chestUI.activeSelf);
}
public void CloseButton()
{
_chestUI.SetActive(false);
}
private void UpdateUI()
{
text1.text = string.Join(Environment.NewLine, _content);
}
}
using Mirror;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
[CreateAssetMenu(fileName = "ItemData", menuName = "GameObjects/Item")]
public class Item : ScriptableObject
{
[SerializeField] private string _id;
[SerializeField] private string _name;
[SerializeField] private string _description;
[SerializeField] public Sprite Icon;
public string Id { get => _id; }
public string Name { get => _name; }
public string Description { get => _description; }
}
#region Using
using System;
using UnityEngine;
using UnityEngine.UI;
using Mirror;
using System.Collections;
using System.Collections.Generic;
#endregion
public class Player : NetworkBehaviour
{
#region Physics and Movement
[SerializeField] private Rigidbody2D rb;
private Joystick joystick;
[SerializeField][Range(1, 20)] private float speed;
private Vector2 direction;
private bool facingRight = true;
#endregion
#region Player UI
[SerializeField] Text Nickname;
[SerializeField] private GameObject UIObjects;
#endregion
[SerializeField] List<string> Items = new List<string>();
private void Start()
{
joystick = GameObject.FindGameObjectWithTag("Joystick").GetComponent<Joystick>();
}
private void Update()
{
if (isOwned)
{
if (Input.GetKeyDown(KeyCode.E))
{
CmdAddItemToChest();
}
}
#region Movement
float horizontal = joystick.Horizontal;
float vertical = joystick.Vertical;
if (!facingRight && horizontal > 0)
{
Flip();
}
else if (facingRight && horizontal < 0)
{
Flip();
}
direction = new Vector2(horizontal, vertical);
#endregion
}
private void FixedUpdate()
{
if (isLocalPlayer)
{
#region Movement
rb.MovePosition(rb.position + speed * direction * Time.fixedDeltaTime);
if (isOwned)
{
if (this.transform.localScale.x < 0)
UIObjects.transform.localScale = new Vector2(-1, 1);
if (this.transform.localScale.x > 0)
UIObjects.transform.localScale = new Vector2(1, 1);
}
#endregion
}
}
private void Flip()
{
if (isOwned)
{
facingRight = !facingRight;
Vector3 Scale = transform.localScale;
Scale.x *= -1;
transform.localScale = Scale;
}
}
[Command(requiresAuthority = false)]
public void CmdAddItemToChest()
{
ChestController.Instance.AddItem(Items[UnityEngine.Random.Range(0, Items.Count - 1)], 1);
}
}
[[[enter image description here](https://i.stack.imgur.com/PB1mx.png)](https://i.stack.imgur.com/eWNAj.png)](https://i.stack.imgur.com/rtkqe.png)
Please don't write to me about the unreliability and insecurity of my code. Thank you for any help and any response!