Skip to content

Instantly share code, notes, and snippets.

@soyliquid
Last active May 16, 2023 08:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soyliquid/9cba2c36f16b573e621c to your computer and use it in GitHub Desktop.
Save soyliquid/9cba2c36f16b573e621c to your computer and use it in GitHub Desktop.
[Unity][Photon]GameObjectの位置と回転、Animatorを同期する
using UnityEngine;
using Hashtable = ExitGames.Client.Photon.Hashtable;
public class SmoothSyncObject : MonoBehaviour
{
public PhotonView OwnerView;
public GameObject[] SyncTargets;
public Animator SycnAnimator;
// public int RootTargetId = 0; // target which affects position.
private bool isDeltaTimeBasedSmoothing = false;
private float fraction = 0.5f;
private Vector3[] actualPositions; // lerp towards to this
private Quaternion[] actualRotations; // lerp towards to this
private Vector3[] movingVectors;
private float lastReceiveTime = 0f;
public void Start() {
if (OwnerView.isMine)
{
enabled = false; // disable sync to myself.
return;
}
Initialize();
}
void Initialize() {
actualPositions = new Vector3[SyncTargets.Length];
actualRotations = new Quaternion[SyncTargets.Length];
movingVectors = new Vector3[SyncTargets.Length];
for(int idx = 0; idx < SyncTargets.Length; idx++) {
// auto disable remote sync object's gravity.(to avoid vertical position glitch)
if(SyncTargets[idx].rigidbody != null && !OwnerView.isMine) {
Debug.LogWarning("Disabled remote object's gravity. it causes vertical position glitch.");
SyncTargets[idx].rigidbody.useGravity = false;
}
actualPositions[idx] = SyncTargets[idx].transform.position;
actualRotations[idx] = SyncTargets[idx].transform.rotation;
movingVectors[idx] = Vector3.zero;
}
}
void Update()
{
SyncTargetsTransform();
}
void SyncTargetsTransform() {
if(isDeltaTimeBasedSmoothing) {
fraction = Time.deltaTime * 8f;
}
for(int idx = 0; idx < SyncTargets.Length; idx++) {
// position affect only root object
// if(idx == RootTargetId) {
// SyncTargets[idx].transform.position =
// Vector3.Lerp(SyncTargets[idx].transform.position,
// actualPositions[idx] + movingVectors[idx],
// fraction);
// }
SyncTargets[idx].transform.position =
Vector3.Lerp(SyncTargets[idx].transform.position,
actualPositions[idx] + movingVectors[idx],
fraction);
SyncTargets[idx].transform.rotation =
Quaternion.Lerp(SyncTargets[idx].transform.rotation,
actualRotations[idx],
fraction);
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
// send to others.
for(int idx = 0; idx < SyncTargets.Length; idx++) {
// if(idx != RootTargetId) {
// stream.SendNext(SyncTargets[idx].transform.position);
// }
stream.SendNext(SyncTargets[idx].transform.position);
stream.SendNext(SyncTargets[idx].transform.rotation);
}
if(SycnAnimator != null) {
stream.SendNext(SycnAnimator.GetFloat("Speed"));
}
}
else
{
// receive from others.
for(int idx = 0; idx < SyncTargets.Length; idx++) {
// if(idx != RootTargetId) {
// Vector3 pos = (Vector3)stream.ReceiveNext();
// actualPositions[idx] = pos;
// }
Vector3 pos = (Vector3)stream.ReceiveNext();
actualPositions[idx] = pos;
actualRotations[idx] = (Quaternion)stream.ReceiveNext(); // inefficient.
//movingVectors[idx] = (pos - actualPositions[idx]) / (Time.time - lastTime); // buggy.
movingVectors[idx] = Vector3.zero;
}
if(SycnAnimator != null) {
SycnAnimator.SetFloat("Speed", (float)stream.ReceiveNext());
}
lastReceiveTime = Time.time;
}
}
}
@gakkossphynx
Copy link

ia this updating seamlessly ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment