Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Need Help On Render Chain at RunTime
#1
Hi, I want Render a Chain at Run Time, but I got this.


NullReferenceException: Object reference not set to an instance of an object
Obi.ObiRopeChainRenderer.CreateChainLinkInstances (Obi.ObiRopeBase rope) (at Assets/ThirdParty/Obi/Scripts/RopeAndRod/Rendering/ObiRopeChainRenderer.cs:98)
Obi.ObiRopeChainRenderer.UpdateRenderer (Obi.ObiActor actor) (at Assets/ThirdParty/Obi/Scripts/RopeAndRod/Rendering/ObiRopeChainRenderer.cs:116)
Obi.ObiActor.Interpolate () (at Assets/ThirdParty/Obi/Scripts/Common/Actors/ObiActor.cs:1016)
Obi.ObiSolver.Interpolate (System.Single stepTime, System.Single unsimulatedTime) (at Assets/ThirdParty/Obi/Scripts/Common/Solver/ObiSolver.cs:1351)
Obi.ObiUpdater.Interpolate (System.Single stepDeltaTime, System.Single accumulatedTime) (at Assets/ThirdParty/Obi/Scripts/Common/Updaters/ObiUpdater.cs:119)
Obi.ObiFixedUpdater.Update () (at Assets/ThirdParty/Obi/Scripts/Common/Updaters/ObiFixedUpdater.cs:79)



I don't know what's wrong.

here is My code:

thanks for the help.

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;


public class HookTool : MonoBehaviour
{

    public ObiSolver solver;
    public ObiCollider character;
    public float hookExtendRetractSpeed = 2;
    public bool canTear;
   
    public ObiRopeSection section;

    //public GameObject chain;
   
    private List<GameObject> PrefabsList;

    ObiRope rope;
    private ObiRopeBlueprint blueprint;
    private ObiRopeExtrudedRenderer ropeRenderer;
    private ObiRopeChainRenderer chainRenderer;

    private ObiRopeCursor cursor;


    KeyCode interKey = KeyCode.Joystick1Button0;
    KeyCode addRope = KeyCode.Joystick1Button4;
    KeyCode lessRope = KeyCode.Joystick1Button5;

    private bool attached = false;

    private GameObject maincam;
    private bool doOnce;
    private SpeedTutorInspectSystem.ObjectController raycastedObj;

    RaycastHit hit;
   

    void Awake()
    {
       
        //找到玩家身上的主攝像機
        GameObject camobject = GameObject.FindGameObjectWithTag("MainCamera");
        maincam = camobject;

        //這裡學到一個超牛的,之前我沒有給chain初始化,public GameObject chain並沒有定義,下面必須初始化,否則後面的一切,update都不會觸發!
       
        PrefabsList = new List<GameObject>();

        //GameObject instance = Instantiate(Resources.Load("ChainLinkRed", typeof(GameObject))) as GameObject;

        GameObject instance = Resources.Load("ChainLinkRed", typeof(GameObject)) as GameObject;
        PrefabsList.Add(instance);
       
       

        // Create both the rope and the solver:    
        rope = gameObject.AddComponent<ObiRope>();
        chainRenderer = gameObject.AddComponent<ObiRopeChainRenderer>();
       
        chainRenderer.linkPrefabs = PrefabsList;
        chainRenderer.linkScale = new Vector3(34,34,34);
        chainRenderer.twistAnchor = 0;
        chainRenderer.sectionTwist = 70;
       
       

        // Setup a blueprint for the rope:
        blueprint = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
   
        blueprint.resolution = 0.5f;

        // Tweak rope parameters:
        rope.maxBending = 0.02f;

        // Add a cursor to be able to change rope length:
        cursor = rope.gameObject.AddComponent<ObiRopeCursor>();
        cursor.cursorMu = 0;
        cursor.direction = true;
    }

    private void OnDestroy()
    {
        DestroyImmediate(blueprint);
    }


