0
\$\begingroup\$

I am trying to play the sound of a car accelerating while a user has a certain button pressed, however, the audio clip isn't playing until after that button is released. Can anyone explain to me where I'm going wrong?

C#

using UnityEngine;
using System.Collections;

public class MoveCar:MonoBehaviour{
    //Car's idle speed
    private float idleSpeed = 0.0f;
    //Car's current speed
    private float speed = 0.0f;
    //Car's top speed
    public float topSpeed = 165.0f;
    //Car's acceleration rate
    public float acceleration = 10.0f;
    //Car's braking power
    public float deceleration = 15.0f;
    private Rigidbody playerCar;

    void Start(){
        playerCar = GetComponent<Rigidbody>();

    }

    void Update(){
        if(Input.GetKey(KeyCode.W)){
            AudioSource accelerate = playerCar.GetComponent<AudioSource>();
            float horizontal = Input.GetAxis("Horizontal");
            float vertical = Input.GetAxis("Vertical");
            if(speed <= topSpeed){
                accelerate.Play();
                speed = speed + (acceleration * Time.deltaTime);
                Vector3 movement = new Vector3(vertical, 0.0f, horizontal);
                playerCar.AddForce(movement * Mathf.Clamp(speed, idleSpeed, topSpeed));
                Debug.Log(Mathf.Clamp(speed, idleSpeed, topSpeed));
            }
            else{
                speed = topSpeed;
                Debug.Log(Mathf.Clamp(speed, idleSpeed, topSpeed));
            }
        }
    }
}

Here's my editor windows enter image description here

\$\endgroup\$
1
\$\begingroup\$

Input.GetKey returns true whilst the key is pressed, you're looking for Input.GetKeyDown; this will only fire once. The reason yours isn't working is because it's constantly running those lines of code, which causes the audio to always be 'starting'. If you combine Input.GetKeyDown and Input.GetKeyUp you'll be able to achieve what you're looking for (make sure loop is on);

private AudioSource accelerate;

public void Start()
{
    accelerate = playerCar.GetComponent<AudioSource>();
}

public void Update()
{
    if (Input.GetKeyDown(KeyCode.W))
        accelerate.Play();

    if (Input.GetKey(KeyCode.W))
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        if (speed < topSpeed)
        {
            speed = Mathf.Clamp(speed + (acceleration * Time.deltaTime), 0f, topSpeed);
            if (speed == topSpeed)
                accelerate.Stop();
        }

        Vector3 movement = new Vector3(vertical, 0.0f, horizontal);
        playerCar.AddForce(movement * Mathf.Clamp(speed, idleSpeed, topSpeed));

    }
    else
        speed = Mathf.Clamp(speed - (acceleration * Time.deltaTime), 0f, topSpeed);
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Would the same thing happen if I just set the playing variable to false initially and just added the GetKeyDown handler but left the GetKey handler, or would they conflict? \$\endgroup\$ – Robert Mar 18 '16 at 20:46
  • 1
    \$\begingroup\$ They wouldn't conflict as GetKeyDown is fired on the frame that the key is pressed no matter what. Assuming you're replacing playing with GetKey, that should also work, in which case you don't need playing (updated solution accordingly, good point) \$\endgroup\$ – MrDiVolo Mar 18 '16 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.