Unity AudioSource.Play has noise - unity3d

I have multiple piano keys with the AudioSource Component, if I press one key repeatedly the sound starts with a tick noise that is not in the original sound clip.
I tried changing the audio clips and set Doppler Factor to 0 but nothing works.
I could manage it by instantiating the key while its playing and the noise is gone now but if I play multiple keys by moving my finger over them I get a "Hall Reverb" effect and its a little expensive too.
if (go.GetComponent<AudioSource>().isPlaying)
{
AudioSource Note = Instantiate(go.GetComponent<AudioSource>(), Clones);
Note.GetComponent<SpriteRenderer>().enabled = false;
Note.GetComponent<BoxCollider>().enabled = false;
Note.Play();
Destroy(Note.gameObject, 2);
}
else
{
go.GetComponent<AudioSource>().Play();
}
I tried PlayOneShot() and it had the exact same effect like the code above.
Could you help me? I am using Unity 2018.2.14f1.

Correct me if I am wrong, but it looks to me that you want to play a note, even when your audiosource is already playing.
Instead of duplicating an existing gameobject (which is prone to errors, use a prefab instead) you can play an audio clip at a point.
AudioSource.PlayClipAtPoint(clip, transform.position);
You would need to add a public variable that takes in the target clip into your script.

Related

How to calculate the length of platform/object in Unity 5?

I'm new to Unity and after watching and reading some tutorials I'm now trying to make a simple 2D platformer kind of game. In the said game both enemies and player can jump to different platforms and traverse it like the old SnowBros game.
The problem I'm facing is related to programming the enemy movement. In my game there would be several types of enemies but generally for now there are two types, one that can jump from the platform and one that only walks upto the length of the platform, wait for 1 second then flip and walk backwards; meaning they don't get off the platform. Now this is an issue I'm having trouble with. I can't seem to find a way to calculate the length of the underlying current platform. I thought of using the collider.bound.min.x and max.x to come around the problem but the issue is I can't seem to find a simple way to reach the current platform's collider without fetching the script and then going through it.
Since, there would be many platforms of many different sizes and each platform is made up of a prefab of other platforms, it just doesn't seem like a workable solution to use the platform script and then traverse through it.
You can use Physics2D.Raycast to "sense" for collisions on a Ray. Imagine the enemy putting their toe one step forward, feeling if there is still solid ground, and then deciding whether to stop.
void Update()
{
Vector2 newPosition = transform.position + velocity * Time.deltaTime;
Vector2 downwardDirection = Vector2.down; // you may have to replace this with your downward direction if you have a different one
RaycastHit2D hit = Physics2D.Raycast(newPosition, downwardDirection);
if (hit.collider != null)
{
// solid ground detected
transform.position = newPosition;
}
else
{
// no ground detected. Do something else...
}
}
You can and should define the Layers your Raycast is supposed to hit, so it can ignore the enemy itself and avoid self-collision.
Well, I hope that you have prefabs of platform and in those prefabs put colliders at start and at end. You can specify layers and tags so that only enemy can detect those colliders and then you can detect tags on collision from enemy script and make your operation.
First create layers by opening Edit -> Project Settings -> Tags and Layers. Create two Layers
Create layers for enemy and enemyColliders and Goto Edit -> Project Settings -> Physics2D. Set collision matrix as EnemyCollider will collider with enemy only.
And your prefab will be looks like,
I hope this would help you.

Delete animation of a certain bone for a number of frames Unity3d

I have an animation of a Mecanim. I wonder how I can delete the animation of only the right-hand for the next couple of frames once I press a certain key in the LateUpdate() function
void LateUpdate ()
{
if (Input.GetKeyDown (KeyCode.D))
{
//delete the next lets say 100 frames of only the right-hand
}
}
If anyone could please advise how this can be done?
Comment is getting Bigger So I will paste it in here.
https://www.youtube.com/watch?v=Xx21y9eJq1U
In this video try to check the 44:51 ish or something. That is what you need. Then Control it with a script when to activate it.
It is a Masking. You can mask the animation and so on. You will get the idea when you watch this.

Getting collisions for multiple object without the collision callbacks

