Posts: 2
Threads: 1
Joined: Apr 2024
Reputation:
0
11-04-2024, 02:48 PM
(This post was last modified: 11-04-2024, 04:32 PM by josemendez.)
I am currently working on a small fishing game using Obi Rope and seeking some advice. Inspired by the RopeGrapplingHook, I'm creating a rope based on the player's lines. My approach involves continuously altering 'cursorMu' between 0.1 and 0.9, along with adjusting 'ChangeLength', to achieve consistent contraction of the rope from both ends. However, I'm encountering a significant challenge: the rope vibrates intensely and behaves unpredictably during generation. I've used a custom outline from a sprite to create a mesh collider. I need to reel in the fish slowly, just like it's shown in the video. If I don't, the fish ends up slipping through the collider of the rope.Could anyone offer insights or suggestions on how to optimize and address this issue?
Thanks in advance for your help!
here is my game video:
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
Hi!
Could you share the code you're using to alternate the position of the cursor?
Since your rope has no visible texture/pattern on it, contracting it from just one side should yield visually similar results. Is there any particular reason why this doesn't work for your use case?
kind regards,
Posts: 2
Threads: 1
Joined: Apr 2024
Reputation:
0
11-04-2024, 05:17 PM
(This post was last modified: 11-04-2024, 06:06 PM by Jack Li.)
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:
Posts: 6,347
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
15-04-2024, 07:03 PM
(This post was last modified: 15-04-2024, 07:05 PM by josemendez.)
(11-04-2024, 05:17 PM)Jack Li Wrote: Here is the code about generating the rope and changing the cursor~ Why is the rope not generated for the points in m_Positions?
What's m_Positions? The code looks like you're trying to generate a rope that passes trough a set of points, but that's precisely what the blueprint is designed for: providing a path that passes trough several control points, and generate a rope out of them. If that's your goal, there isn't any need to loop over m_Positions increasing the length of the rope and manually placing particles yourself. Just create one control point per point in m_Positions.
(11-04-2024, 05:17 PM)Jack Li Wrote: 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.
No need to use raycast queries for this, there's a much simpler way: just iterate trough all elements in the rope -since they can be considered faces of a polygon- and perform a basic point-in-polygon test like this one: https://wrfranklin.org/Research/Short_Notes/pnpoly.html
About your original issue with the rope jittering, I'm afraid that's unavoidable given your approach: every frame you're removing rope from a different part of it, so the mass distribution at both ends of the rope will change every frame leading to a small jitter. You could increase the solver's sleep threshold slightly, see if that can hide this jitter without affecting rope dynamics too much.
kind regards
|