05-02-2021, 09:51 AM
(This post was last modified: 05-02-2021, 10:07 AM by josemendez.)
Tested your script, and there's one more thing missing that I didn't pick up earlier: you're not actually activating the constraints you add to the batch. After the batch.AddConstraint line, add:
Otherwise the batch will have zero active constraints and the pin constraint will be ignored. You can just copy-paste this from the sample in the manual, or the GrapplingHook.cs sample script.
Here's the fixed & tested script, should work correctly. let me know otherwise :
Code:
batch.activeConstraintCount = 1;
Otherwise the batch will have zero active constraints and the pin constraint will be ignored. You can just copy-paste this from the sample in the manual, or the GrapplingHook.cs sample script.
Here's the fixed & tested script, should work correctly. let me know otherwise :
Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Obi;
[RequireComponent(typeof(ObiCollider))]
public class RopeGrabber : MonoBehaviour
{
public bool canGrab = true;
ObiSolver solver;
ObiCollider obiCollider;
public ObiRope rope;
ObiSolver.ObiCollisionEventArgs collisionEvent;
ObiPinConstraintsBatch newBatch;
ObiConstraints<ObiPinConstraintsBatch> pinConstraints;
void Awake()
{
solver = FindObjectOfType<ObiSolver>();
obiCollider = GetComponent<ObiCollider>();
}
void Start()
{
// get a hold of the constraint type we want, in this case, pin constraints:
pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
}
private void OnEnable()
{
if (solver != null)
solver.OnCollision += Solver_OnCollision;
}
private void OnDisable()
{
if (solver != null)
solver.OnCollision -= Solver_OnCollision;
}
private void Solver_OnCollision(object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
{
collisionEvent = e;
}
public void Grab()
{
var world = ObiColliderWorld.GetInstance();
Debug.Log(pinConstraints);
if (solver != null && collisionEvent != null)
{
Debug.Log("Collision");
foreach (Oni.Contact contact in collisionEvent.contacts)
{
if (contact.distance < 0.01f)
{
var contactCollider = world.colliderHandles[contact.other].owner;
ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];
Debug.Log(pa + " hit " + contactCollider);
if (canGrab)
{
if (contactCollider == obiCollider)
{
Debug.Log("Hand Collision");
var batch = new ObiPinConstraintsBatch();
int solverIndex = rope.solverIndices[contact.particle];
Vector3 positionWS = solver.transform.TransformPoint(solver.positions[solverIndex]); // particle position from solver to world space
Vector3 positionCS = obiCollider.transform.InverseTransformPoint(positionWS); // particle position from world to collider space
batch.AddConstraint(rope.solverIndices[contact.particle], obiCollider, positionCS, Quaternion.identity, 0, 0, float.PositiveInfinity);
batch.activeConstraintCount = 1;
newBatch = batch;
pinConstraints.AddBatch(newBatch);
canGrab = false;
// this will cause the solver to rebuild pin constraints at the beginning of the next frame:
rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
}
}
}
}
}
}
public void Release()
{
if (!canGrab)
{
Debug.Log("Release");
pinConstraints.RemoveBatch(newBatch);
rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
canGrab = true;
}
}
}