如何使用 Photon 准确同步触发动画?
Posted
技术标签:
【中文标题】如何使用 Photon 准确同步触发动画?【英文标题】:How to sync trigger animations using Photon accurately? 【发布时间】:2021-12-24 02:18:54 【问题描述】:根据 Photon 开发人员自己的说明,当您尝试使用触发参数设置 Photon Animator View 时,Photon Animator View 似乎无法很好地使用触发参数(我在某处读到它有 40% 的下降率,而我自己的测试显示更糟糕的结果),他们甚至建议我们使用我们自己的自定义代码,使用 RPC 或 RaiseEvents 来获得更好的结果。那么如何同步触发参数触发的动画呢?
【问题讨论】:
你的问题是什么? 请澄清您的具体问题或提供更多详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。 【参考方案1】:我想出了这个可以用来同步动画的类(任何动画,不仅仅是触发动画)。它使用 RaiseEvent(也可以使用 RPC 完成)。
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using ExitGames.Client.Photon;
namespace Workbench.Wolfsbane.Multiplayer
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(PhotonView))]
public class NetworkedAnimation : MonoBehaviourPunCallbacks
#region private fields
Animator anim;
#endregion
#region monobehaviours
public override void OnEnable()
base.OnEnable();
PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
public override void OnDisable()
base.OnDisable();
PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
private void Start()
anim = GetComponent<Animator>();
#endregion
#region private methods
private void OnEvent(EventData photonEvent)
byte eventCode = photonEvent.Code;
if (eventCode == PlayAnimationEventCode)
object[] data = (object[])photonEvent.CustomData;
int targetPhotonView = (int)data[0];
if (targetPhotonView == this.photonView.ViewID)
string animatorParameter = (string)data[1];
string parameterType = (string)data[2];
object parameterValue = (object)data[3];
switch (parameterType)
case "Trigger":
anim.SetTrigger(animatorParameter);
break;
case "Bool":
anim.SetBool(animatorParameter, (bool)parameterValue);
break;
case "Float":
anim.SetFloat(animatorParameter, (float)parameterValue);
break;
case "Int":
anim.SetInteger(animatorParameter, (int)parameterValue);
break;
default:
break;
#endregion
#region public methods
public const byte PlayAnimationEventCode = 1;
public void SendPlayAnimationEvent(int photonViewID, string animatorParameter, string parameterType, object parameterValue = null)
object[] content = new object[] photonViewID, animatorParameter, parameterType, parameterValue ;
RaiseEventOptions raiseEventOptions = new RaiseEventOptions Receivers = ReceiverGroup.All ;
PhotonNetwork.RaiseEvent(PlayAnimationEventCode, content, raiseEventOptions, SendOptions.SendReliable);
#endregion
用法:
// in some other script (that is on the same object)
GetComponent<NetworkedAnimation>().SendPlayAnimationEvent(photonView.ViewID, animation, "Trigger");
发送正确的 photonviewId 至关重要,因为在订阅事件的所有对象上都会调用 RaiseEvents,因此您需要一种方法来仅过滤适当的对象。在我的情况下,我需要同步播放器动画,因为每个播放器都有一个 photonView,所以我使用 photonView.viewID 作为过滤器机制。其他人可能会走不同的方向,不使用 photonView 过滤对象,但可能会将 RaiseEvent 或 RPC 发送到管理器级别的对象,然后将动画命令发送到适当的对象。
【讨论】:
以上是关于如何使用 Photon 准确同步触发动画?的主要内容,如果未能解决你的问题,请参考以下文章