Rasagar/Assets/Starter Assets/Editor/StarterAssetsDeployMenu.cs

154 lines
6.2 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
using Cinemachine;
namespace StarterAssets
{
// This class needs to be a scriptable object to support dynamic determination of StarterAssets install path
public partial class StarterAssetsDeployMenu : ScriptableObject
{
public const string MenuRoot = "Tools/Starter Assets";
// prefab names
private const string MainCameraPrefabName = "MainCamera";
private const string PlayerCapsulePrefabName = "PlayerCapsule";
// names in hierarchy
private const string CinemachineVirtualCameraName = "PlayerFollowCamera";
// tags
private const string PlayerTag = "Player";
private const string MainCameraTag = "MainCamera";
private const string CinemachineTargetTag = "CinemachineTarget";
private static GameObject _cinemachineVirtualCamera;
private static void CheckCameras(Transform targetParent, string prefabFolder)
{
CheckMainCamera(prefabFolder);
GameObject vcam = GameObject.Find(CinemachineVirtualCameraName);
if (!vcam)
{
if (TryLocatePrefab(CinemachineVirtualCameraName, new string[]{prefabFolder}, new[] { typeof(CinemachineVirtualCamera) }, out GameObject vcamPrefab, out string _))
{
HandleInstantiatingPrefab(vcamPrefab, out vcam);
_cinemachineVirtualCamera = vcam;
}
else
{
Debug.LogError("Couldn't find Cinemachine Virtual Camera prefab");
}
}
else
{
_cinemachineVirtualCamera = vcam;
}
GameObject[] targets = GameObject.FindGameObjectsWithTag(CinemachineTargetTag);
GameObject target = targets.FirstOrDefault(t => t.transform.IsChildOf(targetParent));
if (target == null)
{
target = new GameObject("PlayerCameraRoot");
target.transform.SetParent(targetParent);
target.transform.localPosition = new Vector3(0f, 1.375f, 0f);
target.tag = CinemachineTargetTag;
Undo.RegisterCreatedObjectUndo(target, "Created new cinemachine target");
}
CheckVirtualCameraFollowReference(target, _cinemachineVirtualCamera);
}
private static void CheckMainCamera(string inFolder)
{
GameObject[] mainCameras = GameObject.FindGameObjectsWithTag(MainCameraTag);
if (mainCameras.Length < 1)
{
// if there are no MainCameras, add one
if (TryLocatePrefab(MainCameraPrefabName, new string[]{inFolder}, new[] { typeof(CinemachineBrain), typeof(Camera) }, out GameObject camera, out string _))
{
HandleInstantiatingPrefab(camera, out _);
}
else
{
Debug.LogError("Couldn't find Starter Assets Main Camera prefab");
}
}
else
{
// make sure the found camera has a cinemachine brain (we only need 1)
if (!mainCameras[0].TryGetComponent(out CinemachineBrain cinemachineBrain))
mainCameras[0].AddComponent<CinemachineBrain>();
}
}
private static void CheckVirtualCameraFollowReference(GameObject target,
GameObject cinemachineVirtualCamera)
{
var serializedObject =
new SerializedObject(cinemachineVirtualCamera.GetComponent<CinemachineVirtualCamera>());
var serializedProperty = serializedObject.FindProperty("m_Follow");
serializedProperty.objectReferenceValue = target.transform;
serializedObject.ApplyModifiedProperties();
}
private static bool TryLocatePrefab(string name, string[] inFolders, System.Type[] requiredComponentTypes, out GameObject prefab, out string path)
{
// Locate the player armature
string[] allPrefabs = AssetDatabase.FindAssets("t:Prefab", inFolders);
for (int i = 0; i < allPrefabs.Length; ++i)
{
string assetPath = AssetDatabase.GUIDToAssetPath(allPrefabs[i]);
if (assetPath.Contains("/com.unity.starter-assets/"))
{
Object loadedObj = AssetDatabase.LoadMainAssetAtPath(assetPath);
if (PrefabUtility.GetPrefabAssetType(loadedObj) != PrefabAssetType.NotAPrefab &&
PrefabUtility.GetPrefabAssetType(loadedObj) != PrefabAssetType.MissingAsset)
{
GameObject loadedGo = loadedObj as GameObject;
bool hasRequiredComponents = true;
foreach (var componentType in requiredComponentTypes)
{
if (!loadedGo.TryGetComponent(componentType, out _))
{
hasRequiredComponents = false;
break;
}
}
if (hasRequiredComponents)
{
if (loadedGo.name == name)
{
prefab = loadedGo;
path = assetPath;
return true;
}
}
}
}
}
prefab = null;
path = null;
return false;
}
private static void HandleInstantiatingPrefab(GameObject prefab, out GameObject prefabInstance)
{
prefabInstance = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
Undo.RegisterCreatedObjectUndo(prefabInstance, "Instantiate Starter Asset Prefab");
prefabInstance.transform.localPosition = Vector3.zero;
prefabInstance.transform.localEulerAngles = Vector3.zero;
prefabInstance.transform.localScale = Vector3.one;
}
}
}