Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by boddole · Mar 19, 2014 at 08:17 AM · c#eventeventsdelegates

Question on Events and Delegates

Hello everyone, I'm working on using Events and Delegates but I've hit a roadblock and was hoping if someone could tell me A) if what I'm looking for is possible and B) point me in the right direction for how to accomplish it.

What I'm trying to do: I've got a number of playable rooms, and when the play leaves those rooms, I would like all the audio from those rooms to turn off using a generic script that I can pass a int to and call the appropriate event.

My Problem: I'm not sure how to use this int value to call the appropriate event (aside from using a ton of IF statements...). I was not successful in making a array of events or calling the main delegate event by index, so how would this be accomplished?

I've also considered a script that calls a Manager that then calls an event, but that again ends up with many scripts instead of 1.

Below is a basic concept of what I'm trying to do, any help is appreciated.:

 using UnityEngine;
 using System.Collections;
 
 public class MasterManager : MonoBehaviour {
 
     public int roomNumber;
 
     public  delegate void TurnSoundsOff ();
     public static event TurnSoundsOff turnOff1;
     public static event TurnSoundsOff turnOff2;
     
 
     void Update () //would be ontriggerenter or something similar
     {
         if (Input.GetKeyDown (KeyCode.P))
         {
             RelayMessage();
         }
         
     }
     
     
     void RelayMessage ()
     {
         //call specific event based on roomNumber
     }
 }
Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Mar 19, 2014 at 08:30 AM 0
Share

I may be missing details of what you are trying to accomplish, but the way I might structure it is to have the player (or whatever deter$$anonymous$$es what room is the current one), send an event any time a new room is entered or left. That event would include the room number. The generic audio scripts would listen for that event. Since each script knows it's room number, it could compare the room number in the event with the sent room number and would take the appropriate action.

avatar image boddole · Mar 19, 2014 at 08:54 AM 0
Share

I had considered that, but I just thought it would be wasteful to have say 100 gameobjects with audio components on them checking a number passed in from an event when say only 10 really need to know. $$anonymous$$aybe it is not that big of a deal?

avatar image ArkaneX · Mar 19, 2014 at 10:54 AM 0
Share

Events work this way - you're raising them, and one or more subscribers consume. Some of them might decide they were not the valid target, and just ignore the event - nothing wrong with this.

If you want a room to listen only to an event prepared specifically for it, then maybe you should just create a method TurnSoundsOff in the script attached to a room, and call it from your manager?

1 Reply

· Add your reply
  • Sort: 
avatar image
3

Answer by Berenger · Mar 19, 2014 at 08:33 AM

You could have a parent foreach of your rooms, and have their references in your MasterManager. When leaving a room, use that parent and GetComponentsInChildren() to disabled them all. Or search of your own script that knows what to disable and how.

If you still prefere events, have an array of them in MasterManager. The index represent a room. When something that can make sounds is created, have it subscribe the turn off sound function to the event corresponding to its room index. Something like :

 // In a script attach to the thingy that makes sound
 masterManager.SubscribeEvent(TurnOffSound(), roomIndex); 

 // In MasterManager
 public void SubscribeEvent(TurnSoundsOff turnOff,int roomIndex)
 {
     onLeaveRoomArray[roomIndex] += turnOff;
 }
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image boddole · Mar 19, 2014 at 08:57 AM 0
Share

I have been using the foreach method for other things (like keep track of and turning on and off gameobjects for each room). But its just...messy, you end up with large arrays of objects and then a jagged array so I can pass in either what room or what part of a room should be turning off. It just seems like events would be a much cleaner way of going about it.

Also, could you elaborate on your second part of your answer? I tried a few times to make an array of events but I always got errors from it.

avatar image Berenger · Mar 19, 2014 at 10:52 AM 0
Share

Sure :

 using ...
 using System;
 using System.Collection.Generic;
 
 public class $$anonymous$$aster$$anonymous$$anager : $$anonymous$$onoBehaviour 
 {
     // By using System.Action, no need to declare the delegate signature
     Action[] onLeaveRoomArray = null;
 
     // Call this from whatever is making a sound.
     public void SubscribeEvent(Action turnOff,int roomIndex)
     {
         onLeaveRoomArray[roomIndex] += turnOff;
     }
 
     // Call this from the room you're leaving
     public void RaiseEvent(int roomIndex)
     {
         onLeaveRoomArray[roomIndex]();
     }
 
     ...
 }
avatar image Berenger · Mar 19, 2014 at 10:54 AM 0
Share

This implies that whatever makes a sound has a script able : to know the index of the rooms it's in, to have a reference to the master manager (or you can have use static / singleton), to call the SubscribeEvent function at Awake, and to know how to turn off the sound (likely audio.Stop())

avatar image boddole · Mar 19, 2014 at 07:14 PM 0
Share

Ok, so I think I've got everything, but I don't understand where TurnSoundsOff and turnOff come into this. (sorry to keep dragging this out, I'm not smart enough to figure out what I'm sure is a perfectly straight forward answer).

avatar image Berenger · Mar 19, 2014 at 10:37 PM 0
Share

It's all right. There was a mistake in my script, the TurnSoundsOff is actually an Action. Anyway, how do you know when the player leaves the room ? If there is a trigger on the door, with a script implementing OnTriggerEnter, then you have to call RaiseEvent from there.

If you still have difficulties, could you tell me this :

  • How does the room know it's a room ? With a Room script attached maybe ?

  • Is there a script attached to the things making sound, on a jukebox or a radio for instance ?

  • The question above about leaving the room

About actions, here is a bit of code, put it in an awake or start function to see what it does and play around with it :

 System.Action test = () => Debug.Log("A");
 test += () => Debug.Log("B");
 test += () => Debug.Log("C");
 
 System.Action test2 = () => Debug.Log("D");
 test2 += () => Debug.Log("E");
 
 test += test2;
 
 test(); // Should print from A to E

Good luck :)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity Events, Listeners, Delegates, etc. 1 Answer

Question about unsubscribing eventhandlers OnDisable and OnEnable 2 Answers

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Raise and Event with EventMessenger 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges