C# 在没有播放器的情况下重复发射/创建子弹';s输入-UNET统一

C# 在没有播放器的情况下重复发射/创建子弹';s输入-UNET统一,c#,networking,unity3d,unity3d-unet,C#,Networking,Unity3d,Unity3d Unet,设置:创建我的第一个多人游戏时遇到了一个奇怪的问题。 这是一个坦克游戏,玩家可以射出子弹并互相残杀 你可以给子弹充电,让它射得更快/更远 问题: 当客户端玩家完全充注并释放时,子弹会不断重复产生,并且永不停止。如果客户端播放器未完全充电,则不会发生此问题 我认为问题在于中的更新函数(m_CurrentLaunchForce>=m_MaxLaunchForce&&!m_Fired) 注: 主机播放器没有这个问题,因此它在某种程度上与网络有关 private void Update() {

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

你可以给子弹充电,让它射得更快/更远

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

我认为问题在于
中的更新函数(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;

}
private void Update()
{
如果(!isLocalPlayer)
返回;
//跟踪点火按钮的当前状态,并根据当前发射力做出决定。
m_aimslaider.value=m_MinLaunchForce;
如果(m_CurrentLaunchForce>=m_MaxLaunchForce&&!m_已激发){
m_CurrentLaunchForce=m_MaxLaunchForce;
CmdFire();
}else if(Input.GetButtonDown(mu FireButton)和&!mu Fired){
m_Fired=错误;
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_aimslaider.value=m_CurrentLaunchForce;
}else if(Input.GetButtonUp(m_FireButton)){
CmdFire();
}
}
[命令]
私人火灾()
{
//设置fired标志,以便只调用一次Fire。
m_Fired=真;
//创建壳的实例并存储对其刚体的引用。
游戏对象外壳实例=(游戏对象)
实例化(m_Shell、m_FireTransform.position、m_FireTransform.rotation);
//将炮弹速度设置为射击位置前进方向的发射力。
shellInstance.GetComponent().velocity=m_CurrentLaunchForce*m_FireTransform.forward;
//将剪辑更改为射击剪辑并播放。
m_ShootingAudio.clip=m_FireClip;
m_ShootingAudio.Play();
NetworkServer.Spawn(shellInstance);
//重置发射力。这是一项预防措施,以防丢失按钮事件。
m_CurrentLaunchForce=m_MinLaunchForce;
}

如果您仔细查看文档,您会发现->[命令]函数在与连接关联的播放器对象上被调用。这是为响应“ready”消息而设置的,方法是将player对象传递给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;

}
[命令]
私人火灾(枪炮开火)
{
//设置fired标志,以便只调用一次Fire。
m_Fired=真;
//创建壳的实例并存储对其刚体的引用。
游戏对象外壳实例=(游戏对象)
实例化(m_Shell、m_FireTransform.position、m_FireTransform.rotation);
//将炮弹速度设置为射击位置前进方向的发射力。
shellInstance.GetComponent().velocity=m_CurrentLaunchForce*m_FireTransform.forward;
//将剪辑更改为射击剪辑并播放。
m_ShootingAudio.clip=m_FireClip;
m_ShootingAudio.Play();
NetworkServer.Spawn(shellInstance);
//重置发射力。这是一项预防措施,以防丢失按钮事件。
m_CurrentLaunchForce=m_MinLaunchForce;
}
然后这样称呼它:


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

如果查看文档,您会发现此->[命令]函数在与连接关联的玩家对象上调用。这是为响应“ready”消息而设置的,方法是将player对象传递给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;

}
[命令]
私人火灾(枪炮开火)
{
//设置fired标志,以便只调用一次Fire。
m_Fired=真;
//创建壳的实例并存储对其刚体的引用。
游戏对象外壳实例=(游戏对象)
实例化(m_Shell、m_FireTransform.position、m_FireTransform.rotation);
//将炮弹速度设置为射击位置前进方向的发射力。
shellInstance.GetComponent().velocity=m_CurrentLaunchForce*m_FireTransform.forward;
//将剪辑更改为射击剪辑并播放。
m_ShootingAudio.clip=m_FireClip;
m_ShootingAudio.Play();
NetworkServer.Spawn(shellInstance);
//重置发射力。这是一项预防措施,以防丢失按钮事件。
m_CurrentLaunchForce=m_MinLaunchForce;
}
然后这样称呼它:


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

在当前的第一个>max testI do in
CmdFire()中,您从未设置
m_Fired=true
,这是从这个if语句调用的,否?m_Fired是局部变量还是类变量?它是类变量variable@MarcB成功了!但我不明白为什么
m_fired
是一个类变量,在
CmdFire()
中被设置为
true
。在
CmdFire()
中调用的第一个当前>max testI do中,从未设置
m_fired=true
,否?那么,m_fired是局部变量还是类变量?它是一个类变量variable@M