Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Use obi rope to generate player lines
#3
Hi josemendez,

Thanks for your reply! Here is the code about generating the rope and changing the cursor~ Why is the rope not generated for the points in m_Positions? I also want to take a ray starting from the fish and check the number of times the ray passes through the rope to check whether the object is surrounded by the rope, but Query methods don't seem to be able to do it.

Code:
        private async UniTaskVoid ChangeRopeLength1()
        {
            GameManager.Instance.GameStatus = GameStatus.Pull;
           
            // Clear Constraints
            var obiConstraints = m_Rope.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
            obiConstraints?.Clear();
           
            // Generate Blueprint
            var filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
            m_RopeBlueprint.path.Clear();
            m_RopeBlueprint.path.AddControlPoint(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook start");
            m_RopeBlueprint.path.AddControlPoint(new Vector3(0, -0.5f, 0), Vector3.zero, Vector3.zero, Vector3.up, 0.1f, 0.1f, 1, filter, Color.white, "Hook end");
            m_RopeBlueprint.path.FlushEvents();

            await m_RopeBlueprint.Generate().ToUniTask(this);

            m_Rope.ropeBlueprint = m_RopeBlueprint;
           
            await UniTask.Yield();
           
            GetComponent<MeshRenderer>().enabled = true;
           
            // Generate Rope
            var prePos = m_AttachPos;
            var lineLength = 0f;
            foreach (var position in m_Positions)
            {
                var direction = position - prePos;
                var preElementsCount = m_Rope.elements.Count;
                // Calculate distance
                lineLength += direction.magnitude;
                m_RopeCursor.ChangeLength(lineLength);
               
                var currentElementCount = m_Rope.elements.Count - preElementsCount;
               
                // Update Positions
                direction.Normalize();
                var elementIndex = 0;
                while (elementIndex < currentElementCount)
                {
                    var ropeElement = m_Rope.elements[elementIndex];
                    var part1 = ropeElement.particle1;
                    var part2 = ropeElement.particle2;

                    var pre = m_Rope.solver.transform.InverseTransformPoint(prePos);
                    m_Rope.solver.positions[part1] = pre;
                    m_Rope.solver.velocities[part1] = Vector4.zero;

                    prePos += direction * ropeElement.restLength;
                    var next = m_Rope.solver.transform.InverseTransformPoint(prePos);
                    m_Rope.solver.positions[part2] = next;
                    m_Rope.solver.velocities[part2] = Vector4.zero;
                    elementIndex++;
                }

                prePos = position;
            }
           
            // Set Mass
            for (var i = 0; i < m_Rope.activeParticleCount; ++i)
            {
                m_Solver.invMasses[m_Rope.solverIndices[i]] = 100;
            }

            await UniTask.Yield();

            // Add Constraints
            var pinConstraintsBatch = new ObiPinConstraintsBatch();
            pinConstraintsBatch.AddConstraint(m_Rope.elements[0].particle1, m_CatAttach, Vector3.zero, Quaternion.identity, 0, 0, float.PositiveInfinity);
            pinConstraintsBatch.AddConstraint(m_Rope.elements[^1].particle2, m_CatAttach, Vector3.zero, Quaternion.identity, 0, 0, float.PositiveInfinity);
            pinConstraintsBatch.activeConstraintCount = 2;
            obiConstraints?.AddBatch(pinConstraintsBatch);
           
            m_Rope.SetConstraintsDirty(Oni.ConstraintType.Pin);
           
            await UniTask.Yield();
           
            while (true)
            {
                var preLength = m_Rope.restLength;
                m_RopeCursor.cursorMu = 0.1f;
                var deltaLength = GameManager.Instance.RopePullSpeed * Time.fixedDeltaTime;
                m_RopeCursor.ChangeLength(m_Rope.restLength - deltaLength);
                await UniTask.WaitForFixedUpdate();
                m_RopeCursor.cursorMu = 0.9f;
                m_RopeCursor.ChangeLength(m_Rope.restLength - deltaLength);
                await UniTask.WaitForFixedUpdate();
                if (m_Rope.restLength < 5f || GameManager.Instance.GameStatus == GameStatus.End)
                {
                    break;
                }
            }
           
            GameManager.Instance.CheckWin();
        }

I need to create an effect similar to the one in the video:
Reply


Messages In This Thread
RE: Use obi rope to generate player lines - by Jack Li - 11-04-2024, 05:17 PM