So I came across the same issue regarding my code where I need to generate ropes with balls on the end of them from a height and length set up before rendering the ropes. the ropes generate correctly but I have been unable to pin the prefab ball to the ropes as they generate previously I had the issue before with IEnumerators and [] indexing, but your tip on using GetFirstBatch helped solve that, yet now it is giving me a NullReferenceException.
I know the reference to the instantiated object is correct because I used it to set the material of the ball.
Here I believe the offending code is.
And the other code that feeds into the generation code.
I know the reference to the instantiated object is correct because I used it to set the material of the ball.
Here I believe the offending code is.
Code:
using UnityEngine;
using System.Collections;
using Obi;
namespace Obi
{
[RequireComponent(typeof(ObiRope))]
[RequireComponent(typeof(ObiCatmullRomCurve))]
[RequireComponent(typeof(ObiPinConstraints))]
public class RopeMaker : MonoBehaviour {
public ObiSolver solver;
public ObiRopeSection section;
public Material material;
public Vector3 start;
public Vector3 end;
public int ropeNum;
private ObiRope rope;
private ObiCatmullRomCurve path;
public IEnumerator MakeRope () {
// Get all needed components and interconnect them:
rope = GetComponent<ObiRope>();
path = GetComponent<ObiCatmullRomCurve>();
rope.Solver = solver;
rope.ropePath = path;
rope.section = section;
GetComponent<MeshRenderer>().material = material;
// Calculate rope start/end and direction in local space:
Vector3 localStart = transform.InverseTransformPoint(start);
Vector3 localEnd = transform.InverseTransformPoint(end);
Vector3 direction = (localEnd-localStart).normalized;
// Generate rope path:
path.controlPoints.Clear();
path.controlPoints.Add(localStart-direction);
path.controlPoints.Add(localStart);
path.controlPoints.Add(localEnd);
path.controlPoints.Add(localEnd+direction);
// Setup the simulation:
yield return StartCoroutine(rope.GeneratePhysicRepresentationForMesh());
rope.AddToSolver(null);
// Fix first and last particle in place:
rope.invMasses[0] = 0;
Oni.SetParticleInverseMasses(solver.OniSolver,new float[]{0},1,rope.particleIndices[0]);
//Set Phase:
for (int i = 0; i < rope.TotalParticles; ++i) {
rope.phases [i] = Oni.MakePhase (ropeNum, 0);
rope.PushDataToSolver (ParticleData.PHASES);
yield return new WaitForFixedUpdate ();
}
}
public void AddPendulum(ObiCollider pendulum, Vector3 offSet){
ObiPinConstraints pins = rope.GetComponent<ObiPinConstraints>();
ObiPinConstraintBatch batch = pins.GetFirstBatch()[0] as ObiPinConstraintBatch;
pins.RemoveFromSolver (null);
batch.AddConstraint (rope.UsedParticles - 1, pendulum, offSet, 0);
pins.AddToSolver (null);
pins.PushDataToSolver ();
}
}
}
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;
public class RopeSetup : MonoBehaviour {
public Material[] materials = new Material[8];
[Range(1,8)]
public int numBalls = 1;
[Range(0.5f,2.5f)]
public float height = 1f;
[Range(2f,10f)]
public float length = 3f;
public ObiSolver obiSolver;
public ObiCollider ball;
public GameObject rope;
[Range(0.01f,0.05f)]
public float width =0.03f;
[Range(0.001f,1f)]
public float resolution =0.5f;
public bool collision = true;
private Vector3 start;
private Vector3 end;
private int ropeNum =1;
private GameObject ballmesh;
private GameObject newRope;
// Use this for initialization
void update () {
}
public void MakeRopes(){
if (ropeNum <= materials.Length){
start = new Vector3 (0,length+height,0);
end = new Vector3 (0,height,0);
newRope = Instantiate (rope, start, transform.rotation);
RopeMaker setup = (RopeMaker) newRope.GetComponent("RopeMaker");
setup.start = start;
setup.end = end;
setup.material = materials[ropeNum-1];
setup.solver= obiSolver;
setup.ropeNum = ropeNum;
StartCoroutine (GenRopes ());
ObiCollider ballcopy = Instantiate (ball, end, transform.rotation);
MeshRenderer mesh = ballcopy.GetComponentInChildren<MeshRenderer> ();
mesh.material = materials[ropeNum - 1];
ropeNum++;
setup.AddPendulum (ballcopy, new Vector3(0,0,0));
}
}
public IEnumerator GenRopes (){
RopeMaker setup = (RopeMaker)newRope.GetComponent ("RopeMaker");
yield return setup.MakeRope();
}
}