Skip to content

Commit

Permalink
Add instance any package functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
jellejurre committed Sep 12, 2024
1 parent 23dc3b7 commit 5242505
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 21 deletions.
114 changes: 93 additions & 21 deletions Instancer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,62 @@ public static bool RenameInstancesToggleValidate()
return true;
}

[MenuItem("VRLabs/Create Instance/Any Package")]
public static void CreateInstanceAnyPackageStart()
{
string sourceFolder = EditorUtility.OpenFolderPanel("Select Directory To Copy Assets From", "Assets/", "");

if (sourceFolder == "" || sourceFolder == null)
{
Debug.LogError("No folder selected, please select a folder to copy the assets to.");
return;
}

string targetFolder = EditorUtility.OpenFolderPanel("Select Directory To Copy Assets To", "Assets/", "");

if (targetFolder == "" || targetFolder == null)
{
Debug.LogError("No folder selected, please select a folder to copy the assets to.");
return;
}

if (!targetFolder.Contains(Application.dataPath))
{
Debug.LogError("Selected folder is not in the Assets folder, please select a folder in the Assets directory.");
return;
}

if (renameInstances)
{
EnterValueWindow.Open("", "Enter Old Package name", (oldName) =>
{
EnterValueWindow.Open(oldName, "Enter New Instance name", (newName) =>
{
FinishInstancing(oldName, "Assets" + sourceFolder.Replace(Application.dataPath, ""), new[]
{
".*\\.cs",
".*\\.asmdef",
".*\\.shader",
"package.json"
}, targetFolder, newName, null, true);
});
});
}
else
{
EnterValueWindow.Open("", "Enter New Instance name", (newName) =>
{
FinishInstancing(newName, "Assets" + sourceFolder.Replace(Application.dataPath, ""), new[]
{
".*\\.cs",
".*\\.asmdef",
".*\\.shader",
"package.json"
}, targetFolder, null, null, true);
});
}
}

