13-12-2024, 12:19 PM
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)
```
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)
```