Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Adding pin constraints to a rope at runtime
#2
(17-03-2018, 01:12 PM)Chilly5 Wrote: Hello,

I am working on a game in Unity where I want to add pin constraints all the way down the Obi Rope at runtime. Every unit of the rope should be covered with a constraint. The idea is that I'm attaching selectable colliders that can be "grabbed" by the player and then swung on.

I copied almost exactly the code from the "adding/removing constraints" page on the website here: http://obi.virtualmethodstudio.com/tutor...aints.html
Unity didn't like a few of the casts so I modified it slightly, but it's more or less the same.

Here's my current script:


Code:
[SerializeField]
private GameObject _networkedGrabPoint;

private ObiRope _obiRope;

[SerializeField]
private List<GameObject> _chainLinks = new List<GameObject>();

[SerializeField]
private List<GameObject> _ropeLinks = new List<GameObject>();

void Start()
{
_obiRope = GetComponentInChildren<ObiRope>();
_chainLinks = _obiRope.chainLinks;

for (int i = 0; i < _obiRope.positions.Length; i++)
{
GameObject _ropeLink = GameObject.Instantiate(_networkedGrabPoint, transform);
_ropeLink.transform.localPosition = _obiRope.positions[i];
_ropeLinks.Add(_ropeLink);
}
}

void Update () {
if (Input.GetKeyDown(KeyCode.R))
{
ObiPinConstraints constraints = _obiRope.GetComponent<ObiPinConstraints>();
ObiPinConstraintBatch batch = constraints.GetBatches() as ObiPinConstraintBatch;

// remove the constraints from the solver, because we cannot modify the constraints list while the solver is using it.
constraints.RemoveFromSolver(null);

ObiCollider ropeLink = _ropeLinks[0].GetComponent<ObiCollider>();
batch.AddConstraint(0, ropeLink as ObiColliderBase, Vector3.zero, 1.0f);

// add all constraints back:
constraints.AddToSolver(null);

}
}

Almost word for word copied from what was given on the website. For some reason it didn't like the line "(ObiPinConstraintBatch)constraints.Getbatches()[0]" so I modified it to "constraints.GetBatches() as ObiPinConstraintBatch".

Right now, it's giving me a "null reference exception: object reference not set to an instance of an object" error on this line: batch.AddConstraint(0, ropeLink as ObiColliderBase, Vector3.zero, 1.0f);

I don't understand why. I checked the ObiColliderBase and it seems to definitely exist so I don't know why it would give me a null reference error there.

Any help would be very appreciated!

Thank you.

Hi,

This line will always cause "batch" to be null:
Code:
ObiPinConstraintBatch batch = constraints.GetBatches() as ObiPinConstraintBatch;

This is because you're trying to cast a IEnumerable (sort of a fancy array, which is what GetBatches() returns) to a completely unrelated type. The "as" operator in C# tries to perform a cast and returns null if the types are not convertible instead of raising an exception immediately, which is what classic casts do. See:

https://docs.microsoft.com/en-us/dotnet/...eywords/as

Afterwards you call batch.AddConstraint which of course raises a NullReferenceException because batch is null.

Solution:
use this instead:
Code:
ObiPinConstraintBatch batch = constraints.GetFirstBatch() as ObiPinConstraintBatch;

This will grab the first constraint batch (which is an object of type ObiConstraintBatch) and cast it to ObiPinConstraintBatch successfully.
Reply


Messages In This Thread
RE: Adding pin constraints to a rope at runtime - by josemendez - 17-03-2018, 02:39 PM