Search Unity

Fading in audio using coroutine (Specific character)

Discussion in 'Scripting' started by SirWhiteBeard, Mar 18, 2017.

Thread Status:
Not open for further replies.
  1. SirWhiteBeard

    SirWhiteBeard

    Joined:
    Feb 21, 2014
    Posts:
    66
    Hi everyone,

    So I'm having a little issue right here. I'm working with audio for the first time in Unity and figured mu playable character need sound when he's moving. He isn't your typical walking character, but a looper (caterpillar) so he rolls over the ground. For this reason I wanted a audiofile which is constantly making a sound (tone) not your typical footstep. This all worked as intended with audio.Play (); and audio.Pause (); but it gives hard cuts in the audio. For this reason I wanted to fade in the audio when the player is moving and fade out when he stops moving. This is working kind of except I can't seem to manage the volume of the audio file. Currently the volume goes from 0 to 1 and vice versa. The fading out works fine, but the fading in is stuttering in it's volume. When you move the player you see the volume going from 0.7ish to 1 constantly instead of a fixed 1. I have added the code below and hope one of you guys can help me :).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerControl : MonoBehaviour
    5. {
    6.     [HideInInspector]
    7.     public bool facingRight = true;            // For determining which way the player is currently facing.
    8.     [HideInInspector]
    9.     public bool jump = false;                // Condition for whether the player should jump.
    10.  
    11.     public float moveForce = 365f;            // Amount of force added to move the player left and right.
    12.     public float maxSpeed = 5f;                // The fastest the player can travel in the x axis.
    13.     public float startJumpForce = 600f;        // Amount of force the player starts with.
    14.     public float jumpForce;                    // Amount of force the player can mix with.
    15.     public float rockWeight = 100f;         // the weight of one rock
    16.     public float leafWeight = 50f;
    17.  
    18.     public float fadingSteps = 50f;
    19.  
    20.     public GameObject player;
    21.     public GameObject bol;
    22.     public GameObject Module1;
    23.     public GameObject Module2;
    24.     public GameObject Module3;
    25.     public GameObject Module4;
    26.  
    27.     public AudioSource walkingSound;
    28.  
    29.     private Transform groundCheck;            // A position marking where to check if the player is grounded.
    30.  
    31.     private bool grounded = false;            // Whether or not the player is grounded.
    32.  
    33.     void Start()
    34.     {
    35.         walkingSound.volume = 0;
    36.         walkingSound.Play ();
    37.     }
    38.  
    39.     void Awake()
    40.     {
    41.         // Setting up references.
    42.         groundCheck = transform.Find("groundCheck");
    43.  
    44.     }
    45.  
    46.  
    47.     void Update()
    48.     {
    49.         // the actual jumpforce with which the player can jump, calculated on the amount of rocks and leaves the player has.
    50.         jumpForce = startJumpForce - (rockWeight * player.GetComponent<PlayerPickups> ().numberOfRocks) + (leafWeight * player.GetComponent<PlayerPickups> ().numberOfLeaves);
    51.         // The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
    52.         grounded = Physics2D.Linecast (transform.position, groundCheck.position, 1 << LayerMask.NameToLayer ("Ground"));
    53.  
    54.         // If the jump button is pressed and the player is grounded then the player should jump.
    55.         if (Input.GetButtonDown ("Jump") && grounded) {
    56.             jump = true;
    57.         }
    58.  
    59.         if (GetComponent <Rigidbody2D> ().velocity.magnitude >= 0.1f && grounded) {
    60.  
    61.             StartCoroutine(checkSpeeds());
    62.  
    63.         }
    64.     }
    65.     void FixedUpdate ()
    66.     {
    67.             // Cache the horizontal input.
    68.         float h = Input.GetAxis("Horizontal");
    69.  
    70.         // If the player is changing direction (h has a different sign to velocity.x) or hasn't reached maxSpeed yet...
    71.         if(h * GetComponent<Rigidbody2D>().velocity.x < maxSpeed)
    72.             // ... add a force to the player.
    73.             GetComponent<Rigidbody2D>().AddForce(Vector2.right * h * moveForce);
    74.  
    75.         // If the player's horizontal velocity is greater than the maxSpeed...
    76.         if(Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x) > maxSpeed)
    77.             // ... set the player's velocity to the maxSpeed in the x axis.
    78.             GetComponent<Rigidbody2D>().velocity = new Vector2(Mathf.Sign(GetComponent<Rigidbody2D>().velocity.x) * maxSpeed, GetComponent<Rigidbody2D>().velocity.y);
    79.  
    80.  
    81.  
    82.  
    83.         // If the input is moving the player right and the player is facing left...
    84.         if(h > 0 && !facingRight)
    85.             // ... flip the player.
    86.             Flip();
    87.         // Otherwise if the input is moving the player left and the player is facing right...
    88.         else if(h < 0 && facingRight)
    89.             // ... flip the player.
    90.             Flip();
    91.  
    92.         // If the player should jump...
    93.         if(jump) // only jump if button is pressed and heavy is false, which is connected to
    94.         {  
    95.  
    96.             // Add a vertical force to the player.
    97.             StartCoroutine(modulesJump());
    98.             // Make sure the player can't jump again until the jump conditions from Update are satisfied.
    99.             jump = false;
    100.         }
    101.     }
    102.  
    103.     void Flip ()
    104.     {
    105.  
    106.     }
    107.  
    108.     IEnumerator modulesJump() {
    109.         // your head jump code here
    110.  
    111.         GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    112.         yield return new WaitForSeconds (0.0f);
    113.         Module1.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    114.         yield return new WaitForSeconds (0.0f);
    115.         Module2.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    116.         yield return new WaitForSeconds (0.0f);
    117.         Module3.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    118.         yield return new WaitForSeconds (0.0f);
    119.         Module4.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
    120.  
    121.     }
    122.  
    123.     IEnumerator checkSpeeds(){
    124.         float currentSpeed = Mathf.Abs (GetComponent<Rigidbody2D> ().velocity.x);
    125.         yield return new WaitForSecondsRealtime (0.1f);
    126.         float newSpeed = Mathf.Abs (GetComponent<Rigidbody2D> ().velocity.x);
    127.         if (newSpeed < currentSpeed){
    128.             StartCoroutine (FadeOutSound ());
    129.         }else{
    130.             StartCoroutine (FadeInSound ());
    131.         }
    132.     }
    133.     IEnumerator FadeOutSound(){
    134.         if (!walkingSound){
    135.             // Get menuMusic if not already defined in Inspector
    136.  
    137.             walkingSound = GetComponent<AudioSource> ();
    138.         }
    139.         if (walkingSound) {
    140.  
    141.             for (var i = fadingSteps; i > 0f; i--){
    142.  
    143.                 //                Debug.Log ("i  " + i);
    144.                 walkingSound.volume = i * .1f;
    145.                 yield return new WaitForEndOfFrame();
    146.                 //                Debug.Log("Fading...");
    147.             }
    148.             walkingSound.volume = 0;
    149.         }
    150.     }
    151.  
    152.     IEnumerator FadeInSound(){
    153.         if (!walkingSound){
    154.             // Get menuMusic if not already defined in Inspector
    155.  
    156.             walkingSound = GetComponent<AudioSource> ();
    157.         }
    158.         if (walkingSound) {
    159.  
    160.             for (var i = fadingSteps; i > 0f; i--){
    161.                 if(walkingSound.volume < .5f)
    162.                     walkingSound.volume = walkingSound.volume + 0.05f;
    163.                 yield return new WaitForEndOfFrame();
    164.                 //                Debug.Log("Fading...");
    165.             }
    166.             walkingSound.volume = 0.5f;
    167.         }
    168.     }
    169. }
     
  2. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    Try lerp

    Code (csharp):
    1. IEnumerator FadeInSound(){
    2.         float SecondsToFade = 1.5f;
    3.         float startVol = walkingSound.volume;
    4.         float rate = 1.0f / SecondsToFade;
    5.  
    6.         for (float x = 0.0f; x <= 1.0f; x += Time.deltaTime * rate) {
    7.              walkingSound.volume = Mathf.Lerp(startVol, targetVol, x);
    8.              yield return null;
    9.         }
    10. }
     
    Last edited: Mar 18, 2017
  3. SirWhiteBeard

    SirWhiteBeard

    Joined:
    Feb 21, 2014
    Posts:
    66
    I'm not sure what you mean? I had huge help from a fellow student yesterday who helped me setting this up. How would the fade in and fade out work with lerp?
     
  4. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    Lerp = linear interpolation. It's what you're trying to do.

    https://unity3d.com/learn/tutorials/topics/scripting/linear-interpolation
    So, if we use it within a loop, we can move from one value to another by rate x each time it is called
    The rate in this case is time. We want to fade it over a fixed period of time.

    Multiplying by Deltatime makes it frame rate independent. So, the interpolation doesn't take different periods of time based on how fast or slow the users PC is. It will always take secondsToFade whether you're running 120 fps or 40 fps.

    If you don't use that, then the PC running at 120 fps will fade 3 times more quickly than the guy running 40 fps, and unstable frame rates will not have a smooth fade. That's because a couroutine is called every frame, just like update.
     
  5. vitamiin

    vitamiin

    Joined:
    Sep 16, 2021
    Posts:
    3
    How do i reverse this?
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    Please don't necro old posts. Please don't cross-post either. You correctly posted the question here.
     
Thread Status:
Not open for further replies.