Skip to content

Instantly share code, notes, and snippets.

@GeorgiyRyaposov
Last active April 15, 2021 09:54
Show Gist options
  • Save GeorgiyRyaposov/94796f20901e896d899396db92d99187 to your computer and use it in GitHub Desktop.
Save GeorgiyRyaposov/94796f20901e896d899396db92d99187 to your computer and use it in GitHub Desktop.
Unity models imported with animation import
namespace Assets.Editor
{
public class ModelsImporter : AssetPostprocessor
{
private void OnPreprocessModel()
{
var modelImporter = assetImporter as ModelImporter;
if (modelImporter == null)
{
Debug.LogError("Error during import of models: ModelImporter is null");
return;
}
modelImporter.isReadable = false;
modelImporter.importMaterials = false;
if (modelImporter.assetPath.Contains("Locations"))
{
ImportLocationRelatedItem(modelImporter);
}
if (modelImporter.assetPath.Contains("Skins"))
{
ImportSkinRelatedItem(modelImporter);
}
}
private void ImportSkinRelatedItem(ModelImporter modelImporter)
{
modelImporter.resampleCurves = false;
var animClips = modelImporter.clipAnimations;
if (animClips.Length < 3)
{
animClips = new ModelImporterClipAnimation[3];
animClips[0] = new ModelImporterClipAnimation
{
name = "Walk",
firstFrame = 1,
lastFrame = 30,
loopTime = true
};
animClips[1] = new ModelImporterClipAnimation {
name = "Balancing",
firstFrame = 31,
lastFrame = 75,
loopTime = true
};
animClips[2] = new ModelImporterClipAnimation {
name = "Idle",
firstFrame = 76,
lastFrame = 200,
loopTime = true
};
modelImporter.clipAnimations = animClips;
}
var skinsContainer = Resources.Load<SkinsContainer>("Data/SkinsContainer");
if (skinsContainer == null)
{
Debug.LogError("Failed to find skinsContainer");
return;
}
AssetDatabase.StartAssetEditing();
var skinObj = AssetDatabase.LoadAssetAtPath<Object>(modelImporter.assetPath);
var prefabInstance = (GameObject)GameObject.Instantiate(skinObj);
if (prefabInstance == null)
{
Debug.LogError("Failed to initialize prefab " + modelImporter.assetPath);
return;
}
if (prefabInstance.GetComponent<CubeMeshHelper>() == null)
{
prefabInstance.AddComponent<CubeMeshHelper>();
}
var animator = prefabInstance.GetComponent<Animator>();
if (animator != null)
{
var controllerPath = Path.ChangeExtension(modelImporter.assetPath, "controller");
var controller = AssetDatabase.LoadAssetAtPath<AnimatorController>(controllerPath);
if (controller == null)
{
var animationClips = new List<AnimationClip>();
Object[] objects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
foreach (Object obj in objects)
{
AnimationClip clip = obj as AnimationClip;
if (clip != null)
{
animationClips.Add(clip);
}
}
// Creates the controller
controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
var rootStateMachine = controller.layers[0].stateMachine;
var idleState = rootStateMachine.AddState("Idle");
idleState.motion = animationClips.FirstOrDefault(c => c.name.ToLower() == "idle");
var walkState = rootStateMachine.AddState("Walk");
walkState.motion = animationClips.FirstOrDefault(c => c.name.ToLower() == "walk");
var balancingState = rootStateMachine.AddState("Balancing");
balancingState.motion = animationClips.FirstOrDefault(c => c.name.ToLower() == "balancing");
}
animator.runtimeAnimatorController = controller;
}
if (prefabInstance.GetComponentInChildren<CubeObstacle>() == null)
{
var collectable = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Resources/Prefabs/CollectableCube.prefab");
var collectableInstance = PrefabUtility.InstantiatePrefab(collectable) as GameObject;
if (collectableInstance == null)
{
Debug.LogError("Failed to find collectable prefab");
return;
}
collectableInstance.transform.SetParent(prefabInstance.transform);
collectableInstance.transform.localPosition = Vector3.zero;
}
var renderer = prefabInstance.GetComponentInChildren<SkinnedMeshRenderer>();
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
renderer.receiveShadows = false;
renderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
renderer.useLightProbes = false;
var playerMaterial = AssetDatabase.LoadAssetAtPath<Material>("Assets/Materials/Player.mat");
if (playerMaterial == null)
Debug.LogError("Failed to load player material");
else
renderer.sharedMaterial = playerMaterial;
var prefab = PrefabUtility.CreatePrefab(Path.ChangeExtension(modelImporter.assetPath, "prefab"), prefabInstance, ReplacePrefabOptions.Default);
Object.DestroyImmediate(prefabInstance);
var skinGroupName = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(modelImporter.assetPath)));
if (string.IsNullOrEmpty(skinGroupName))
{
Debug.LogError("failed to find skin grouper directory");
return;
}
var modelName = Path.ChangeExtension(Path.GetFileName(modelImporter.assetPath), string.Empty);
modelName = modelName.Remove(modelName.Length-1); //remove dot at end
var skinGroup = skinsContainer.skinsData.FirstOrDefault(s => s.name.ToLower() == skinGroupName.ToLower());
if (skinGroup != null)
{
var skinData = skinGroup.skins.FirstOrDefault(sd => sd.skinPrefab == prefab || sd.name == modelName);
if (skinData == null)
{
skinGroup.skins.Add(new SkinData
{
name = modelName,
skinPrefab = prefab
});
}
else
{
skinData.skinPrefab = prefab;
}
EditorUtility.SetDirty(skinsContainer);
}
var pool = GameObject.FindObjectOfType<ObjectPool>();
pool.CreatePoolFromEditor(prefab, 5);
AssetDatabase.StopAssetEditing();
AssetDatabase.SaveAssets();
}
private void ImportLocationRelatedItem(ModelImporter modelImporter)
{
var themesContainer = Resources.Load<ThemesContainer>("Data/ThemesContainer");
if (themesContainer == null)
{
Debug.LogError("Failed to find themesContainer");
return;
}
var stageName = Path.GetFileName(Path.GetDirectoryName(modelImporter.assetPath));
if (string.IsNullOrEmpty(stageName))
{
Debug.LogError("Failed to find directory name of " + modelImporter.assetPath);
return;
}
if (stageName.ToLower() == "topstuff")
{
stageName = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(modelImporter.assetPath)));
if (string.IsNullOrEmpty(stageName))
{
Debug.LogError("Failed to find directory name of " + modelImporter.assetPath);
return;
}
}
stageName = stageName.ToLower();
//Debug.Log(stageName);
var modelName = Path.ChangeExtension(Path.GetFileName(modelImporter.assetPath), string.Empty);
var modelPath = modelImporter.assetPath;
//Debug.Log(modelPath);
//Debug.Log("modelName " + modelName);
var model = AssetDatabase.LoadAssetAtPath<GameObject>(modelPath);
if (model == null)
{
Debug.LogError("Failed to find model at path: " + modelPath);
return;
}
var meshFilter = model.GetComponent<MeshFilter>();
var foundType = false;
var themeType = TryGetThemeByPath(modelImporter.assetPath, out foundType);
if (!foundType)
return;
var themeContainer = themesContainer.themesData.FirstOrDefault(t => t.themeType == themeType);
if (themeContainer == null)
{
Debug.LogError("Failed to find type: " + themeType);
return;
}
ThemeStageData themeStageData = null;
foreach (var stageData in themeContainer.themeStagesData)
{
if (stageData.themeStageName.ToLower() == stageName)
{
themeStageData = stageData;
break;
}
}
if (themeStageData == null)
{
themeStageData = new ThemeStageData { themeStageName = stageName };
AddNewObjToArray(ref themeContainer.themeStagesData, themeStageData);
}
AddMeshToStageData(themeStageData, modelName, meshFilter.sharedMesh);
EditorUtility.SetDirty(themesContainer);
}
private static void AddMeshToStageData(ThemeStageData data, string modelName, Mesh mesh)
{
if (modelName.StartsWith("Cube2"))
{
AddMeshToArray(ref data.cubes2, mesh);
}
else if (modelName.StartsWith("Cube3"))
{
AddMeshToArray(ref data.cubes3, mesh);
}
else if (modelName.StartsWith("Cube4"))
{
data.cube4 = mesh;
}
else if (modelName.StartsWith("Cube5"))
{
data.cube5 = mesh;
}
else if (modelName.StartsWith("Cube6"))
{
AddMeshToArray(ref data.cubes6, mesh);
}
else if (modelName.StartsWith("Cube8"))
{
data.cube8 = mesh;
}
else
{
AddMeshToArray(ref data.topStuff, mesh);
}
}
private static void AddMeshToArray(ref Mesh[] meshes, Mesh mesh)
{
if (meshes == null)
{
meshes = new Mesh[1];
meshes[0] = mesh;
return;
}
foreach (var oldMesh in meshes)
{
if (oldMesh.name == mesh.name)
{
//replace?...
//meshes[System.Array.IndexOf(meshes, oldMesh)] = mesh;
return;
}
}
AddNewObjToArray(ref meshes, mesh);
}
private static void AddNewObjToArray<T>(ref T[] objectsArray, T newObj)
{
System.Array.Resize<T>(ref objectsArray, objectsArray.Length + 1);
objectsArray[objectsArray.Length - 1] = newObj;
}
private static ThemeType TryGetThemeByPath(string path, out bool success)
{
if (path.Contains(ThemeType.Canyon.ToString().ToLower()))
{
success = true;
return ThemeType.Canyon;
}
Debug.LogError("failed to find theme by path " + path);
success = false;
return ThemeType.Canyon;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment