Unity Runtime Transform Handles is a powerful tool that allows developers to transform objects at runtime using a set of intuitive and professional gizmos. Ideal for building modding tools, runtime editors, or games that require object manipulation, this plugin provides multiple object selection, changeable origin points, auto-scaling handles, configurable snapping, and a full event system.
- Position, Rotation, and Scale handles
- Multiple object selection and manipulation
- Changeable origin points (pivot/center)
- World and Local coordinate space support
- Configurable snapping for precise transformations
- Auto-scaling handles based on camera distance
- Customizable keyboard shortcuts via Settings asset
- Event system for handle interactions
- Works with both Legacy Input Manager and New Input System out of the box
- Unity 2019.4 or higher
- Works with both Legacy Input Manager and New Input System (auto-detected via
ENABLE_INPUT_SYSTEMpreprocessor)
- Open the Package Manager from
Window > Package Manager - Click the
"+" button > Add package from git URL - Enter the following URL:
https://github.com/manaporkun/UnityRuntimeTransformHandles.git#upm
Open Packages/manifest.json and add the following to the dependencies block:
{
"dependencies": {
"com.orkunmanap.runtime-transform-handles": "https://github.com/manaporkun/UnityRuntimeTransformHandles.git#upm"
}
}To install a specific version, append the version tag:
{
"dependencies": {
"com.orkunmanap.runtime-transform-handles": "https://github.com/manaporkun/UnityRuntimeTransformHandles.git#v1.16.0"
}
}After installing the package, set up the required layer:
- Go to
Tools > Transform Handles > Setup Layer - This creates the "TransformHandle" layer needed for handle raycasting
using TransformHandles;
using UnityEngine;
public class SimpleExample : MonoBehaviour
{
private TransformHandleManager _manager;
void Start()
{
_manager = TransformHandleManager.Instance;
}
void CreateHandleForObject(Transform target)
{
// Create a handle for a single object
Handle handle = _manager.CreateHandle(target);
// Subscribe to events
handle.OnInteractionStartEvent += OnHandleStart;
handle.OnInteractionEndEvent += OnHandleEnd;
}
void OnHandleStart(Handle handle)
{
Debug.Log("Started manipulating: " + handle.target.name);
}
void OnHandleEnd(Handle handle)
{
Debug.Log("Finished manipulating: " + handle.target.name);
}
}// Create a handle for multiple objects
List<Transform> targets = new List<Transform> { obj1, obj2, obj3 };
Handle handle = _manager.CreateHandleFromList(targets);
// Add more targets to an existing handle
_manager.AddTarget(newTarget, handle);
// Remove a target from a handle
_manager.RemoveTarget(targetToRemove, handle);// Change handle type
TransformHandleManager.ChangeHandleType(handle, HandleType.Position);
TransformHandleManager.ChangeHandleType(handle, HandleType.Rotation);
TransformHandleManager.ChangeHandleType(handle, HandleType.Scale);
TransformHandleManager.ChangeHandleType(handle, HandleType.All);
// Change coordinate space
_manager.ChangeHandleSpace(handle, Space.World);
_manager.ChangeHandleSpace(handle, Space.Self);
// Configure snapping
handle.positionSnap = new Vector3(0.5f, 0.5f, 0.5f);
handle.rotationSnap = 15f;
handle.scaleSnap = new Vector3(0.1f, 0.1f, 0.1f);Create a settings asset to customize shortcuts, defaults, and highlight color:
Assets > Create > Transform Handles > Settings- Assign to
TransformHandleManager.Settingsin Inspector or via code:
TransformHandleManager.Instance.Settings = mySettings;If no settings asset is assigned, the manager uses its serialized field values.
| Key | Action |
|---|---|
| W | Position mode |
| E | Rotation mode |
| R | Scale mode |
| A | All modes (Position + Rotation + Scale) |
| X | Toggle World/Local space |
| Z | Toggle Pivot/Center origin |
Packages/com.orkunmanap.runtime-transform-handles/
├── Editor/
│ └── TransformHandleLayerSetup.cs # Layer setup menu item
├── Runtime/
│ ├── Materials/ # Handle materials
│ ├── Models/ # Mesh assets (cone, torus, tube)
│ ├── Prefabs/ # Handle and Ghost prefabs
│ ├── Scripts/
│ │ ├── Colliders/ # Runtime mesh collider controllers
│ │ ├── Enums/ # HandleType, HandleAxes, SnappingType, Origin
│ │ ├── HandleComponents/
│ │ │ ├── HandleBase.cs # Abstract base for axis components
│ │ │ ├── Position/ # PositionHandle, PositionAxis, PositionPlane
│ │ │ ├── Rotation/ # RotationHandle, RotationAxis
│ │ │ └── Scale/ # ScaleHandle, ScaleAxis, ScaleGlobal
│ │ ├── Utils/ # InputWrapper, MathUtils, MeshUtils, Singleton
│ │ ├── Ghost.cs # Pivot point for manipulation
│ │ ├── Handle.cs # Per-target handle controller
│ │ ├── TransformGroup.cs # Multi-object grouping
│ │ ├── TransformHandleManager.cs # Central singleton manager
│ │ └── TransformHandleSettings.cs # ScriptableObject settings
│ └── Shader/ # Handle and origin shaders
└── package.json
Central manager for all transform handles in the scene. Handles creation, destruction, and interaction with transform handles.
Key Methods:
CreateHandle(Transform target)- Creates a handle for a single objectCreateHandleFromList(List<Transform> targets)- Creates a handle for multiple objectsAddTarget(Transform target, Handle handle)- Adds an object to an existing handleRemoveTarget(Transform target, Handle handle)- Removes an object from a handleRemoveHandle(Handle handle)- Removes a handleDestroyAllHandles()- Destroys all handlesChangeHandleType(Handle handle, HandleType type)- Changes the handle typeChangeHandleSpace(Handle handle, Space space)- Changes the coordinate space
Main handle component that manages transform manipulation through position, rotation, and scale handles.
Properties:
target- The transform being manipulatedtype- Current handle type (Position, Rotation, Scale, or combinations)space- Coordinate space (Self or World)axes- Active axes (X, Y, Z, or combinations)positionSnap,rotationSnap,scaleSnap- Snapping valuesautoScale- Enable/disable auto-scaling based on camera distance
Events:
OnInteractionStartEvent- Fired when interaction beginsOnInteractionEvent- Fired during interactionOnInteractionEndEvent- Fired when interaction endsOnHandleDestroyedEvent- Fired when handle is destroyed
Represents an empty transform object that serves as the pivot point for handle manipulation. The Ghost transform is instantiated when a handle is created and updates its position, rotation, and scale based on user input.
Groups and transforms multiple Unity Transform objects together. Contains methods to add/remove transforms and update the group's position, rotation, and scale collectively.
public enum HandleType
{
Position,
Rotation,
Scale,
PositionRotation,
PositionScale,
RotationScale,
All
}Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes using Conventional Commits:
feat: add new feature(triggers minor version bump)fix: resolve bug(triggers patch version bump)feat!: breaking change(triggers major version bump)
- Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Releases are automated via GitHub Actions based on commit messages.
This project is licensed under the MIT License - see the LICENSE file for details.
- Created and maintained by Orkun Manap
If you encounter any issues or have questions, please open an issue on GitHub.