    public void LaunchHook()
    {
        //以後都是從整個class讀取ray
        hit = maincam.GetComponent<SpeedTutorInspectSystem.InspectionRaycast>().hit;

        if (hit.collider.CompareTag("InteractObject"))
        {
            //Debug.Log("hit" + hit.collider.gameObject.name);
            StartCoroutine(AttachHook());
            //yield
            chainRenderer.enabled = true;
            chainRenderer.twistAnchor = 0.2f;
        }
       
    }


    private IEnumerator AttachHook()
    {
        //Debug.Log("hook begin");
        yield return 0;
        Vector3 localHit = rope.transform.InverseTransformPoint(hit.point);

        // 將rope由兩點畫出來:
        blueprint.path.Clear();
        blueprint.path.AddControlPoint(Vector3.zero, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "Hook start");
        blueprint.path.AddControlPoint(localHit, -localHit.normalized, localHit.normalized, Vector3.up, 0.1f, 0.1f, 1, 1, Color.white, "Hook end");
        blueprint.path.FlushEvents();

        // 畫出rope的blueprint:
        yield return blueprint.Generate();

        // 設置兩點的交互,rope對物體的影響在這裡設置:
        var pinConstraints = blueprint.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
        var batch = pinConstraints.batches[0];
        batch.AddConstraint(0, character, transform.localPosition, Quaternion.identity);
        batch.AddConstraint(blueprint.activeParticleCount - 1, hit.collider.GetComponent<ObiColliderBase>(),
                                                          hit.collider.transform.InverseTransformPoint(hit.point), Quaternion.identity);
                                                         
        batch.activeConstraintCount = 2;
       
       
        // 最終顯示出來.
        rope.ropeBlueprint = blueprint;
        chainRenderer.enabled = true;
        rope.tearingEnabled = canTear;
        rope.selfCollisions = true;
        // 這裡是讓物理正常
        pinConstraints = rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
        batch = pinConstraints.batches[0];
        batch.stiffnesses[0 * 2 + 1] = 10000;
        batch.stiffnesses[1 * 2 + 1] = 10000;
       
        //rope.GetComponent<ObiRopeChainRenderer>().enabled = true;
        //chainRenderer.twistAnchor = 0.1f;
       
       
    }

    public void DetachHook()
    {
        // Set the rope blueprint to null (automatically removes the previous blueprint from the solver, if any).
        rope.ropeBlueprint = null;
        chainRenderer.enabled = false;
        //rope.GetComponent<ObiRopeChainRenderer>().enabled = false;
    }


    void Update()
    {
       
        //如果用getkey的話就會一秒內按無數次,必須是Getkeydown才可以!gfg
        if (Input.GetKeyDown(interKey))
        {
           
            if (!rope.isLoaded)
            {
                LaunchHook();
            }
               
            else
                DetachHook();
        }

        if (rope.isLoaded)
        {
            if (Input.GetKey(lessRope))
            {
                cursor.ChangeLength(rope.restLength - hookExtendRetractSpeed * Time.deltaTime);
            }
            if (Input.GetKey(addRope))
            {
                cursor.ChangeLength(rope.restLength + hookExtendRetractSpeed * Time.deltaTime);
            }
        }

        if (Input.GetKeyDown(KeyCode.P))
        {
            //chainRenderer.enabled = true;
            chainRenderer.twistAnchor += 0.1f;
            //chainRenderer.gameObject.SetActive(true);
        }
    }
}
Reply
#2
Hi,

If the chain component has not yet been serialized, the instances list will be null. Modify ObiRopeChainRenderer.cs, line 14 should look like this:

Code:
[HideInInspector][SerializeField] public List<GameObject> linkInstances = new List<GameObject>();

kind regards,
Reply
#3
(14-08-2020, 07:21 AM)josemendez Wrote: Hi,

If the chain component has not yet been serialized, the instances list will be null. Modify ObiRopeChainRenderer.cs, line 14 should look like this:

Code:
[HideInInspector][SerializeField] public List<GameObject> linkInstances = new List<GameObject>();

kind regards,
 IT worked! thanks!
Reply