2026-05-18 기획 수정 : 플레이어와 에너미의 body간 충돌은 없다
This commit is contained in:
442
Assembly-CSharp.csproj.lscache
Normal file
442
Assembly-CSharp.csproj.lscache
Normal file
@@ -0,0 +1,442 @@
|
||||
version=1
|
||||
|
||||
# This file caches language service data to improve the performance of C# Dev Kit.
|
||||
# It is not intended for manual editing. It can safely be deleted and will be
|
||||
# regenerated automatically. For more information, see https://aka.ms/lscache
|
||||
#
|
||||
# To control where cache files are stored, use the following VS Code setting:
|
||||
# "dotnet.projectsystem.cacheInProjectFolder": true
|
||||
|
||||
[project]
|
||||
language=C#
|
||||
primary
|
||||
lastDtbSucceeded
|
||||
|
||||
[properties]
|
||||
AssemblyName=Assembly-CSharp
|
||||
CommandLineArgsForDesignTimeEvaluation=-langversion:9.0 -define:UNITY_6000_3_9;UNITY_6000_3;UNITY_6000;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_2023_1_OR_NEWER;UNITY_2023_2_OR_NEWER;UNITY_2023_3_OR_NEWER;UNITY_6000_0_OR_NEWER;UNITY_6000_1_OR_NEWER;UNITY_6000_2_OR_NEWER;UNITY_6000_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_AUDIO_SCRIPTABLE_PIPELINE;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_UNITY_CONSENT;ENABLE_UNITY_CLOUD_IDENTIFIERS;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_MARSHALLING_TESTS;ENABLE_VIDEO;ENABLE_NAVIGATION_OFFMESHLINK_TO_NAVMESHLINK;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_ACCESSIBILITY_SCREEN_READER;TEXTCORE_1_0_OR_NEWER;EDITOR_ONLY_NAVMESH_BUILDER_DEPRECATED;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_AMD;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_CLOUD_SERVICES_ENGINE_DIAGNOSTICS;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;PLATFORM_USES_EXPLICIT_MEMORY_MANAGER_INITIALIZER;PLATFORM_SUPPORTS_WAIT_FOR_PRESENTATION;PLATFORM_SUPPORTS_SPLIT_GRAPHICS_JOBS;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_INPUT_SYSTEM;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;TEXTCORE_TEXT_ENGINE_1_5_OR_NEWER;TEXTCORE_FONT_ENGINE_1_6_OR_NEWER;UNITY_TEMPLATE_PLATFORMER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER
|
||||
CompilerGeneratedFilesOutputPath=
|
||||
MaxSupportedLangVersion=8.0
|
||||
ProjectAssetsFile=<PATH>Temp/obj/Assembly-CSharp/project.assets.json
|
||||
RootNamespace=
|
||||
RunAnalyzers=
|
||||
RunAnalyzersDuringLiveAnalysis=
|
||||
SolutionPath=<PATH>Unity_2D_WhiteAction.slnx
|
||||
TargetFrameworkIdentifier=.NETStandard
|
||||
TargetPath=<PATH>Temp/bin/Debug/Assembly-CSharp.dll
|
||||
TargetRefPath=
|
||||
TemporaryDependencyNodeTargetIdentifier=netstandard2.1
|
||||
|
||||
[commandLineArguments]
|
||||
/noconfig
|
||||
/unsafe-
|
||||
/checked-
|
||||
/nowarn:0169,USG0001,1701,1702
|
||||
/fullpaths
|
||||
/nostdlib+
|
||||
/errorreport:prompt
|
||||
/define:UNITY_6000_3_9;UNITY_6000_3;UNITY_6000;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_2_OR_NEWER;UNITY_2017_3_OR_NEWER;UNITY_2017_4_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2018_2_OR_NEWER;UNITY_2018_3_OR_NEWER;UNITY_2018_4_OR_NEWER;UNITY_2019_1_OR_NEWER;UNITY_2019_2_OR_NEWER;UNITY_2019_3_OR_NEWER;UNITY_2019_4_OR_NEWER;UNITY_2020_1_OR_NEWER;UNITY_2020_2_OR_NEWER;UNITY_2020_3_OR_NEWER;UNITY_2021_1_OR_NEWER;UNITY_2021_2_OR_NEWER;UNITY_2021_3_OR_NEWER;UNITY_2022_1_OR_NEWER;UNITY_2022_2_OR_NEWER;UNITY_2022_3_OR_NEWER;UNITY_2023_1_OR_NEWER;UNITY_2023_2_OR_NEWER;UNITY_2023_3_OR_NEWER;UNITY_6000_0_OR_NEWER;UNITY_6000_1_OR_NEWER;UNITY_6000_2_OR_NEWER;UNITY_6000_3_OR_NEWER;PLATFORM_ARCH_64;UNITY_64;UNITY_INCLUDE_TESTS;ENABLE_AR;ENABLE_AUDIO;ENABLE_AUDIO_SCRIPTABLE_PIPELINE;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_EVENT_QUEUE;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_TEXTURE_STREAMING;ENABLE_VIRTUALTEXTURING;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_VR;ENABLE_WEBCAM;ENABLE_UNITYWEBREQUEST;ENABLE_WWW;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_UNITY_CONSENT;ENABLE_UNITY_CLOUD_IDENTIFIERS;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_NATIVE_CRASH_REPORTING;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_EDITOR_GAME_SERVICES;ENABLE_UNITY_GAME_SERVICES_ANALYTICS_SUPPORT;ENABLE_CLOUD_LICENSE;ENABLE_EDITOR_HUB_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_GENERATE_NATIVE_PLUGINS_FOR_ASSEMBLIES_API;ENABLE_DIRECTOR_AUDIO;ENABLE_DIRECTOR_TEXTURE;ENABLE_MANAGED_JOBS;ENABLE_MANAGED_TRANSFORM_JOBS;ENABLE_MANAGED_ANIMATION_JOBS;ENABLE_MANAGED_AUDIO_JOBS;ENABLE_MANAGED_UNITYTLS;INCLUDE_DYNAMIC_GI;ENABLE_SCRIPTING_GC_WBARRIERS;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;ENABLE_MARSHALLING_TESTS;ENABLE_VIDEO;ENABLE_NAVIGATION_OFFMESHLINK_TO_NAVMESHLINK;ENABLE_ACCELERATOR_CLIENT_DEBUGGING;ENABLE_ACCESSIBILITY_SCREEN_READER;TEXTCORE_1_0_OR_NEWER;EDITOR_ONLY_NAVMESH_BUILDER_DEPRECATED;PLATFORM_STANDALONE_WIN;PLATFORM_STANDALONE;UNITY_STANDALONE_WIN;UNITY_STANDALONE;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_NVIDIA;ENABLE_AMD;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_CLOUD_SERVICES_ENGINE_DIAGNOSTICS;ENABLE_OUT_OF_PROCESS_CRASH_HANDLER;ENABLE_CLUSTER_SYNC;ENABLE_CLUSTERINPUT;PLATFORM_UPDATES_TIME_OUTSIDE_OF_PLAYER_LOOP;GFXDEVICE_WAITFOREVENT_MESSAGEPUMP;PLATFORM_USES_EXPLICIT_MEMORY_MANAGER_INITIALIZER;PLATFORM_SUPPORTS_WAIT_FOR_PRESENTATION;PLATFORM_SUPPORTS_SPLIT_GRAPHICS_JOBS;ENABLE_MONO;NET_STANDARD_2_0;NET_STANDARD;NET_STANDARD_2_1;NETSTANDARD;NETSTANDARD2_1;ENABLE_PROFILER;DEBUG;TRACE;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_WIN;ENABLE_UNITY_COLLECTIONS_CHECKS;ENABLE_BURST_AOT;UNITY_TEAM_LICENSE;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_DIRECTOR;ENABLE_LOCALIZATION;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_TILEMAP;ENABLE_TIMELINE;ENABLE_INPUT_SYSTEM;TEXTCORE_FONT_ENGINE_1_5_OR_NEWER;TEXTCORE_TEXT_ENGINE_1_5_OR_NEWER;TEXTCORE_FONT_ENGINE_1_6_OR_NEWER;UNITY_TEMPLATE_PLATFORMER;CSHARP_7_OR_LATER;CSHARP_7_3_OR_NEWER;DEBUG;NETSTANDARD;NETSTANDARD2_1;NETSTANDARD1_0_OR_GREATER;NETSTANDARD1_1_OR_GREATER;NETSTANDARD1_2_OR_GREATER;NETSTANDARD1_3_OR_GREATER;NETSTANDARD1_4_OR_GREATER;NETSTANDARD1_5_OR_GREATER;NETSTANDARD1_6_OR_GREATER;NETSTANDARD2_0_OR_GREATER;NETSTANDARD2_1_OR_GREATER
|
||||
/highentropyva+
|
||||
/debug+
|
||||
/debug:portable
|
||||
/filealign:512
|
||||
/optimize-
|
||||
/out:Temp\obj\Assembly-CSharp\Assembly-CSharp.dll
|
||||
/target:library
|
||||
/warnaserror-
|
||||
/utf8output
|
||||
/deterministic+
|
||||
/langversion:9.0
|
||||
/warnaserror+:NU1605
|
||||
|
||||
[sourceFiles]
|
||||
Assets/02_Scripts/Combat/
|
||||
ActionData.cs
|
||||
AttackHitbox.cs
|
||||
ComboNode.cs
|
||||
IDamageable.cs
|
||||
Assets/02_Scripts/
|
||||
Enemy/Enemy.cs
|
||||
GlobalObject.cs
|
||||
Input/GameInput.cs
|
||||
Managers/InputManager.cs
|
||||
Player/PlayerController.cs
|
||||
Temp/obj/Assembly-CSharp/.NETStandard,Version=v2.1.AssemblyAttributes.cs
|
||||
|
||||
[metadataReferences]
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/Managed/UnityEngine/
|
||||
UnityEditor.AccessibilityModule.dll
|
||||
UnityEditor.AdaptivePerformanceModule.dll
|
||||
UnityEditor.AssetComplianceModule.dll
|
||||
UnityEditor.BuildProfileModule.dll
|
||||
UnityEditor.ClothModule.dll
|
||||
UnityEditor.CoreBusinessMetricsModule.dll
|
||||
UnityEditor.CoreModule.dll
|
||||
UnityEditor.DeviceSimulatorModule.dll
|
||||
UnityEditor.DiagnosticsModule.dll
|
||||
UnityEditor.dll
|
||||
UnityEditor.EditorToolbarModule.dll
|
||||
UnityEditor.EmbreeModule.dll
|
||||
UnityEditor.GIModule.dll
|
||||
UnityEditor.GraphicsStateCollectionSerializerModule.dll
|
||||
UnityEditor.GraphViewModule.dll
|
||||
UnityEditor.GridAndSnapModule.dll
|
||||
UnityEditor.GridModule.dll
|
||||
UnityEditor.HierarchyModule.dll
|
||||
UnityEditor.InAppPurchasingModule.dll
|
||||
UnityEditor.LevelPlayModule.dll
|
||||
UnityEditor.MediaModule.dll
|
||||
UnityEditor.MultiplayerModule.dll
|
||||
UnityEditor.Physics2DModule.dll
|
||||
UnityEditor.PhysicsModule.dll
|
||||
UnityEditor.PlayModeModule.dll
|
||||
UnityEditor.PresetsUIModule.dll
|
||||
UnityEditor.PropertiesModule.dll
|
||||
UnityEditor.QuickSearchModule.dll
|
||||
UnityEditor.SafeModeModule.dll
|
||||
UnityEditor.SceneTemplateModule.dll
|
||||
UnityEditor.SceneViewModule.dll
|
||||
UnityEditor.ShaderBuildSettingsModule.dll
|
||||
UnityEditor.ShaderCompilationModule.dll
|
||||
UnityEditor.ShaderFoundryModule.dll
|
||||
UnityEditor.SketchUpModule.dll
|
||||
UnityEditor.SpriteMaskModule.dll
|
||||
UnityEditor.SpriteShapeModule.dll
|
||||
UnityEditor.SubstanceModule.dll
|
||||
UnityEditor.TerrainModule.dll
|
||||
UnityEditor.TextCoreFontEngineModule.dll
|
||||
UnityEditor.TextCoreTextEngineModule.dll
|
||||
UnityEditor.TextRenderingModule.dll
|
||||
UnityEditor.TilemapModule.dll
|
||||
UnityEditor.TreeModule.dll
|
||||
UnityEditor.UIAutomationModule.dll
|
||||
UnityEditor.UIBuilderModule.dll
|
||||
UnityEditor.UIElementsModule.dll
|
||||
UnityEditor.UIElementsSamplesModule.dll
|
||||
UnityEditor.UIToolkitAuthoringModule.dll
|
||||
UnityEditor.UmbraModule.dll
|
||||
UnityEditor.UnityConnectModule.dll
|
||||
UnityEditor.VectorGraphicsModule.dll
|
||||
UnityEditor.VFXModule.dll
|
||||
UnityEditor.VideoModule.dll
|
||||
UnityEditor.XRModule.dll
|
||||
UnityEngine.AccessibilityModule.dll
|
||||
UnityEngine.AdaptivePerformanceModule.dll
|
||||
UnityEngine.AIModule.dll
|
||||
UnityEngine.AndroidJNIModule.dll
|
||||
UnityEngine.AnimationModule.dll
|
||||
UnityEngine.ARModule.dll
|
||||
UnityEngine.AssetBundleModule.dll
|
||||
UnityEngine.AudioModule.dll
|
||||
UnityEngine.ClothModule.dll
|
||||
UnityEngine.ClusterInputModule.dll
|
||||
UnityEngine.ClusterRendererModule.dll
|
||||
UnityEngine.ContentLoadModule.dll
|
||||
UnityEngine.CoreModule.dll
|
||||
UnityEngine.CrashReportingModule.dll
|
||||
UnityEngine.DirectorModule.dll
|
||||
UnityEngine.dll
|
||||
UnityEngine.DSPGraphModule.dll
|
||||
UnityEngine.GameCenterModule.dll
|
||||
UnityEngine.GIModule.dll
|
||||
UnityEngine.GraphicsStateCollectionSerializerModule.dll
|
||||
UnityEngine.GridModule.dll
|
||||
UnityEngine.HierarchyCoreModule.dll
|
||||
UnityEngine.HotReloadModule.dll
|
||||
UnityEngine.IdentifiersModule.dll
|
||||
UnityEngine.ImageConversionModule.dll
|
||||
UnityEngine.IMGUIModule.dll
|
||||
UnityEngine.InputForUIModule.dll
|
||||
UnityEngine.InputLegacyModule.dll
|
||||
UnityEngine.InputModule.dll
|
||||
UnityEngine.InsightsModule.dll
|
||||
UnityEngine.JSONSerializeModule.dll
|
||||
UnityEngine.LocalizationModule.dll
|
||||
UnityEngine.MarshallingModule.dll
|
||||
UnityEngine.MultiplayerModule.dll
|
||||
UnityEngine.ParticleSystemModule.dll
|
||||
UnityEngine.PerformanceReportingModule.dll
|
||||
UnityEngine.Physics2DModule.dll
|
||||
UnityEngine.PhysicsBackendPhysXModule.dll
|
||||
UnityEngine.PhysicsModule.dll
|
||||
UnityEngine.PropertiesModule.dll
|
||||
UnityEngine.RenderAs2DModule.dll
|
||||
UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll
|
||||
UnityEngine.ScreenCaptureModule.dll
|
||||
UnityEngine.ShaderRuntimeModule.dll
|
||||
UnityEngine.ShaderVariantAnalyticsModule.dll
|
||||
UnityEngine.SharedInternalsModule.dll
|
||||
UnityEngine.SpriteMaskModule.dll
|
||||
UnityEngine.SpriteShapeModule.dll
|
||||
UnityEngine.StreamingModule.dll
|
||||
UnityEngine.SubstanceModule.dll
|
||||
UnityEngine.SubsystemsModule.dll
|
||||
UnityEngine.TerrainModule.dll
|
||||
UnityEngine.TerrainPhysicsModule.dll
|
||||
UnityEngine.TextCoreFontEngineModule.dll
|
||||
UnityEngine.TextCoreTextEngineModule.dll
|
||||
UnityEngine.TextRenderingModule.dll
|
||||
UnityEngine.TilemapModule.dll
|
||||
UnityEngine.TLSModule.dll
|
||||
UnityEngine.UIElementsModule.dll
|
||||
UnityEngine.UIModule.dll
|
||||
UnityEngine.UmbraModule.dll
|
||||
UnityEngine.UnityAnalyticsCommonModule.dll
|
||||
UnityEngine.UnityAnalyticsModule.dll
|
||||
UnityEngine.UnityConnectModule.dll
|
||||
UnityEngine.UnityConsentModule.dll
|
||||
UnityEngine.UnityCurlModule.dll
|
||||
UnityEngine.UnityWebRequestAssetBundleModule.dll
|
||||
UnityEngine.UnityWebRequestAudioModule.dll
|
||||
UnityEngine.UnityWebRequestModule.dll
|
||||
UnityEngine.UnityWebRequestTextureModule.dll
|
||||
UnityEngine.UnityWebRequestWWWModule.dll
|
||||
UnityEngine.VectorGraphicsModule.dll
|
||||
UnityEngine.VehiclesModule.dll
|
||||
UnityEngine.VFXModule.dll
|
||||
UnityEngine.VideoModule.dll
|
||||
UnityEngine.VirtualTexturingModule.dll
|
||||
UnityEngine.VRModule.dll
|
||||
UnityEngine.WindModule.dll
|
||||
UnityEngine.XRModule.dll
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/NetStandard/compat/2.1.0/shims/netfx/
|
||||
mscorlib.dll
|
||||
System.ComponentModel.Composition.dll
|
||||
System.Core.dll
|
||||
System.Data.dll
|
||||
System.dll
|
||||
System.Drawing.dll
|
||||
System.IO.Compression.FileSystem.dll
|
||||
System.Net.dll
|
||||
System.Numerics.dll
|
||||
System.Runtime.Serialization.dll
|
||||
System.ServiceModel.Web.dll
|
||||
System.Transactions.dll
|
||||
System.Web.dll
|
||||
System.Windows.dll
|
||||
System.Xml.dll
|
||||
System.Xml.Linq.dll
|
||||
System.Xml.Serialization.dll
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/NetStandard/compat/2.1.0/shims/netstandard/
|
||||
Microsoft.Win32.Primitives.dll
|
||||
System.AppContext.dll
|
||||
System.Buffers.dll
|
||||
System.Collections.Concurrent.dll
|
||||
System.Collections.dll
|
||||
System.Collections.NonGeneric.dll
|
||||
System.Collections.Specialized.dll
|
||||
System.ComponentModel.dll
|
||||
System.ComponentModel.EventBasedAsync.dll
|
||||
System.ComponentModel.Primitives.dll
|
||||
System.ComponentModel.TypeConverter.dll
|
||||
System.Console.dll
|
||||
System.Data.Common.dll
|
||||
System.Diagnostics.Contracts.dll
|
||||
System.Diagnostics.Debug.dll
|
||||
System.Diagnostics.FileVersionInfo.dll
|
||||
System.Diagnostics.Process.dll
|
||||
System.Diagnostics.StackTrace.dll
|
||||
System.Diagnostics.TextWriterTraceListener.dll
|
||||
System.Diagnostics.Tools.dll
|
||||
System.Diagnostics.TraceSource.dll
|
||||
System.Diagnostics.Tracing.dll
|
||||
System.Drawing.Primitives.dll
|
||||
System.Dynamic.Runtime.dll
|
||||
System.Globalization.Calendars.dll
|
||||
System.Globalization.dll
|
||||
System.Globalization.Extensions.dll
|
||||
System.IO.Compression.dll
|
||||
System.IO.Compression.ZipFile.dll
|
||||
System.IO.dll
|
||||
System.IO.FileSystem.dll
|
||||
System.IO.FileSystem.DriveInfo.dll
|
||||
System.IO.FileSystem.Primitives.dll
|
||||
System.IO.FileSystem.Watcher.dll
|
||||
System.IO.IsolatedStorage.dll
|
||||
System.IO.MemoryMappedFiles.dll
|
||||
System.IO.Pipes.dll
|
||||
System.IO.UnmanagedMemoryStream.dll
|
||||
System.Linq.dll
|
||||
System.Linq.Expressions.dll
|
||||
System.Linq.Parallel.dll
|
||||
System.Linq.Queryable.dll
|
||||
System.Memory.dll
|
||||
System.Net.Http.dll
|
||||
System.Net.NameResolution.dll
|
||||
System.Net.NetworkInformation.dll
|
||||
System.Net.Ping.dll
|
||||
System.Net.Primitives.dll
|
||||
System.Net.Requests.dll
|
||||
System.Net.Security.dll
|
||||
System.Net.Sockets.dll
|
||||
System.Net.WebHeaderCollection.dll
|
||||
System.Net.WebSockets.Client.dll
|
||||
System.Net.WebSockets.dll
|
||||
System.Numerics.Vectors.dll
|
||||
System.ObjectModel.dll
|
||||
System.Reflection.DispatchProxy.dll
|
||||
System.Reflection.dll
|
||||
System.Reflection.Emit.dll
|
||||
System.Reflection.Emit.ILGeneration.dll
|
||||
System.Reflection.Emit.Lightweight.dll
|
||||
System.Reflection.Extensions.dll
|
||||
System.Reflection.Primitives.dll
|
||||
System.Resources.Reader.dll
|
||||
System.Resources.ResourceManager.dll
|
||||
System.Resources.Writer.dll
|
||||
System.Runtime.CompilerServices.VisualC.dll
|
||||
System.Runtime.dll
|
||||
System.Runtime.Extensions.dll
|
||||
System.Runtime.Handles.dll
|
||||
System.Runtime.InteropServices.dll
|
||||
System.Runtime.InteropServices.RuntimeInformation.dll
|
||||
System.Runtime.Numerics.dll
|
||||
System.Runtime.Serialization.Formatters.dll
|
||||
System.Runtime.Serialization.Json.dll
|
||||
System.Runtime.Serialization.Primitives.dll
|
||||
System.Runtime.Serialization.Xml.dll
|
||||
System.Security.Claims.dll
|
||||
System.Security.Cryptography.Algorithms.dll
|
||||
System.Security.Cryptography.Csp.dll
|
||||
System.Security.Cryptography.Encoding.dll
|
||||
System.Security.Cryptography.Primitives.dll
|
||||
System.Security.Cryptography.X509Certificates.dll
|
||||
System.Security.Principal.dll
|
||||
System.Security.SecureString.dll
|
||||
System.Text.Encoding.dll
|
||||
System.Text.Encoding.Extensions.dll
|
||||
System.Text.RegularExpressions.dll
|
||||
System.Threading.dll
|
||||
System.Threading.Overlapped.dll
|
||||
System.Threading.Tasks.dll
|
||||
System.Threading.Tasks.Extensions.dll
|
||||
System.Threading.Tasks.Parallel.dll
|
||||
System.Threading.Thread.dll
|
||||
System.Threading.ThreadPool.dll
|
||||
System.Threading.Timer.dll
|
||||
System.ValueTuple.dll
|
||||
System.Xml.ReaderWriter.dll
|
||||
System.Xml.XDocument.dll
|
||||
System.Xml.XmlDocument.dll
|
||||
System.Xml.XmlSerializer.dll
|
||||
System.Xml.XPath.dll
|
||||
System.Xml.XPath.XDocument.dll
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/NetStandard/
|
||||
Extensions/2.0.0/System.Runtime.InteropServices.WindowsRuntime.dll
|
||||
ref/2.1.0/netstandard.dll
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/PlaybackEngines/AndroidPlayer/
|
||||
Unity.Android.Gradle.dll
|
||||
Unity.Android.Types.dll
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/PlaybackEngines/iOSSupport/
|
||||
UnityEditor.Apple.Extensions.Common.dll
|
||||
UnityEditor.iOS.Extensions.Common.dll
|
||||
UnityEditor.iOS.Extensions.Xcode.dll
|
||||
Library/PackageCache/com.unity.collections@aea9d3bd5e19/
|
||||
Unity.Collections.LowLevel.ILSupport/Unity.Collections.LowLevel.ILSupport.dll
|
||||
Unity.Collections.Tests/
|
||||
System.IO.Hashing/System.IO.Hashing.dll
|
||||
System.Runtime.CompilerServices.Unsafe/System.Runtime.CompilerServices.Unsafe.dll
|
||||
Library/PackageCache/
|
||||
com.unity.ext.nunit@d8c07649098d/net40/unity-custom/nunit.framework.dll
|
||||
com.unity.nuget.mono-cecil@ecb9724e46ff/Mono.Cecil.dll
|
||||
com.unity.nuget.newtonsoft-json@4dfd81071c64/Runtime/Newtonsoft.Json.dll
|
||||
com.unity.testtools.codecoverage@19a841221620/lib/ReportGenerator/ReportGeneratorMerged.dll
|
||||
com.unity.visualscripting@191c0d7e3b69/Runtime/VisualScripting.Flow/Dependencies/NCalc/Unity.VisualScripting.Antlr3.Runtime.dll
|
||||
Library/ScriptAssemblies/
|
||||
MCPForUnity.Editor.dll
|
||||
MCPForUnity.Runtime.dll
|
||||
PPv2URPConverters.dll
|
||||
PsdPlugin.dll
|
||||
Unity.2D.Animation.Editor.dll
|
||||
Unity.2D.Animation.Runtime.dll
|
||||
Unity.2D.Aseprite.Common.dll
|
||||
Unity.2D.Aseprite.Editor.dll
|
||||
Unity.2D.Common.Editor.dll
|
||||
Unity.2D.Common.Path.Editor.dll
|
||||
Unity.2D.Common.Runtime.dll
|
||||
Unity.2D.IK.Editor.dll
|
||||
Unity.2D.IK.Runtime.dll
|
||||
Unity.2D.PixelPerfect.dll
|
||||
Unity.2D.PixelPerfect.Editor.dll
|
||||
Unity.2D.Psdimporter.Editor.dll
|
||||
Unity.2D.Sprite.Editor.dll
|
||||
Unity.2D.SpriteShape.Editor.dll
|
||||
Unity.2D.SpriteShape.Runtime.dll
|
||||
Unity.2D.Tilemap.Editor.dll
|
||||
Unity.2D.Tilemap.Extras.dll
|
||||
Unity.2D.Tilemap.Extras.Editor.dll
|
||||
Unity.2D.Tooling.Editor.dll
|
||||
Unity.Burst.dll
|
||||
Unity.Burst.Editor.dll
|
||||
Unity.Cinemachine.dll
|
||||
Unity.Cinemachine.Editor.dll
|
||||
Unity.Collections.dll
|
||||
Unity.Collections.Editor.dll
|
||||
Unity.EditorCoroutines.Editor.dll
|
||||
Unity.InputSystem.dll
|
||||
Unity.InputSystem.ForUI.dll
|
||||
Unity.InternalAPIEditorBridge.001.dll
|
||||
Unity.InternalAPIEditorBridge.007.dll
|
||||
Unity.InternalAPIEditorBridgeDev.001.dll
|
||||
Unity.InternalAPIEngineBridge.001.dll
|
||||
Unity.InternalAPIEngineBridge.004.dll
|
||||
Unity.InternalAPIEngineBridge.007.dll
|
||||
Unity.Mathematics.dll
|
||||
Unity.Mathematics.Editor.dll
|
||||
Unity.Multiplayer.Center.Common.dll
|
||||
Unity.Multiplayer.Center.Editor.dll
|
||||
Unity.Performance.Profile-Analyzer.Editor.dll
|
||||
Unity.Play.Publisher.Editor.dll
|
||||
Unity.Rendering.LightTransport.Editor.dll
|
||||
Unity.RenderPipeline.Universal.ShaderLibrary.dll
|
||||
Unity.RenderPipelines.Core.Editor.dll
|
||||
Unity.RenderPipelines.Core.Editor.Shared.dll
|
||||
Unity.RenderPipelines.Core.Runtime.dll
|
||||
Unity.RenderPipelines.Core.Runtime.Shared.dll
|
||||
Unity.RenderPipelines.Core.ShaderLibrary.dll
|
||||
Unity.RenderPipelines.GPUDriven.Runtime.dll
|
||||
Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll
|
||||
Unity.RenderPipelines.Universal.2D.Editor.Overrides.dll
|
||||
Unity.RenderPipelines.Universal.2D.Runtime.dll
|
||||
Unity.RenderPipelines.Universal.Config.Runtime.dll
|
||||
Unity.RenderPipelines.Universal.Editor.dll
|
||||
Unity.RenderPipelines.Universal.Runtime.dll
|
||||
Unity.RenderPipelines.Universal.Shaders.dll
|
||||
Unity.Rider.Editor.dll
|
||||
Unity.Searcher.Editor.dll
|
||||
Unity.Settings.Editor.dll
|
||||
Unity.ShaderGraph.Editor.dll
|
||||
Unity.Splines.dll
|
||||
Unity.Splines.Editor.dll
|
||||
Unity.TestTools.CodeCoverage.Editor.dll
|
||||
Unity.TestTools.CodeCoverage.Editor.OpenCover.Model.dll
|
||||
Unity.TestTools.CodeCoverage.Editor.OpenCover.Mono.Reflection.dll
|
||||
Unity.TextMeshPro.dll
|
||||
Unity.TextMeshPro.Editor.dll
|
||||
Unity.Timeline.dll
|
||||
Unity.Timeline.Editor.dll
|
||||
Unity.Tutorials.Core.dll
|
||||
Unity.Tutorials.Core.Editor.dll
|
||||
Unity.UnifiedRayTracing.Runtime.dll
|
||||
Unity.VisualScripting.Core.dll
|
||||
Unity.VisualScripting.Core.Editor.dll
|
||||
Unity.VisualScripting.Flow.dll
|
||||
Unity.VisualScripting.Flow.Editor.dll
|
||||
Unity.VisualScripting.SettingsProvider.Editor.dll
|
||||
Unity.VisualScripting.Shared.Editor.dll
|
||||
Unity.VisualScripting.State.dll
|
||||
Unity.VisualScripting.State.Editor.dll
|
||||
Unity.VisualStudio.Editor.dll
|
||||
UnityEditor.UI.Analytics.dll
|
||||
UnityEditor.UI.dll
|
||||
UnityEngine.UI.dll
|
||||
|
||||
[analyzerReferences]
|
||||
../../../../Program Files/Unity/Hub/Editor/6000.3.9f1/Editor/Data/Tools/BuildPipeline/Unity.SourceGenerators/
|
||||
Unity.Properties.SourceGenerator.dll
|
||||
Unity.SourceGenerators.dll
|
||||
Unity.UIToolkit.SourceGenerator.dll
|
||||
../../.vscode/extensions/visualstudiotoolsforunity.vstuc-1.2.2/Analyzers/Microsoft.Unity.Analyzers.dll
|
||||
|
||||
[analyzerConfigFiles]
|
||||
Temp/obj/Assembly-CSharp/Assembly-CSharp.GeneratedMSBuildEditorConfig.editorconfig
|
||||
BIN
Assets/01_Scenes/GameScene.unity
LFS
BIN
Assets/01_Scenes/GameScene.unity
LFS
Binary file not shown.
@@ -25,8 +25,6 @@ public class ActionData : ScriptableObject
|
||||
public bool UseInputDirection = true;
|
||||
public bool PreserveYVelocity = true;
|
||||
public bool StopHorizontalVelocityOnEnd = true;
|
||||
public bool IgnoreCollisionDuringAction;
|
||||
public LayerMask IgnoredCollisionLayers;
|
||||
|
||||
[Header("Hit")]
|
||||
public bool HasHit = true;
|
||||
|
||||
66
Assets/02_Scripts/Combat/AttackHitbox.cs
Normal file
66
Assets/02_Scripts/Combat/AttackHitbox.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(CircleCollider2D))]
|
||||
public class AttackHitbox : MonoBehaviour
|
||||
{
|
||||
private CircleCollider2D _collider;
|
||||
private int _damage;
|
||||
private Vector2 _hitVelocity;
|
||||
private string _hitReactionState;
|
||||
private LayerMask _targetLayer;
|
||||
private readonly HashSet<IDamageable> _alreadyHit = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_collider = GetComponent<CircleCollider2D>();
|
||||
// The player body does not collide with enemies; this trigger is the only attack contact.
|
||||
_collider.isTrigger = true;
|
||||
_collider.enabled = false;
|
||||
}
|
||||
|
||||
public void Activate(ActionData data, Vector2 localPosition, Vector2 hitVelocity, LayerMask targetLayer)
|
||||
{
|
||||
transform.localPosition = localPosition;
|
||||
_collider.radius = data.Radius;
|
||||
_damage = data.Damage;
|
||||
_hitVelocity = hitVelocity;
|
||||
_hitReactionState = data.HitReactionAnimationState;
|
||||
_targetLayer = targetLayer;
|
||||
_alreadyHit.Clear();
|
||||
_collider.enabled = true;
|
||||
|
||||
// Catch enemies already inside the hitbox on the same frame it opens.
|
||||
ScanImmediateOverlap();
|
||||
}
|
||||
|
||||
public void Deactivate()
|
||||
{
|
||||
_collider.enabled = false;
|
||||
_alreadyHit.Clear();
|
||||
}
|
||||
|
||||
private void ScanImmediateOverlap()
|
||||
{
|
||||
Collider2D[] hits = Physics2D.OverlapCircleAll(transform.position, _collider.radius, _targetLayer);
|
||||
foreach (var hit in hits)
|
||||
TryDamage(hit);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other) => TryDamage(other);
|
||||
private void OnTriggerStay2D(Collider2D other) => TryDamage(other);
|
||||
|
||||
private void TryDamage(Collider2D other)
|
||||
{
|
||||
if ((_targetLayer.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
|
||||
// Hurtboxes may live on child objects, while damage handling usually lives on the root.
|
||||
if (!other.TryGetComponent<IDamageable>(out var target))
|
||||
target = other.GetComponentInParent<IDamageable>();
|
||||
if (target == null) return;
|
||||
if (_alreadyHit.Contains(target)) return;
|
||||
|
||||
_alreadyHit.Add(target);
|
||||
target.TakeDamage(_damage, _hitVelocity, _hitReactionState);
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/Combat/AttackHitbox.cs.meta
Normal file
2
Assets/02_Scripts/Combat/AttackHitbox.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90c25ca9d3ad4c8d9e4cc0b98ff95e12
|
||||
@@ -73,6 +73,7 @@ public void TakeDamage(int amount, Vector2 hitVelocity = default, string hitReac
|
||||
if (_anim != null && !string.IsNullOrEmpty(hitReactionAnimationState))
|
||||
_anim.Play(hitReactionAnimationState);
|
||||
|
||||
// HitVelocity is an immediate launch/knockback velocity, not an additive force.
|
||||
if (_rb != null)
|
||||
{
|
||||
Vector2 nextVelocity = GetHitReactionVelocity(hitVelocity);
|
||||
@@ -116,6 +117,7 @@ private void OnCollisionExit2D(Collision2D collision)
|
||||
|
||||
private Vector2 GetHitReactionVelocity(Vector2 hitVelocity)
|
||||
{
|
||||
// Airborne follow-up hits pop the enemy with a fixed Y velocity for stable combos.
|
||||
if (_hitReactionTimer <= 0f || _isGrounded)
|
||||
return hitVelocity;
|
||||
|
||||
@@ -139,6 +141,7 @@ private void UpdateGroundedState(Collision2D collision)
|
||||
|
||||
private void BounceOffWall(Vector2 wallNormal)
|
||||
{
|
||||
// While in hit reaction, side-wall impacts reflect the current knockback.
|
||||
Vector2 incomingVelocity = _lastVelocity.sqrMagnitude > _rb.linearVelocity.sqrMagnitude
|
||||
? _lastVelocity
|
||||
: _rb.linearVelocity;
|
||||
|
||||
@@ -34,24 +34,17 @@ public class PlayerController : MonoBehaviour
|
||||
[SerializeField] private ComboNode _rollRootNode;
|
||||
private readonly Dictionary<ActionData, float> _motionCooldownTimers = new();
|
||||
private readonly List<ActionData> _motionCooldownKeys = new();
|
||||
private readonly List<IgnoredLayerCollision> _ignoredLayerCollisions = new();
|
||||
private readonly List<Collider2D> _overlapResults = new();
|
||||
private readonly List<RaycastHit2D> _castResults = new();
|
||||
private int _activeCollisionRecoveryLayerMask;
|
||||
private Collider2D[] _bodyColliders;
|
||||
private CancellationTokenSource _restoreCollisionCts;
|
||||
private CancellationTokenSource _motionCts;
|
||||
|
||||
[Header("Collision Recovery")]
|
||||
[SerializeField] private float _overlapRecoverySpeed = 8f;
|
||||
[SerializeField] private float _overlapRecoveryOtherBodyRatio = 0.5f;
|
||||
[SerializeField] private float _bodyBlockCastDistance = 0.08f;
|
||||
[Header("Kinematic Physics")]
|
||||
[SerializeField] private float _gravity = -25f;
|
||||
[SerializeField] private float _maxFallSpeed = 20f;
|
||||
[SerializeField] private float _skinWidth = 0.02f;
|
||||
|
||||
[Header("Attack")]
|
||||
[SerializeField] private ComboNode _punchRootNode;
|
||||
[SerializeField] private ComboNode _kickRootNode;
|
||||
[SerializeField] private LayerMask _enemyLayer;
|
||||
[SerializeField] private LayerMask _bodyCollisionIgnoredLayers;
|
||||
[SerializeField] private AttackHitbox _attackHitbox;
|
||||
[SerializeField] private string _idleAnimationState = "Idle";
|
||||
[SerializeField] private float _bufferOpenTime = 0.1f;
|
||||
[SerializeField] private float _bufferLifetime = 0.5f;
|
||||
@@ -61,9 +54,9 @@ public class PlayerController : MonoBehaviour
|
||||
private ComboNode _currentNode;
|
||||
private float _comboWindowTimer;
|
||||
private CancellationTokenSource _attackCts;
|
||||
private CancellationTokenSource _motionCts;
|
||||
private CancellationTokenSource _animationSpeedCts;
|
||||
private ActionData _lastAttackGizmoData;
|
||||
private float _lastAttackGizmoTime = -1f;
|
||||
[SerializeField] private float _hitGizmoFadeDuration = 0.5f;
|
||||
private ActionData _lastHitData;
|
||||
private Vector2 _lastHitCenter;
|
||||
@@ -74,6 +67,8 @@ public class PlayerController : MonoBehaviour
|
||||
private float _attackStartTime = -1f;
|
||||
private bool _hitFired;
|
||||
|
||||
private readonly List<RaycastHit2D> _castResults = new();
|
||||
private Collider2D[] _bodyColliders;
|
||||
private Rigidbody2D _rb;
|
||||
private Animator _anim;
|
||||
private SpriteRenderer _spriteRenderer;
|
||||
@@ -84,14 +79,13 @@ private void Awake()
|
||||
_anim = GetComponent<Animator>();
|
||||
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||
IgnoreBodyCollisions();
|
||||
EnsureAttackHitbox();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
InputManager.Instance.OnMove_Event += OnMoveInput;
|
||||
InputManager.Instance.OnJump_Event += OnJumpInput;
|
||||
|
||||
InputManager.Instance.OnPunch_Event += OnPunchInput;
|
||||
InputManager.Instance.OnKick_Event += OnKickInput;
|
||||
InputManager.Instance.OnDash_Event += OnDashInput;
|
||||
@@ -112,19 +106,17 @@ private void OnDestroy()
|
||||
|
||||
_attackCts?.Cancel();
|
||||
_attackCts?.Dispose();
|
||||
_animationSpeedCts?.Cancel();
|
||||
_animationSpeedCts?.Dispose();
|
||||
_motionCts?.Cancel();
|
||||
_motionCts?.Dispose();
|
||||
_restoreCollisionCts?.Cancel();
|
||||
_restoreCollisionCts?.Dispose();
|
||||
RestoreIgnoredLayerCollisions();
|
||||
_animationSpeedCts?.Cancel();
|
||||
_animationSpeedCts?.Dispose();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
// Sample collision probes first; movement, wall slide, and jump decisions all use these flags.
|
||||
_isGrounded = Physics2D.OverlapCircle(_groundCheck.position, _groundCheckRadius, _groundLayer);
|
||||
_isTouchingLeftWall = Physics2D.OverlapCircle(_wallCheckLeft.position, _wallCheckRadius, _groundLayer);
|
||||
_isTouchingLeftWall = Physics2D.OverlapCircle(_wallCheckLeft.position, _wallCheckRadius, _groundLayer);
|
||||
_isTouchingRightWall = Physics2D.OverlapCircle(_wallCheckRight.position, _wallCheckRadius, _groundLayer);
|
||||
_wallDirection = _isTouchingRightWall ? 1 : (_isTouchingLeftWall ? -1 : 0);
|
||||
|
||||
@@ -132,43 +124,53 @@ private void FixedUpdate()
|
||||
_attackCooldownTimer -= Time.fixedDeltaTime;
|
||||
|
||||
UpdateMotionCooldowns();
|
||||
|
||||
if (_attackCooldownTimer <= 0f && _pendingInput.HasValue)
|
||||
{
|
||||
ComboInputType buffered = _pendingInput.Value;
|
||||
bool stillValid = Time.time - _pendingInputTime <= _bufferLifetime;
|
||||
_pendingInput = null;
|
||||
if (stillValid) ExecuteComboInput(buffered);
|
||||
}
|
||||
|
||||
if (_comboWindowTimer > 0f)
|
||||
{
|
||||
_comboWindowTimer -= Time.fixedDeltaTime;
|
||||
if (_comboWindowTimer <= 0f)
|
||||
_currentNode = null;
|
||||
}
|
||||
ExecuteBufferedInputIfReady();
|
||||
TickComboWindow();
|
||||
|
||||
if (_inputLockTimer > 0f)
|
||||
_inputLockTimer -= Time.fixedDeltaTime;
|
||||
else
|
||||
_rb.linearVelocity = new Vector2(GetBodyBlockedXVelocity(_moveInputX * _moveSpeed), _rb.linearVelocity.y);
|
||||
_rb.linearVelocity = new Vector2(_moveInputX * _moveSpeed, _rb.linearVelocity.y);
|
||||
|
||||
if (_facingLockTimer > 0f)
|
||||
_facingLockTimer -= Time.fixedDeltaTime;
|
||||
else
|
||||
UpdateFacingFromMoveInput();
|
||||
|
||||
ApplyGravity();
|
||||
|
||||
if (IsTouchingWall && !_isGrounded && _rb.linearVelocity.y < -_wallSlideSpeed)
|
||||
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, -_wallSlideSpeed);
|
||||
|
||||
// Player and Enemy bodies do not physically collide; only ground/walls clamp player velocity.
|
||||
ClampVelocityToGround();
|
||||
}
|
||||
|
||||
private void ExecuteBufferedInputIfReady()
|
||||
{
|
||||
if (_attackCooldownTimer > 0f || !_pendingInput.HasValue) return;
|
||||
|
||||
ComboInputType buffered = _pendingInput.Value;
|
||||
bool stillValid = Time.time - _pendingInputTime <= _bufferLifetime;
|
||||
_pendingInput = null;
|
||||
if (stillValid)
|
||||
ExecuteComboInput(buffered);
|
||||
}
|
||||
|
||||
private void TickComboWindow()
|
||||
{
|
||||
if (_comboWindowTimer <= 0f) return;
|
||||
|
||||
_comboWindowTimer -= Time.fixedDeltaTime;
|
||||
if (_comboWindowTimer <= 0f)
|
||||
_currentNode = null;
|
||||
}
|
||||
|
||||
private void OnMoveInput(Vector2 value)
|
||||
{
|
||||
_moveInputX = value.x == 0f ? 0f : Mathf.Sign(value.x);
|
||||
|
||||
if (_facingLockTimer > 0f) return;
|
||||
|
||||
UpdateFacingFromMoveInput();
|
||||
if (_facingLockTimer <= 0f)
|
||||
UpdateFacingFromMoveInput();
|
||||
}
|
||||
|
||||
private void UpdateFacingFromMoveInput()
|
||||
@@ -213,6 +215,7 @@ private void HandleComboInput(ComboInputType input)
|
||||
|
||||
private void ExecuteComboInput(ComboInputType input)
|
||||
{
|
||||
// Continue from the current combo node while its window is open.
|
||||
if (_comboWindowTimer > 0f && _currentNode != null)
|
||||
{
|
||||
foreach (var transition in _currentNode.Transitions)
|
||||
@@ -228,10 +231,11 @@ private void ExecuteComboInput(ComboInputType input)
|
||||
}
|
||||
}
|
||||
|
||||
// No active combo route matched, so start from the input's root node.
|
||||
ComboNode root = input switch
|
||||
{
|
||||
ComboInputType.Punch => _punchRootNode,
|
||||
ComboInputType.Kick => _kickRootNode,
|
||||
ComboInputType.Kick => _kickRootNode,
|
||||
_ => null
|
||||
};
|
||||
if (root == null || root.Action == null) return;
|
||||
@@ -277,218 +281,9 @@ private bool IsMotionOnCooldown(ActionData data)
|
||||
private void SetMotionCooldown(ActionData data)
|
||||
{
|
||||
if (data == null || data.Cooldown <= 0f) return;
|
||||
|
||||
_motionCooldownTimers[data] = data.Cooldown;
|
||||
}
|
||||
|
||||
private void IgnoreBodyCollisions()
|
||||
{
|
||||
int ignoredLayers = _bodyCollisionIgnoredLayers.value;
|
||||
if (ignoredLayers == 0) return;
|
||||
|
||||
int playerLayer = gameObject.layer;
|
||||
for (int layer = 0; layer < 32; layer++)
|
||||
{
|
||||
if ((ignoredLayers & (1 << layer)) == 0) continue;
|
||||
Physics2D.IgnoreLayerCollision(playerLayer, layer, true);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetBodyBlockedXVelocity(float xVelocity, ActionData action = null)
|
||||
{
|
||||
if (Mathf.Approximately(xVelocity, 0f)) return 0f;
|
||||
if (_bodyCollisionIgnoredLayers.value == 0) return xVelocity;
|
||||
if (CanPassBodyCollision(action)) return xVelocity;
|
||||
if (!IsBodyBlocked(Mathf.Sign(xVelocity))) return xVelocity;
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
private bool CanPassBodyCollision(ActionData action)
|
||||
{
|
||||
return action != null
|
||||
&& action.IgnoreCollisionDuringAction
|
||||
&& (action.IgnoredCollisionLayers.value & _bodyCollisionIgnoredLayers.value) != 0;
|
||||
}
|
||||
|
||||
private bool IsBodyBlocked(float direction)
|
||||
{
|
||||
if (_bodyColliders == null || _bodyColliders.Length == 0)
|
||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||
|
||||
ContactFilter2D filter = new ContactFilter2D
|
||||
{
|
||||
useLayerMask = true,
|
||||
layerMask = _bodyCollisionIgnoredLayers,
|
||||
useTriggers = false
|
||||
};
|
||||
|
||||
Vector2 castDirection = new Vector2(direction, 0f);
|
||||
for (int i = 0; i < _bodyColliders.Length; i++)
|
||||
{
|
||||
Collider2D bodyCollider = _bodyColliders[i];
|
||||
if (bodyCollider == null || bodyCollider.isTrigger) continue;
|
||||
|
||||
_castResults.Clear();
|
||||
if (bodyCollider.Cast(castDirection, filter, _castResults, _bodyBlockCastDistance) > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void IgnoreCollisionsIfNeeded(ActionData data)
|
||||
{
|
||||
_restoreCollisionCts?.Cancel();
|
||||
if (!data.IgnoreCollisionDuringAction)
|
||||
{
|
||||
RestoreIgnoredLayerCollisionsWhenClear();
|
||||
return;
|
||||
}
|
||||
|
||||
int playerLayer = gameObject.layer;
|
||||
int ignoredLayers = data.IgnoredCollisionLayers.value;
|
||||
_activeCollisionRecoveryLayerMask = ignoredLayers;
|
||||
for (int layer = 0; layer < 32; layer++)
|
||||
{
|
||||
if ((ignoredLayers & (1 << layer)) == 0) continue;
|
||||
if (Physics2D.GetIgnoreLayerCollision(playerLayer, layer)) continue;
|
||||
|
||||
Physics2D.IgnoreLayerCollision(playerLayer, layer, true);
|
||||
_ignoredLayerCollisions.Add(new IgnoredLayerCollision(playerLayer, layer));
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreIgnoredLayerCollisions()
|
||||
{
|
||||
for (int i = 0; i < _ignoredLayerCollisions.Count; i++)
|
||||
{
|
||||
IgnoredLayerCollision ignored = _ignoredLayerCollisions[i];
|
||||
Physics2D.IgnoreLayerCollision(ignored.LayerA, ignored.LayerB, false);
|
||||
}
|
||||
|
||||
_ignoredLayerCollisions.Clear();
|
||||
_activeCollisionRecoveryLayerMask = 0;
|
||||
}
|
||||
|
||||
private void RestoreIgnoredLayerCollisionsWhenClear(LayerMask ignoredLayers = default)
|
||||
{
|
||||
int recoveryLayerMask = ignoredLayers.value != 0 ? ignoredLayers.value : _activeCollisionRecoveryLayerMask;
|
||||
if (_ignoredLayerCollisions.Count == 0 && recoveryLayerMask == 0) return;
|
||||
|
||||
_restoreCollisionCts?.Cancel();
|
||||
_restoreCollisionCts?.Dispose();
|
||||
_restoreCollisionCts = CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken);
|
||||
WaitUntilClearThenRestoreCollisions(recoveryLayerMask, _restoreCollisionCts.Token);
|
||||
}
|
||||
|
||||
private async void WaitUntilClearThenRestoreCollisions(int recoveryLayerMask, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (IsOverlappingIgnoredLayers(recoveryLayerMask))
|
||||
{
|
||||
ResolveIgnoredLayerOverlap(recoveryLayerMask);
|
||||
await Awaitable.NextFrameAsync(token);
|
||||
}
|
||||
}
|
||||
catch (System.OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RestoreIgnoredLayerCollisions();
|
||||
}
|
||||
|
||||
private void ResolveIgnoredLayerOverlap(int layerMask)
|
||||
{
|
||||
if (layerMask == 0) return;
|
||||
|
||||
if (_bodyColliders == null || _bodyColliders.Length == 0)
|
||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||
|
||||
ContactFilter2D filter = new ContactFilter2D
|
||||
{
|
||||
useLayerMask = true,
|
||||
layerMask = layerMask,
|
||||
useTriggers = false
|
||||
};
|
||||
|
||||
Vector2 selfCenter = _rb.position;
|
||||
float distance = _overlapRecoverySpeed * Time.deltaTime;
|
||||
|
||||
for (int i = 0; i < _bodyColliders.Length; i++)
|
||||
{
|
||||
Collider2D bodyCollider = _bodyColliders[i];
|
||||
if (bodyCollider == null || bodyCollider.isTrigger) continue;
|
||||
|
||||
_overlapResults.Clear();
|
||||
bodyCollider.Overlap(filter, _overlapResults);
|
||||
|
||||
for (int j = 0; j < _overlapResults.Count; j++)
|
||||
{
|
||||
Collider2D other = _overlapResults[j];
|
||||
if (other == null) continue;
|
||||
|
||||
Vector2 pushDirection = selfCenter - (Vector2)other.bounds.center;
|
||||
if (pushDirection.sqrMagnitude < 0.0001f)
|
||||
pushDirection = GetFacingDirection();
|
||||
pushDirection.Normalize();
|
||||
|
||||
Rigidbody2D otherRb = other.attachedRigidbody;
|
||||
bool canMoveOther = otherRb != null && otherRb != _rb && otherRb.bodyType != RigidbodyType2D.Static;
|
||||
float otherDistance = canMoveOther ? distance * _overlapRecoveryOtherBodyRatio : 0f;
|
||||
float selfDistance = distance - otherDistance;
|
||||
|
||||
_rb.position += pushDirection * selfDistance;
|
||||
if (canMoveOther)
|
||||
otherRb.position -= pushDirection * otherDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 GetFacingDirection()
|
||||
{
|
||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||
return new Vector2(facing, 0f);
|
||||
}
|
||||
|
||||
private bool IsOverlappingIgnoredLayers(int layerMask)
|
||||
{
|
||||
if (layerMask == 0) return false;
|
||||
|
||||
if (_bodyColliders == null || _bodyColliders.Length == 0)
|
||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||
|
||||
ContactFilter2D filter = new ContactFilter2D
|
||||
{
|
||||
useLayerMask = true,
|
||||
layerMask = layerMask,
|
||||
useTriggers = false
|
||||
};
|
||||
|
||||
for (int i = 0; i < _bodyColliders.Length; i++)
|
||||
{
|
||||
Collider2D bodyCollider = _bodyColliders[i];
|
||||
if (bodyCollider == null || bodyCollider.isTrigger) continue;
|
||||
|
||||
_overlapResults.Clear();
|
||||
if (bodyCollider.Overlap(filter, _overlapResults) > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int GetCurrentIgnoredLayerMask()
|
||||
{
|
||||
int layerMask = 0;
|
||||
for (int i = 0; i < _ignoredLayerCollisions.Count; i++)
|
||||
layerMask |= 1 << _ignoredLayerCollisions[i].LayerB;
|
||||
|
||||
return layerMask;
|
||||
}
|
||||
|
||||
private async void PerformAttack(ActionData data, bool preserveHorizontalVelocity = false)
|
||||
{
|
||||
_attackCts?.Cancel();
|
||||
@@ -504,25 +299,26 @@ private async void PerformAttack(ActionData data, bool preserveHorizontalVelocit
|
||||
PlayActionAnimation(data);
|
||||
|
||||
if (data.HasMotion)
|
||||
{
|
||||
ApplyActionVelocity(data);
|
||||
}
|
||||
|
||||
LockMovementIfNeeded(data, preserveHorizontalVelocity);
|
||||
LockFacingIfNeeded(data);
|
||||
IgnoreCollisionsIfNeeded(data);
|
||||
|
||||
try
|
||||
{
|
||||
await HitRoutine(data, token);
|
||||
}
|
||||
catch (System.OperationCanceledException) { }
|
||||
RestoreIgnoredLayerCollisionsWhenClear(data.IgnoredCollisionLayers);
|
||||
catch (System.OperationCanceledException)
|
||||
{
|
||||
_attackHitbox?.Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
private async void PerformMotion(ActionData data)
|
||||
{
|
||||
if (data == null || IsMotionOnCooldown(data)) return;
|
||||
|
||||
// Motions such as dash/roll interrupt attacks and become the new combo node.
|
||||
CancelAttack();
|
||||
_motionCts?.Cancel();
|
||||
_motionCts?.Dispose();
|
||||
@@ -530,13 +326,10 @@ private async void PerformMotion(ActionData data)
|
||||
CancellationToken token = _motionCts.Token;
|
||||
|
||||
SetMotionCooldown(data);
|
||||
|
||||
FaceMotionDirection(data);
|
||||
PlayActionAnimation(data);
|
||||
|
||||
LockMovementIfNeeded(data);
|
||||
LockFacingIfNeeded(data);
|
||||
IgnoreCollisionsIfNeeded(data);
|
||||
|
||||
bool completed = false;
|
||||
try
|
||||
@@ -551,7 +344,6 @@ private async void PerformMotion(ActionData data)
|
||||
StopActionVelocity(data);
|
||||
PlayIdleAnimation();
|
||||
}
|
||||
RestoreIgnoredLayerCollisionsWhenClear(data.IgnoredCollisionLayers);
|
||||
}
|
||||
|
||||
private async Awaitable MotionRoutine(ActionData data, CancellationToken token)
|
||||
@@ -562,7 +354,6 @@ private async Awaitable MotionRoutine(ActionData data, CancellationToken token)
|
||||
while (elapsed < duration)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
||||
ApplyActionVelocity(data, normalizedTime);
|
||||
|
||||
@@ -579,6 +370,79 @@ private void CancelAttack()
|
||||
_attackCts?.Cancel();
|
||||
_attackCooldownTimer = 0f;
|
||||
_pendingInput = null;
|
||||
_attackHitbox?.Deactivate();
|
||||
}
|
||||
|
||||
private async Awaitable HitRoutine(ActionData data, CancellationToken token)
|
||||
{
|
||||
float attackStartTime = Time.time;
|
||||
|
||||
if (!data.HasHit)
|
||||
{
|
||||
if (data.MotionDuration > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(data.MotionDuration, token);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.HitTiming > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(data.HitTiming, token);
|
||||
|
||||
// Hit windows are represented by a real trigger collider instead of overlap checks.
|
||||
ActivateAttackHitbox(data);
|
||||
|
||||
float activeTime = Mathf.Max(data.HitDuration, 0.02f);
|
||||
await Awaitable.WaitForSecondsAsync(activeTime, token);
|
||||
_attackHitbox.Deactivate();
|
||||
|
||||
float remaining = data.MotionDuration - (Time.time - attackStartTime);
|
||||
if (remaining > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(remaining, token);
|
||||
|
||||
PlayIdleAnimation();
|
||||
}
|
||||
|
||||
private void ActivateAttackHitbox(ActionData data)
|
||||
{
|
||||
Vector2 localPosition = GetAttackLocalPosition(data.Offset);
|
||||
Vector2 hitVelocity = GetHitVelocity(data.HitVelocity);
|
||||
|
||||
_lastHitData = data;
|
||||
_lastHitCenter = transform.TransformPoint(localPosition);
|
||||
_lastHitTime = Time.time;
|
||||
_hitFired = true;
|
||||
|
||||
_attackHitbox.Activate(data, localPosition, hitVelocity, _enemyLayer);
|
||||
}
|
||||
|
||||
private void EnsureAttackHitbox()
|
||||
{
|
||||
// Allow designers to assign a hitbox, but create one automatically for simple setup.
|
||||
if (_attackHitbox != null)
|
||||
{
|
||||
SetAttackHitboxLayer();
|
||||
return;
|
||||
}
|
||||
|
||||
_attackHitbox = GetComponentInChildren<AttackHitbox>(true);
|
||||
if (_attackHitbox != null)
|
||||
{
|
||||
SetAttackHitboxLayer();
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject hitboxObject = new GameObject("AttackHitbox");
|
||||
hitboxObject.transform.SetParent(transform, false);
|
||||
hitboxObject.AddComponent<CircleCollider2D>();
|
||||
_attackHitbox = hitboxObject.AddComponent<AttackHitbox>();
|
||||
SetAttackHitboxLayer();
|
||||
}
|
||||
|
||||
private void SetAttackHitboxLayer()
|
||||
{
|
||||
// The hitbox must not inherit the Player layer, because Player vs Enemy physics is disabled.
|
||||
int defaultLayer = LayerMask.NameToLayer("Default");
|
||||
if (defaultLayer >= 0)
|
||||
_attackHitbox.gameObject.layer = defaultLayer;
|
||||
}
|
||||
|
||||
private void ApplyActionVelocity(ActionData data, float normalizedTime = 0f)
|
||||
@@ -587,9 +451,9 @@ private void ApplyActionVelocity(ActionData data, float normalizedTime = 0f)
|
||||
float speedMultiplier = data.MotionSpeedCurve != null
|
||||
? data.MotionSpeedCurve.Evaluate(normalizedTime)
|
||||
: 1f;
|
||||
|
||||
Vector2 velocity = data.Velocity * speedMultiplier;
|
||||
velocity.x *= direction;
|
||||
velocity.x = GetBodyBlockedXVelocity(velocity.x, data);
|
||||
|
||||
if (data.PreserveYVelocity)
|
||||
velocity.y = _rb.linearVelocity.y;
|
||||
@@ -600,22 +464,14 @@ private void ApplyActionVelocity(ActionData data, float normalizedTime = 0f)
|
||||
private void StopActionVelocity(ActionData data)
|
||||
{
|
||||
if (!data.StopHorizontalVelocityOnEnd) return;
|
||||
|
||||
_rb.linearVelocity = new Vector2(0f, _rb.linearVelocity.y);
|
||||
}
|
||||
|
||||
private bool IsActionAnimationComplete(ActionData data)
|
||||
{
|
||||
if (_anim == null || string.IsNullOrEmpty(data.AnimationState)) return false;
|
||||
|
||||
AnimatorStateInfo stateInfo = _anim.GetCurrentAnimatorStateInfo(0);
|
||||
return stateInfo.IsName(data.AnimationState) && stateInfo.normalizedTime >= 1f;
|
||||
}
|
||||
|
||||
private void LockMovementIfNeeded(ActionData data, bool preserveHorizontalVelocity = false)
|
||||
{
|
||||
if (data.CanMoveDuringAction) return;
|
||||
|
||||
// Non-moving attacks should not inherit walking velocity from the previous frame.
|
||||
if (!preserveHorizontalVelocity && !data.HasMotion)
|
||||
_rb.linearVelocity = new Vector2(0f, _rb.linearVelocity.y);
|
||||
|
||||
@@ -625,7 +481,6 @@ private void LockMovementIfNeeded(ActionData data, bool preserveHorizontalVeloci
|
||||
private void LockFacingIfNeeded(ActionData data)
|
||||
{
|
||||
if (data.CanTurnDuringAction) return;
|
||||
|
||||
_facingLockTimer = Mathf.Max(data.MotionDuration, 0.02f);
|
||||
}
|
||||
|
||||
@@ -664,7 +519,6 @@ private async void ApplyAnimationSpeedCurve(ActionData data, CancellationToken t
|
||||
while (elapsed < duration)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
||||
_anim.speed = GetAnimationSpeed(data, normalizedTime);
|
||||
|
||||
@@ -701,71 +555,6 @@ private void FaceMotionDirection(ActionData data)
|
||||
_facingLockTimer = 0f;
|
||||
}
|
||||
|
||||
private async Awaitable HitRoutine(ActionData data, CancellationToken token)
|
||||
{
|
||||
float attackStartTime = Time.time;
|
||||
|
||||
if (!data.HasHit)
|
||||
{
|
||||
if (data.MotionDuration > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(data.MotionDuration, token);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.HitTiming > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(data.HitTiming, token);
|
||||
|
||||
_lastAttackGizmoTime = Time.time;
|
||||
_lastHitData = data;
|
||||
_hitFired = true;
|
||||
|
||||
if (data.HitDuration <= 0f)
|
||||
{
|
||||
ApplyDamageInArea(data, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var alreadyHit = new HashSet<IDamageable>();
|
||||
float elapsed = 0f;
|
||||
while (elapsed < data.HitDuration)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
ApplyDamageInArea(data, alreadyHit);
|
||||
await Awaitable.NextFrameAsync(token);
|
||||
elapsed += Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
float remaining = data.MotionDuration - (Time.time - attackStartTime);
|
||||
if (remaining > 0f)
|
||||
await Awaitable.WaitForSecondsAsync(remaining, token);
|
||||
|
||||
PlayIdleAnimation();
|
||||
}
|
||||
|
||||
private void ApplyDamageInArea(ActionData data, HashSet<IDamageable> alreadyHit)
|
||||
{
|
||||
Vector2 center = GetAttackCenter(data.Offset);
|
||||
|
||||
_lastHitData = data;
|
||||
_lastHitCenter = center;
|
||||
_lastHitTime = Time.time;
|
||||
|
||||
Collider2D[] hits = Physics2D.OverlapCircleAll(center, data.Radius, _enemyLayer);
|
||||
foreach (var hit in hits)
|
||||
{
|
||||
if (!hit.TryGetComponent<IDamageable>(out var target)) continue;
|
||||
|
||||
if (alreadyHit != null)
|
||||
{
|
||||
if (alreadyHit.Contains(target)) continue;
|
||||
alreadyHit.Add(target);
|
||||
}
|
||||
|
||||
target.TakeDamage(data.Damage, GetHitVelocity(data.HitVelocity), data.HitReactionAnimationState);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 GetHitVelocity(Vector2 hitVelocity)
|
||||
{
|
||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||
@@ -773,19 +562,19 @@ private Vector2 GetHitVelocity(Vector2 hitVelocity)
|
||||
return hitVelocity;
|
||||
}
|
||||
|
||||
private Vector2 GetAttackLocalPosition(Vector2 offset)
|
||||
{
|
||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||
offset.x *= facing;
|
||||
return offset;
|
||||
}
|
||||
|
||||
private string GetActionName(ActionData data)
|
||||
{
|
||||
if (data == null) return string.Empty;
|
||||
return string.IsNullOrEmpty(data.ActionName) ? data.name : data.ActionName;
|
||||
}
|
||||
|
||||
private Vector2 GetAttackCenter(Vector2 offset)
|
||||
{
|
||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||
offset.x *= facing;
|
||||
return (Vector2)transform.position + offset;
|
||||
}
|
||||
|
||||
private void ApplyForwardStep(float distance, float duration)
|
||||
{
|
||||
if (distance <= 0f) return;
|
||||
@@ -798,6 +587,98 @@ private void ApplyForwardStep(float distance, float duration)
|
||||
_inputLockTimer = safeDuration;
|
||||
}
|
||||
|
||||
private bool IsActionAnimationComplete(ActionData data)
|
||||
{
|
||||
if (_anim == null || string.IsNullOrEmpty(data.AnimationState)) return false;
|
||||
|
||||
AnimatorStateInfo stateInfo = _anim.GetCurrentAnimatorStateInfo(0);
|
||||
return stateInfo.IsName(data.AnimationState) && stateInfo.normalizedTime >= 1f;
|
||||
}
|
||||
|
||||
private void ApplyGravity()
|
||||
{
|
||||
float vy = _rb.linearVelocity.y;
|
||||
|
||||
if (_isGrounded && vy <= 0f)
|
||||
{
|
||||
if (vy != 0f)
|
||||
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, 0f);
|
||||
return;
|
||||
}
|
||||
|
||||
float newY = Mathf.Max(vy + _gravity * Time.fixedDeltaTime, -_maxFallSpeed);
|
||||
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, newY);
|
||||
}
|
||||
|
||||
private void ClampVelocityToGround()
|
||||
{
|
||||
int solidMask = _groundLayer.value;
|
||||
if (solidMask == 0) return;
|
||||
|
||||
Vector2 velocity = _rb.linearVelocity;
|
||||
bool changed = false;
|
||||
|
||||
if (Mathf.Abs(velocity.x) > 0.001f)
|
||||
{
|
||||
float sign = Mathf.Sign(velocity.x);
|
||||
float maxDist = Mathf.Abs(velocity.x * Time.fixedDeltaTime);
|
||||
float hitDist = GetClosestHitDistance(new Vector2(sign, 0f), maxDist + _skinWidth, solidMask);
|
||||
if (hitDist < maxDist + _skinWidth)
|
||||
{
|
||||
float allowed = Mathf.Max(hitDist - _skinWidth, 0f);
|
||||
velocity.x = sign * (allowed / Time.fixedDeltaTime);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Mathf.Abs(velocity.y) > 0.001f)
|
||||
{
|
||||
float sign = Mathf.Sign(velocity.y);
|
||||
float maxDist = Mathf.Abs(velocity.y * Time.fixedDeltaTime);
|
||||
float hitDist = GetClosestHitDistance(new Vector2(0f, sign), maxDist + _skinWidth, solidMask);
|
||||
if (hitDist < maxDist + _skinWidth)
|
||||
{
|
||||
float allowed = Mathf.Max(hitDist - _skinWidth, 0f);
|
||||
velocity.y = sign * (allowed / Time.fixedDeltaTime);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
_rb.linearVelocity = velocity;
|
||||
}
|
||||
|
||||
private float GetClosestHitDistance(Vector2 direction, float distance, int layerMask)
|
||||
{
|
||||
if (_bodyColliders == null || _bodyColliders.Length == 0)
|
||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||
|
||||
ContactFilter2D filter = new ContactFilter2D
|
||||
{
|
||||
useLayerMask = true,
|
||||
layerMask = layerMask,
|
||||
useTriggers = false
|
||||
};
|
||||
|
||||
// Cast every non-trigger body collider so high-speed motion cannot tunnel into level geometry.
|
||||
float closest = float.PositiveInfinity;
|
||||
for (int i = 0; i < _bodyColliders.Length; i++)
|
||||
{
|
||||
Collider2D bodyCollider = _bodyColliders[i];
|
||||
if (bodyCollider == null || bodyCollider.isTrigger) continue;
|
||||
|
||||
_castResults.Clear();
|
||||
int hitCount = bodyCollider.Cast(direction, filter, _castResults, distance);
|
||||
for (int j = 0; j < hitCount; j++)
|
||||
{
|
||||
if (_castResults[j].distance < closest)
|
||||
closest = _castResults[j].distance;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (_lastHitData == null || _lastHitTime < 0f) return;
|
||||
@@ -833,34 +714,6 @@ private void OnDrawGizmosSelected()
|
||||
Gizmos.color = _isTouchingRightWall ? Color.green : Color.red;
|
||||
Gizmos.DrawWireSphere(_wallCheckRight.position, _wallCheckRadius);
|
||||
}
|
||||
|
||||
DrawLastAttackGizmo();
|
||||
}
|
||||
|
||||
private void DrawLastAttackGizmo()
|
||||
{
|
||||
if (_lastAttackGizmoData == null) return;
|
||||
if (!Application.isPlaying) return;
|
||||
|
||||
float elapsed = Time.time - _lastAttackGizmoTime;
|
||||
if (elapsed < 0f) return;
|
||||
|
||||
ActionData data = _lastAttackGizmoData;
|
||||
float activeDuration = Mathf.Max(data.HitDuration, 0.05f);
|
||||
float fadeDuration = 0.4f;
|
||||
float total = activeDuration + fadeDuration;
|
||||
if (elapsed > total) return;
|
||||
|
||||
float alpha = elapsed < activeDuration
|
||||
? 1f
|
||||
: 1f - (elapsed - activeDuration) / fadeDuration;
|
||||
alpha = Mathf.Clamp01(alpha);
|
||||
|
||||
Vector2 center = GetAttackCenter(data.Offset);
|
||||
Gizmos.color = new Color(1f, 0.3f, 0.3f, alpha * 0.35f);
|
||||
Gizmos.DrawSphere(center, data.Radius);
|
||||
Gizmos.color = new Color(1f, 0f, 0f, alpha);
|
||||
Gizmos.DrawWireSphere(center, data.Radius);
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
@@ -919,7 +772,7 @@ private void DrawTimelineBar(ActionData data, float elapsed)
|
||||
GUI.color = new Color(0f, 0f, 0f, 0.6f);
|
||||
GUI.DrawTexture(new Rect(barX, barY, barW, barH), Texture2D.whiteTexture);
|
||||
|
||||
float hitX = barX + (data.HitTiming / totalTime) * barW;
|
||||
float hitX = barX + (data.HitTiming / totalTime) * barW;
|
||||
float hitEndX = barX + ((data.HitTiming + data.HitDuration) / totalTime) * barW;
|
||||
GUI.color = new Color(1f, 0.3f, 0.3f, 0.5f);
|
||||
GUI.DrawTexture(new Rect(hitX, barY, Mathf.Max(hitEndX - hitX, 4f), barH), Texture2D.whiteTexture);
|
||||
@@ -938,16 +791,4 @@ private void DrawTimelineBar(ActionData data, float elapsed)
|
||||
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
private readonly struct IgnoredLayerCollision
|
||||
{
|
||||
public readonly int LayerA;
|
||||
public readonly int LayerB;
|
||||
|
||||
public IgnoredLayerCollision(int layerA, int layerB)
|
||||
{
|
||||
LayerA = layerA;
|
||||
LayerB = layerB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Assets/05_Data/Motion/Dash.asset
LFS
BIN
Assets/05_Data/Motion/Dash.asset
LFS
Binary file not shown.
BIN
Assets/05_Data/Motion/Roll.asset
LFS
BIN
Assets/05_Data/Motion/Roll.asset
LFS
Binary file not shown.
Binary file not shown.
BIN
ProjectSettings/TagManager.asset
LFS
BIN
ProjectSettings/TagManager.asset
LFS
Binary file not shown.
Reference in New Issue
Block a user