How to stop particle system with a timer? - unity3d

so I have a simple code that Spawn particle when player stay at a trigger. But the particles keeping turn on and i want to turn off after a few seconds. What i have to do?
if (other.gameObject.tag == "Player" && Input.GetKeyDown(KeyCode.E))
{
PlayerManager.health += 1;
MyParticleEffect.SetActive(true);
Debug.Log("e key was pressed");
}

If you dont want to change this value you can turn off the loop property and play with the duration.
If you want to change this dynamically, its best to use StartCoroutine:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
This is used like a timer, and you can turn the particle system off when the timer elapses.

Your particle system is probably set to 'loop'. Set the loop property of the particle effect to false.

Related

Checking collision only during animations

I have this knight character with a sword and an attacking animation. I want to check if the sword is colliding with an enemy and then decrease the enemy health. I managed to do that but EVERY TIME the sowrd's collider hits the enemy's collider I have the interaction. Obviously I don't want that, but the interaction should happen ONLY when the player is attacking.
I tried different approahces:
Check the attack with a boolean, by doing this in the character script
if (Input.GetButtonDown("Fire1"))
{
GetComponent<Animator>().SetBool("hit1", true);
isAttacking = true;
}
and this in the enemy script
if (other.gameObject.CompareTag("Sword") && knight.isAttacking)
{
Debug.Log("Hit");
currentHealth -= 10;
Debug.Log("Enemy healh: " + currentHealth.ToString());
healthBar.UpdateHealthBar();
}
Check if the animation is running using animator.GetCurrentAnimatorStateInfo(0).IsName("nameOfTheAnimationState") instead of knight.isAttacking
Nothing seems to work so far, I know that I'm missing something stupid and I'm going to facepalm when you guys will tell me so, please, make me facepalm!
Thanks.
In the animation window, open the attack animation of the player which roughly looks like this
Now, try playing with the vertical white bar, moving it shows the animation snapshot of the player at each keyframe. Now, find the keyframe at which the player lifts the sword to hit the enemy. Add an event there by clicking the button that's circled red in the image below
After adding the event, you'll see the function in the inspector that's invoked by the event when the animation reaches that keyframe.
Now, create a function to set the attack point active in your script.
Find the keyframe at which the player drops the sword after hitting the enemy and add an event there. Invoke another function that sets the attack point to false.

Move During playing Jump Animation

So the case is that I have a 36 frames long jumping animation and the jump itself starts at frame 12, where my object raises along y axis.
What would be the most easiest way to move my object forward while it's in air(during frames 12-36)?
How is jumping with animation generally done in games? I don't think my way is the best one. But I would also like to know how its usually done in my way too. Thanks
I have just read the comments and your question. Why not write this code:
Whenever You want him to jump at whatever condition:
Here I'll show you how to do it onClick of Space i.e, whenever you click space the jump animation plays whatever animation you have now the object moving in y-axis
if(Input.GetKeyDown(Keycode.Space))
{
yourPlayerAnimator.setBool("TheAnimatorCondition",true); //Bool for your animation to play if u have a idle with you.
}
if(yourPlayerAnimator.GetBool("TheAnimatorCondition")== true)
{
transform.Translate(Vector3.forward * Time.deltaTime)
}
All these Happens inside void update
Animation transition is your friend.
Put any condition when jumping to move to another animation. In this case i.e. when pressed left displacement key, move from "jump" to "jump&moveleft" or similar and when unpress return to jump state increasing the frames you spent moving to left.

How to keep track of the damage taken?

So I'm making a simple 3D RPG game in Unity with a player and a bunch of enemies. What is the standard way to keep track of the damage taken in combat? I think the easiest way is to count damage everytime the attack animation is triggered, but how? How do I know whether an animation is triggered or not? Or is there any other way to do it? Please help, thanks in advance!
So you want to detect if the enemy hits you with a projectile/melee. The way to do that is attaching a collider to their weapon, you can do this by setting empty game objects as children of the weapon and attach individual collider components to them (Don’t do this unless you know how to make it not take multiple damages at once. Just for extra precision). Then what you want to do is for each/the collider hit the isTrigger check box so it has a check in it. Add a tag to the collider(s) that has a name like “damage” or “weapon”. Then open a script to attach to your player. Use OnTriggerEnter() to detect the weapon hitting your player:
...//the rest of your code before this.
public float health = 10f; //health value.
public float damageTick = 1f; //damage taken per hit
void OnTriggerEnter(Collider obj)
{
//for same damage per different weapon hit.
if (obj.GameObject.Tag == “damage”) //remember this is what the tag of the weapon was.
{
health -= damageTick;
//play the animation. You can do that.
}
//*optional* for different damage per weapon type.
if (obj.GameObject.Tag == “sword1”)
{
health -= sword1Damage; //make sure you have a variable for sword1Damage.
}
else if (obj.GameObject.Tag == “bow8”)
{
health -= bow8Damage; //make sure you have a variable for bow8Damage.
}
// add on to this if else, to make more weapons take different damage.
}
It's too expensive. If you have 10 enemies, then the calculations through the colliders will overload the system.
It's easier to calculate, when the user clicks on the attack button, create a primitive and see what objects are included in this primitive around it. Push them onto the stack. Further, if your attack is at a distance, you can count through the vectors of the nearest enemy, if the damage is massive, then you can set the hitting radius and inflict damage on all enemies in this zone using the observer pattern

Is there a way to break out of Update() function

So, I'm trying to make my own movement script for Unity with a Rigidbody component attached to my character, and I'm using this code inside of the update function:
// Up above, in public scope, before Start and Update functions
public float speed = 1f;
public Rigidbody body;
void Update() {
if (Input.GetKey(KeyCode.LeftArrow())) { // Left arrow key
body.AddForce(transform.forward * speed * Time.deltaTime);
}
}
My problem is, since it's inside of the Update() function, it keeps going, it keeps turning, even if I don't have the key pressed.
Does anyone know how to fix this problem? I have tried taking away Time.deltaTime but Brackeys said you use it so that it's frame rate dependent, so if you have a higher frame rate it doesn't turn faster, and same with a low frame rate, you turn slower. Thanks in advance.
It keeps turning even after releasing the key? Yep that's what AddForce will do.
After you apply a force to an object it will continue to move based on that force uless it has drag or an opposing force is applied. Go into the rigidbody to set the drag or create a script that applies an opposing force once you stop pressing the button.
If you put a Debug.Log within the if statement you will see it is not called every frame but only when you have the button held down.
And last, I don't think that your keycode should have () after LeftArrow, does this not produce an error?
An object in motion stays in motion with the same speed and in the
same direction unless acted upon by an unbalanced force.
---- Isaac Newton
So if you want to stop the object, you can do:
Add an oppsite force
if (Input.GetKey(KeyCode.LeftArrow())) {
...
} else if (!body.IsSleeping()) {
body.AddForce(-body.velocity * factor);
}
Give a drag value
body.drag = dragValue;
You have two questions, one on the title and another one on the description.
For the title one:
The only way to stop/break Update() cycle is to disable the script, like this:
enabled = false;
For the description one:
You have to stop the force applied to the object (as the rest of the answers exemplify).
You can apply an opposite force, or just set velocity to 0.
rigidbody.velocity = Vector3.zero;

Unity AudioSource.Play has noise

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.