Documentation index for AI agents (llms.txt) A Markdown version of every page is available: request the page's source under /docs/, follow the "alternate" link in this page's head, or start from /llms.txt.
Visual Script logo Manual

Closest Point on Segment#

Math / Closest Point on Segment

  • Can Read

  • Cannot Write

Description#

The point of a segment that is the nearest one to another position

Parameters#

Name Description
Position The position the nearest point is measured from
Start The position where the segment begins
End The position where the segment ends

Code#

using System;
using UnityEngine;
using VisualScript.Icons;

namespace VisualScript.Runtime
{
    [Get]

    [Title("Closest Point on Segment")]
    [Category("Math/Closest Point on Segment")]

    [Description("The point of a segment that is the nearest one to another position")]
    [Image(typeof(IconLineStartEnd), ColorTheme.Type.Yellow)]

    [Parameter("Position", "The position the nearest point is measured from")]
    [Parameter("Start", "The position where the segment begins")]
    [Parameter("End", "The position where the segment ends")]

    [Keywords("Vector", "Nearest", "Project", "Line", "Segment", "Clamp", "Snap")]

    [Serializable]
    public class TypeVector3MathClosestPointOnSegment : TypeVector3
    {
        [SerializeField] private GetVector3 m_Position = new GetVector3();
        [SerializeField] private GetVector3 m_Start = new GetVector3();
        [SerializeField] private GetVector3 m_End = new GetVector3();

        public override Vector3 GetPreview(GameObject source) => Closest(
            this.m_Position.GetPreview(source),
            this.m_Start.GetPreview(source),
            this.m_End.GetPreview(source)
        );

        public override Vector3 Get(Args args) => Closest(
            this.m_Position.Get(args),
            this.m_Start.Get(args),
            this.m_End.Get(args)
        );

        private static Vector3 Closest(Vector3 position, Vector3 start, Vector3 end)
        {
            Vector3 segment = end - start;
            float lengthSquared = segment.sqrMagnitude;

            if (lengthSquared <= Mathf.Epsilon) return start;

            float ratio = Mathf.Clamp01(Vector3.Dot(position - start, segment) / lengthSquared);
            return start + segment * ratio;
        }

        public override string ToString()
        {
            return $"Closest to {this.m_Position} on ({this.m_Start}, {this.m_End})";
        }

        protected override SubscriptionMode Subscription => SubscriptionMode.OnChange;
    }
}
Visual Script logoVisual Script © Catsoft Works 2026. All rights reserved.