Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Adding pin constraints to a rope at runtime
#4
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.
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 ();
            
        }

    }
}
And the other code that feeds into the generation code.
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();
    }
        
}
Reply


Messages In This Thread
RE: Adding pin constraints to a rope at runtime - by Gieve - 18-03-2018, 05:46 PM