Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Suggestion / Idea  [Workaround] Setting target at runtime for ObiParticleAttachment
#1
Bombilla 
Made a thread awhile back regarding this issue here.

I havent fully tested this workaround but since my current project has networking and players have "body parts" that are ropes it requires me to spawn them on player creation for those ropes to sync across the network. Once instantiated then I have to assign the "target" variable from the ropes ObiParticleAttachment component and found out if you assign the ropes game object position to where you want it then set the target variable attachment without it being under a solver (as a child) and then reparent it to the solver (so it can simulate) it keeps its position you assigned originally without it doing what you can see in the old thread.


Code:
private void SpawnBodyPart(GameObject bodyGO)
   {
       // Instantiate locally then on server for all clients
       var goInstance = Instantiate(bodyGO, transform.position, bodyGO.transform.rotation);
       NetworkServer.Spawn(goInstance);

       // Assign target attachment to player
       var attachment = goInstance.GetComponent<ObiParticleAttachment>();
       attachment.target = transform;
       
       // Reparent to main solver
       var solver = GameObject.FindGameObjectWithTag("ObiSolver");
       goInstance.transform.SetParent(solver.transform);
   }

Thats on creation, there some other functions I will be testing and one of the main ones is having player pick up items which is very easy to do with ObiRope. Once the rope end reaches the item ill try this workaround to see if I can attach the ropes (arm) end to the item object. I really like the new pin/attachment system in Obi5 for the dynamic 2 way physics and will probably have to attach quite a bit at runtime.

I just wanted to bring this up because I think attaching at runtime would be a nice feature.

Ill update this if attaching with the other functions work.
Reply
#2
(11-03-2020, 10:30 PM)VirtualCucumber Wrote: Made a thread awhile back regarding this issue here.

I havent fully tested this workaround but since my current project has networking and players have "body parts" that are ropes it requires me to spawn them on player creation for those ropes to sync across the network. Once instantiated then I have to assign the "target" variable from the ropes ObiParticleAttachment component and found out if you assign the ropes game object position to where you want it then set the target variable attachment without it being under a solver (as a child) and then reparent it to the solver (so it can simulate) it keeps its position you assigned originally without it doing what you can see in the old thread.


Code:
private void SpawnBodyPart(GameObject bodyGO)
   {
       // Instantiate locally then on server for all clients
       var goInstance = Instantiate(bodyGO, transform.position, bodyGO.transform.rotation);
       NetworkServer.Spawn(goInstance);

       // Assign target attachment to player
       var attachment = goInstance.GetComponent<ObiParticleAttachment>();
       attachment.target = transform;
       
       // Reparent to main solver
       var solver = GameObject.FindGameObjectWithTag("ObiSolver");
       goInstance.transform.SetParent(solver.transform);
   }

Thats on creation, there some other functions I will be testing and one of the main ones is having player pick up items which is very easy to do with ObiRope. Once the rope end reaches the item ill try this workaround to see if I can attach the ropes (arm) end to the item object. I really like the new pin/attachment system in Obi5 for the dynamic 2 way physics and will probably have to attach quite a bit at runtime.

I just wanted to bring this up because I think attaching at runtime would be a nice feature.

Ill update this if attaching with the other functions work.


After carefully testing this, I spotted a bug in ObiParticleAttachment.cs.

Swap lines 47 and 48, so that the target property looks like this (that is, so that binding takes place after setting the target).

Code:
public Transform target
       {
           get { return m_Target; }
           set
           {
               if (value != m_Target)
               {
                   Disable(m_AttachmentType);
                   m_Target = value;
                   Bind();
                   UpdateEnabledState();
               }
           }
       }

Now setting the target should be enough for attachments to work properly without having to manually call Bind() afterwards, or reparenting to a solver.
Reply
#3
Hi Guys,

I'm working on ObiParticleAttachment at runtime too. After made some tries I spotted something weird.
I procedurally generate a rope and its blueprint, then I add an ObiParticleAttachement on my rope and assign the target and the particle group by script.

In the ObiParticleAttachment component generated, everything seems good but my rope still not attached to my target.
So I looked for the reason, the issue seems be when I set my particleGroup to the attachment by      
  
Code:
attachment.particleGroup = rope.blueprint.groups[0];

In the particlegroup set accessor inside ObiParticleAttachment.cs the new value is assigned after the Bind method, so the script doesn't go through. 
I've fixed that simply by set the value before the bind()

Code:
           set
           {
               if (value != m_ParticleGroup)
               {
                   Disable(m_AttachmentType);
                   m_ParticleGroup = value;
                   Bind();
                   UpdateEnabledState();
               }
           }

However I didn't try if this correction could cause some issues elsewhere. For my case, it's working now !
Reply
#4
(27-03-2020, 06:41 PM)Chess Wrote: Hi Guys,

I'm working on ObiParticleAttachment at runtime too. After made some tries I spotted something weird.
I procedurally generate a rope and its blueprint, then I add an ObiParticleAttachement on my rope and assign the target and the particle group by script.

In the ObiParticleAttachment component generated, everything seems good but my rope still not attached to my target.
So I looked for the reason, the issue seems be when I set my particleGroup to the attachment by      
  
Code:
attachment.particleGroup = rope.blueprint.groups[0];

In the particlegroup set accessor inside ObiParticleAttachment.cs the new value is assigned after the Bind method, so the script doesn't go through. 
I've fixed that simply by set the value before the bind()

Code:
           set
           {
               if (value != m_ParticleGroup)
               {
                   Disable(m_AttachmentType);
                   m_ParticleGroup = value;
                   Bind();
                   UpdateEnabledState();
               }
           }

However I didn't try if this correction could cause some issues elsewhere. For my case, it's working now !

Your code is 100% correct. Note that this has been fixed in 5.2 (and the code is identical to yours).
Reply