-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"EditorFolderRoot": "Assets/StarterAssets/", | ||
"PackagesToAdd": [ | ||
"com.unity.cinemachine", | ||
"com.unity.inputsystem" | ||
] | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
using System; | ||
using System.Linq; | ||
using StarterAssetsPackageChecker; | ||
using UnityEditor; | ||
using UnityEngine; | ||
using Object = UnityEngine.Object; | ||
#if STARTER_ASSETS_PACKAGES_CHECKED | ||
using Cinemachine; | ||
#endif | ||
|
||
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; | ||
|
||
/// <summary> | ||
/// Deletes the scripting define set by the Package Checker. | ||
/// See Assets/Editor/PackageChecker/PackageChecker.cs for more information | ||
/// </summary> | ||
[MenuItem(MenuRoot + "/Reinstall Dependencies", false)] | ||
static void ResetPackageChecker() | ||
{ | ||
PackageChecker.RemovePackageCheckerScriptingDefine(); | ||
} | ||
|
||
#if STARTER_ASSETS_PACKAGES_CHECKED | ||
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("/StarterAssets/")) | ||
{ | ||
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; | ||
} | ||
#endif | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace StarterAssets | ||
{ | ||
public partial class StarterAssetsDeployMenu : ScriptableObject | ||
{ | ||
// prefab paths | ||
private const string PlayerArmaturePrefabName = "PlayerArmature"; | ||
|
||
#if STARTER_ASSETS_PACKAGES_CHECKED | ||
/// <summary> | ||
/// Check the Armature, main camera, cinemachine virtual camera, camera target and references | ||
/// </summary> | ||
[MenuItem(MenuRoot + "/Reset Third Person Controller Armature", false)] | ||
static void ResetThirdPersonControllerArmature() | ||
{ | ||
var thirdPersonControllers = FindObjectsOfType<ThirdPersonController>(); | ||
var player = thirdPersonControllers.FirstOrDefault(controller => | ||
controller.GetComponent<Animator>() && controller.CompareTag(PlayerTag)); | ||
|
||
GameObject playerGameObject = null; | ||
|
||
// player | ||
if (player == null) | ||
{ | ||
if (TryLocatePrefab(PlayerArmaturePrefabName, null, new[] { typeof(ThirdPersonController), typeof(StarterAssetsInputs) }, out GameObject prefab, out string _)) | ||
{ | ||
HandleInstantiatingPrefab(prefab, out playerGameObject); | ||
} | ||
else | ||
{ | ||
Debug.LogError("Couldn't find player armature prefab"); | ||
} | ||
} | ||
else | ||
{ | ||
playerGameObject = player.gameObject; | ||
} | ||
|
||
if (playerGameObject != null) | ||
{ | ||
// cameras | ||
CheckCameras(playerGameObject.transform, GetThirdPersonPrefabPath()); | ||
} | ||
} | ||
|
||
[MenuItem(MenuRoot + "/Reset Third Person Controller Capsule", false)] | ||
static void ResetThirdPersonControllerCapsule() | ||
{ | ||
var thirdPersonControllers = FindObjectsOfType<ThirdPersonController>(); | ||
var player = thirdPersonControllers.FirstOrDefault(controller => | ||
!controller.GetComponent<Animator>() && controller.CompareTag(PlayerTag)); | ||
|
||
GameObject playerGameObject = null; | ||
|
||
// player | ||
if (player == null) | ||
{ | ||
if (TryLocatePrefab(PlayerCapsulePrefabName, null, new[] { typeof(ThirdPersonController), typeof(StarterAssetsInputs) }, out GameObject prefab, out string _)) | ||
{ | ||
HandleInstantiatingPrefab(prefab, out playerGameObject); | ||
} | ||
else | ||
{ | ||
Debug.LogError("Couldn't find player capsule prefab"); | ||
} | ||
} | ||
else | ||
{ | ||
playerGameObject = player.gameObject; | ||
} | ||
|
||
if (playerGameObject != null) | ||
{ | ||
// cameras | ||
CheckCameras(playerGameObject.transform, GetThirdPersonPrefabPath()); | ||
} | ||
} | ||
|
||
static string GetThirdPersonPrefabPath() | ||
{ | ||
if (TryLocatePrefab(PlayerArmaturePrefabName, null, new[] { typeof(ThirdPersonController), typeof(StarterAssetsInputs) }, out GameObject _, out string prefabPath)) | ||
{ | ||
var pathString = new StringBuilder(); | ||
var currentDirectory = new FileInfo(prefabPath).Directory; | ||
while (currentDirectory.Name != "Assets") | ||
{ | ||
pathString.Insert(0, $"/{currentDirectory.Name}"); | ||
currentDirectory = currentDirectory.Parent; | ||
} | ||
|
||
pathString.Insert(0, currentDirectory.Name); | ||
return pathString.ToString(); | ||
} | ||
|
||
return null; | ||
} | ||
#endif | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.