How do you play an audio clip on a collision? - c#

I'm trying to make a sound clip play when my player collides with a specific obstacle. I created an AudioSource on the obstacle, and wrote this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class sound : MonoBehaviour {
AudioSource audioSource;
void Start()
{
audioSource = GetComponent<AudioSource>();
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.CompareTag("Player"))
Debug.Log("hit");
GetComponent<AudioSource>().Play();
}
}
I gave the player a tag "Player", but when they collide, even though they both have a 2Dcollider component, the collision is not registered. There is no sound, nor does it say "hit" in the debug.log statement I wrote to check.
I have looked on the Unity documentation and I don't see what I'm doing wrong - what am I missing?

When working in a 2D environment with 2D component you need to use the 2D endings for some of your functions to work.
In your case you use
void OnCollisionEnter(Collision c)
But you need to use
void OnCollisionEnter2D(Collission2D c)
Docs:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html
Further more you might aswell use your audioSource.Play() since you already set the variable to the component in your Start(). Instead of GetComponent().Play();

If 3D,
void OnTriggerEnter(Collider other){
if(other.tag == "Player"){
this.GetComponent<AudioSource>().Play();
Debug.Log("PLayed Sound!");
}
}
Simple. Good Luck on whatever your doing!

Related

How to change a sprite with a script Unity

I'm new to Unity and C#. I'm trying to make the sprite of "bird" change when he dies in unity. I tried following some tutorials but it doesn't work, so now I'm just trying to make the sprite change when "A" is pressed, but it still doesn't work. Is it a problem of the script or of the sprite?
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeSprite : MonoBehaviour
{
public Sprite deadBird;
void Start()
{
}
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
GetComponent<SpriteRenderer>().sprite = deadBird;
}
}
}
Here is a screenshot: https://i.stack.imgur.com/PTd9W.png
I think #derHugo is correct, if you have an Animator then that will most likely overwrite any change you try and do. To fix this, you can use that animator and create an animation that is the deadBird. once you have that, connect it to the animator controller from the normal state. in that connection you can create and set a new animator boolean like "isDead" and set it to switch to the dead animation is the bool is true. then change your code from
GetComponent<SpriteRenderer>().sprite = deadBird;
To
anim = gameObject.GetComponent<Animator>() //place this instead of the bird sprite
anim.SetBool("isDead", true); //place this in the if statement
Hope that helps! it's much cleaner to go through the animator as it allows for easier changes as you build your game.

unity 2020.3 NavMesh AI not moving

so this issue is fixed, the problem was that the U in Update wasnt capitalised
me and a few friends started making a FPS a few weeks ago and I'm now trying to get the AI to just walk towards the player but the enemy just stands still like a random object.
I have tried to rewrite the code, redo the NavMesh, redo the player and enemy components (with help from my brother who is an indie dev), I followed unity's documentation, even tried to do the AI in a different project but it just doesn't work.
I don't get any errors, so I don't know what I'm doing wrong, been at this AI for a day or two now
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class PlayerNavMesh : MonoBehaviour{
private NavMeshAgent agent;
private GameObject target;
private void Start()
{
agent = GetComponent<NavMeshAgent>();
}
private void update() {
target = GameObject.FindGameObjectWithTag("Player");
if(target != null)
{
agent.destination = target.transform.position;
}
else
{
Debug.Log("No target found");
}
}
}
Update() should be capitalized. Also, why are you setting target every frame?

Why does this error keep popping up? Index out of range: Unity 2D/WebGL C#

I am relatively new to Unity and have a recurring error. I am creating a simple 2D game in which the player can shoot these bullets at enemies, which are prefabs. In Unity itself, everything works fine but when I try to make a build in WebGL to play in my browser, and error keeps popping up saying my memory is out of bounds or index is out of range.
I have tried doing this on chrome, firefox, and explorer but the same thing keeps happening. I have tried searching the internet but have found no answers on how to fix this problem so far. Here is the code for my bullet script, if it helps.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WebShooter : MonoBehaviour {
public Transform firePoint;
public GameObject bulletPrefab;
void Update() {
if (Input.GetKeyDown(KeyCode.Space)) {
Shoot();
}
}
void Shoot() {
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
}
private void OnTriggerEnter2D(Collider2D hitInfo) {
Destroy(gameObject);
}
}
https://imgur.com/G9ysLFM
Could it have something to do with the fact that you are not destroying the bullets that don't hit the gameobject? do you have any code to destroy them once they go off the screen?
If(Mathf.Abs(bulletPrefab.position) - Mathf.Abs(firePoint.position) > 10)
{
Destroy(gameObject);
}
I'm just thinking that you might be overloading the memory with lots of undestroyed bullets flying off into infinity

