Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ThirdPersonController starter assets added #62

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions Basic/ClientDriven/Assets/StarterAssets.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Basic/ClientDriven/Assets/StarterAssets/Editor.meta

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.

Binary file not shown.

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.

8 changes: 8 additions & 0 deletions Basic/ClientDriven/Assets/StarterAssets/Environment.meta

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.