Had some issues with the update from Obi Rope 6 -> 7 in a project that used Obi Rope 6. Luckily it's a scratch project.
1. I tried upgrading on top of the old version but saw script errors so I removed all Obi files and installed fresh instead. Of course, I have scripts and prefabs that depend on the older Obi files, so all of those break in the process of installation. Even after the other issues were patched below, my existing code runs into Index Of Of Range errors on trying to load my existing rope blueprints, so now I have to see if it's a code issue or a blueprint schema change issue. [Edit: I see the forum update guide says you have to regen blueprints. I'm creating them from code, see below.]
2. The demo scenes use a resource script called FPSDisplay. It does not use a namespace, so it conflicted with another script I already had called FPSDisplay. This caused compilation errors and breaks the script references in scenes that used either one (my existing scenes, as well as your demo scenes.) Even after I added a namespace to my existing FPSDisplay, the script references were broken, so I had to add a namespace to your file and re-add it to the demo scene objects. I thought Unity demanded all assets used namespaces to avoid this sort of conflict. [Edit: Similar breakage on SlowmoToggler which does not have a namespace (I have no such script but your demo scene had a broken link to it and Unity couldn't find it until I added one).]
3. Many of your demo scenes use a built-in diffuse material for many objects. Please define your own material for these objects, so that when I update all materials to URP these objects don't remain pink.
4. There is no longer a type for ObiFixedUpdater. I had a script that expected this type to force a regeneration of ropes (as I would deactivate and reactivate ropes in proximity to the player). The CHANGELOG says all ObiUpdater types have been removed. No guidance on what to do about scripts that referenced them.
Here is the code I'm trying to migrate. It generates new blueprints on the fly during Start.
My prefab has four of these, and each one is spitting out Null Reference errors in your DrawGizmos in Edit mode.
Once I try running, I get Index Out Of Bounds errors in your ObiActor.LoadBlueprintParticles, when I provide the generated blueprint to ObiRope. One error per rope, with different starting index numbers.
1. I tried upgrading on top of the old version but saw script errors so I removed all Obi files and installed fresh instead. Of course, I have scripts and prefabs that depend on the older Obi files, so all of those break in the process of installation. Even after the other issues were patched below, my existing code runs into Index Of Of Range errors on trying to load my existing rope blueprints, so now I have to see if it's a code issue or a blueprint schema change issue. [Edit: I see the forum update guide says you have to regen blueprints. I'm creating them from code, see below.]
2. The demo scenes use a resource script called FPSDisplay. It does not use a namespace, so it conflicted with another script I already had called FPSDisplay. This caused compilation errors and breaks the script references in scenes that used either one (my existing scenes, as well as your demo scenes.) Even after I added a namespace to my existing FPSDisplay, the script references were broken, so I had to add a namespace to your file and re-add it to the demo scene objects. I thought Unity demanded all assets used namespaces to avoid this sort of conflict. [Edit: Similar breakage on SlowmoToggler which does not have a namespace (I have no such script but your demo scene had a broken link to it and Unity couldn't find it until I added one).]
3. Many of your demo scenes use a built-in diffuse material for many objects. Please define your own material for these objects, so that when I update all materials to URP these objects don't remain pink.
4. There is no longer a type for ObiFixedUpdater. I had a script that expected this type to force a regeneration of ropes (as I would deactivate and reactivate ropes in proximity to the player). The CHANGELOG says all ObiUpdater types have been removed. No guidance on what to do about scripts that referenced them.
Here is the code I'm trying to migrate. It generates new blueprints on the fly during Start.
My prefab has four of these, and each one is spitting out Null Reference errors in your DrawGizmos in Edit mode.
Quote:NullReferenceException: Object reference not set to an instance of an object
Obi.ObiRopeCursorEditor.DrawGizmos (Obi.ObiRopeCursor cursor, UnityEditor.GizmoType gizmoType) (at Assets/Plugins/Obi/Editor/RopeAndRod/ObiRopeCursorEditor.cs:75)
Once I try running, I get Index Out Of Bounds errors in your ObiActor.LoadBlueprintParticles, when I provide the generated blueprint to ObiRope. One error per rope, with different starting index numbers.
Quote:IndexOutOfRangeException: Writing to index 0 is out of range of '0' Capacity.
Obi.ObiNativeList`1[T].set_Item (System.Int32 index, T value) (at Assets/Plugins/Obi/Scripts/Common/DataStructures/NativeList/ObiNativeList.cs:98)
Obi.ObiActor.LoadBlueprintParticles (Obi.ObiActorBlueprint bp) (at Assets/Plugins/Obi/Scripts/Common/Actors/ObiActor.cs:995)
Obi.ObiActor.LoadBlueprint (Obi.ObiSolver solver) (at Assets/Plugins/Obi/Scripts/Common/Actors/ObiActor.cs:1161)
Obi.ObiRope.LoadBlueprint (Obi.ObiSolver solver) (at Assets/Plugins/Obi/Scripts/RopeAndRod/Actors/ObiRope.cs:187)
Screenplay.TightRope.Generate () (at Assets/__SHARED__/Scripts/For/Obi/TightRope.cs:109)
Screenplay.TightRope.Start () (at Assets/__SHARED__/Scripts/For/Obi/TightRope.cs:45)
Code:
// TightRope.cs
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using Obi;
namespace Screenplay
{
//
// Combines the logic of Obi's RopeBetweenTwoPoints and ObiRopeReel
// to form a simulated rope between any two transforms, with managed slack.
//
public class TightRope: MonoBehaviour, ICraneRope
{
public ObiSolver solver;
public ObiRopeCursor cursor;
public ObiRope rope;
public Transform start;
public ObiParticleAttachment startAttachment;
public Transform end;
public ObiParticleAttachment endAttachment;
public const float MINIMUM_SLACK = 0.0f;
public const float MAXIMUM_SLACK = 1.0f;
[Range(MINIMUM_SLACK, MAXIMUM_SLACK)]
[Tooltip("How much additional length beyond distance from start to end")]
public float slack = 0.1f;
[Tooltip("How much change in length required to recalculate rope")]
public float deltaLength = 0.05f;
public float cursorMu = 0.5f;
public float sourceMu = 0.95f;
private float priorLength = float.NegativeInfinity;
void Start()
{
Generate();
// the rope actor must be a child under a solver to start the simulation
transform.SetParent(solver.transform);
}
// ICraneRope
public float GetLength()
{
if (priorLength > 0f)
return priorLength;
return IdealLength();
}
public float GetMaximumSlack() => MAXIMUM_SLACK;
private float IdealLength()
{
float taut = start.Distance(end);
if (slack < MINIMUM_SLACK)
slack = MINIMUM_SLACK;
return taut + slack;
}
public void Generate()
{
if (start == null || end == null)
return;
// Adjust our transform:
transform.position = start.position;
transform.rotation = start.rotation;
// Calculate control point positions and tangent vector:
Vector3 startPositionLS = transform.InverseTransformPoint(start.position);
Vector3 endPositionLS = transform.InverseTransformPoint(end.position);
Vector3 tangentLS = (endPositionLS - startPositionLS).normalized;
Vector3 normalLS = start.right;
// Add rope actor / renderer / attachment components:
rope = gameObject.GetComponent<ObiRope>();
rope.ropeBlueprint = null;
// Create the blueprint:
ObiRopeBlueprint clone;
clone = ScriptableObject.CreateInstance<ObiRopeBlueprint>();
clone.resolution = 0.5f;
// Build the rope path:
int filter = ObiUtils.MakeFilter(ObiUtils.CollideWithEverything, 0);
clone.path.AddControlPoint(
startPositionLS, -tangentLS, tangentLS, normalLS,
0.1f, 0.1f, 1, filter, Color.white, "start");
clone.path.AddControlPoint(
endPositionLS, -tangentLS, tangentLS, normalLS,
0.1f, 0.1f, 1, filter, Color.white, "end");
clone.path.FlushEvents();
// Generate particles/constraints:
clone.GenerateImmediate();
// Set the blueprint:
rope.ropeBlueprint = clone;
rope.LoadBlueprint(solver);
cursor = gameObject.GetComponent<ObiRopeCursor>();
// Attach both ends:
startAttachment.target = start;
startAttachment.particleGroup = clone.groups[0];
endAttachment.target = end;
endAttachment.particleGroup = clone.groups[1];
}
// Update is called once per frame
void Update()
{
// get ideal rest length:
float restLength = IdealLength();
// if we haven't changed sufficiently, don't disturb it
if (Mathf.Abs(restLength - priorLength) < deltaLength)
return;
cursor.cursorMu = cursorMu;
cursor.sourceMu = sourceMu;
cursor.UpdateCursor();
// set the new rest length:
cursor.ChangeLength(restLength);
priorLength = restLength;
}
}
}