Unity particle system only plays if i hit SIMULATE button - unity3d

I have a prefab with a particle system attached. In the code I play the particle by using this code
ps.enableEmission = true;
When i run the game, and that code executes, the particle emitter does not emit anything in the "game" window unless i press simulate button in the "scene" window.
Anybody knows why?

For the emission property to work the particle system has to actually be playing. To do this you can either enable Play On Awake in the ParticleSystem component or you use the Play method on an instance of the ParticleSystem component.
As a side note, if you are using 5.3+ the enableEmission property is now obsolete and you may want to consider using the emission property. One thing to keep in mind when using this property is you have to assign it to a variable before attempting to modify it:
public ParticleSystem _ps;
...
private void Update()
{
ParticleSystem.EmissionModule module = _ps.emission;
module.enabled = true;
}
UPDATE #1
In response to your tractor beam example in the comments I would probably suggest using SetActive on the game object that has the ParticleSystem component. By using SetActive it will prevent extra particles being emitted and will destroy any that are active, i.e. those currently in the scene.
If you use the Emission property, then it will prevent the emission of extra particles, but it will not destroy any that have already been emitted.
One other approach would be to use Play and Stop methods but these, as with the emission property, will not destroy any active particles. If you use these methods, then some things to watch out for are:
If the Prewarm option is not enabled, then Play does not start
emitting particles (not sure why this happens)
The isPlaying property will remain true as along as there are
active particles in the scene. Once these die, then it will
be set to false
The Stop method will not destroy particles active in the scene
If the ParticleSystem has stopped and you call Play while there are particles active
in the scene, then all active particles are destroyed and the
ParticleSystem starts emitting a new set of particles

Check out to see if particle GameObject is active when you call ps.enableEmission = true; on it. To show or hide particles i normally use gameObject.setActive() not ps.enableEmission.

My particle was not simulating and after I changed the culling Mode to Automatic everything worked. The default is pause and catch-up.

Related

OnCollisionExit not called when parenting object

Basically, I am trying to implement very simple event system for player to interact with different objects.
Right now, I have three states:
OnCollisionEnter, OnCollisionStay and OnCollisionExit and when my player is standing on top of the pressure plate It calls OnCollisionStay and everything is working properly. When the player gets off the pressure plate OnCollisionExit is called.
The problem comes when an Item is picked up and placed on the pressure plate.
I am using simple parenting approach - just parent item on my players hand on the desired position using this piece of code:
ObjectIwantToPickUp.pickupRigidbody.isKinematic = true; //makes the rigidbody not be acted upon by forces
ObjectIwantToPickUp.transform.SetParent(myHands.transform); // sets the position of the object to your hand position
ObjectIwantToPickUp.transform.localPosition = ObjectIwantToPickUp.pickPosition; //makes the object become a child of the parent so that it moves with the hands
ObjectIwantToPickUp.transform.localEulerAngles = ObjectIwantToPickUp.rotatePosition;
After that, if I pick up the item again, the item is parented, but the pressure plate stays active, since OnCollisionExit does not being called.
I tried replacing OnCollision methods with OnTrigger but the issue still persists.
Am I missing something?
OnCollisionEnter, OnCollisionExit and OnCollisionStay will only call on components that share the same GameObject as the collider and a non-kinematic Rigidbody.
Make sure the instance of your script is on the right GameObject.
You could try attaching an EventTrigger and dynamically add event hooks after your reparenting (not recommended).

Unity: I can not access to GameObject.SetActive() if there is an Animation that modifies it?

