Added basic character controller via importing Starter Assets from Unity.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
using Unity.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(CinemachineCamera) }, 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<CinemachineCamera>());
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e75357183ea302c4d998136de2cc9669
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 267961
|
||||
packageName: 'Starter Assets: Character Controllers | URP'
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/Starter Assets/Editor/StarterAssetsDeployMenu.cs
|
||||
uploadId: 721456
|
||||
@@ -0,0 +1,102 @@
|
||||
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";
|
||||
|
||||
/// <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 = FindObjectsByType<ThirdPersonController>(FindObjectsSortMode.None);
|
||||
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 = FindObjectsByType<ThirdPersonController>(FindObjectsSortMode.None);
|
||||
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 != "Packages")
|
||||
{
|
||||
pathString.Insert(0, $"/{currentDirectory.Name}");
|
||||
currentDirectory = currentDirectory.Parent;
|
||||
}
|
||||
|
||||
pathString.Insert(0, currentDirectory.Name);
|
||||
return pathString.ToString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b70f45aa92a641feb261c5d55ce46edf
|
||||
timeCreated: 1621532436
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 267961
|
||||
packageName: 'Starter Assets: Character Controllers | URP'
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/Starter Assets/Editor/ThirdPersonStarterAssetsDeployMenu.cs
|
||||
uploadId: 721456
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a936c3509519d6b48bb3a44692f8695a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "URPWizard",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.RenderPipelines.Universal.Runtime"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "",
|
||||
"define": "USE_URP"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18828b1d1020dde47bec693eef18a5b9
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 267961
|
||||
packageName: 'Starter Assets: Character Controllers | URP'
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/Starter Assets/Editor/URPWizard/URPWizard.asmdef
|
||||
uploadId: 721456
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
#if USE_URP
|
||||
using UnityEngine.Rendering.Universal;
|
||||
#endif
|
||||
|
||||
public class URPWizard : EditorWindow
|
||||
{
|
||||
[InitializeOnLoadMethod]
|
||||
static void OnInitialize()
|
||||
{
|
||||
URPCheck();
|
||||
}
|
||||
|
||||
static void URPCheck()
|
||||
{
|
||||
if (GraphicsSettings.currentRenderPipeline != null)
|
||||
return;
|
||||
|
||||
var request = Client.List();
|
||||
while (!request.IsCompleted) { }
|
||||
|
||||
if (request.Status != StatusCode.Success)
|
||||
return;
|
||||
|
||||
if (request.Result.All(info => info.name != "com.unity.render-pipelines.universal"))
|
||||
{
|
||||
var addRequest = Client.Add("com.unity.render-pipelines.universal");
|
||||
|
||||
while (!addRequest.IsCompleted) { }
|
||||
|
||||
Client.Resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
FindAndAssignPipeline();
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_URP
|
||||
static void FindAndAssignPipeline()
|
||||
{
|
||||
var existingPipelines = AssetDatabase.FindAssets("t:UniversalRenderPipelineAsset");
|
||||
|
||||
if (existingPipelines.Length == 0)
|
||||
{
|
||||
Debug.LogError($"Universal Render Pipeline Asset was not found.\n" +
|
||||
$"Please create one and assign under the Project Settings > Graphics > Scriptable Render Pipeline Settings.");
|
||||
return;
|
||||
}
|
||||
|
||||
var pipeline = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineAsset>(AssetDatabase.GUIDToAssetPath(existingPipelines[0]));
|
||||
GraphicsSettings.defaultRenderPipeline = pipeline;
|
||||
}
|
||||
|
||||
class PipelineAssetProcessor : AssetPostprocessor
|
||||
{
|
||||
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
|
||||
{
|
||||
//if we have no pipeline set, we try to find one as one may have been imported
|
||||
if (GraphicsSettings.currentRenderPipeline != null)
|
||||
return;
|
||||
|
||||
FindAndAssignPipeline();
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void FindAndAssignPipeline(){}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c1ba780f87ca5a4ea89d3330464ecf5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 267961
|
||||
packageName: 'Starter Assets: Character Controllers | URP'
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/Starter Assets/Editor/URPWizard/URPWizard.cs
|
||||
uploadId: 721456
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Unity.StarterAssets.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.StarterAssets",
|
||||
"Unity.Cinemachine"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65197035c7dd3894d8e8f7a6513ffc01
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 267961
|
||||
packageName: 'Starter Assets: Character Controllers | URP'
|
||||
packageVersion: 2.0.2
|
||||
assetPath: Assets/Starter Assets/Editor/Unity.StartAssets.Editor.asmdef
|
||||
uploadId: 721456
|
||||
Reference in New Issue
Block a user