I'm making a platformer (sidescroller), and right now I'm making a grenade-launcher for the player.
It spawns grenades which is a prefab, this prefab has a Circle Collider 2D which is the blast radius for the explosion.
When a grenade is spawned I run this (amongst other things);
// Add the initial force
rBody.AddForce(new Vector2(forceX, forceY) *300f);
Invoke("Explode", 2.5f);
I'm having trouble figuring out how I should handle the Explode function.
I would like to find all the GameObjects that are colliding with the Circle Collider 2D at that point, but I can't find a way to do it.
I would like to be able to do something like this (not real code but you understand what I'm trying to do)
void Explode () {
collidingObjects = circleCollider.getCollisions();
foreach(collidingObject as entity) {
if(entity = 'player')
player.pushLeftOrRight()
elseif(entity = 'enemy')
grenade.dealDamage(grenade.damage)
}
Debug.Log("Explode");
Destroy(gameObject);
}
I'm guessing that it wouldn't work so can anyone point me in the right direction?
In your grenade's script, use OnTriggerEnter or OnCollisionEnter to log collisions; basically just have a HashSet for each grenade that is updated and keeps track of what it is colliding with. Then Explode just has to iterate through this set when you call it.

Trigger in Unity 3D project working not constantly

There is a remake of the Snake game. The snake's head is a trigger, and the apple uses only a collider. Now OnTriggerEnter() does not work every time - the snake's trigger have to enter several times into apple's body to get it.
There is code used for eating:
void Head.OnTriggerEnter(Collider col)
{
if(col.CompareTag("Food"))
{
gameController.FoodEated();
}
}
public void GameController FoodEated()
{
Destroy(currentFood);
InitializeMeal();
head.GrowUp();
}
void GameController.InitializeMeal()
{
currentFood = (GameObject)Instantiate(foodPrefab, FindFreeSpace(), Quaternion.identity);
}
And there is some kind of magic: The first apple could be eaten normally, but the snake can walk through the second apple a few times before the apple will be activated.
I tried every trigger functions and none of them are working. http://www.youtube.com/watch?v=z_UQi7SGOLw - video of a bug. The snake is going through the apple for 3-4 frame updates. I have another idea for realizing an apple, but a trigger is more appropriate, I think.
If your snake moves too fast and the apple collider is too small than I guess that Unity's engine can sometimes miss collisions.
If on the snake you have a Rigidbody component than you can increase collision detection quality by changing "Collision Detection" from "Discrete" to "Continues" or "Continues Dynamic".
As you can see on the video above, my snake is growing by creating a tailelement at the current transform.position. TailElement starts moving when the distance between last two tail elements is more or equals 1.
I just tried to decrease the radius of the head's collider by 10% and now the tail element is not collider during the movement of snake. Now it works fine.

unity3d 4.3 bullets coming back down

I am trying to build a 2D space shooter game where the player will remain constant at the bottom of the screen and will move left and right. When the player fires a bullet(projectile), the bullet is going up just fine, but it is coming back again. Also if two bullets collide, they react to the collision.
I have two questions here:
How can I ensure that the bullet does not come back? (One way is to destroy it after a few seconds, but not sure if this is the right way)
How do I avoid collision between the bullets.
Here is my code snippet:
void Update () {
if (Input.GetButtonDown("Fire1"))
{
Rigidbody2D clone = (Rigidbody2D)Instantiate(bullet, transform.position + transform.up, transform.rotation);
clone.velocity = transform.TransformDirection(Vector3.up * 20);
}
}
I am very new to Unity and somehow wrote this code by looking into Unity Forums.Any help will be very much appreciated.
Thanks
More details:
I have created the bullet and added Rigidbody2D and a BoxCollider2D for this object. Made the bullet object a prefab and I dragged it under the Player object. Now bullet is a child of the Player object. Attached the script above to the Player object.
To answer your immediate questions:
1) I am not too sure about how you have the scene setup or about using the Unity 2D tools but usually if your bullets are coming back down then I would assume that you still have gravity applied to the rigidbody -- so make sure that you have that unchecked.
2) With Unity3D for objects to interact with each other they need rigidbodies attached. This is vital, say, if you want your lasers to destroy Monster #1. However, you only need one rigidbody attached to an object to have a desired effect. I would suggest removing the rigidbody from your laser and attach rigidbodies to objects ( Monster #1 ) that you want to be affected by the laser fire. ( That should work, if not there are other options -- one using layers and ignoring particular objects on those layers ).
Tips:
Here are some extra things. When you are creating objects and they fly off screen over time they will build up. Imagine you are in a large battle and you instantiated hundreds of lasers -- it will eventually be an issue for performance. So always consider Destroying objects after a certain amount of time.
Also, after looking at your code, I can't tell whether the velocity of the object is based upon its current position and nothing is being added. What I think is happening is when you instantiate an object it may be moving up, but because there is no incrementer, the object ( as it gets higher ) slows until it is at a rate which it is falling. For example this
clone.velocity = transform.TransformDirection(Vector3.up * 20);
should probably do this:
clone.velocity += transform.TransformDirection(Vector3.up * 20);
Heres http://docs.unity3d.com/Documentation/ScriptReference/Vector3-up.html, to read up on velocity. The problem is is that you need to continuously apply a constant forward motion so things in motion will tend to stay in motion. If not gravity will pull it down.
Also, heres a bit of code that I've used in the past that's created a pretty cool shooting laser effect thing:
public class Laser : MonoBehaviour {
public int fireRate = 70;
void Start(){
InvokeRepeating("FireLaser", 0.01f, 0.009f);
Destroy( gameObject, 2.0f );
}
void FireLaser(){
transform.Translate( Vector3.up * fireRate * Time.deltaTime );
}
}
edit: it's 3 a.m. and I hate proofreading.