I have a system in my game. To summarize briefly, there is a UI in my Player prefab and this UI should show my active slot.
There is no problem when a single player enters the game, but when a second player enters, things get complicated.
When player 1 presses 1,2,3,4, it controls player 2’s UI and vice versa.
How can I solve this problem?
using UnityEngine;
using Photon.Pun;
using UnityEngine.UI;
using System.Collections;
public class InventorySystem : MonoBehaviourPunCallbacks
{
public Transform holdPosition;
public GameObject[] inventorySlots = new GameObject[4];
private int activeSlot = 0;
private GameObject currentHeldObject = null;
public Image[] slotImages;
public Color activeSlotColor = Color.yellow;
public Color defaultSlotColor = Color.white;
void Start()
{
UpdateSlotUI();
}
void Update()
{
if (photonView.IsMine)
{
if (Input.GetKeyDown(KeyCode.E))
{
if (currentHeldObject == null)
{
TryPickupObject();
}
else
{
DropObject();
}
}
if (Input.GetKeyDown(KeyCode.Alpha1)) { SwitchSlot(0); }
if (Input.GetKeyDown(KeyCode.Alpha2)) { SwitchSlot(1); }
if (Input.GetKeyDown(KeyCode.Alpha3)) { SwitchSlot(2); }
if (Input.GetKeyDown(KeyCode.Alpha4)) { SwitchSlot(3); }
}
UpdateHeldObject();
}
void TryPickupObject()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, 5f);
foreach (Collider collider in colliders)
{
if (collider.CompareTag("Pickable"))
{
PhotonView objView = collider.GetComponent<PhotonView>();
PickableObject pickable = collider.GetComponent<PickableObject>();
if (objView != null && pickable != null && !pickable.isOwned)
{
objView.TransferOwnership(PhotonNetwork.LocalPlayer);
StartCoroutine(WaitForOwnership(objView, collider.gameObject));
break;
}
}
}
}
IEnumerator WaitForOwnership(PhotonView objView, GameObject obj)
{
while (objView.Owner != PhotonNetwork.LocalPlayer)
{
yield return null;
}
AddToInventory(obj);
photonView.RPC("SyncPickupObject", RpcTarget.Others, objView.ViewID, activeSlot);
}
[PunRPC]
void SyncPickupObject(int viewID, int slotIndex)
{
PhotonView objView = PhotonView.Find(viewID);
GameObject obj = objView.gameObject;
inventorySlots[slotIndex] = obj;
obj.SetActive(false);
}
void AddToInventory(GameObject obj)
{
if (photonView.IsMine)
{
if (inventorySlots[activeSlot] == null)
{
inventorySlots[activeSlot] = obj;
obj.SetActive(false);
Rigidbody rb = obj.GetComponent<Rigidbody>();
if (rb != null)
{
rb.isKinematic = true;
rb.detectCollisions = false;
}
obj.GetComponent<PickableObject>().isOwned = true;
}
}
}
void DropObject()
{
if (currentHeldObject != null)
{
GameObject obj = currentHeldObject;
PhotonView objView = obj.GetComponent<PhotonView>();
PickableObject pickable = obj.GetComponent<PickableObject>();
if (objView.IsMine)
{
obj.transform.SetParent(null);
Vector3 dropPosition = GetGroundPosition();
obj.transform.position = dropPosition;
Rigidbody rb = obj.GetComponent<Rigidbody>();
if (rb != null)
{
rb.isKinematic = false;
rb.useGravity = true;
rb.detectCollisions = true;
}
Collider collider = obj.GetComponent<Collider>();
if (collider != null)
{
collider.enabled = true;
}
obj.SetActive(true);
currentHeldObject = null;
inventorySlots[activeSlot] = null;
objView.TransferOwnership(PhotonNetwork.MasterClient);
pickable.isOwned = false;
photonView.RPC("SyncDropObject", RpcTarget.Others, objView.ViewID, dropPosition);
UpdateSlotUI();
}
}
}
[PunRPC]
void SyncDropObject(int viewID, Vector3 dropPosition)
{
PhotonView objView = PhotonView.Find(viewID);
GameObject obj = objView.gameObject;
PickableObject pickable = obj.GetComponent<PickableObject>();
obj.transform.SetParent(null);
obj.transform.position = dropPosition;
Rigidbody rb = obj.GetComponent<Rigidbody>();
if (rb != null)
{
rb.isKinematic = false;
rb.useGravity = true;
rb.detectCollisions = true;
}
Collider collider = obj.GetComponent<Collider>();
if (collider != null)
{
collider.enabled = true;
}
obj.SetActive(true);
pickable.isOwned = false;
}
Vector3 GetGroundPosition()
{
RaycastHit hit;
if (Physics.Raycast(transform.position + Vector3.up, transform.forward, out hit, 3f))
{
return hit.point;
}
else
{
return transform.position + transform.forward * 2f;
}
}
void SwitchSlot(int slotIndex)
{
if (photonView.IsMine)
{
// Eğer elinde bir obje varsa, bu objeyi geçerli slotta gizle
if (inventorySlots[activeSlot] != null)
{
currentHeldObject = inventorySlots[activeSlot];
currentHeldObject.SetActive(false);
}
// Yeni slotu aktif olarak ayarla
activeSlot = slotIndex;
UpdateSlotUI();
UpdateHeldObject(); // Obje güncellemelerini yap
// Diğer oyuncularla senkronize et
photonView.RPC("SyncSlotSwitch", RpcTarget.Others, activeSlot);
}
}
[PunRPC]
void SyncSlotSwitch(int slotIndex)
{
if (!photonView.IsMine)
{
// Eğer diğer oyuncunun elindeki objeyi gizlememişsek, elindeki objeyi kapat
if (inventorySlots[activeSlot] != null)
{
inventorySlots[activeSlot].SetActive(false);
}
// Yeni slotu aktif olarak ayarla
activeSlot = slotIndex;
UpdateSlotUI();
UpdateHeldObject(); // Obje güncellemelerini yap
}
}
void UpdateHeldObject()
{
if (photonView.IsMine)
{
// Eğer önceki bir obje varsa, onu gizle
if (currentHeldObject != null && inventorySlots[activeSlot] != currentHeldObject)
{
currentHeldObject.SetActive(false);
}
if (inventorySlots[activeSlot] != null)
{
currentHeldObject = inventorySlots[activeSlot];
currentHeldObject.transform.position = holdPosition.position;
currentHeldObject.transform.rotation = holdPosition.rotation;
currentHeldObject.SetActive(true);
photonView.RPC("SyncHeldObject", RpcTarget.Others, activeSlot, currentHeldObject.GetComponent<PhotonView>().ViewID, holdPosition.position, holdPosition.rotation);
}
else
{
if (currentHeldObject != null)
{
currentHeldObject.SetActive(false);
currentHeldObject = null;
photonView.RPC("SyncHeldObject", RpcTarget.Others, activeSlot, -1, Vector3.zero, Quaternion.identity);
}
}
}
}
[PunRPC]
void SyncHeldObject(int slotIndex, int viewID, Vector3 position, Quaternion rotation)
{
if (!photonView.IsMine)
{
if (viewID != -1)
{
PhotonView objView = PhotonView.Find(viewID);
GameObject obj = objView.gameObject;
inventorySlots[slotIndex] = obj;
obj.transform.position = position;
obj.transform.rotation = rotation;
obj.SetActive(true);
Rigidbody rb = obj.GetComponent<Rigidbody>();
if (rb != null)
{
rb.isKinematic = true;
rb.detectCollisions = false;
}
}
else
{
if (inventorySlots[slotIndex] != null)
{
inventorySlots[slotIndex].SetActive(false);
inventorySlots[slotIndex] = null;
}
}
}
}
void UpdateSlotUI()
{
for (int i = 0; i < slotImages.Length; i++)
{
slotImages[i].color = (i == activeSlot) ? activeSlotColor : defaultSlotColor;
}
}
}