Particle Simulate Local And World Space question
Guys
I need your help. The following script kills the particle when it get to the target. When I set my particle System to Emulate Local Space it can't calculate the particle position in World Space but my energy beam behaves like it should ( Direction wise but goes past the target). If I set the particles to World Space. It dies at the target cause the distance gets calculated in word space which is correct. What I want to do is simulate in Local Space ( Energy Beam looks behaves nice) But use the particles Word position to calculate the distance. Please see Video to clarify what I am trying to say.
https://www.youtube.com/watch?v=--QvAGjO8bw
var laser : ParticleSystem ;
var particles : ParticleSystem.Particle[];
var target : Transform;
var endpoint : Vector3;
function Update(){
}
function LateUpdate() {
InitializeIfNeeded();
var lenght = laser.GetParticles(particles);
transform.LookAt(target);
endpoint = target.position;
for (var i = 0; i < lenght; i++) {
if(Vector3.Distance(target.position, particles[i].position) < 2f) {
particles[i].lifetime = -0.1f; //Kill the particle
}
}
Answer by NoseKills · Sep 21, 2015 at 08:53 PM
Actually it even says it in the API docs for Particle.position. You can use Transform.InverseTransformPoint() to get the world position in local space :)
var targetLocal = transform.InverseTransformPoint(target.position);
...
if (Vector3.Distance(targetLocal, particles[i].position) < 2f)
Also, it's a small thing but whenever you only compare distances ( Vector3.Distance(a, b) < x
) and you don't really need to know the actual distance in units, it's usually better to use properties / functions like Vector3.sqrMagnitude that don't do the last step of the Pythagoras formula to calculate the length of the distance vector (square root) which is a bit performance heavy.
// particle emitter is at(0,0) in this object, so this is also the distance vector to target
var targetLocal = transform.InverseTransformPoint(target.position);
for (var i = 0; i < lenght; i++) {
// distance vector between particle and target
var distToTarget : Vector3 = particles[i].position - targetLocal;
// compare the square of distance to square of your limit (2f)
if (distToTarget.sqrMagnitude < 4f) ...
Or even better, since you need to compare if a particle has gone past a certain point (if it's really fast, it might slip through your current check where it needs to be close to target) you could use dot product. It's a fast calculation that checks whether 2 vectors point in similar direction ( dot > 0 ) or opposite direction ( dot < 0 ).
// particle emitter is at(0,0) in this object, so this is also the distance vector to target
var targetLocal = transform.InverseTransformPoint(target.position);
for (var i = 0; i < lenght; i++) {
var distToTarget : Vector3 = particles[i].position - targetLocal;
// if vector from particle source to target points in the same direction as
// vector from target to particle, it means the particle has passed the target
if (Vector3.Dot(distToTarget, targetLocal) > 0) ...
Thanks. On my way to post here. I got it working using Simulate Local World Space. I did a very similar thing.
var localPos : Vector3 = transform.InverseTransformDirection(target.position - transform.position);
and then Compared the distance. This gave me a perfect result.
I tried using your but that gave me dash like effect for some reason.
Then I combined my script above with
var distToTarget : Vector3 = particles[i].position - localPos;
and
if (Vector3.Dot(distToTarget, localPos) > 0)
making the calculation faster like you Said.
Thank you!
Your answer
Follow this Question
Related Questions
Creating Meteor with Physics (where the Particle System Works) 0 Answers
Script not playing Particle Effect 0 Answers
Play sound on particle death C# 0 Answers
How can I get the game object that a particle trigger detects? 0 Answers
Particle System trigger script not working,Particle system trigger script not working 0 Answers