public static void Instance(string packageName, string installFilePath, string[] excludeRegexs)
{
InstanceWithCallback(packageName, installFilePath, excludeRegexs, null);
Expand All @@ -56,7 +112,7 @@ public static void InstanceWithCallback(string packageName, string installFilePa

if (renameInstances)
{
EnterValueWindow.Open(packageName, (newName) => FinishInstancing(packageName, installFilePath, excludeRegexs, targetFolder, newName, callBack));
EnterValueWindow.Open(packageName, "Enter new Instance Name",(newName) => FinishInstancing(packageName, installFilePath, excludeRegexs, targetFolder, newName, callBack));
return;
}

Expand All @@ -65,11 +121,11 @@ public static void InstanceWithCallback(string packageName, string installFilePa

// Done this way because we need the unity editor to continue running during the rename popup window.
public static void FinishInstancing(string packageName, string installFilePath, string[] excludeRegexs,
string targetFolder, string newInstanceName = null, Action<string> callBack = null)
string targetFolder, string newInstanceName = null, Action<string> callBack = null, bool isAnyPackage = false)
{
targetFolder = PrepareTargetFolderPath(targetFolder, packageName);
targetFolder = PrepareTargetFolderPath(targetFolder, newInstanceName != null ? newInstanceName : packageName);

string sourceFolder = GetSourceFolder(installFilePath);
string sourceFolder = isAnyPackage ? installFilePath : GetSourceFolder(installFilePath);

string[] localAssetPaths = GetLocalAssetPaths(sourceFolder, excludeRegexs);

Expand Down Expand Up @@ -190,31 +246,45 @@ static void FixReferences(string[] localAssetPaths, string sourceFolder, string
foreach (string localAssetPath in localAssetPaths)
{
string targetAssetPath = targetFolder + localAssetPath;
UnityEngine.Object[] targetAssets = AssetDatabase.LoadAllAssetsAtPath(targetAssetPath);
UnityEngine.Object[] targetAssets = AssetDatabase.LoadAllAssetsAtPath(targetAssetPath).Where(x => x != null).ToArray();
foreach (var targetAsset in targetAssets)
{
SerializedObject serializedObject = new SerializedObject(targetAsset);
SerializedProperty property = serializedObject.GetIterator();
bool changed = false;
bool newChanged = false;
do
{
if (property.propertyType == SerializedPropertyType.ObjectReference)
{
if (property.objectReferenceValue != null)
{
property.objectReferenceValue = GetTargetVersion(sourceFolder, targetFolder, property.objectReferenceValue);
Object newObject;
(newObject, newChanged) = GetTargetVersion(sourceFolder, targetFolder, property.objectReferenceValue);
if (newChanged)
{
changed = true;
property.objectReferenceValue = newObject;
}
}
}

if (property.propertyType == SerializedPropertyType.ExposedReference)
{
if (property.exposedReferenceValue != null)
{
property.exposedReferenceValue = GetTargetVersion(sourceFolder, targetFolder, property.exposedReferenceValue);
Object newObject;
(newObject, newChanged) = GetTargetVersion(sourceFolder, targetFolder, property.exposedReferenceValue);
if (newChanged)
{
changed = true;
property.exposedReferenceValue = newObject;
}
}
}
} while (property.Next(true));

serializedObject.ApplyModifiedProperties();
if (changed) serializedObject.ApplyModifiedProperties();
}
}
}
Expand All @@ -224,8 +294,8 @@ static void RenameInstance(string[] localAssetPaths, string targetFolder, string
foreach (string localAssetPath in localAssetPaths)
{
string targetAssetPath = targetFolder + localAssetPath;
UnityEngine.Object[] targetAssets = AssetDatabase.LoadAllAssetsAtPath(targetAssetPath);

UnityEngine.Object[] targetAssets = AssetDatabase.LoadAllAssetsAtPath(targetAssetPath).Where(x => x != null).ToArray();
if (targetAssets.Length == 0) continue;
string[] possibleNames = new []{packageName, packageName.Replace("-", ""), packageName.Replace("-", " ")};

String fileName = Path.GetFileName(targetAssetPath);
Expand All @@ -249,7 +319,7 @@ static void RenameInstance(string[] localAssetPaths, string targetFolder, string
{
string value = property.stringValue;
if (value == null) continue;

foreach (string possibleName in possibleNames)
{
if (value.StartsWith(possibleName) && !value.StartsWith(newInstanceName))
Expand All @@ -270,41 +340,43 @@ public static string ReplaceAtStart(string str, string oldValue, string newValue
{
return newValue + str.Substring(oldValue.Length);
}
private static Object GetTargetVersion(string sourceFolder, string targetFolder, Object target)
private static (Object, bool) GetTargetVersion(string sourceFolder, string targetFolder, Object target)
{
string targetPath = AssetDatabase.GetAssetPath(target);
if (targetPath.StartsWith(sourceFolder))
{
string newTargetPath = targetFolder + targetPath.Remove(0, sourceFolder.Length);
return AssetDatabase.LoadAllAssetsAtPath(newTargetPath).Where(obj => obj.GetType() == target.GetType()).FirstOrDefault(x => x.name == target.name);
string newTargetPath = targetFolder + targetPath.Remove(0, sourceFolder.Length);
Object newObject = AssetDatabase.LoadAllAssetsAtPath(newTargetPath).Where(obj => obj.GetType() == target.GetType()).FirstOrDefault(x => x.name == target.name);
return (newObject, newObject != null);
}

return target;
return (target, false);
}
}

public class EnterValueWindow : EditorWindow
{
private string value = "";
private string windowTitle;
private Action<string> callBack;
public static void Open(string packageName, Action<string> callBack)
public static void Open(string packageName, string windowTitle, Action<string> callBack)
{
var window = GetWindow<EnterValueWindow>("Enter new Instance Name");
var window = GetWindow<EnterValueWindow>(windowTitle);
window.windowTitle = windowTitle;
window.value = packageName;
window.callBack = callBack;
window.position = new Rect(Screen.width / 2, Screen.height / 2, 250, 100);
window.Show();
}

private void OnGUI()
{
EditorGUILayout.LabelField("New Instance Name:", EditorStyles.boldLabel);
EditorGUILayout.LabelField(windowTitle, EditorStyles.boldLabel);
value = EditorGUILayout.TextField(value);

if (GUILayout.Button("Submit"))
{
callBack(value);
{
Close();
callBack(value);
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ VRLabs' Instancing system that copies files over for use in the Assets directory

* Click the `VRLabs/[PackageName]` button in the toolbar and select an output folder to copy to.

### Instance Any Package

* You can use the `VRLabs/Instance Any Package` button to instance and rename any package in the Assets folder.
* It will ask you for the package name and the new instance name.
* Note that it will only rename things that start with the package name, so if you have e.g. controller parameters that start with a different name, they wont be renamed and will clash with the initial package.
* Note that materials will reference shaders from the original package as shaders are not copied over.
* Note that big packages might crash your Unity Editor and cancel the renames, so notall packages will work.

## Contributors

* [Jelle](https://jellejurre.dev)
Expand Down

0 comments on commit 5242505

Please sign in to comment.