14_SoundEffects.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. // Copyright (c) 2015 Xamarin Inc
  4. // Copyright (c) 2016 THUNDERBEAST GAMES LLC
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. using System.Collections.Generic;
  25. using System.Linq;
  26. using AtomicEngine;
  27. namespace FeatureExamples
  28. {
  29. public class SoundEffectsSample : Sample
  30. {
  31. readonly Dictionary<string, string> sounds = new Dictionary<string, string>
  32. {
  33. {"Fist", "Sounds/PlayerFistHit.wav"},
  34. {"Explosion", "Sounds/BigExplosion.wav"},
  35. {"Power-up", "Sounds/Powerup.wav"},
  36. };
  37. public SoundEffectsSample() : base() { }
  38. public override void Start()
  39. {
  40. base.Start();
  41. CreateUI();
  42. }
  43. void CreateUI()
  44. {
  45. var cache = GetSubsystem<ResourceCache>();
  46. var layout = new UILayout() { Axis = UI_AXIS.UI_AXIS_Y };
  47. layout.Rect = UIView.Rect;
  48. UIView.AddChild(layout);
  49. // Create a scene which will not be actually rendered, but is used to hold SoundSource components while they play sounds
  50. scene = new Scene();
  51. // Create buttons for playing back sounds
  52. foreach (var item in sounds)
  53. {
  54. var button = new UIButton();
  55. layout.AddChild(button);
  56. button.Text = item.Key;
  57. button.SubscribeToEvent<WidgetEvent>(button, e => {
  58. if (e.Type == UI_EVENT_TYPE.UI_EVENT_TYPE_CLICK)
  59. {
  60. // Get the sound resource
  61. Sound sound = cache.Get<Sound>(item.Value);
  62. if (sound != null)
  63. {
  64. // Create a scene node with a SoundSource component for playing the sound. The SoundSource component plays
  65. // non-positional audio, so its 3D position in the scene does not matter. For positional sounds the
  66. // SoundSource3D component would be used instead
  67. Node soundNode = scene.CreateChild("Sound");
  68. SoundSource soundSource = soundNode.CreateComponent<SoundSource>();
  69. soundSource.Play(sound);
  70. // In case we also play music, set the sound volume below maximum so that we don't clip the output
  71. soundSource.Gain = 0.75f;
  72. // Set the sound component to automatically remove its scene node from the scene when the sound is done playing
  73. }
  74. }
  75. });
  76. }
  77. // Create buttons for playing/stopping music
  78. var playMusicButton = new UIButton();
  79. layout.AddChild(playMusicButton);
  80. playMusicButton.Text = "Play Music";
  81. playMusicButton.SubscribeToEvent<WidgetEvent> (playMusicButton, e => {
  82. if (e.Type != UI_EVENT_TYPE.UI_EVENT_TYPE_CLICK)
  83. return;
  84. if (scene.GetChild ("Music", false) != null)
  85. return;
  86. var music = cache.Get<Sound>("Music/StoryTime.ogg");
  87. music.Looped = true;
  88. Node musicNode = scene.CreateChild ("Music");
  89. SoundSource musicSource = musicNode.CreateComponent<SoundSource> ();
  90. // Set the sound type to music so that master volume control works correctly
  91. musicSource.SetSoundType ("Music");
  92. musicSource.Play (music);
  93. });
  94. var audio = GetSubsystem<Audio>();
  95. // FIXME: Removing the music node is not stopping music
  96. var stopMusicButton = new UIButton();
  97. layout.AddChild(stopMusicButton);
  98. stopMusicButton.Text = "Stop Music";
  99. stopMusicButton.SubscribeToEvent<WidgetEvent>(stopMusicButton, e =>
  100. {
  101. if (e.Type != UI_EVENT_TYPE.UI_EVENT_TYPE_CLICK)
  102. return;
  103. scene.RemoveChild(scene.GetChild("Music", false));
  104. });
  105. // Effect Volume Slider
  106. var slider = new UISlider();
  107. layout.AddChild(slider);
  108. slider.SetLimits(0, 1);
  109. slider.Text = "Sound Volume";
  110. slider.SubscribeToEvent<WidgetEvent>(slider, e =>
  111. {
  112. if (e.Type != UI_EVENT_TYPE.UI_EVENT_TYPE_CHANGED)
  113. return;
  114. Log.Info($"Setting Effects to {slider.Value}");
  115. audio.SetMasterGain("Effect", slider.Value);
  116. });
  117. // Music Volume Slider
  118. var slider2 = new UISlider();
  119. layout.AddChild(slider2);
  120. slider2.SetLimits(0, 1);
  121. slider2.Text = "Music Volume";
  122. slider2.SubscribeToEvent<WidgetEvent>(slider2, e =>
  123. {
  124. if (e.Type != UI_EVENT_TYPE.UI_EVENT_TYPE_CHANGED)
  125. return;
  126. Log.Info($"Setting Music to {slider2.Value}");
  127. audio.SetMasterGain("Music", slider2.Value);
  128. });
  129. }
  130. }
  131. }