使用 Mirror 在 Unity 中的网络播放器上停止和播放粒子系统
Stop and Play Particle System on Networked Player in Unity using Mirror
我正在尝试播放和停止播放器预制件的子粒子系统。到目前为止,我已经获得了主机客户端的推力粒子效果,可以在所有客户端上进行更新,但我还没有弄清楚非主机客户端。我希望每次玩家按下推进器按钮时,游戏都会在所有客户端上显示推进器效果,当他们停止时粒子系统停止,其他客户端也会看到它。
目前我的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class PlayerMovement : NetworkBehaviour
{
public float thrustPower = 300f;
Rigidbody2D m_playerRb;
bool m_thrustOn = false;
public ParticleSystem m_playerPs;
[SyncVar(hook = nameof(SetThrusters))]
bool m_thrusterState = false;
private void Start()
{
m_playerRb = GetComponent<Rigidbody2D>();
m_playerPs.Stop();
}
private void Update()
{
if (isLocalPlayer)
{
MovePlayer();
m_thrusterState = m_thrustOn;
}
}
private void FixedUpdate()
{
if (m_thrustOn)
{
m_playerRb.AddForce(gameObject.transform.up * thrustPower * Time.fixedDeltaTime, ForceMode2D.Force);
}
}
private void SetThrusters(bool oldVal, bool newVal)
{
if (newVal) m_playerPs.Play();
else if (newVal == false) m_playerPs.Stop();
}
private void MovePlayer()
{
m_thrustOn = Input.GetKey(KeyCode.W) ? true : false;
float horizontalInput = Input.GetAxisRaw("Horizontal");
transform.Rotate(new Vector3(0, 0, horizontalInput * -180 * Time.deltaTime));
}
}
在粒子系统方面,我真的无法在网上找到任何关于 Mirror 的信息。如果您需要更多信息,请告诉我。
谢谢!
SyncVar
总是只往 HOST -> CLIENT 方向走!
相反,您需要使用 Command
例如
[Command]
void CmdSetSetThrusters(bool newVal)
{
// the hook would not be executed on the host => do it manually now
SetThrusters(m_thrusterState, newVal);
// set it on the host -> now via synVar automatically forwarded to others
m_thrusterState = newVal;
}
然后您必须添加一个检查您是否是主持人,例如
if (isLocalPlayer)
{
MovePlayer();
if(isServer)
{
// afaik this you still have to call manually for yourself
// not sure here how SyncVar Hooks are handled on the host itself
SetThrusters(m_thrusterState, m_thrustOn);
// this is now synced to others
m_thrusterState = m_thrustOn;
}
else
{
// if your not Host send the command
CmdSetSetThrusters(m_thrustOn);
}
}
就我个人而言,出于这个原因,SyncVar
与 Hooks 总是有点令人困惑和怀疑。
您也可以自己简单地实现这两个方向,例如
[Command]
void CmdSetSetThrusters(bool newVal)
{
// set the value on yourself
SetThrusters(newVal);
// Then directly forward it to all clients
RpcSetThrusters(newVal);
}
[ClientRpc]
private void RpcSetThrusters(bool newValue)
{
// set the value on all clients
SetThrusters(newVal);
}
private void SetThrusters(bool newVal)
{
if (newVal)
{
m_playerPs.Play();
}
else
{
m_playerPs.Stop();
}
// if you are the HOST forward to all clients
if(isServer)
{
RpcSetThrusters(newVal);
}
}
然后
if (isLocalPlayer)
{
MovePlayer();
if(isServer)
{
SetThrusters(m_thrusterState);
}
else
{
// if your not Host send the command
CmdSetSetThrusters(m_thrustOn);
}
}
我正在尝试播放和停止播放器预制件的子粒子系统。到目前为止,我已经获得了主机客户端的推力粒子效果,可以在所有客户端上进行更新,但我还没有弄清楚非主机客户端。我希望每次玩家按下推进器按钮时,游戏都会在所有客户端上显示推进器效果,当他们停止时粒子系统停止,其他客户端也会看到它。
目前我的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class PlayerMovement : NetworkBehaviour
{
public float thrustPower = 300f;
Rigidbody2D m_playerRb;
bool m_thrustOn = false;
public ParticleSystem m_playerPs;
[SyncVar(hook = nameof(SetThrusters))]
bool m_thrusterState = false;
private void Start()
{
m_playerRb = GetComponent<Rigidbody2D>();
m_playerPs.Stop();
}
private void Update()
{
if (isLocalPlayer)
{
MovePlayer();
m_thrusterState = m_thrustOn;
}
}
private void FixedUpdate()
{
if (m_thrustOn)
{
m_playerRb.AddForce(gameObject.transform.up * thrustPower * Time.fixedDeltaTime, ForceMode2D.Force);
}
}
private void SetThrusters(bool oldVal, bool newVal)
{
if (newVal) m_playerPs.Play();
else if (newVal == false) m_playerPs.Stop();
}
private void MovePlayer()
{
m_thrustOn = Input.GetKey(KeyCode.W) ? true : false;
float horizontalInput = Input.GetAxisRaw("Horizontal");
transform.Rotate(new Vector3(0, 0, horizontalInput * -180 * Time.deltaTime));
}
}
在粒子系统方面,我真的无法在网上找到任何关于 Mirror 的信息。如果您需要更多信息,请告诉我。
谢谢!
SyncVar
总是只往 HOST -> CLIENT 方向走!
相反,您需要使用 Command
例如
[Command]
void CmdSetSetThrusters(bool newVal)
{
// the hook would not be executed on the host => do it manually now
SetThrusters(m_thrusterState, newVal);
// set it on the host -> now via synVar automatically forwarded to others
m_thrusterState = newVal;
}
然后您必须添加一个检查您是否是主持人,例如
if (isLocalPlayer)
{
MovePlayer();
if(isServer)
{
// afaik this you still have to call manually for yourself
// not sure here how SyncVar Hooks are handled on the host itself
SetThrusters(m_thrusterState, m_thrustOn);
// this is now synced to others
m_thrusterState = m_thrustOn;
}
else
{
// if your not Host send the command
CmdSetSetThrusters(m_thrustOn);
}
}
就我个人而言,出于这个原因,SyncVar
与 Hooks 总是有点令人困惑和怀疑。
您也可以自己简单地实现这两个方向,例如
[Command]
void CmdSetSetThrusters(bool newVal)
{
// set the value on yourself
SetThrusters(newVal);
// Then directly forward it to all clients
RpcSetThrusters(newVal);
}
[ClientRpc]
private void RpcSetThrusters(bool newValue)
{
// set the value on all clients
SetThrusters(newVal);
}
private void SetThrusters(bool newVal)
{
if (newVal)
{
m_playerPs.Play();
}
else
{
m_playerPs.Stop();
}
// if you are the HOST forward to all clients
if(isServer)
{
RpcSetThrusters(newVal);
}
}
然后
if (isLocalPlayer)
{
MovePlayer();
if(isServer)
{
SetThrusters(m_thrusterState);
}
else
{
// if your not Host send the command
CmdSetSetThrusters(m_thrustOn);
}
}