Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved Playing audio on server event

Discussion in 'Netcode for GameObjects' started by Tsunamisukoto, Sep 13, 2023.

  1. Tsunamisukoto

    Tsunamisukoto

    Joined:
    Apr 21, 2023
    Posts:
    24
    Hey there,
    I have server authoratative actions in my shooting game like "successfully hit" sound effect etc
    Im starting to toy with audio and playing sounds so I might be going about this the completely wrong way.
    I am currently using

    AudioSource.PlayClipAtPoint(deathSound, transform.position);

    What is the recommended method to get an audio clip to play on all machines at the location?
    Do I just write a simple prefab prefab with an audio clip and network object and spawn it or is there a better way to "make an audio clip play at location for all clients"?, heck, is there a built in method on a network behaviour or something?
     
  2. Tsunamisukoto

    Tsunamisukoto

    Joined:
    Apr 21, 2023
    Posts:
    24
    sorry, thought I'd give more context for where/how this sits.
    I have this script sitting on a spell projectile:

    Code (CSharp):
    1.  
    2. public class DestroyOnCollision : NetworkBehaviour
    3. {
    4.     private ProjectileCommonParams projectileParams;
    5.     [SerializeField] private bool withOwner;
    6.     [SerializeField] private AudioClip deathSound;
    7.     void Start()
    8.     {
    9.         projectileParams = GetComponent<ProjectileCommonParams>();
    10.     }
    11.  
    12.     // Update is called once per frame
    13.  
    14.     private void OnCollisionEnter2D(Collision2D collision)
    15.     {
    16.         if (!IsServer)
    17.             return;
    18.         var physicsObject = collision.gameObject.GetComponentInChildren<PhysicsObject>();
    19.         if (physicsObject != null)
    20.         {
    21.             if (collision.gameObject.TryGetComponent<SpellTarget>(out var spellTarget))
    22.             {
    23.                 if (withOwner || !spellTarget.IsInvalidTarget(projectileParams.playerId))
    24.                 {
    25.                     DestroyThisAndApplyBuffs(collision.gameObject);
    26.                 }
    27.             }
    28.         }
    29.     }
    30.  
    31.     private void DestroyThisAndApplyBuffs(GameObject collisionGameObject)
    32.     {
    33.         if(TryGetComponent<AppliesBuff>(out var appliesBuff))
    34.         {
    35.             appliesBuff.ApplyBuff(collisionGameObject);
    36.         }
    37.         if (deathSound != null)
    38.         {
    39.  
    40.             AudioSource.PlayClipAtPoint(deathSound, transform.position);
    41.         }
    42.         Destroy(gameObject);
    43.     }
    44. }
     
  3. Tsunamisukoto

    Tsunamisukoto

    Joined:
    Apr 21, 2023
    Posts:
    24
    or is this one that works well with clientRPCs? sorry for spam, just spitballing
     
  4. Mj-Kkaya

    Mj-Kkaya

    Joined:
    Oct 10, 2017
    Posts:
    188
    Hi there,
    If you want to destroy NetworkObject you should use ".Despawn()" method because this method triggers on all players.
    You mentioned above, you can use "clientRPCs" or listen to "OnNetworkSpawn" method then play the audio.
     
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,596
    If something dies, that state change has already been communicated over the network. Whatever that thing is, when it responds to its death it plays a sound fx indiscriminately, meaning it shouldn‘t check if it‘s the owner or a local instance or whatever. It just play the audio and other things (vfx, animation) when it dies.
     
  6. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Hi @Tsunamisukoto , all you need to do is to call a ClientRPC from the server. You don't need to pass the AudioClip to it as you can retrieve it locally (I.E: assign it in the inspector), just the position.

    Does this help?
     
    Tsunamisukoto likes this.
  7. Tsunamisukoto

    Tsunamisukoto

    Joined:
    Apr 21, 2023
    Posts:
    24
    Riku that helps immensely and suits how I like to code things. Thanks everyone.
     
    RikuTheFuffs-U likes this.
  8. YalnizCanavar

    YalnizCanavar

    Joined:
    May 31, 2020
    Posts:
    10
    Hi Riku, i am having the same problem audiosource is a non nullable value so it does not serialize it and i cant play it on server rpc, how exactly can i play the audio source
     
  9. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Your code should never play sounds on a server. Servers are for handling logic. Always assume a server has no local player, or you'll have serious issues when implementing server-authoritative models proeprly.

    You need to change the logic of your code so that the clip is played on client, I.E: through a ClientRPC