【问题标题】:Bullets being fired / created repeatedly without player's input - UNET Unity在没有玩家输入的情况下重复发射/创建子弹 - UNET Unity
【发布时间】:2016-03-10 02:26:53
【问题描述】:

设置:创建我的第一个多人游戏并遇到一个奇怪的问题。 这是一款坦克游戏,玩家可以射击子弹并互相残杀。

您可以为子弹充电以更快/更远地射击。

问题: 当客户端玩家完全充电并释放时,子弹会继续重复生成并且永不停止。如果客户端播放器未完全充电,则不会出现此问题。

我认为问题在于if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired) 中的更新功能

注意: 主机播放器没有这个问题,因此它与网络有关。

private void Update()
{
    if (!isLocalPlayer)
        return;
    // Track the current state of the fire button and make decisions based on the current launch force.
    m_AimSlider.value = m_MinLaunchForce;

    if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired) {
        m_CurrentLaunchForce = m_MaxLaunchForce;
        CmdFire ();
    } else if (Input.GetButtonDown (m_FireButton) && !m_Fired) {
        m_Fired = false;
        m_CurrentLaunchForce = m_MinLaunchForce;
        m_ShootingAudio.clip = m_ChargingClip;
        m_ShootingAudio.Play();
    } else if (Input.GetButton (m_FireButton)) {
        m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;
        m_AimSlider.value = m_CurrentLaunchForce;
    } else if (Input.GetButtonUp(m_FireButton)) {
        CmdFire ();
    }
}

[Command]
private void CmdFire()
{
    // Set the fired flag so only Fire is only called once.
    m_Fired = true;

    // Create an instance of the shell and store a reference to it's rigidbody.
    GameObject shellInstance = (GameObject)
        Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) ;

    // Set the shell's velocity to the launch force in the fire position's forward direction.
    shellInstance.GetComponent<Rigidbody>().velocity = m_CurrentLaunchForce * m_FireTransform.forward; 

    // Change the clip to the firing clip and play it.
    m_ShootingAudio.clip = m_FireClip;
    m_ShootingAudio.Play ();
    NetworkServer.Spawn (shellInstance);
    // Reset the launch force.  This is a precaution in case of missing button events.
    m_CurrentLaunchForce = m_MinLaunchForce;

}

【问题讨论】:

  • 你从未在第一个电流 > 最大测试中设置 m_Fired = true
  • 我在 CmdFire() 中执行此 if 语句调用,不是吗?
  • 嗯,m_fired 是局部变量还是类变量?
  • 它是一个类变量
  • @MarcB 成功了!但我不明白为什么! m_fired 是一个类变量,它在CmdFire() 中被设置为true

标签: c# networking unity3d unity3d-unet


【解决方案1】:

如果您查看文档,您会发现 -> 在与连接关联的播放器对象上调用 [Command] 函数。这是通过将播放器对象传递给 NetworkServer.PlayerIsReady() 函数来响应“就绪”消息而设置的。命令调用的参数在网络上被序列化,因此服务器函数的调用值与客户端函数的值相同。

我认为它对您不起作用的原因是因为您必须将参数传递给函数,例如

[Command]
private void CmdFire(bool m_Fired)
{
    // Set the fired flag so only Fire is only called once.
    m_Fired = true;

    // Create an instance of the shell and store a reference to it's rigidbody.
    GameObject shellInstance = (GameObject)
        Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) ;

    // Set the shell's velocity to the launch force in the fire position's forward direction.
    shellInstance.GetComponent<Rigidbody>().velocity = m_CurrentLaunchForce * m_FireTransform.forward; 

    // Change the clip to the firing clip and play it.
    m_ShootingAudio.clip = m_FireClip;
    m_ShootingAudio.Play ();
    NetworkServer.Spawn (shellInstance);
    // Reset the launch force.  This is a precaution in case of missing button events.
    m_CurrentLaunchForce = m_MinLaunchForce;

}

然后这样称呼它:

CmdFire(m_Fired) 其中 m_Fired 必须指向玩家自己的变量。

【讨论】:

  • 感谢您的尝试,但这对我没有帮助
  • 没问题。另一个要查看的建议是您的 m_Fired 变量。从您发布的内容中,我看不到您再次将 m_fired 设置为 false 的位置。尝试在命令函数结束时将其设置为 false。
猜你喜欢
  • 1970-01-01
  • 2016-06-24
  • 2023-04-11
  • 2018-11-28
  • 2016-12-21
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多