Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Null Reference, actor not loading
#1
Good morning,

I created a code to grasp an obiRope. It is not the first time i use it and untill now it worked fine, I have anotehr simulation that uses the same logic and I have no issues. 
Now when the simulation starts the obiActor is not loaded in the script, even if i associated the code to it or passed it as a reference. 
The grasping works but badly, and I think it is because of this issue.  
the code:
```
using UnityEngine;
using Obi;
using System.Collections.Generic;

[RequireComponent(typeof(ObiActor))]
public class DistanceAnchor : MonoBehaviour
{
    public ObiActor actor;
    public ObiParticleAttachment attachment;
    public Transform anchor;
    public float anchorRadius = 0.5f;
    private ForcepsControl forcepsControl;

    private int groupIndex;
    private bool isGrasping;
    public bool IsGrasping
    {
        get { return isGrasping; }
    }
   

    void Awake()
    {
        actor = GetComponent<ObiActor>();
        forcepsControl = FindObjectOfType<ForcepsControl>();
        if (forcepsControl != null)
        {
            forcepsControl.OnRestPositionReached += CheckAndAnchorParticles;
            forcepsControl.OnReleasePositionReached += Release;
        }
    }



    void CheckAndAnchorParticles()
    {
        if (!actor.isLoaded)
        {
            Debug.LogError("Actor is not loaded");
            return;
        }

        for (int i = 0; i < actor.solverIndices.count; ++i)
        {
            int solverIndex = actor.solverIndices[i];
            float distance = Vector3.Distance(actor.GetParticlePosition(solverIndex), anchor.position);
            Debug.Log($"Distance to Anchor: {distance}, Grasping State: {isGrasping}");
            if (distance < anchorRadius && !isGrasping)
            {
                Grasp(actor, i);
            }
        }
    }



    private void Grasp(ObiActor actor, int index)
    {
        if (attachment != null)
        {
            Destroy(attachment);
        }

        attachment = actor.gameObject.AddComponent<ObiParticleAttachment>();
        attachment.target = anchor; // Attach to the anchor
        attachment.particleGroup = actor.blueprint.AppendNewParticleGroup("GraspedParticles");
        groupIndex = actor.blueprint.groups.Count - 1; // Ensure it's the last added group
        attachment.particleGroup.particleIndices = new List<int> { index };
        attachment.compliance = 0;
        attachment.attachmentType = ObiParticleAttachment.AttachmentType.Static;
        isGrasping = true;

        actor.solver.RemoveActor(actor); // Refresh the actor in the solver
        actor.solver.AddActor(actor);
    }
    private void Release()
    {
        if (attachment != null)
        {
           
            Destroy(attachment);
            actor.blueprint.RemoveParticleGroupAt(groupIndex);
            actor.solver.RemoveActor(actor); // Refresh the actor in the solver
            actor.solver.AddActor(actor);

            isGrasping = false;
        }
    }


    void OnDestroy()
    {
        if (forcepsControl != null)
        {
            forcepsControl.OnRestPositionReached -= CheckAndAnchorParticles;
            forcepsControl.OnReleasePositionReached -= Release;
        }

        // Ensure to release any grasped particles
        Release();

        // Additional cleanup if needed
        if (attachment != null)
        {
            Destroy(attachment);
            attachment = null;
        }
    }
}
```

the error: 

```
Actor is not loaded
UnityEngine.Debug:LogError (object)
DistanceAnchor:CheckAndAnchorParticles () (at Assets/Scripts/DistanceAnchor.cs:39)
ForcepsControl:UpdateThimbleRotation () (at Assets/Scripts/ForcepsControl.cs:70)
ForcepsControl:Update () (at Assets/Scripts/ForcepsControl.cs:51)

NullReferenceException: Object reference not set to an instance of an object
DistanceAnchor.CheckAndAnchorParticles () (at Assets/Scripts/DistanceAnchor.cs:43)
ForcepsControl.Update () (at Assets/Scripts/ForcepsControl.cs:48)
```
Reply
#2
Hi,

These are two separate errors.

(13-12-2024, 12:19 PM)alicecatalano Wrote: NullReferenceException: Object reference not set to an instance of an object
DistanceAnchor.CheckAndAnchorParticles () (at Assets/Scripts/DistanceAnchor.cs:43)
ForcepsControl.Update () (at Assets/Scripts/ForcepsControl.cs:48)

This is a null reference on DistanceAnchor line 43. Most likely, "actor" or "actor.solverIndices" is null because the actor has not been loaded into any solver yet.

(13-12-2024, 12:19 PM)alicecatalano Wrote: Actor is not loaded
UnityEngine.Debug:LogError (object)
DistanceAnchor:CheckAndAnchorParticles () (at Assets/Scripts/DistanceAnchor.cs:39)
ForcepsControl:UpdateThimbleRotation () (at Assets/Scripts/ForcepsControl.cs:70)
ForcepsControl:Update () (at Assets/Scripts/ForcepsControl.cs:51)

This simply means the actor has not been loaded by any solver.

Could be that there's no solver to be found up the actor's hierarchy, or that the actor's OnEnable (which is where the actor gets loaded) hasn't been called yet by the time your script's CheckAndAnchorParticles() is called. Keep in mind that the order in which Unity calls events for different components is undefined, this means your script's OnEnable(), Awake(), etc could be called before or after any other script's.

kind regards,
Reply