Advertisement
Staggart

Create Spline From Points

Apr 24th, 2024 (edited)
801
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.66 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Mathematics;
  4. using UnityEngine;
  5. using UnityEngine.Splines;
  6.  
  7. namespace sc.modeling.splines.runtime.auxiliary
  8. {
  9.     public class CreateSplineFromPoints : MonoBehaviour
  10.     {
  11.         [Header("Input")]
  12.         [Tooltip("Positional points in local-space")]
  13.         public List<float3> points = new List<float3>()
  14.         {
  15.             new float3(-1f, 0f, -5f),
  16.             new float3(1f, 0f, -2.5f),
  17.             new float3(-1f, 0f, 0),
  18.             new float3(1f, 0f, 2.5f),
  19.             new float3(-1f, 0f, 5f),
  20.         };
  21.        
  22.         [Space]
  23.        
  24.         [Header("Output")]
  25.         public SplineContainer splineContainer;
  26.         public bool closed = false;
  27.         [Tooltip("The error threshold to use. Represents the largest distance between any of the provided points and the curve.")]
  28.         public float errorThreshold = 0.85f;
  29.  
  30.         private void Reset()
  31.         {
  32.             splineContainer = GetComponent<SplineContainer>();
  33.             if (!splineContainer) splineContainer = this.gameObject.AddComponent<SplineContainer>();
  34.         }
  35.        
  36.         private void OnValidate()
  37.         {
  38.             if (!splineContainer)
  39.             {
  40.                 throw new Exception("Failed to create a spline from a position list. No SplineContainer is assigned to the component");
  41.             }
  42.             int pointCount = points.Count;
  43.  
  44.             if (pointCount < 2)
  45.             {
  46.                 throw new Exception("Failed to create a spline from a position list. At least 2 points need to be provided");
  47.             }
  48.            
  49.             //First, delete all existing splines
  50.             for (int s = 0; s < splineContainer.Splines.Count; s++)
  51.             {
  52.                 splineContainer.RemoveSpline(splineContainer.Splines[s]);
  53.             }
  54.            
  55.             var pointsCopy = new List<float3>(points);
  56.             //Convert points from world-space to local-space
  57.             for (int i = 0; i < points.Count; i++)
  58.             {
  59.                 pointsCopy[i] = splineContainer.transform.InverseTransformPoint(points[i]);
  60.             }
  61.  
  62.             SplineUtility.FitSplineToPoints(pointsCopy, errorThreshold, closed, out var spline);
  63.  
  64.             //Adding a spline automatically rebuilds the mesh
  65.             splineContainer.AddSpline(spline);
  66.         }
  67.  
  68.         private void OnDrawGizmosSelected()
  69.         {
  70.             if (!splineContainer) return;
  71.  
  72.             Gizmos.matrix = splineContainer.transform.localToWorldMatrix;
  73.             foreach (Vector3 p in points)
  74.             {
  75.                 Gizmos.DrawSphere(p, 0.25f);
  76.             }
  77.         }
  78.     }
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement