08-12-2023, 11:57 AM
(This post was last modified: 08-12-2023, 03:23 PM by Christoffer.)
Hi!
I am creating a simulation where a cable is fed onto a spool, and for performance reasons i cant simulate the entire rope after more than a few turns of the spool.
I need to be able to stop the physics simulation for the particles that have reached about 1-2 turns on the spool, and after that they should be parented to the spool and only used for collision. The plan is to feed quite alot of rope with accurate collision. The user will be in charge of the speed on both rope feeding speed and spool speed, resulting in a failure if the tension gets too high.
Setup:
I have no idea if this is even remotely close to performant or even possible, but i know that the alternative of simulating the entire rope is not.
Especially as i am trying to use it as a cable with high stiffness (many Bending-constraint iterations).
Result:
Every other run the original attachment works.
Every other run half the rope is attached way off and incorrectly.
Seems almost as if the particle group is saved from the previous run.
I tried clearing the particle group in the Start-event, no difference.
If i create a new particle group on start and modify it time a new particle is added, then set that group as the attachment's particle group , the particles get attached but not to the correct transform. They just float in place as if attached to scene root.
Any tips on how to achieve the result im after?
Also, any tips on getting the feeling of a cable rather than a rope, without going overboard with iterations? Cant use ObiCable as i cant change the length of it in runtime :/
Edit:
Adding some code which is added to the ObiRope-object:
Thanks in advance, Christoffer
I am creating a simulation where a cable is fed onto a spool, and for performance reasons i cant simulate the entire rope after more than a few turns of the spool.
I need to be able to stop the physics simulation for the particles that have reached about 1-2 turns on the spool, and after that they should be parented to the spool and only used for collision. The plan is to feed quite alot of rope with accurate collision. The user will be in charge of the speed on both rope feeding speed and spool speed, resulting in a failure if the tension gets too high.
Setup:
- Rotating spool
- Rope between a start position and the spool
- Cursor at the start of the rope, calling ChangeLength on update
- Spline point (particle group?) at the end of the rope, using attachment to connect it to the spool
- Continously compare the pool of particles to the attached particle group, making sure all but the 100 particles closest to start are in the group
(Essentially this means that each time one particle is added, another is added to the attachment group)
I have no idea if this is even remotely close to performant or even possible, but i know that the alternative of simulating the entire rope is not.
Especially as i am trying to use it as a cable with high stiffness (many Bending-constraint iterations).
Result:
Every other run the original attachment works.
Every other run half the rope is attached way off and incorrectly.
Seems almost as if the particle group is saved from the previous run.
I tried clearing the particle group in the Start-event, no difference.
If i create a new particle group on start and modify it time a new particle is added, then set that group as the attachment's particle group , the particles get attached but not to the correct transform. They just float in place as if attached to scene root.
Any tips on how to achieve the result im after?
Also, any tips on getting the feeling of a cable rather than a rope, without going overboard with iterations? Cant use ObiCable as i cant change the length of it in runtime :/
Edit:
Adding some code which is added to the ObiRope-object:
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Obi;
public class SC_CableLengthController : MonoBehaviour
{
public Transform attachmentTarget;
public float speed = 0.5f;
private ObiRopeCursor cursor;
private ObiRope rope;
private ObiParticleAttachment attachment;
private ObiParticleGroup group;
void Start()
{
cursor = GetComponentInChildren<ObiRopeCursor>();
rope = GetComponent<ObiRope>();
group = rope.blueprint.AppendNewParticleGroup("Frozen");
attachment = gameObject.AddComponent<ObiParticleAttachment>();
attachment.attachmentType = ObiParticleAttachment.AttachmentType.Static;
attachment.target = attachmentTarget;
attachment.particleGroup = group;
}
void FixedUpdate()
{
// Length
cursor.ChangeLength(rope.restLength + (Time.fixedDeltaTime * speed));
// Attachment
Debug.Log((attachment.particleGroup.particleIndices.Count, rope.blueprint.groups[rope.blueprint.groups.Count - 1].particleIndices.Count));
Debug.DrawLine(rope.GetParticlePosition(rope.elements[0].particle1), rope.GetParticlePosition(rope.elements[0].particle1) + (Vector3.up), Color.red, 1);
for (int i = rope.elements.Count - 10; i > 60; i--) // Number of particles will be swapped for a more sophisticated distance based solution once i get the dynamic attachment/"freezing" to work as i intended.
{
Debug.DrawLine(rope.GetParticlePosition(rope.elements[i].particle1), rope.GetParticlePosition(rope.elements[i].particle1) + (Vector3.up), Color.red);
if (!group.ContainsParticle(rope.elements[i].particle1))
{
attachment.particleGroup.particleIndices.Add(rope.elements[i].particle1);
}
}
}
}
Thanks in advance, Christoffer