Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pin constraint attached to hanging platform has strange behavior
#1


For context, I have a helicopter which will fly over a wood pallet and upon user input, 4 ropes will attach each corner of the pallet to the helicopter. These ropes are deactivated on start and the gameObjects are set active on user input.

I used the GrapplingHook.cs example as a reference. This video was the result.

Some observations:
  • Upon connecting the ropes, the helicopters rotation was immediately locked to (0, 0, 0)
  • The top end of the ropes seems to be constantly moving
  • The pallet has a very strange gravity behavior
This is the code I used for the pin constraints:
Code:
for (int i = 0; i < m_Ropes.Length; i++)
{
    Transform anchorPoint = Pallet.GetAnchorPoints()[i];

    // Create a new blueprint
    ObiRopeBlueprint blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
    blueprint.path.Clear();
    blueprint.path.AddControlPoint(m_Ropes[i].transform.InverseTransformPoint(m_HelicopterAnchorPoints[i].position), m_HelicopterAnchorPoints[i].up, -m_HelicopterAnchorPoints[i].up, m_HelicopterAnchorPoints[i].up, 0.1f, 0.1f, 1, 1, Color.white, "Start");
    blueprint.path.AddControlPoint(m_Ropes[i].transform.InverseTransformPoint(anchorPoint.position), anchorPoint.up, -anchorPoint.up, anchorPoint.up, 0.1f, 0.1f, 1, 1, Color.white, "End");
    blueprint.path.FlushEvents();

    await blueprint.Generate();

    // Pin both ends of the rope
    var pinConstraints = blueprint.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
    var batch = pinConstraints.batches[0];
    batch.AddConstraint(0, m_ObiCollider, Vector3.zero, Quaternion.identity);
    batch.AddConstraint(blueprint.activeParticleCount - 1, Pallet.GetObiCollider(), anchorPoint.localPosition, Quaternion.identity);
    batch.activeConstraintCount = 2;

    m_Ropes[i].ropeBlueprint = blueprint;

    // Enable the ropes
    m_Ropes[i].gameObject.SetActive(true);
}


I also tried another approach using the ObiParticleAttachment scripts, I tried combinations of static and dynamic constraints but this was always the result:

[Image: C9tjnm8.png]
Reply
#2
Hi,

Make sure the ends of the rope aren't colliding with the platform. This will result in a situation in which the pin constraints try to push the rope inside the platform, while the collision constraints try to push it outside, causing unphysical behavior.


This is described in the manual, along with the solution. See the last part of:
http://obi.virtualmethodstudio.com/tutor...aints.html
Reply
#3
Setting phases and using the inverse transformed position from the collider solved the issue.


Code:
batch.AddConstraint(0, m_ObiCollider, m_ObiCollider.transform.InverseTransformPoint(m_HelicopterAnchorPoints[i].position), Quaternion.identity);
batch.AddConstraint(blueprint.activeParticleCount - 1, Pallet.GetObiCollider(), Pallet.GetObiCollider().transform.InverseTransformPoint(anchorPoint.position), Quaternion.identity);


HOWEVER, it still freezes the rotation of both the platform and the helicopter. Why is this?

Nevermind. Solved using the regular ObiParticleAttachment components.

Code:
// Get components
ObiParticleAttachment mainRopeAttachment = m_Ropes[i].gameObject.AddComponent<ObiParticleAttachment>();ObiParticleAttachment palletAttachment = m_Ropes[i].gameObject.AddComponent<ObiParticleAttachment>();

// Find the particle groups
var groups = m_Ropes[i].blueprint.groups;

// Attach sub rope to main rope
mainRopeAttachment.target = m_ObiCollider.transform;
mainRopeAttachment.particleGroup = groups[0];
mainRopeAttachment.attachmentType = ObiParticleAttachment.AttachmentType.Static;

// Attach the rope to the pallet
palletAttachment.target = m_Pallet;
palletAttachment.particleGroup = groups[groups.Count - 1];
palletAttachment.attachmentType = ObiParticleAttachment.AttachmentType.Dynamic;
Reply
#4
(14-07-2020, 12:10 AM)mr-matt Wrote: Setting phases and using the inverse transformed position from the collider solved the issue.

HOWEVER, it still freezes the rotation of both the platform and the helicopter. Why is this?

By default, pin constraints constrain both position and orientation. You must set the orientation compliance to a higher than zero value if you want free rotation. Each batch has an "stiffnesses" array that contains 2 * constraintCount entries: the first entry is the positional compliance, and the second one the rotational compliance. So:

Code:
batch.stiffnesses[constraintIndex * 2 + 1] = 10000; // really high compliance value frees up rotation.
Reply