first commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b965d7c48dbdb594cb2678be44f7ea34
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,192 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
namespace Unity.AI.Navigation.Samples.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// This class creates (if missing) or resets (after reimporting the samples) the agent types used by the samples.
|
||||
/// It is in no way necessary for using the Navigation package and is only used for the correct functioning of the samples.
|
||||
/// </summary>
|
||||
public static class NavigationSampleProjectSettingsGenerator
|
||||
{
|
||||
const string k_NavMeshSettingsPath = "ProjectSettings/NavMeshAreas.asset";
|
||||
|
||||
const float k_DefaultAgentRadius = 0.5f;
|
||||
const float k_DefaultAgentHeight = 2.0f;
|
||||
const float k_DefaultAgentClimb = 0.4f;
|
||||
const float k_DefaultAgentSlope = 45.0f;
|
||||
|
||||
const string k_HumanoidAgentTypeName = "Humanoid for Navigation Sample";
|
||||
const int k_HumanoidAgentTypeID = 1;
|
||||
const float k_HumanoidAgentClimb = 0.75f;
|
||||
|
||||
const string k_OgreAgentTypeName = "Ogre for Navigation Sample";
|
||||
const int k_OgreAgentTypeID = 2;
|
||||
const float k_OgreAgentRadius = 1.0f;
|
||||
const float k_OgreAgentSlope = 36.0f;
|
||||
|
||||
static SerializedObject s_NavMeshParameters;
|
||||
static SerializedProperty s_AgentsSettings;
|
||||
static SerializedProperty s_SettingNames;
|
||||
|
||||
public static void GenerateAllProjectSettings(NavigationSampleSettingsState settingsState)
|
||||
{
|
||||
s_NavMeshParameters = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath(k_NavMeshSettingsPath)[0]);
|
||||
|
||||
s_AgentsSettings = s_NavMeshParameters.FindProperty("m_Settings");
|
||||
s_SettingNames = s_NavMeshParameters.FindProperty("m_SettingNames");
|
||||
|
||||
var hasInitializedOnProjectLoad = settingsState.generated;
|
||||
|
||||
GenerateProjectSettings(k_HumanoidAgentTypeName, k_HumanoidAgentTypeID, CreateHumanoidAgentSettings, hasInitializedOnProjectLoad);
|
||||
GenerateProjectSettings(k_OgreAgentTypeName, k_OgreAgentTypeID, CreateOgreAgentSettings, hasInitializedOnProjectLoad);
|
||||
s_NavMeshParameters.ApplyModifiedProperties();
|
||||
settingsState.generated = true;
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
static void GenerateProjectSettings(string agentTypeName, int agentTypeID, CreateAgentSettings createAgentSettings, bool hasInitializedOnProjectLoad)
|
||||
{
|
||||
var agentProperty = GetSerializedSettingsByID(agentTypeID, out var index);
|
||||
if (index < 0)
|
||||
{
|
||||
// Create new settings
|
||||
var agentSettings = createAgentSettings();
|
||||
agentSettings.agentTypeID = agentTypeID;
|
||||
AddAgentSettings(agentSettings, agentTypeName, agentTypeID);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!HasSettingsNameAtIndex(index, agentTypeName))
|
||||
{
|
||||
// Don't update the settings
|
||||
var settingsName = s_SettingNames.GetArrayElementAtIndex(index).stringValue;
|
||||
if (!IsAgentTypeSetWithDefaultValues(index, agentTypeID))
|
||||
{
|
||||
Debug.LogWarning($"The agent type {agentTypeName} used in the Navigation Samples could not be created. The agent type {settingsName} will be used instead. {settingsName} does not have the expected values for {agentTypeName}. The expected values for {agentTypeName} are written in the README.md file of the samples. The values of agent types are updatable in the Agents tab of the AI > Navigation window.");
|
||||
}
|
||||
}
|
||||
else if (!hasInitializedOnProjectLoad && !IsAgentTypeSetWithDefaultValues(index, agentTypeID))
|
||||
{
|
||||
// Update existing settings to default values
|
||||
var radius = agentProperty.FindPropertyRelative("agentRadius").floatValue;
|
||||
var height = agentProperty.FindPropertyRelative("agentHeight").floatValue;
|
||||
var climb = agentProperty.FindPropertyRelative("agentClimb").floatValue;
|
||||
var slope = agentProperty.FindPropertyRelative("agentSlope").floatValue;
|
||||
|
||||
var tempAgentSettings = createAgentSettings();
|
||||
UpdateSettings(agentProperty, tempAgentSettings);
|
||||
NavMesh.RemoveSettings(tempAgentSettings.agentTypeID);
|
||||
|
||||
Debug.Log($"Navigation Samples reimport detected. The agent type {agentTypeName} has been reset to its default values. Its values before the reset were: Radius = {radius}, Height = {height}, Step height = {climb} and Max Slope = {slope}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsAgentTypeSetWithDefaultValues(int index, int agentTypeID)
|
||||
{
|
||||
var agentTypeSettings = s_AgentsSettings.GetArrayElementAtIndex(index);
|
||||
var radius = agentTypeSettings.FindPropertyRelative("agentRadius").floatValue;
|
||||
var height = agentTypeSettings.FindPropertyRelative("agentHeight").floatValue;
|
||||
var climb = agentTypeSettings.FindPropertyRelative("agentClimb").floatValue;
|
||||
var slope = agentTypeSettings.FindPropertyRelative("agentSlope").floatValue;
|
||||
|
||||
var result = false;
|
||||
switch (agentTypeID)
|
||||
{
|
||||
case k_HumanoidAgentTypeID:
|
||||
result = radius == k_DefaultAgentRadius && height == k_DefaultAgentHeight && climb == k_HumanoidAgentClimb && slope == k_DefaultAgentSlope;
|
||||
break;
|
||||
case k_OgreAgentTypeID:
|
||||
result = radius == k_OgreAgentRadius && height == k_DefaultAgentHeight && climb == k_DefaultAgentClimb && slope == k_OgreAgentSlope;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
delegate NavMeshBuildSettings CreateAgentSettings();
|
||||
|
||||
static NavMeshBuildSettings CreateHumanoidAgentSettings()
|
||||
{
|
||||
var humanoidAgentSettings = NavMesh.CreateSettings();
|
||||
humanoidAgentSettings.agentRadius = k_DefaultAgentRadius;
|
||||
humanoidAgentSettings.agentHeight = k_DefaultAgentHeight;
|
||||
humanoidAgentSettings.agentClimb = k_HumanoidAgentClimb;
|
||||
humanoidAgentSettings.agentSlope = k_DefaultAgentSlope;
|
||||
|
||||
return humanoidAgentSettings;
|
||||
}
|
||||
|
||||
static NavMeshBuildSettings CreateOgreAgentSettings()
|
||||
{
|
||||
var ogreAgentSettings = NavMesh.CreateSettings();
|
||||
ogreAgentSettings.agentRadius = k_OgreAgentRadius;
|
||||
ogreAgentSettings.agentHeight = k_DefaultAgentHeight;
|
||||
ogreAgentSettings.agentClimb = k_DefaultAgentClimb;
|
||||
ogreAgentSettings.agentSlope = k_OgreAgentSlope;
|
||||
|
||||
return ogreAgentSettings;
|
||||
}
|
||||
|
||||
static SerializedProperty GetSerializedSettingsByID(int agentTypeID, out int index)
|
||||
{
|
||||
index = -1;
|
||||
SerializedProperty settings = null;
|
||||
for (var i = 0; i < s_AgentsSettings.arraySize; i++)
|
||||
{
|
||||
if (s_AgentsSettings.GetArrayElementAtIndex(i).FindPropertyRelative("agentTypeID").intValue == agentTypeID)
|
||||
{
|
||||
index = i;
|
||||
settings = s_AgentsSettings.GetArrayElementAtIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static bool HasSettingsNameAtIndex(int index, string agentTypeName)
|
||||
{
|
||||
return s_SettingNames.GetArrayElementAtIndex(index).stringValue.Equals(agentTypeName);
|
||||
}
|
||||
|
||||
static void AddAgentSettings(NavMeshBuildSettings agentSettings, string agentTypeName, int agentTypeID)
|
||||
{
|
||||
var nbNames = s_SettingNames.arraySize;
|
||||
s_SettingNames.InsertArrayElementAtIndex(nbNames);
|
||||
var newName = s_SettingNames.GetArrayElementAtIndex(nbNames);
|
||||
newName.stringValue = agentTypeName;
|
||||
|
||||
var nbAgents = s_AgentsSettings.arraySize;
|
||||
s_AgentsSettings.InsertArrayElementAtIndex(nbAgents);
|
||||
var addedAgentType = s_AgentsSettings.GetArrayElementAtIndex(nbAgents);
|
||||
|
||||
UpdateSettings(addedAgentType, agentSettings);
|
||||
|
||||
SetAgentPropertyValue(addedAgentType, "agentTypeID", agentTypeID);
|
||||
}
|
||||
|
||||
static void UpdateSettings(SerializedProperty agentToUpdate, NavMeshBuildSettings newSettings)
|
||||
{
|
||||
SetAgentPropertyValue(agentToUpdate, "agentRadius", newSettings.agentRadius);
|
||||
SetAgentPropertyValue(agentToUpdate, "agentHeight", newSettings.agentHeight);
|
||||
SetAgentPropertyValue(agentToUpdate, "agentClimb", newSettings.agentClimb);
|
||||
SetAgentPropertyValue(agentToUpdate, "agentSlope", newSettings.agentSlope);
|
||||
}
|
||||
|
||||
static void SetAgentPropertyValue(SerializedProperty agent, string propertyName, int value)
|
||||
{
|
||||
var property = agent.FindPropertyRelative(propertyName);
|
||||
property.intValue = value;
|
||||
}
|
||||
|
||||
static void SetAgentPropertyValue(SerializedProperty agent, string propertyName, float value)
|
||||
{
|
||||
var property = agent.FindPropertyRelative(propertyName);
|
||||
property.floatValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7eeb774ee02ee2e4eb6e3387169f1ada
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.AI.Navigation.Samples.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// This ScriptableObject is used by the NavigationSampleProjectSettingsGenerator to check whether the generation of agent types for the samples has already been done.
|
||||
/// It is in no way necessary for using the Navigation package and is only used for the correct functioning of the samples.
|
||||
/// </summary>
|
||||
public class NavigationSampleSettingsState : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
bool hasGeneratedSettings;
|
||||
|
||||
public bool generated
|
||||
{
|
||||
get => hasGeneratedSettings;
|
||||
set => hasGeneratedSettings = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 299341368f0a4ce5beba0c07f7bb5bbb
|
||||
timeCreated: 1655319459
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Unity.AI.Navigation.Samples.Initialization.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dcde1c83efa6e14e8e75ed67addeba3
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
#if UNITY_EDITOR
|
||||
using Unity.AI.Navigation.Samples.Editor;
|
||||
using UnityEditor.SceneManagement;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.AI.Navigation.Samples
|
||||
{
|
||||
/// <summary>
|
||||
/// The Navigation samples use a couple of custom agent types.
|
||||
/// This class calls the NavigationSampleProjectSettingsGenerator to ensure that these agent types do exist within your Unity project.
|
||||
/// It is in no way necessary for using the Navigation package and is only used for the correct functioning of the samples.
|
||||
/// </summary>
|
||||
[ExecuteAlways]
|
||||
public class NavigationSampleInitializer : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[SerializeField]
|
||||
NavigationSampleSettingsState settingsState;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
NavigationSampleProjectSettingsGenerator.GenerateAllProjectSettings(settingsState);
|
||||
|
||||
DestroyGameObjectAndSave(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyGameObjectAndSave(GameObject gameObject)
|
||||
{
|
||||
var scene = gameObject.scene;
|
||||
DestroyImmediate(gameObject);
|
||||
EditorSceneManager.SaveScene(scene);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b4f798af8320134f8549651d7ea621a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user