243 lines
8.6 KiB
C#
243 lines
8.6 KiB
C#
using Codice.CM.SEIDInfo;
|
|
using IconsCreationTool.Editor.Core;
|
|
using JetBrains.Annotations;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Unity.EditorCoroutines.Editor;
|
|
using Unity.VisualScripting;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using static UnityEditor.Experimental.GraphView.GraphView;
|
|
using static UnityEngine.GraphicsBuffer;
|
|
|
|
public class PrefabCreatorTool
|
|
{
|
|
static BlockDataCreatorEditor BDCE = new BlockDataCreatorEditor();
|
|
static IconsCreator IC = new IconsCreator();
|
|
|
|
[MenuItem("Youssef Tools/Create Prefab", false, 0)]
|
|
static void CreatePrefab()
|
|
{
|
|
string SavedPath = EditorPrefs.GetString("YoussefTool_SettingsPath", "");
|
|
if (string.IsNullOrEmpty(SavedPath))
|
|
{
|
|
Debug.Log("Couldn't find settings script. Please add it via the setup window");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Found settings scriptable object");
|
|
}
|
|
PrefabCreatorSettings Settings = AssetDatabase.LoadAssetAtPath<PrefabCreatorSettings>(SavedPath);
|
|
if (Settings == null)
|
|
{
|
|
Debug.LogError("The assigned settings file was deleted or moved. Please reassign in the Settings Manager.");
|
|
return;
|
|
}
|
|
|
|
GameObject[] selectedObjects = Selection.gameObjects;
|
|
int count = selectedObjects.Length;
|
|
|
|
if (count == 0)
|
|
{
|
|
Debug.LogError("Please select a GameObject in the hierarchy first");
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
float progress = (float)i / count;
|
|
EditorUtility.DisplayProgressBar("Creating Prefabs", $"Processing {selectedObjects[i].name}...", progress);
|
|
|
|
GameObject instObj = Object.Instantiate(selectedObjects[i]);
|
|
Undo.RegisterCreatedObjectUndo(instObj, "Create Prefab");
|
|
|
|
CreateStart(instObj, Settings);
|
|
}
|
|
|
|
EditorUtility.ClearProgressBar();
|
|
}
|
|
|
|
|
|
// Logic (ngl Youssef cooked here)
|
|
public static void CreateStart(GameObject Target, PrefabCreatorSettings Settings)
|
|
{
|
|
|
|
if (Target.transform.childCount == 0)
|
|
{
|
|
Debug.LogError("Please setup the target object by supplying it with the spheres as children");
|
|
return;
|
|
}
|
|
|
|
// Main mesh part
|
|
var MC = Settings.MainComponents;
|
|
|
|
if (MC.GrabInteractable != null)
|
|
{
|
|
var scriptType = MC.GrabInteractable.GetClass();
|
|
if (scriptType == null || !typeof(GrabInteractable).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Grab Interactable script is incorrect or does not inherit from GrabInteractable");
|
|
else
|
|
{
|
|
var gInteract = Target.AddComponent(scriptType);
|
|
}
|
|
}
|
|
|
|
if (MC.MechanicalBlock != null)
|
|
{
|
|
var scriptType = MC.MechanicalBlock.GetClass();
|
|
if (scriptType == null || !typeof(Block).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Block script is incorrect!");
|
|
else
|
|
{
|
|
var mBlock = Target.AddComponent(scriptType);
|
|
}
|
|
}
|
|
|
|
if (MC.AttachableBlock != null)
|
|
{
|
|
var scriptType = MC.AttachableBlock.GetClass();
|
|
if (scriptType == null || !typeof(AttachableBlock).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Attachable Block script is incorrect!");
|
|
else
|
|
{
|
|
Target.AddComponent(scriptType);
|
|
BlockType layerM = Settings.BlockSettings.attachableBlock.Type;
|
|
Target.GetComponent<AttachableBlock>().SetBlockType(layerM);
|
|
}
|
|
}
|
|
|
|
if (MC.SocketContainer != null)
|
|
{
|
|
var scriptType = MC.SocketContainer.GetClass();
|
|
if (scriptType == null || !typeof(SocketContainer).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Socket Container script is incorrect!");
|
|
else
|
|
{
|
|
var sContain = Target.AddComponent(scriptType);
|
|
}
|
|
}
|
|
|
|
if (MC.PlacementValidator != null)
|
|
{
|
|
var scriptType = MC.PlacementValidator.GetClass();
|
|
if (scriptType == null || !typeof(IValidator).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Validator script is incorrect!");
|
|
else
|
|
{
|
|
var pValidate = Target.AddComponent(scriptType);
|
|
LayerMask Coll = Settings.BlockSettings.validator.CollisionLayerMask;
|
|
Target.GetComponent<IValidator>().SetLayerMask(Coll);
|
|
}
|
|
}
|
|
|
|
if (MC.ContainerInit != null)
|
|
{
|
|
var scriptType = MC.ContainerInit.GetClass();
|
|
if (scriptType == null || !typeof(BlockContainerInit).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Block Container Init script is incorrect");
|
|
else
|
|
{
|
|
var cInit = Target.AddComponent(scriptType);
|
|
}
|
|
}
|
|
|
|
Rigidbody RB = Target.AddComponent<Rigidbody>();
|
|
MeshCollider MeshC = Target.AddComponent<MeshCollider>();
|
|
|
|
MeshC.convex = false;
|
|
RB.isKinematic = true;
|
|
RB.useGravity = false;
|
|
|
|
Target.transform.localEulerAngles = new Vector3(0, 0, 0);
|
|
|
|
var Tlayer = Settings.BlockSettings.MiscellaneousSettings.BlockLayer;
|
|
|
|
// Children part
|
|
Transform[] Children = Target.GetComponentsInChildren<Transform>().Where(x => x != Target.transform).ToArray();
|
|
|
|
if (Children.Length < 0)
|
|
Debug.Log($"No children exist for object {Target.name}, please make sure the object has children or add sockets manually");
|
|
|
|
else
|
|
{
|
|
foreach (Transform t in Children)
|
|
{
|
|
Object.DestroyImmediate(t.GetComponent<MeshRenderer>());
|
|
if (MC.SocketPoint != null)
|
|
{
|
|
var scriptType = MC.SocketPoint.GetClass();
|
|
if (scriptType == null || !typeof(SocketPoint).IsAssignableFrom(scriptType))
|
|
Debug.LogError("The Socket Point script is incorrect!");
|
|
else
|
|
{
|
|
t.gameObject.AddComponent(scriptType);
|
|
var sPoint = t.gameObject.GetComponent<SocketPoint>();
|
|
sPoint.SetSocketRadius(Settings.BlockSettings.socketPoint.SocketRadius);
|
|
}
|
|
}
|
|
Rigidbody rb = t.AddComponent<Rigidbody>();
|
|
CapsuleCollider sc = t.AddComponent<CapsuleCollider>();
|
|
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
sc.isTrigger = true;
|
|
t.localPosition = new Vector3(t.localPosition.x, t.localPosition.y / 2, t.localPosition.z);
|
|
t.localScale = new Vector3(0.006f, 0.006f, 0.006f);
|
|
}
|
|
}
|
|
|
|
if (!Directory.Exists(Settings.SavePath))
|
|
{
|
|
Directory.CreateDirectory(Settings.SavePath);
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
string fileName = Settings.Name + Settings.Suffix;
|
|
string localPath = $"{Settings.SavePath}/{fileName}.prefab";
|
|
|
|
if (Settings.IteratedNumbering || !Settings.OverwriteExisting)
|
|
{
|
|
localPath = AssetDatabase.GenerateUniqueAssetPath(localPath);
|
|
}
|
|
|
|
bool success;
|
|
GameObject prefabAsset = PrefabUtility.SaveAsPrefabAsset(Target, localPath, out success);
|
|
|
|
if (success)
|
|
{
|
|
Debug.Log($"Success! Prefab created at: {localPath}");
|
|
EditorGUIUtility.PingObject(prefabAsset);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Prefab failed to save. Check the Save Path in Settings.");
|
|
}
|
|
var BD = BDCE.CreateBlockData(prefabAsset);
|
|
prefabAsset.GetComponent<MechanicalBlock>().SetBlockData(BD);
|
|
if (Settings.categoryData)
|
|
{
|
|
var Category = Settings.categoryData;
|
|
BD.associatedCategory = Category;
|
|
Category.blocks.Add(BD);
|
|
}
|
|
|
|
List<Object> list = new List<Object>();
|
|
list.Add(prefabAsset);
|
|
|
|
IconBackgroundData IBD = new IconBackgroundData(IconBackground.None, Color.white, Texture2D.whiteTexture);
|
|
IconsCreatorData ICD = new IconsCreatorData(1024, 0, null, null, IBD, list, true);
|
|
IC.SetData(ICD);
|
|
IC.CreateIcon();
|
|
|
|
PrefabUtility.RecordPrefabInstancePropertyModifications(prefabAsset);
|
|
EditorUtility.SetDirty(prefabAsset);
|
|
AssetDatabase.SaveAssetIfDirty(prefabAsset);
|
|
AssetDatabase.Refresh();
|
|
|
|
Object.DestroyImmediate(Target);
|
|
}
|
|
}
|