So I have network objects called Minis, some of which are controlled by clients. They have a component attached to them called Sheet. This Sheet (as it is now) is just a monobehavior. Each Mini has a Sheet and each sheet has a Mini.
I want each client’s UI’s elements to reflect the Mini’s Sheet that they control. So, if a Mini’s Sheet’s hitpoints change, I want that change to change the UI healthbar.
Note: the mini is not the player prefab. Which is why I’m not sure what the best way is to go about this.
Mini.cs
public class Mini : NetworkBehaviour
{
[SerializeField] private Sheet sheet;
private ulong ownerClientId; //Is set when the server spawns the Mini.
public ulong GetClientId() => ownerClientId;
//...stuff.
}
Sheet.cs
public class Sheet : Monobehaviour
{
[SerializeField] private Mini mini;
public readonly int HitpointsFull = 20;
public int HitpointsRemaining { get; private set; }
private void Start()
{
HitpointsRemaining = HitpointsFull;
}
public void TakeDamage(int damage)
{
HitpointsRemaining = Mathf.Clamp(HitpointsRemaining - damage, 0, HitpointsFull);
//What to put here?
}
}
UIPlayerController.cs
public class UIPlayerController : MonoBehaviour
{
[SerializeField] private GameObject healthbar;
public void SetHealth(float health) => healthbar.transform.Find("HealthbarRemaining").GetComponent<Image>().fillAmount = health;
}
Okay, got it. So I made these changes. Unfortunately it only works when player 2 (red client) damages player 1 (green host). I made a video to show you. It’s after the code.
Again, the minis are not player prefabs (in case that’s relevant). The player prefab makes requests to the server to do things with the mini(s) that are theirs.
Sheet.cs
public class Sheet : NetworkBehaviour
{
[SerializeField] private Mini mini;
public readonly int HitpointsFull = 20;
public static event Action<float> HitpointChangedEvent;
public int HitpointsRemaining { get; private set; }
public int AC { get; private set; }
private void Start()
{
HitpointsRemaining = HitpointsFull;
AC = 10;
Weapon = new Weapon(5);
}
public void TakeDamage(int damage)
{
HitpointsRemaining = Mathf.Clamp(HitpointsRemaining - damage, 0, HitpointsFull);
if (HitpointsRemaining == 0) Die();
if (!IsOwner) return;
if (mini.GetOwnerType() == Owner.player)
HitpointChangedEvent?.Invoke((float)HitpointsRemaining / (float)HitpointsFull);
}
public void DealDamage(Mini target, int damage)
{
Sheet targetSheet = target.GetComponent<Sheet>();
if (11 > targetSheet.AC)
{
targetSheet.TakeDamage(damage);
Debug.Log($"{name} deals {damage} damage to {target.name}!");
}
else
Debug.Log("Missed!");
}