first commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:36:52 +07:00
commit 6f2eafa33c
14093 changed files with 1253472 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b965d7c48dbdb594cb2678be44f7ea34
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7eeb774ee02ee2e4eb6e3387169f1ada
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 299341368f0a4ce5beba0c07f7bb5bbb
timeCreated: 1655319459

View File

@@ -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
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1dcde1c83efa6e14e8e75ed67addeba3
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b4f798af8320134f8549651d7ea621a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: