18-03-2025, 12:20 AM
(This post was last modified: 18-03-2025, 12:32 AM by sinoth.
Edit Reason: spacing
)
I have a rope attached statically via ObiParticleAttachment to an immobile object at the beginning, and a movable object (my hand in VR) at the end.
The initial scripted attach works great and the rope behaves as expected. However I can't figure out how to properly grow or shrink via the cursor.
The cursor is set to Cursor Mu 1, Source Mu 1, Direction checked. The rope does grow and shrink. However it seems that the ObiParticleAttachment becomes invalidated because of this. I attempted to repair the attachment every time the cursor is changed but this also fails -- the rope hangs limp as though unattached.
The solver doesn't seem to be initialized in Start which is why I moved the initial attach logic to Update.
If there is a better way to do this please let me know. I just want to grow/shrink the rope from the end but still have it stuck to my hand.
I think I may have figured it out... I changed the attach at the bottom to this:
The main changes were to disable, target null, then set target, and re-enable. Is that the intended way to do this?
Also I'm unsure how RebuildConstraintsFromElements() fits into the picture... should this be called every time after cursor.ChangeLength is called?
The initial scripted attach works great and the rope behaves as expected. However I can't figure out how to properly grow or shrink via the cursor.
The cursor is set to Cursor Mu 1, Source Mu 1, Direction checked. The rope does grow and shrink. However it seems that the ObiParticleAttachment becomes invalidated because of this. I attempted to repair the attachment every time the cursor is changed but this also fails -- the rope hangs limp as though unattached.
Code:
public class RopeController : MonoBehaviour
{
public float speed = 0.1f;
public GameObject handObject;
private bool _addedAttachment;
private ObiParticleAttachment _attachment;
private ObiRopeCursor _cursor;
private ObiParticleGroup _group;
private ObiRope _rope;
private InputAction _ropeDecrease;
private InputAction _ropeIncrease;
private void Start()
{
_ropeIncrease = InputSystem.actions.FindActionMap("Player").FindAction("Rope Increase");
_ropeDecrease = InputSystem.actions.FindActionMap("Player").FindAction("Rope Decrease");
_cursor = GetComponent<ObiRopeCursor>();
_rope = _cursor.GetComponent<ObiRope>();
}
private void Update()
{
if (!_addedAttachment && _rope.solver.positions.count > 0)
{
var lastParticleInitId = _rope.elements[^1].particle2;
_group = ScriptableObject.CreateInstance<ObiParticleGroup>();
_group.particleIndices.Add(lastParticleInitId);
_rope.solver.positions[lastParticleInitId] =
_rope.solver.transform.InverseTransformPoint(handObject.transform.position);
_attachment = gameObject.AddComponent<ObiParticleAttachment>();
_attachment.attachmentType = ObiParticleAttachment.AttachmentType.Static;
_attachment.particleGroup = _group;
_attachment.target = handObject.transform;
_addedAttachment = true;
}
if (!_addedAttachment || (!_ropeIncrease.IsPressed() && !_ropeDecrease.IsPressed()))
return;
if (_ropeIncrease.IsPressed())
_cursor.ChangeLength(speed * Time.deltaTime);
if (_ropeDecrease.IsPressed())
_cursor.ChangeLength(-speed * Time.deltaTime);
_rope.RebuildConstraintsFromElements();
var lastParticleId = _rope.elements[^1].particle2;
_group.particleIndices.Clear();
_group.particleIndices.Add(lastParticleId);
_rope.solver.positions[lastParticleId] =
_rope.solver.transform.InverseTransformPoint(handObject.transform.position);
_attachment.particleGroup = _group;
_attachment.target = handObject.transform;
}
}
The solver doesn't seem to be initialized in Start which is why I moved the initial attach logic to Update.
If there is a better way to do this please let me know. I just want to grow/shrink the rope from the end but still have it stuck to my hand.
I think I may have figured it out... I changed the attach at the bottom to this:
Code:
var lastParticleId = _rope.elements[^1].particle2;
_group.particleIndices.Clear();
_group.particleIndices.Add(lastParticleId);
_rope.solver.positions[lastParticleId] =
_rope.solver.transform.InverseTransformPoint(handObject.transform.position);
_attachment.enabled = false;
_attachment.target = null;
_attachment.target = handObject.transform;
_attachment.enabled = true;
The main changes were to disable, target null, then set target, and re-enable. Is that the intended way to do this?
Also I'm unsure how RebuildConstraintsFromElements() fits into the picture... should this be called every time after cursor.ChangeLength is called?