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;
}