10-12-2024, 11:20 AM
(This post was last modified: 10-12-2024, 11:40 AM by alicecatalano.)
(10-12-2024, 10:50 AM)josemendez Wrote: Hi Alice,Hi,
Can't see any images attached to or posted along with your description of the issue. Also, how are you implementing grasping? could you share your code? otherwise it's quite difficult to tell what might be going on.
kind regards,
now the image should be there, sorry
this is my code
using UnityEngine;
using Obi;
using System.Collections.Generic;
[RequireComponent(typeof(ObiActor))]
public class DistanceAnchor : MonoBehaviour
{
ObiActor actor;
public ObiParticleAttachment rightAttachment;
public ObiParticleAttachment leftAttachment;
public Transform anchorRight;
public Transform anchorLeft;
public float anchorRadius = 5f; // Radius for grasping
public DistanceCalculation forcepsRight; // Reference to the DistanceCalculation script
public DistanceLeft forcepsLeft; // Reference to the DistanceCalculation script
private bool isRightGrasping = false;
private bool isLeftGrasping = false;
private bool isLeftInRelease = false; // Indicates if the left elastic is in release state
private bool isRightInRelease = false;
public bool IsLeftInRelease => isLeftInRelease;
public bool IsRightInRelease => isRightInRelease;
void Awake()
{
actor = GetComponent<ObiActor>();
forcepsRight = FindObjectOfType<DistanceCalculation>();
forcepsLeft = FindObjectOfType<DistanceLeft>();
if (forcepsRight != null)
{
forcepsRight.OnForcepsClosingRight += () => CheckAndGraspParticles(anchorRight, ref isRightGrasping, ref rightAttachment, GraspRight);
forcepsRight.OnForcepsOpeningRight += HandleRightForcepsOpening; // Handles release when opening.
}
if (forcepsLeft != null)
{
forcepsLeft.OnForcepsClosingLeft += () => CheckAndGraspParticles(anchorLeft, ref isLeftGrasping, ref leftAttachment, GraspLeft);
forcepsLeft.OnForcepsOpeningLeft += HandleLeftForcepsOpening; // Handles release when opening.
}
}
void CheckAndGraspParticles(Transform anchor, ref bool isGrasping, ref ObiParticleAttachment attachment, System.Action<ObiActor, int> graspAction)
{
Debug.Log($"Checking grasping for anchor {anchor.name}, isGrasping: {isGrasping}");
if (actor.isLoaded && !isGrasping)
{
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
int solverIndex = actor.solverIndices[i];
float distance = Vector3.Distance(actor.GetParticlePosition(solverIndex), anchor.position);
Debug.Log($"Particle {i}: Solver Index {solverIndex}, Distance: {distance}");
if (distance < anchorRadius)
{
Debug.Log($"Grasp condition met for particle {i}.");
graspAction(actor, i);
break;
}
}
}
}
private void GraspRight(ObiActor actor, int index)
{
rightAttachment = CreateAttachment(actor, index, anchorRight, ref isRightGrasping);
isRightInRelease = false;
Debug.Log(" RIGHT GRASP");
}
private void GraspLeft(ObiActor actor, int index)
{
leftAttachment = CreateAttachment(actor, index, anchorLeft, ref isLeftGrasping);
isLeftInRelease = false;
Debug.Log(" LEFT GRASP");
}
private ObiParticleAttachment CreateAttachment(ObiActor actor, int index, Transform anchor, ref bool isGrasping)
{
Debug.Log($"Creating attachment: isGrasping = {isGrasping}, index = {index}, anchor = {anchor.name}");
if (isGrasping) return null; // Prevent double attachment
var attachment = actor.gameObject.AddComponent<ObiParticleAttachment>();
attachment.target = anchor; // Attach to the specified anchor
attachment.particleGroup = actor.blueprint.AppendNewParticleGroup("GraspedParticles");
attachment.particleGroup.particleIndices = new List<int> { index };
attachment.compliance = 0;
attachment.attachmentType = ObiParticleAttachment.AttachmentType.Static;
Debug.Log($"Attachment created for particle index {index} at anchor {anchor.name}.");
actor.solver.RemoveActor(actor); // Refresh the actor in the solver
actor.solver.AddActor(actor);
Debug.Log("Actor re-added to solver.");
isGrasping = true;
return attachment;
}
private void ReleaseRight()
{
Release(ref rightAttachment, ref isRightGrasping);
isRightInRelease = true;
}
private void ReleaseLeft()
{
Release(ref leftAttachment, ref isLeftGrasping);
isLeftInRelease = true;
}
private void Release(ref ObiParticleAttachment attachment, ref bool isGrasping)
{
if (attachment != null)
{
Destroy(attachment);
isGrasping = false;
}
}
private void HandleRightForcepsOpening()
{
if (isRightGrasping)
{
Debug.Log(" RIGHT RELEASE");
ReleaseRight();
}
}
private void HandleLeftForcepsOpening()
{
if (isLeftGrasping)
{
Debug.Log(" LEFT RELEASE");
ReleaseLeft();
}
}
void OnDestroy()
{
// Ensure to release any grasped particles
Release(ref rightAttachment, ref isRightGrasping);
Release(ref leftAttachment, ref isLeftGrasping);
// Unsubscribe from events to avoid memory leaks
if (forcepsRight != null)
{
forcepsRight.OnForcepsClosingRight -= () => CheckAndGraspParticles(anchorRight, ref isRightGrasping, ref rightAttachment, GraspRight);
forcepsRight.OnForcepsOpeningRight -= HandleRightForcepsOpening;
}
if (forcepsLeft != null)
{
forcepsLeft.OnForcepsClosingLeft -= () => CheckAndGraspParticles(anchorLeft, ref isLeftGrasping, ref leftAttachment, GraspLeft);
forcepsLeft.OnForcepsOpeningLeft -= HandleLeftForcepsOpening;
}
}
}
Also i noticed that i the the following error when at runtime i click on the partcile Group menu in the obi Attachment component
NullReferenceException: Object reference not set to an instance of an object
Obi.ObiParticleAttachmentEditor.OnInspectorGUI () (at C:/Users/Alice Catalano/Desktop/Alice/ObiTraining/Assets/Obi/Editor/Common/Utils/ObiParticleAttachmentEditor.cs:75)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass72_0.<CreateInspectorElementUsingIMGUI>b__0 () (at <9920ff0c944845d7b9f9a61ef1478edc>:0)
UnityEngine.GUIUtilityrocessEvent(Int32, IntPtr, Boolean&)
and this path doesn't exist anymore. I cleared the cache and rebuilt but still this happens