17-03-2018, 02:39 PM
(This post was last modified: 17-03-2018, 02:41 PM by josemendez.)
(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.