Unfortunately, it doesn’t. That part of the code gets triggered properly because it gets called by the owner. Everything gets triggered properly until the StartInteractionServer() method, after that the testClientRPC() method doesn’t trigger.
Your comment did make me realize I was using the version 2.3.2 of NGO, so I updated it to 2.7.0, but the bug persist).
Here’s the full code in text form.
public class ButtonAbilityInput
{
public delegate void ButtonAbilityInputEvent(AbilityButtonInputType input, bool hold);
private AbilityButtonInputType input;
public event ButtonAbilityInputEvent OnUpdateButtonHeld;
public ButtonAbilityInput(AbilityButtonInputType input, InputAction inputAction)
{
this.input = input;
inputAction.performed += InputAction_performed;
inputAction.canceled += InputAction_canceled;
}
private void InputAction_performed(InputAction.CallbackContext obj)
{
OnUpdateButtonHeld?.Invoke(input, true);
}
private void InputAction_canceled(InputAction.CallbackContext obj)
{
OnUpdateButtonHeld?.Invoke(input, false);
}
}
LocalInputs.cs (implements a singleton pattern)
public event ButtonAbilityInput.ButtonAbilityInputEvent OnAbilityInput;
protected void Awake()
{
for (int i = 0; i < inputActionNameByAbilityInputs.Length; i++)
{
var current = inputActionNameByAbilityInputs[i];
InputAction inputAction = inputActions[current.value];
var buttonInput = new ButtonAbilityInput(current.key, inputAction);
buttonInput.OnUpdateButtonHeld += ButtonInput_OnUpdateButtonHeld;
}
}
private void ButtonInput_OnUpdateButtonHeld(AbilityButtonInputType input, bool hold)
=> OnAbilityInput?.Invoke(input, hold);
AvatarInputs.cs
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (!IsOwner) return;
LocalInputs localInputs = LocalInputs.Instance;
localInputs.OnAbilityInput += LocalInputs_OnAbilityInput;
}
private void LocalInputs_OnAbilityInput(AbilityButtonInputType input, bool hold)
{
SetAbilityInput_ServerRpc(input, hold);
}
[Rpc(SendTo.Server)]
private void SetAbilityInput_ServerRpc(AbilityButtonInputType input, bool hold)
{
SetAbilityInput(input, hold);
}
private void SetAbilityInput(AbilityButtonInputType input, bool hold)
{
Debug.Assert(IsServer);
if (promptActionByInputs.TryGetValue(input, out Action onPress))
{
if (hold) onPress?.Invoke();
return;
}
}
public void AddPrompt(PromptInfo prompt, Action onPress)
{
Debug.Assert(IsServer);
Log($"Add prompt {prompt} {this}");
if (!TryAddPromptInput(prompt.Button, onPress)) return;
}
public bool TryAddPromptInput(AbilityButtonInputType button, Action onPress)
{
Debug.Assert(IsServer);
if (promptActionByInputs.ContainsKey(button))
{
Debug.LogError($"There is already a prompt for input {button} !");
return false;
}
promptActionByInputs.Add(button, onPress);
return true;
}
AvatarInteract.cs
private void SetCurrentInteractable(Interactable newInteractable)
{
currentInteractable = newInteractable;
if (currentInteractable != null)
{
currentPromptInfo = currentInteractable.GetInteractPrompt();
avatarInputs.AddPrompt(currentPromptInfo, OnPressInteract);
}
}
private void OnPressInteract()
{
currentInteractable.Interact(this, networkAvatar);
}
Interactable.cs
public abstract void Interact(AvatarInteract avatarInteract, NetworkAvatar networkAvatar);
CrowdHumanInteractableFan.cs
public class CrowdHumanInteractableFan : Interactable
{
public override void Interact(AvatarInteract avatarInteract, NetworkAvatar avatar)
{
if (!TryGetPossesser(out CrowdPossesser possesser)) return;
avatar.AvatarStar.AvatarStarFan.StartInteraction(possesser);
}
}
AvatarStarFan.cs
public void StartInteraction(CrowdPossesser possesser)
{
avatarStarFanInteraction.StartInteractionServer(possesser);
}
AvatarStarFanInteraction.cs
public class AvatarStarFanInteraction : NetworkBehaviour
{
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (IsServer)
{
Debug.Log("start server");//This log "start server" on server
testClientRPC(false);//This correctly triggers on client
}
}
[Rpc(SendTo.Owner)]
private void testClientRPC(bool interaction)
{
Debug.Log($"test client {interaction}");
}
public void StartInteractionServer(CrowdPossesser possesser)
{
Debug.Assert(IsServer);
//This log "start interaction True 0 1" on server
Debug.Log($"start interaction {IsSpawned} {NetworkManager.LocalClientId} {OwnerClientId}");
testClientRPC(true);//This does not triggers on client
}
}
And here are how the scripts are placed on the gameobjects
Is there anything you see that could go wrong ? This is making me crazy.