Skip to content

Instantly share code, notes, and snippets.

@nevernotsean
Created July 17, 2022 21:04
Show Gist options
  • Save nevernotsean/be110c6730b09a2a6d0ef1c16bf3003e to your computer and use it in GitHub Desktop.
Save nevernotsean/be110c6730b09a2a6d0ef1c16bf3003e to your computer and use it in GitHub Desktop.
Updated Spline Raycast with Unity Dreamteck Splines, adds support for raycasting across a closed Spline.
using System.Collections.Generic;
using UnityEngine;
namespace Dreamteck.Splines
{
static class SplineUtilities
{
/// <summary>
/// Casts a ray along the transformed spline against all scene colliders.
/// </summary>
public static bool Raycast(SplineComputer spline, float xOffset, float yOffset, ref SplineSample sample, out RaycastHit hit, out double hitPercent, LayerMask layerMask, double from = 0.0, double to = 1.0, double resolution = 1.0, Spline.Direction direction = Spline.Direction.Forward, QueryTriggerInteraction hitTriggers = QueryTriggerInteraction.UseGlobal)
{
Spline.FormatFromTo(ref from, ref to, false);
resolution = DMath.Clamp01(resolution);
from = DMath.Clamp01(from);
to = DMath.Clamp01(to);
double percent = from;
spline.Evaluate(percent, ref sample);
Vector3 fromPos = sample.position + sample.up * yOffset + sample.right * xOffset;
hitPercent = 0f;
while (true)
{
double prevPercent = percent;
double nextStep = spline.moveStep / resolution;
percent = direction == Spline.Direction.Forward ?
MoveForward(percent, to, nextStep) :
MoveBackward(percent, to, nextStep);
// percent = DMath.Move(percent, to, nextStep);
spline.Evaluate(percent, ref sample);
Vector3 toPos = sample.position + sample.up * yOffset + sample.right * xOffset;
Debug.DrawLine(fromPos, toPos, Color.red, Time.deltaTime);
if (Physics.Linecast(fromPos, toPos, out hit, layerMask, hitTriggers))
{
double segmentPercent = (hit.point - fromPos).sqrMagnitude / (toPos - fromPos).sqrMagnitude;
hitPercent = DMath.Lerp(prevPercent, percent, segmentPercent);
return true;
}
fromPos = toPos;
if (percent >= to) break;
}
return false;
}
public static double MoveForward(double from, double to, double amount)
{
double current = from;
if (current + amount > to)
current = to;
else if (current > 1.0)
current = 1.0 - current;
else
current += amount;
return current;
}
public static double MoveBackward(double from, double to, double amount)
{
double current = from;
if (current - amount < to)
current = to;
else if (current < 0.0)
current = 1.0 + current;
else
current -= amount;
return current;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment