I am creating a climbing character which climbs various slopes and shapes with its arms. I am trying to modify the SkeletonUtilityGroundConstraints.cs script, so it works the other way around (with the roof/top instead of the ground).
I'm not the most professional coder, but I get the general idea of the original script: a ray is casting from above the ground, so I've reversed that etc.
Everything is working so far in Play Mode, but in Edit Mode I receive a lot of errors when leaving the climb (when the ray isn't hitting anything).
transform.position assign attempt for 'rear_foot_goal' is not valid. Input position is { -6.835991, Infinity, 0.000000 }.
I want to re-position the IK to the default/original animation position, when leaving the climb. I noticed the original script uses float.MaxValue (as some type of reset?), which only returns NaN in my scenario (don't really know why), so I'm using Mathf.Infinity, but that causes errors in Edit Mode. Is it a bug, or what am I doing wrong?
I am doing all of my testing in the SkeletonUtilityGroundConstraint Spine Example scene with the raptor, the "rear_foot_goal" and "front_foot_goal" has these scripts attached.
Thanks in advance for all suggestions
using Spine.Unity;
using UnityEngine;
[RequireComponent(typeof(SkeletonUtilityBone))]
public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint
{
[Tooltip("LayerMask for what objects to raycast against")]
public LayerMask groundMask;
[Tooltip("How high above the target bone to begin casting from")]
public float castDistance = 4f;
[Tooltip("How fast the target IK position adjusts to the ground. Use smaller values to prevent snapping")]
public float adjustSpeed = 5;
private Vector3 origin = new Vector3(0, 0, 0);
public Vector3 rayDir = new(0, 1, 0);
float hitY;
float lastHitY;
private Vector3 newPosition;
protected override void OnEnable()
{
base.OnEnable();
lastHitY = transform.position.y;
}
public override void DoUpdate()
{
origin = transform.position + new Vector3(0, -castDistance/2, 0);
var distance = castDistance;
var positionScale = hierarchy.PositionScale;
var adjustDistanceThisFrame = adjustSpeed * positionScale * Time.deltaTime;
var hit = Physics2D.Raycast(origin, rayDir, distance, groundMask);
if (hit)
{
hitY = hit.point.y;
if (Application.isPlaying)
hitY = Mathf.MoveTowards(lastHitY, hitY, adjustDistanceThisFrame);
Debug.DrawRay(origin, rayDir * distance, Color.green);
}
else
{
hitY = Mathf.Infinity; // the problematic area (?)
if (Application.isPlaying)
hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustDistanceThisFrame);
Debug.DrawRay(origin, rayDir * distance, Color.red);
}
newPosition = transform.position;
newPosition.y = hitY;
transform.position = newPosition;
bone.bone.X = transform.localPosition.x / positionScale;
bone.bone.Y = transform.localPosition.y / positionScale;
lastHitY = hitY;
}
}