I am new in Unity and I don't know if I am missing something. I have found this problem repeatedly.
I have a GameObject that I deactivate/activate by code.
The same GameObject is deactivate/activate by animation(s).
Well, this doesn't work.
My commands in code are ignored. Even if the animation is not active right now.
It is easy to see when I am having this issue because while game is in Play I can not modify the active state of the GameObject from the Inspector. Only if I pause the game I can modify the active state in the Inspector but after un-pause the element go backs to the previous state.
I understand that the animation can override whatever is said in code. But I asume that this should happen only when the animation is active.
How can I play with the SetActive() of one GameObject in the animations but also in the code?
In general: You shouldn't mix changes via the animator with runtime changes via script.
It is very easy to lose the overview and you will not anymore know which changes happened because of the animator and which because of a script.
If this is really necessary you should rather use parenting and do e.g.
SomeParent
|-- SomeChild
and either control the SomeParent via the script and the SomeChild via Animator or the other way round.
As soon as there is an Animator where any animation state holds only any keyframe on a certain property, the Animator "locks" that property against any changes via script since the Animator is executed almost latest within one frame.
Try doing your change in LateUpdate or via Coroutine via yield return new WaitForEndOfFrame(); which would be executed after the Animator.
Or if possible you could disable the Animator for the time where you want to "manually" overwrite the property via script like
_animator.enabled = false;
theObject.SetActive(false);

Unity | How to play animations that are stored in a variable (without having them in the animator)

I'm creating a 2D fighting game, where the player can choose from a number of fighters. the fighters have different attacks with different animations.
the data (damage, hitbox, cast time, animation, etc.) for every attack is stored in a Scriptable Object that is then triggered by the player script. this worked out fine so far, but I can't find out how to play an animation from code without needing it to be in the animator.
I've tried several solutions that I found here but they seem to end up having to fall back to putting the animation in the animator.
but I can't find out how to play an animation from code without needing it to be in the animator.
You will need the Animator-Component to run an animation.
But you can assign the animation you want to play at runtime. For this you need the RuntimeAnimationController to hold the AnimatorController-object and assign it to your Animator (in code).
You do not necessarily need the Animator component as stated in this answer.
There is also the Animation component. It is marked as legacy but is still quite powerful especially when you do not need to configure an entire state machine but want to rather simply playback single AnimationClip. Might be the reason why this still makes it into newer Unity versions:
public AnimationClip clip;
private void Awake()
{
var animation = GetComponent<Animation>();
animation.clip = clip;
animation.Play();
}
Also see Animation.Play

best way to change 2d sprite to animation

I have a GameObject for Chest(with Collider and SpriteRenderer)
By default it is a static sprite on the screen
now i want to add animation to this game object when open is triggered (by script), I do not have Idle animation, idle animation must be the sprite itself
what is the best to add an animation(no looping, 1 time and then show the animated sprite) to sprite?
I can do it by adding the sprite array and using an coroutine to set the sprite periodically with 0.2f delay (it work fine but not sure if it is the only way which using coroutine with delays to simulate an animation by myself...).
I can do it by create 1 more GameObject with the Animator, when the box open event is triggered, I set the original GameObject to inactive and instantiate the GameObject with the animation (but it requires to create 2 prefabs for two different gameObject).
But none of them look proper way to do this. What is the best solution for this?

Particle at Input.mousePosition Point

I am trying to understand this link which, I believe, is supposed to create a particle where you left-click your mouse. Am I correct?
I have attached the script to an empty game object, so it runs when I run my Unity project. I added a new Particle System game object and dragged it onto the public field of the inspector. Is this the right way of doing it, or should I assign something else to the public variable?
The particle system starts firing up as soon as I run the project, so how do I stop that and then make it begin when and where I have clicked my mouse curser?
public GameObject particle;
if ( Input.GetButtonDown("Fire1") )
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if ( Physics.Raycast(ray) )
Instantiate(particle, transform.position, transform.rotation);
Debug.Log(Input.mousePosition.x);
}
You should either turn off looping in the particle system or Stop() or Pause() it on Awake() in your script and Play() when clicking the fire button.
Check this page: http://docs.unity3d.com/ScriptReference/ParticleSystem.html
The sample that you have provided doesn't take a particle system, but some 'projectile' prefab, it basically spawns the prefab instance when you click mouse button. It is just an example of very very basic shooting mechanic. I believe that naming on that script could have been better. (I believe that this sample was taken from one of Unity's Merry Fragmas videos, they used some kind of particle system in a similar manner, you'll have to configure the particle system to burst a bunch of particles and not loop after that if you want to use it this way)