Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Teleport attachment to the transform target
#1
Hi,

I'm attachingĀ control point in runtime and I want to move the position of the control point to the position of the transform to which it is attached.
What is the simple way to move the control point from script ?

(I know it'll add a lot of kinetic energy to the rope resulting in unwanted motion)
Reply
#2
(02-03-2022, 01:40 PM)lufydad Wrote: Hi,

I'm attachingĀ control point in runtime and I want to move the position of the control point to the position of the transform to which it is attached.
What is the simple way to move the control point from script ?

(I know it'll add a lot of kinetic energy to the rope resulting in unwanted motion)

Hi!

Not sure I understand your question. You mention "control point" instead of particles (control points are a concept that only exists in blueprints, as they are simply a construct to help define a path. At runtime all you deal with are particles, control points don't exist).

So I'm going to assume you want to do this when generating a rope blueprint programmatically:

When you call blueprint.path.AddControlPoint(); just pass in the position you want to place the control point at. Note that AddControlPoint() expects data in the rope's local space, so if you have a position expressed in the attached object's local space you will have to convert it:

object's local space-->world space-->rope's local space.

You can do this with Unity's TransformPoint/InverseTransformPoint functions.

let me know if I can be of further help.
Reply
#3
(02-03-2022, 01:51 PM)josemendez Wrote: Hi!

Not sure I understand your question. You mention "control point" instead of particles (control points are a concept that only exists in blueprints, as they are simply a construct to help define a path. At runtime all you deal with are particles, control points don't exist).

So I'm going to assume you want to do this when generating a rope blueprint programmatically:

When you call blueprint.path.AddControlPoint(); just pass in the position you want to place the control point at. Note that AddControlPoint() expects data in the rope's local space, so if you have a position expressed in the attached object's local space you will have to convert it:

object's local space-->world space-->rope's local space.

You can do this with Unity's TransformPoint/InverseTransformPoint functions.

let me know if I can be of further help.

Indeed I am confused between the control point and the particles... Sorry for that ^^
With your remark, I was indeed talking about particles and not about control point. Therefore I rewrite my question : my blueprint is already made and I want to edit the particles positions in runtime and make them teleport to attached transform. Is it more clear ?
Reply
#4
(02-03-2022, 02:04 PM)lufydad Wrote: Indeed I am confused between the control point and the particles... Sorry for that ^^
With your remark, I was indeed talking about particles and not about control point. Therefore I rewrite my question : my blueprint is already made and I want to edit the particles positions in runtime and make them teleport to attached transform. Is it more clear ?

Oh ok! Clearer now Sonrisa

Similar to how you'd move a control point, you have to convert from the object's local space to the solver's local space (again, using Unity's transform functions).

Once you have the position you want the particle to be attached to (expressed in solver space), you just set it:

Code:
var solverIndex = rope.solverIndices[attachment.ParticleGroup.particleIndices[0]];
rope.solver.positions[solverIndex] = position;

Now if the attachment component already exists and the simulation is running when you do this, you need to re-bind the attachment so that it picks up the new position. This is done automatically when you change either the particle group or the target, but you might want to call it manually in this case to force it. Since it's a private method, open ObiParticleAttachment.cs and make its Bind() method public.

Then you can call attachment.Bind(); and you're done. This is what tells the attachment "see where the particle is in relation to the object right now? I want it to stay right there".
Reply
#5
(02-03-2022, 02:14 PM)josemendez Wrote: Now if the attachment component already exists and the simulation is running when you do this, you need to re-bind the attachment so that it picks up the new position. This is done automatically when you change either the particle group or the target, but you might want to call it manually in this case to force it. Since it's a private method, open ObiParticleAttachment.cs and make its Bind() method public.

Then you can call attachment.Bind(); and you're done. This is what tells the attachment "see where the particle is in relation to the object right now? I want it to stay right there".

Thank you a lot it seems to work, with the code you give (it's just "particleGroup" and not "ParticleGroup", at least for my version of ObiRope). But, I don't understand what does the function Bind() add to your code ?
Reply
#6
(02-03-2022, 05:02 PM)lufydad Wrote: Thank you a lot it seems to work, with the code you give (it's just "particleGroup" and not "ParticleGroup", at least for my version of ObiRope). But, I don't understand what does the function Bind() add to your code ?

An attachments makes sure the position of a particle stays fixed relative to the attached object. Without them, particle and object would move independently.

To do this, the attachment stores a "reference pose" so to speak, which is nothing more than the position the particle is in when you call Bind(). Each frame, the attachment makes sure to keep the relative position the particle and the object were in at the time of calling Bind(). For instance if you call Bind() when the particle is 3 units to the left of the object, the attachment will make sure that from that point on the particle is always 3 units left of the object as the simulation progresses.

If you didn't call Bind() after setting the position of the particle, the attachment would immediately revert the particle back to the position where it was last time Bind() was called.

This is all very similar to how character mesh skinning works in all programs: you create a mesh, create a skeleton for it, then bind the mesh to the skeleton. If at some point you want to change the topology of the mesh, you need to re-bind it to the skeleton to generate a new "bind pose".
Reply
#7
(02-03-2022, 05:26 PM)josemendez Wrote: An attachments makes sure the position of a particle stays fixed relative to the attached object. Without them, particle and object would move independently.

To do this, the attachment stores a "reference pose" so to speak, which is nothing more than the position the particle is in when you call Bind(). Each frame, the attachment makes sure to keep the relative position the particle and the object were in at the time of calling Bind(). For instance if you call Bind() when the particle is 3 units to the left of the object, the attachment will make sure that from that point on the particle is always 3 units left of the object as the simulation progresses.

If you didn't call Bind() after setting the position of the particle, the attachment would immediately revert the particle back to the position where it was last time Bind() was called.

This is all very similar to how character mesh skinning works in all programs: you create a mesh, create a skeleton for it, then bind the mesh to the skeleton. If at some point you want to change the topology of the mesh, you need to re-bind it to the skeleton to generate a new "bind pose".

Ok it makes sense, but then I don't understand why even without using the Bind() function as you suggest, I have an attachment which stay hang (see. https://imgur.com/a/CmIx43l).
Reply
#8
(03-03-2022, 09:41 AM)lufydad Wrote: Ok it makes sense, but then I don't understand why even without using the Bind() function as you suggest, I have an attachment which stay hang (see. https://imgur.com/a/CmIx43l).

Bind() is automatically called when:
A) you create the attachment
B) you set the attachment's target
C) you set the attachment's particle group

If any of these are happening after you set the new particle position, then there's no need to manually call Bind(). You should only manually call it if you change the particle position while the attachment currently exists and is being simulated.
Reply
#9
Sonrisa 
(03-03-2022, 09:45 AM)josemendez Wrote: Bind() is automatically called when:
A) you create the attachment
B) you set the attachment's target
C) you set the attachment's particle group

If any of these are happening after you set the new particle position, then there's no need to manually call Bind(). You should only manually call it if you change the particle position while the attachment currently exists and is being simulated.

Alright I understand, thank you Gran sonrisa
Reply