Bug / Crash Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - Printable Version +- Obi Official Forum (https://obi.virtualmethodstudio.com/forum) +-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html) +--- Forum: Obi Rope (https://obi.virtualmethodstudio.com/forum/forum-4.html) +--- Thread: Bug / Crash Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange (/thread-4425.html) |
Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - alicecatalano - 10-12-2024 Good morning, I’m encountering a strange issue with grasping a closed-loop ObiRope using two tools. My goal is to grasp different points on the rope with each tool, without using constraints. The Problem:
What I’ve Tried:
In the attached image:
Question: Why does this behavior occur when the right tool is the second one to grasp? Could this be a bug in ObiRope's particle attachment system, or am I missing something in the setup? Thank you for any insights or suggestions! RE: Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - josemendez - 10-12-2024 Hi Alice, 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, RE: Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - alicecatalano - 10-12-2024 (10-12-2024, 10:50 AM)josemendez Wrote: Hi Alice,Hi, 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 RE: Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - josemendez - 10-12-2024 Hi Alice, The following code is unnecessary, and may lead to incorrect behavior as it resets the state of the rope every time you attach a particle: Code: actor.solver.RemoveActor(actor); // Refresh the actor in the solver What this does is take out all particles and constraints from the solver and reorder all other actor's data (which is expensive), then re-add the actor using the data stored in the blueprint. Adding attachments at runtime does not require doing this. Additionally you're adding new particle groups to the blueprint: Code: actor.blueprint.AppendNewParticleGroup("GraspedParticles"); but never deleting them. This might not be a problem but over time can add up to a significant amount of scriptable objects being created. Also keep in mind that having multiple attachments on the same particle will yield undefined behavior as warned in the manual. Your code does not check whether the particle about to be attached is already attached, so in case both left and right hands grasp the same particle you'll be in trouble: Quote:Particles affected by more than one attachment will follow the attachment that was updated last. The update order for attachment is undefined. kind regards, RE: Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - alicecatalano - 12-12-2024 (10-12-2024, 11:47 AM)josemendez Wrote: Hi Alice,Thank you for the answer, but unfortunately all of this work is lost. yesterday my laptop crashed while the simulaiton was running and now seems like the simulation is not able to run anymore without continous lags. I created another simulation that would have the same objects and behaviours but when I imported obi and used the same exact codes nothing was working anymore. the behavior of the elastic is totally different even if i keep the same values of the characteristics. Now when i grasp it the grasped particle is visually detached from the grasping point and the elastic "updates" when i grasp it, by fastly appearing and disappearing. the code is exactly the same as the one i provided you before. RE: Issue with Grasping ObiRope Using Two ToolsGood morning, I’m encountering a strange - josemendez - 12-12-2024 (12-12-2024, 11:34 AM)alicecatalano Wrote: the simulation is not able to run anymore without continous lags. Hi Alice, If you're using Burst in the editor, make sure the jobs debugger is disabled as that will have a *huge* negative effect on performance. (12-12-2024, 11:34 AM)alicecatalano Wrote: I created another simulation that would have the same objects and behaviours but when I imported obi and used the same exact codes nothing was working anymore. Code can't just stop working due to a crash, it is impossible. More likely your current setup and/or parameters are not entirely identical to the original one. (12-12-2024, 11:34 AM)alicecatalano Wrote: Now when i grasp it the grasped particle is visually detached from the grasping point and the elastic "updates" when i grasp it, by fastly appearing and disappearing. the code is exactly the same as the one i provided you before. If the code is the same but behavior is different, that means the parameters used for simulation are not the same. I can't possibly know however, since I don't know how your project was set up before this incident and how it is set up now. let me know if I can be of any help, kind regards |