Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to make the Start/End Prefab able to be Raycasted?
#16
Is this pin constraint doing something different than what you are doing with the particle handles? If so..

You're going to have to keep track of the index yourself. When adding a pin constraint you'll need to set the pins index to the current pin constraints count. When removing a pin index, all the higher indices will need to be decremented. You can see in this snippet the dictionary keeps a pair of an ObiCollider and its pinned index. If you are pinning multiple indices to the same collider, this method won't work but you can get the jist of what needs to happen.


Code:
public Dictionary<ObiCollider, int> pinnedColliders = new Dictionary<ObiCollider, int>();

       public ObiRope actor;

       public void PinObiColliderToParticle(ObiCollider obiCollider, int particleIndex, Vector3? pinOffset = null, int? pinStiffness = null)
       {
           if (pinnedColliders.ContainsKey(obiCollider))
               return;

           ObiPinConstraintBatch batch = actor.PinConstraints.GetBatches()[0] as ObiPinConstraintBatch;
           actor.PinConstraints.RemoveFromSolver(null);

           // Set the pin as the next availiable index in the batch
           pinnedColliders.Add(obiCollider, batch.ConstraintCount);

           batch.AddConstraint(particleIndex, obiCollider, pinOffset == null ? Vector3.zero : pinOffset.Value, pinStiffness == null ? 1 : pinStiffness.Value);

           actor.PinConstraints.AddToSolver(null);
           actor.PinConstraints.PushDataToSolver();
       }

       public void UnpinObiCollider(ObiCollider obiCollider)
       {
           if (!pinnedColliders.ContainsKey(obiCollider))
               return;

           ObiPinConstraintBatch batch = actor.PinConstraints.GetBatches()[0] as ObiPinConstraintBatch;
           actor.PinConstraints.RemoveFromSolver(null);

           int pinIndex = pinnedColliders[obiCollider];

           batch.RemoveConstraint(pinIndex);

           pinnedColliders.Remove(obiCollider);

           List<ObiCollider> keys = new List<ObiCollider>(pinnedColliders.Keys);

           // Decrement the pinned indices that are greater than the removed index
           foreach (ObiCollider collider in keys)
           {
               int checkIndex = pinnedColliders[collider];

               if (checkIndex >= 0 && checkIndex > pinIndex)
               {
                   pinnedColliders[collider]--;
               }
           }

           actor.PinConstraints.AddToSolver(null);
           actor.PinConstraints.PushDataToSolver();
       }

You may use the snippet you're using at the start of a scene to assign what indices each object are. This is useful for when you pin things in the editor. Then from there you would need to manage them manually. Once a pin index is removed all other indices must be updated like i mentioned, so you need some kind of structure to keep track.

To see if the rope is stretching, you will also need to keep track of whats happening. Once your character has touched to rope, get the ropes length to get the initial stretch. Then as the character is interacting with the rope, keep checking against the initial stretch value to see if it has increased. If it has increased, then have the rope cursor extend the rope. I have a few snippets on seeing if the rope is stretching. There are other ways which might be more useful if you're checking the stretch to start the cursor. You can get the force resistance between the particles and if it exceeds your defined force threshold you can tell the cursor to extend the rope. I don't know what you're dealing with exactly so I'll give you a simple one. All this does is iterate though the particles and gets the distance between each one and adds them up.


Code:
public float GetRopeLength(ObiRope rope)
       {
           float ropeLength = 0;
           Vector3 a, b;

           for (int i = 0; i < rope.particleIndices.Length - 1; i++)
           {
               int particleIndex = rope.particleIndices[i];

               a = rope.GetParticlePosition(particleIndex);
               b = rope.GetParticlePosition(particleIndex + 1);

               ropeLength += Vector3.Distance(a, b);
           }

           return ropeLength;
       }
Reply


Messages In This Thread
RE: How to make the Start/End Prefab able to be Raycasted? - by niZmo - 04-11-2017, 06:30 PM