Initial Commit

This commit is contained in:
jellejurre
2025-07-19 01:03:02 +02:00
commit e7904e3140
304 changed files with 22521 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
{
"name": "BetterUnityEditor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,86 @@
using UnityEngine;
using UnityEditor;
using System.IO;
//Adds 3 new Assets context menu items: Copy, Cut & Paste
namespace BetterUnity
{
public class CopyCutPaste
{
private static bool copy;
private static string[] _tempGUID;
private static string[] assetsGUID;
[MenuItem("Assets/Copy", false, 20)]
private static void Copy()
{
copy = true;
assetsGUID = _tempGUID;
}
[MenuItem("Assets/Cut", false, 20)]
private static void Cut()
{
copy = false;
assetsGUID = _tempGUID;
}
[MenuItem("Assets/Paste", false, 20)]
private static void Paste()
{
string folderPath = AssetDatabase.GetAssetPath(Selection.activeObject);
Move(folderPath, assetsGUID, copy);
}
public static void Move(string destination, string[] assetsGUID, bool copy)
{
if (!string.IsNullOrEmpty(Path.GetExtension(destination)) && !AssetDatabase.IsValidFolder(destination))
destination = Path.GetDirectoryName(destination);
try
{
AssetDatabase.StartAssetEditing();
foreach (string s in assetsGUID)
{
string filePath = AssetDatabase.GUIDToAssetPath(s);
string fileName = Path.GetFileName(filePath);
if (copy)
{
AssetDatabase.CopyAsset(filePath, AssetDatabase.GenerateUniqueAssetPath(destination + "/" + fileName));
}
else
{
if (destination + "/" + fileName != filePath)
AssetDatabase.MoveAsset(filePath, AssetDatabase.GenerateUniqueAssetPath(destination + "/" + fileName));
}
}
}
catch(System.Exception e) { Debug.LogError(e);}
finally
{
AssetDatabase.StopAssetEditing();
}
}
[MenuItem("Assets/Copy", true, 20)]
[MenuItem("Assets/Cut", true, 20)]
private static bool ValidateSelect()
{
_tempGUID = Selection.assetGUIDs;
return _tempGUID.Length > 0;
}
[MenuItem("Assets/Paste", true, 20)]
private static bool ValidateMove()
{
return (assetsGUID != null && assetsGUID.Length > 0 && Selection.activeObject);
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CopyGUID : MonoBehaviour
{
[MenuItem("Assets/Copy GUID")]
private static void CopyGUIDMethod()
{
if (Selection.assetGUIDs.Length > 0)
EditorGUIUtility.systemCopyBuffer = Selection.assetGUIDs[0];
}
}

View File

@@ -0,0 +1,36 @@
using UnityEditor;
using System.IO;
//Adds new context menu item: Assets > Create > Text File
//Creates a new text file in the destination folder
namespace BetterUnity
{
public class CreateTxt
{
[MenuItem("Assets/Create/Text File", false, 20)]
private static void CreateMyHeckingTextFile()
{
//Get the path of what was used on right click
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
//If using Unity's toolbar context menu. There may be no selection. So use the main Assets folder.
if (string.IsNullOrWhiteSpace(path)) path = "Assets";
//If it's a folder, use it. If it's a file, get the parent folder. Name it "New Text File".
string txtPath = (AssetDatabase.IsValidFolder(path) ? path : Path.GetDirectoryName(path)) + "/New Text File.txt";
//Make it unique
txtPath = AssetDatabase.GenerateUniqueAssetPath(txtPath);
//Create it and Dispose of the StreamWriter
File.CreateText(txtPath).Dispose();
//Import it
AssetDatabase.ImportAsset(txtPath);
//Highlight it
EditorGUIUtility.PingObject(AssetDatabase.LoadMainAssetAtPath(txtPath));
}
}
}

View File

@@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
//Copy the path from the root transform to the target GameObject
namespace BetterUnity
{
public class GOCopyPath
{
private const bool log = true;
[MenuItem("GameObject/Copy Path", false, -1000)]
private static void GameObjectCopyPath()
{
var go = Selection.activeGameObject;
if (!go)
{
Debug.LogWarning("No GameObject selected");
return;
}
string path = AnimationUtility.CalculateTransformPath(go.transform, go.transform.root);
if (log) Debug.Log("Path: " + path);
GUIUtility.systemCopyBuffer = path;
}
}
}

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEditor;
//Replicates Unity's Transform Inspector but adds new Context Menu to each field.
//Allows you to Copy, Paste and Reset any transform field individually.
namespace BetterUnity
{
[CanEditMultipleObjects]
[CustomEditor(typeof(Transform))]
public class TransformEditor : Editor
{
private static System.Type RotationGUIType;
private static MethodInfo RotationGUIEnableMethod;
private static MethodInfo DrawRotationGUIMethod;
private object rotationGUI;
private SerializedProperty m_LocalPosition;
private SerializedProperty m_LocalRotation;
private SerializedProperty m_LocalScale;
private static Vector3 copiedValues;
private static bool hasCopiedValues;
private static int contextChoice;
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_LocalPosition, positionContent);
Rect posRect = GUILayoutUtility.GetLastRect();
DrawRotationGUIMethod.Invoke(rotationGUI, null);
Rect rotRect = GUILayoutUtility.GetLastRect();
EditorGUILayout.PropertyField(m_LocalScale, scaleContent);
Rect scaleRect = GUILayoutUtility.GetLastRect();
serializedObject.ApplyModifiedProperties();
Event e = Event.current;
Vector2 m = e.mousePosition;
if (e.type == EventType.ContextClick)
{
contextChoice = 0;
if (posRect.Contains(m)) contextChoice = 1;
if (rotRect.Contains(m)) contextChoice = 2;
if (scaleRect.Contains(m)) contextChoice = 3;
if (contextChoice > 0)
{
GenericMenu myMenu = new GenericMenu();
myMenu.AddItem(new GUIContent("Copy"), false, CopyFieldValues);
myMenu.AddItem(new GUIContent("Paste"), false, hasCopiedValues ? new GenericMenu.MenuFunction(PasteFieldValues) : null);
myMenu.AddItem(new GUIContent("Reset"), false, ResetFieldValues);
myMenu.ShowAsContext();
}
}
}
private void ResetFieldValues()
{
switch (contextChoice)
{
case 1:
m_LocalPosition.vector3Value = Vector3.zero;
break;
case 2:
m_LocalRotation.quaternionValue = new Quaternion();
break;
case 3:
m_LocalScale.vector3Value = Vector3.one;
break;
}
serializedObject.ApplyModifiedProperties();
}
private void CopyFieldValues()
{
hasCopiedValues = true;
switch (contextChoice)
{
case 1: copiedValues = m_LocalPosition.vector3Value;
break;
case 2:
copiedValues = m_LocalRotation.quaternionValue.eulerAngles;
break;
case 3:
copiedValues = m_LocalScale.vector3Value;
break;
}
}
private void PasteFieldValues()
{
switch (contextChoice)
{
case 1:
m_LocalPosition.vector3Value = copiedValues;
break;
case 2:
var tempQuaternion = new Quaternion {eulerAngles = copiedValues};
m_LocalRotation.quaternionValue = tempQuaternion;
break;
case 3:
m_LocalScale.vector3Value = copiedValues ;
break;
}
serializedObject.ApplyModifiedProperties();
}
private void OnEnable()
{
if (RotationGUIType == null) RotationGUIType = System.Type.GetType("UnityEditor.TransformRotationGUI, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
if (RotationGUIEnableMethod == null) RotationGUIEnableMethod = RotationGUIType.GetMethod("OnEnable", BindingFlags.Public | BindingFlags.Instance);
if (DrawRotationGUIMethod == null) DrawRotationGUIMethod = RotationGUIType.GetMethod("RotationField", Array.Empty<System.Type>());
m_LocalPosition = serializedObject.FindProperty("m_LocalPosition");
m_LocalRotation = serializedObject.FindProperty("m_LocalRotation");
m_LocalScale = serializedObject.FindProperty("m_LocalScale");
if (rotationGUI == null) rotationGUI = Activator.CreateInstance(RotationGUIType);
RotationGUIEnableMethod.Invoke(rotationGUI, new object[] {m_LocalRotation, rotationContent});
}
private GUIContent positionContent = new GUIContent("Position", "The local position of this GameObject relative to the parent.");
private GUIContent rotationContent = new GUIContent("Rotation", "The local rotation of this GameObject relative to the parent.");
private GUIContent scaleContent = new GUIContent("Scale", "The local scaling of this GameObject relative to the parent.");
private const string floatingPointWarning = "Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.";
}
}