How to fix "Can't Play a Disabled Audio Source"?

I am trying to add a sound into my game that whenever the player moves over a certain space it plays a crunch sound. I have created the AudioSource file and a .OGG file for the sound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpaceBlue : MonoBehaviour
{
public Transform spaceNext;
public AudioSource stepOnObject;
public AudioClip stepOnSound;
private void Start()
{
stepOnObject.clip = stepOnSound;
stepOnObject.enabled = true;
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
stepOnObject.Play();
if (BoardScript.diceValue > 0)
{
BoardScript.diceValue -= 1;
Debug.Log("The dice are now " +BoardScript.diceValue);
other.transform.LookAt(spaceNext);
}
}
}
}
I have included the source and clip to my game object and i have tried it both with and without "Play on wake" selected.
Whenever the play walks over the player walks over the object i get a warning in the unity engine saying that the source is disabled.
Any help is appreciated :)
I had a similar problem and I fixed it by changing the location of the Play() call to after calling Destroy(GameObject). I would recommend trying moving the call to Play() to the end of the function, or trying Invoke("stepOnObject.Play", 0.5f); to ensure it gets called.
Otherwise, make sure its checkbox is ticked, and that the AudioSource actually has a AudioClip attached.
If you have any piece of code in some other script that Destroys this game object or makes SetActive false, then the best way to solve this problem will be to delay that piece of code by some time using a Coroutine.

OnCollisionEnter somehow not working [duplicate]

i am bloody beginner with Unity and i am currently working on a 2D Brawler. The movement works perfectly but my colliders don't do what they should... I want to detect if two GameObjects Collide (Spear and Player2) and if the collide Player2s healthPoints should decrease by Spears AttackDamage.
The names of the GameObjects are also their tags. The Spears Prefab has following configuration: SpriteRendered(Material Sprites-Default), BoxCollider2D(Material None Physics Material 2D, IsTrigger(not activated), UsedByEffector(also not activated) Rigidbody2D(Kinematic, None Material, Simulated(Activated), KinematicContacts(activated), Standard configs for the rest))
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpearCtr : MonoBehaviour {
public Vector2 speed;
public float delay;
Rigidbody2D rb;
void Start ()
{
rb = GetComponent<Rigidbody2D>();
rb.velocity = speed;
Destroy(gameObject, delay);
}
void Update ()
{
rb.velocity = speed;
}
}
The Players Configurations
The Spears Configurations
This was the code i have tried before
OnCollision2D(Collision2D target);
{
if (target.gameObject.tag == "Spear")
{
hp = -1;
if (hp <= 0)
{
alive = false;
}
}
}
I hope someone can tell me how to get this working
Thanks for all the answers
(BTW sorry for my bad english I am austrian)
enter image description here
enter image description here
Reasons why OnCollisionEnter() does not work:
Collison:
1.Rigidbody or Rigidbody2D is not attached.
At-least, one of the two GameObjects must have Rigidbody attached to it if it is a 3D GameObject. Rigidbody2D should be attached if it is a 2D GameObject/2D Collider.
2.Incorrect Spelling
You failed to spell it right. Its spelling is also case sensitive.
The correct Spellings:
For 3D MeshRenderer/Collider:
OnCollisionEnter
OnCollisionStay
OnCollisionExit
For 2D SpriteRenderer/Collider2D:
OnCollisionEnter2D
OnCollisionStay2D
OnCollisionExit2D
3.Collider has IsTrigger checked. Uncheck this for the OnCollisionXXX functions to be called.
4.The script is not attached to any of the Colliding GameObjects. Attach the script to the GameObject.
5.You provided the wrong parameter to the callback functions.
For 3D MeshRenderer/Collider:
The parameter is Collision not Collider.
It is:
void OnCollisionEnter(Collision collision) {}
not
void OnCollisionEnter(Collider collision) {}
For 2D SpriteRenderer/Collider2D:
6.Both Rigidbody that collides has a isKinematic enabled. The callback function will not be called in this case.
This is the complete collison table:

Categories