Utilities
NWH Common ships math, geometry, unit-conversion, and control helpers. The examples below use only the current public API.
Namespaces
| Type | Namespace |
|---|---|
MathUtility |
NWH.Common |
GeomUtility |
NWH.Common.Utility |
UnitConverter |
NWH.Common.Utility |
PIDController |
NWH.Common.Utility |
AnimationCurveExtensions |
NWH.Common.Utility |
ArrayExtensions |
NWH.Common.Utility |
GameObjectExtensions |
NWH.Common.Utility |
QuaternionExtensions |
NWH.Common.Utility |
MathUtility
MathUtility.ClampWithRemainder(ref float x, in float range, out float remainder) clamps x to
[-range, range] and returns the signed overflow.
Partial example (place these statements inside a method):
using NWH.Common;
float steering = 1.25f;
MathUtility.ClampWithRemainder(ref steering, 1f, out float overflow);
// steering == 1f; overflow == 0.25f
ClampWithRemainder is the complete public surface of MathUtility in the current Common package.
Use Unity's Mathf methods for ordinary clamp, interpolation, and comparison operations.
GeomUtility
GeomUtility contains vector, quadrilateral, mesh, and transform helpers. Frequently used current
members include:
| Member | Purpose |
|---|---|
Vector3.NearEqual(Vector3, float) |
Compare vectors using a squared-distance threshold |
Vector3.ClampMagnitude(float, float) |
Clamp a vector to a minimum and maximum magnitude |
Vector3.Perpendicular() |
Return a perpendicular vector |
NearestPointOnLine(Vector3, Vector3, Vector3) |
Project a point onto a line |
FindDistanceToSegment(Vector3, Vector3, Vector3) |
Distance from a point to a finite segment, in 3D |
SquareDistance(Vector3, Vector3) |
Squared distance without a square root |
AreaFromThreePoints(...) / AreaFromFourPoints(...) |
Triangle or quadrilateral area |
MeshArea(Mesh) / ProjectedMeshArea(Mesh, Vector3) |
Surface or projected mesh area |
VolumeOfMesh(Mesh) |
Signed-triangle-based mesh volume |
TransformPointUnscaled(...) / InverseTransformPointUnscaled(...) |
Transform a point without scale |
QuadLerp(...) |
Bilinear interpolation over four corners |
Partial example (place these statements inside a method):
using NWH.Common.Utility;
using UnityEngine;
Vector3 point = new(2f, 1f, 5f);
Vector3 nearest = GeomUtility.NearestPointOnLine(
Vector3.zero,
Vector3.forward,
point);
bool close = nearest.NearEqual(new Vector3(0f, 0f, 5f));
float area = GeomUtility.AreaFromThreePoints(
Vector3.zero,
Vector3.right,
Vector3.up);
NearestPointOnLine normalizes the direction it is given, so any non-zero vector along the line
works. Mesh area and volume helpers operate on the mesh data supplied by the caller; they do not
apply a Transform's scale automatically.
UnitConverter
The current converter provides distance, speed, fuel-economy, angular-velocity, and RPM helpers. Method names are part of the API and are case-sensitive.
| Conversion | Current methods |
|---|---|
| Inches / meters | Inch_To_Meter, Meter_To_Inch |
| Meters per second / km/h / mph | MpsToKph, MpsToMph, MphToKph |
| Alternate speed names | Speed_kmhToMph, Speed_kmhToMs, Speed_mphToKmh, Speed_mphToMs, Speed_msToKph, Speed_msToMph |
| Angular velocity / RPM | AngularVelocityToRPM, RPMToAngularVelocity |
| Fuel economy | KmlToL100km, KmlToMpg, L100kmToKml, L100kmToMpg, MpgToKml, MpgToL100km |
Partial example (place these statements inside a method):
using NWH.Common.Utility;
float speedKph = UnitConverter.MpsToKph(20f);
float angularVelocity = UnitConverter.RPMToAngularVelocity(3000f);
float meters = UnitConverter.Inch_To_Meter(24f);
Two things to watch. The mpg conversions use imperial gallons, not US: 1 km/l is 2.824809
imperial mpg and 2.352146 US mpg. And the fuel-economy converters return Mathf.Infinity for a zero
input rather than zero, since zero consumption is infinite efficiency; guard the result before
feeding it to a UI field.
The current class does not provide torque, power, mass, or temperature conversions.
PIDController
Create a controller with proportional, integral, and derivative gains followed by the output
minimum and maximum. On each update, assign SetPoint and ProcessVariable, then call
ControlVariable(deltaTime).
using NWH.Common.Utility;
using UnityEngine;
public sealed class SpeedHoldExample : MonoBehaviour
{
public float currentSpeed;
public float targetSpeed = 20f;
private PIDController _controller;
private void Awake()
{
_controller = new PIDController(
gainProportional: 0.8f,
gainIntegral: 0.1f,
gainDerivative: 0.05f,
outputMin: -1f,
outputMax: 1f);
_controller.integralLimit = 0.5f;
}
private void FixedUpdate()
{
_controller.SetPoint = targetSpeed;
_controller.ProcessVariable = currentSpeed;
float command = _controller.ControlVariable(Time.fixedDeltaTime);
ApplyCommand(command);
}
public void ResetController()
{
_controller.Reset();
}
private void ApplyCommand(float command)
{
// Apply the clamped command to the controlled system.
}
}
Reset() clears the accumulated integral term and aligns the stored previous process value. Call
it when a controller is re-enabled or its target changes discontinuously.
Extension methods
| Member | Purpose |
|---|---|
AnimationCurve.MakeSmooth() |
Return a copy with smoothed tangents |
AnimationCurve.GenerateCurveArray(int resolution = 256) |
Sample a curve into a lookup array |
T[].Fill<T>(params T[]) |
Fill an array with a repeating value |
GameObject.FindBoundsIncludeChildren() |
Combined MeshRenderer bounds of an object and its children |
Transform.GetComponentInParent<T>(bool includeInactive = true) |
Parent lookup that also finds inactive components |
Transform.GetComponentInParentsOrChildren<T>(bool includeInactive = true) |
Parent lookup that falls back to children |
QuaternionExtensions.Lerp / .Slerp / .ScalarMultiply / .Add |
Quaternion math the Unity API does not expose |
GenerateCurveArray samples at j / resolution for j in [0, resolution), so the domain is
[0, 1) and the curve value at exactly 1 is never sampled. That is the usual lookup-table
convention: index = t * resolution maps back exactly. Do not assume the last array entry is the
curve's endpoint.
Editor tools
Tools > NWH > Convert Folder URP to Built-in rewrites the materials in a chosen folder, and in its subfolders, from URP shaders to their Built-in equivalents, mapping the properties it recognizes. The folder must be inside the project. The whole batch is a single undo step, and the console reports how many materials were converted, skipped and failed. It converts materials only: it does not change the project's render pipeline, and there is no reverse conversion.
API Reference
Use the generated API reference for the full GeomUtility member list and exact parameter
descriptions.