【问题标题】:Stop and Play Particle System on Networked Player in Unity using Mirror在 Unity 中使用 Mirror 在联网播放器上停止和播放粒子系统
【发布时间】:2021-06-24 08:47:16
【问题描述】:

我正在尝试播放和停止作为玩家预制子的粒子系统。到目前为止,我已经让主机客户端的推力粒子效果在所有客户端上更新,但我无法找出非主机客户端。我希望玩家每次按下推进器按钮时,游戏都会在所有客户端上显示推进器效果,并且当它们停止时,粒子系统会停止并且其他客户端也会看到它。

目前我的代码如下:

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 的信息。如果您需要更多信息,请告诉我。

谢谢!

【问题讨论】:

    标签: unity3d mirror


    【解决方案1】:

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

    出于这个原因,对我个人而言,带有 Hooks 的 SyncVar 总是有点令人困惑和怀疑。

    您也可以使用例如简单地自己实现两个方向

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

    【讨论】:

    • 啊,这很有道理。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多