Invoke Method on players [Command] VS [ClientRpc]

Hi
i am trying to hit a player
i have a simple raycasting attack
and a simple damage script

when i use the [ClientRpc] and attack the Host i get this error
Rpc Function (“RpcMethodName” ) called on client
if i attack the client with the host it works fine
if i attack the client with a client nothing happens at all no errors too

when i use the [Command] and attack the host it works Fine
when i attack the client with the host it works on the server only the client doesn’t actually move
because it wasn’t invoked locally

when i attack a client with a client nothing works and no errors again

this is the code

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class HitSimulate : NetworkBehaviour {
public Transform raycastCenter;
public LayerMask playerMask;
public Collider[] overlapCasts;
public float radius=1;


public PlayerGetHit playerGetHit;

public Animator animator;
public bool cast1;
public bool attack1;
[SyncVar]
public GameObject HittedPlayer;

public bool timeTillSendAttackAgain;
    public float timeTillSendAttackAgainTimer = 0.2f;
    // Use this for initialization
    void Start () {
    raycastCenter = transform.FindChild("rayCenter");
playerGetHit = GetComponentInParent<PlayerGetHit>();

animator = GetComponent<Animator>();
    }

    public void AnimationCast1True()
    {
        cast1 = true;
    }
    public void AnimationCast1False()
    {
        cast1 = false;
        animator.SetBool("Attack1",false);
         attack1 = false;
    }
   
    void Update () {
    if(isLocalPlayer){
            if(timeTillSendAttackAgain == true)
            {
                timeTillSendAttackAgainTimer -=Time.deltaTime;
                if(timeTillSendAttackAgainTimer <=0)
                {
                    timeTillSendAttackAgain = false;
                    timeTillSendAttackAgainTimer = 0.2f;
                }
            }

    if(Input.GetMouseButton(0))
    {
            animator.SetBool("Attack1",true);
            attack1 = true;
    }
    if(cast1 == true){

    overlapCasts =     Physics.OverlapSphere(raycastCenter.position,radius,playerMask);
        }else{
            overlapCasts = null;
        }
        if(overlapCasts != null){
            foreach(Collider tmp in overlapCasts)
            {
                if(tmp != null){
               
                        //Debug.DrawLine(transform.position,tmp.gameObject.transform.position,Color.red);
               
            //    tmp.GetComponent<PhotonView>().RPC("Damage",PhotonTargets.All,transform.parent.forward);
if(timeTillSendAttackAgain == false){

       
                                CmdDamagePlayer(tmp.gameObject);
                        //    RpcDamagePlayer(tmp.gameObject);

                timeTillSendAttackAgain = true;
                }
           
                }
            }
        }
    }

    }//Update Finish

    //

[Command]
    void CmdDamagePlayer(GameObject hittedPlayer)
    {
   
   
        HittedPlayer=    hittedPlayer;
        Debug.Log(hittedPlayer.name);
        HittedPlayer.GetComponent<PlayerGetHit>().Damage(transform.forward);
        //    hittedPlayer.GetComponent<PlayerGetHit>().curHealth -=10;
   
    }

    /*[ClientRpc]
    void RpcDamagePlayer(GameObject hittedPlayer)
    {
   
   
        HittedPlayer=    hittedPlayer;
        Debug.Log(hittedPlayer.name);
        HittedPlayer.GetComponent<PlayerGetHit>().Damage(transform.forward);
        //    hittedPlayer.GetComponent<PlayerGetHit>().curHealth -=10;
   
    }
    */

    }

And this is the player getting hit code

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;
public class PlayerGetHit : NetworkBehaviour {
public JM jm;
public bool canGetHit;
public float canGetHitTimer = 0.4f;
public bool moveBackHit;
public float moveBackHitTimer = 0.5f;
public Vector3 hitterForwardSave;

public float TuneValue;

public Animator animator;

public int curHealth = 100;
public int maxHealth = 100;

    // Use this for initialization
    void Start () {
    jm = GetComponent<JM>();
    animator = GetComponent<Animator>();


    }

    // Update is called once per frame
    void Update () {

    if(moveBackHit == true)
    {
    animator.SetBool("BackHit",true);
    transform.position += hitterForwardSave * 17* Time.deltaTime;
    moveBackHitTimer -= Time.deltaTime;
    if(moveBackHitTimer <=0)
            {    animator.SetBool("BackHit",false);
    moveBackHitTimer = 0.4f;
    moveBackHit = false;
    hitterForwardSave = Vector3.zero;
    jm.enabled = true;
    }
    }

    if(canGetHit == false)
    {
    canGetHitTimer -=Time.deltaTime;
    if(canGetHitTimer<=0)
    {
    canGetHitTimer = 0.3f;
    canGetHit= true;
    }
    }


    }

    public void Damage(Vector3 hitterForward)
    {
    if(canGetHit == true)
    {
    Debug.Log("gotHit");
    canGetHit  = false;
    jm.enabled = false;

    hitterForwardSave = hitterForward;
    moveBackHit = true;

    }

    }
}

I tried to use [Client] and it works on all of them no matter host or client
but it works on the server only its not invoked on the players
is it me or Unreal engine team started to work on unity? cuz its HARD as hell
lol

Client RPCs can only be sent from the server (host). Commands can only be sent from clients. Here’s how to make it work both ways:

[Command]
void CmdDamagePlayer(arguments)
{
     RpcDamagePlayer(arguments);
}

[ClientRpc]
void RpcDamagePlayer(arguments)
{
     //All your damage stuff here!
}

void Foo()
{
     //If we are the server, do the Rpc. If we are a client, do the Command.
     if(!Network.isServer)
          CmdDamagePlayer(arguments);
     else
          RpcDamagePlayer(arguments);
}

Basically, as the host, you are already the server, so you can send an RPC to all clients by calling the RPC function. As a client, however, you do not have a direct connection to the other clients - thus, you have to tell the server to tell the clients to do something. Think of the server as the middleman in this case.

Note that this code has to be used on an object with a NetworkIdentity attached or Network.isServer will not be able to tell if you are the server or a client.

8 Likes