Photon PUN 2 - Bone Rotations Not Syncing

This should work from what I have seen but isn’t. I want to sync the rotations of target bones across the network. Here is how I am doing it:

private Transform local_head, local_neck, local_spine, local_chest = null;
    private Quaternion server_head, server_neck, server_spine, server_chest = Quaternion.identity;
...
...

public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) //this function called by Photon View component
    {
        if (_syncBones == true)
        {
            if (stream.IsWriting)   //Authoritative player sending data to server
            {
                //Bone Rotations
                stream.SendNext(local_head.localRotation);
                stream.SendNext(local_neck.localRotation);
                stream.SendNext(local_spine.localRotation);
                stream.SendNext(local_chest.localRotation);
            }
            else  //Network player copies receiving data from server
            {
                //Bone Rotations
                server_head = (Quaternion)stream.ReceiveNext();
                server_neck = (Quaternion)stream.ReceiveNext();
                server_spine = (Quaternion)stream.ReceiveNext();
                server_chest = (Quaternion)stream.ReceiveNext();

                lag = Mathf.Abs((float)(PhotonNetwork.Time - info.timestamp));
            }
        }
    }
void LateUpdate()
    {
        if (GetComponent<PhotonView>().IsMine == false)
        {
            SyncBoneRotation();
        }
    }
    void SyncBoneRotation()
    {
        local_head.localRotation = Quaternion.Lerp(local_head.localRotation, server_head, Time.deltaTime * _boneLerpRate);
        local_neck.localRotation = Quaternion.Lerp(local_neck.localRotation, server_neck, Time.deltaTime * _boneLerpRate);
        local_spine.localRotation = Quaternion.Lerp(local_spine.localRotation, server_spine, Time.deltaTime * _boneLerpRate);
        local_chest.localRotation = Quaternion.Lerp(local_chest.localRotation, server_chest, Time.deltaTime * _boneLerpRate);
    }

I think what is happening is that the line stream.ReceiveNext() is setting the rotation to Quaternion.identity every other frame. Honestly I am just not sure if I am missing something obvious here…

Note: All of the local_* are getting set like the following:

local_head = animator.GetBoneTransform(HumanBodyBones.Head).transform;

I did the same thing I did for UNet: UNet Sync Bone Rotations - Jittering - Questions & Answers - Unity Discussions

I didn’t use Photons Method to send my updates across the network because it’s insanely buggy. I did it manually:

    [SerializeField] private bool _syncBones = true;
    [SerializeField] private int _syncBonesRate = 5;
    [SerializeField] private float _boneLerpRate = 90.0f;
    private int currentBoneRate = 0;

..
..

void FixedUpdate()
    {
        if (_syncBones == true && GetComponent<PhotonView>().IsMine == true)
        {
            if (currentBoneRate == _syncBonesRate)
            {
                currentBoneRate = 0;
                photonView.RPC("SyncRotations", RpcTarget.Others, local_head.localRotation, local_neck.localRotation, local_spine.localRotation, local_chest.localRotation);
            }
            else
            {
                currentBoneRate += 1;
            }
        }
    }
    void SyncBoneRotation()
    {
        if (_syncBones == true && GetComponent<PhotonView>().IsMine == false)
        {
            local_head.localRotation = Quaternion.Lerp(local_head.localRotation, correctBoneHeadRot, Time.deltaTime * _boneLerpRate);
            local_neck.localRotation = Quaternion.Lerp(local_neck.localRotation, correctBoneNeckRot, Time.deltaTime * _boneLerpRate);
            local_spine.localRotation = Quaternion.Lerp(local_spine.localRotation, correctBoneSpineRot, Time.deltaTime * _boneLerpRate);
            local_chest.localRotation = Quaternion.Lerp(local_chest.localRotation, correctBoneChestRot, Time.deltaTime * _boneLerpRate);
        }
    }

mind posting your full script, here is what I have done

void OnAnimatorIK()
{
if(PV.IsMine)
{
anim.SetLookAtWeight(0.7f, 0.5f);
anim.SetLookAtPosition(targetFocus.position);
}
}

void Update()
{
    if(PV.IsMine == true && _syncBones == true)
    {
        if (currentBoneRate == _syncBonesRate)
        {
            
            currentBoneRate = 0;
            PV.RPC("RPC_UpdateBoneRotations", RpcTarget.AllBuffered, local_head.localRotation, local_neck.localRotation, local_spine.localRotation, local_chest.localRotation);
        
        }
        else
        {
            currentBoneRate += 1;
        }
    }
    if (_syncBones == true && PV.IsMine == false)
    {
        Debug.Log("Attempting to sync bones for other clients");
        local_head.localRotation = Quaternion.Lerp(local_head.localRotation, correctBoneHeadRot, Time.deltaTime *  _boneLerpRate);
        local_neck.localRotation = Quaternion.Lerp(local_neck.localRotation, correctBoneNeckRot, Time.deltaTime * _boneLerpRate);
        local_spine.localRotation = Quaternion.Lerp(local_spine.localRotation, correctBoneSpineRot, Time.deltaTime * _boneLerpRate);
        local_chest.localRotation = Quaternion.Lerp(local_chest.localRotation, correctBoneChestRot, Time.deltaTime * _boneLerpRate);
    }
}

[PunRPC]
void RPC_UpdateBoneRotations (Quaternion h, Quaternion n, Quaternion s, Quaternion c)
{
    Debug.Log("SyncingBones");
    correctBoneHeadRot = h;
    correctBoneNeckRot = n;
    correctBoneSpineRot = s;
    correctBoneChestRot = c;
   
}

and it aint syncing

Thank you for your help man! I used this method because it works better for me.
This is my script if anyone is struggling with it.

private Quaternion server_head;
[SerializeField] private Transform Head;
private void LateUpdate()
	{
		if (photonView.IsMine == false)
		{
			Head.localRotation = server_head;
		}
	}

	private void FixedUpdate()
	{
		if (photonView.IsMine == true)
		{
			Move();
			switch (stance)
			{
				case CharacterStance.Standing:
					if (inputs.Crouch.PressedDown()) { RequestStanceChange(CharacterStance.Crouching); }
					break;

				case CharacterStance.Crouching:
					if (inputs.Crouch.PressedDown()) { RequestStanceChange(CharacterStance.Standing); }
					break;
			}
			photonView.RPC("RPC_UpdateBoneRotations", RpcTarget.AllBuffered, Head.localRotation);
		}

	}

	[PunRPC]
	private void RPC_UpdateBoneRotations(Quaternion h)
	{
		server_head = h;
	}