diff --git a/Assembly-CSharp.csproj.lscache b/Assembly-CSharp.csproj.lscache new file mode 100644 index 0000000..2d94f52 --- /dev/null +++ b/Assembly-CSharp.csproj.lscache @@ -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=Temp/obj/Assembly-CSharp/project.assets.json +RootNamespace= +RunAnalyzers= +RunAnalyzersDuringLiveAnalysis= +SolutionPath=Unity_2D_WhiteAction.slnx +TargetFrameworkIdentifier=.NETStandard +TargetPath=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 diff --git a/Assets/01_Scenes/GameScene.unity b/Assets/01_Scenes/GameScene.unity index 7d87ca9..2618deb 100644 --- a/Assets/01_Scenes/GameScene.unity +++ b/Assets/01_Scenes/GameScene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0753f43382b6471b985b9460794faa29aed9ac8aad2560fcab7b9bde8d08fd6 -size 52624 +oid sha256:6d99b9098b9796ccaead6c35e1691fe7ea32bb5ba0c3ec3a73849b6d04bea673 +size 52185 diff --git a/Assets/02_Scripts/Combat/ActionData.cs b/Assets/02_Scripts/Combat/ActionData.cs index 8b8cf7d..2be1401 100644 --- a/Assets/02_Scripts/Combat/ActionData.cs +++ b/Assets/02_Scripts/Combat/ActionData.cs @@ -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; diff --git a/Assets/02_Scripts/Combat/AttackHitbox.cs b/Assets/02_Scripts/Combat/AttackHitbox.cs new file mode 100644 index 0000000..27df236 --- /dev/null +++ b/Assets/02_Scripts/Combat/AttackHitbox.cs @@ -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 _alreadyHit = new(); + + private void Awake() + { + _collider = GetComponent(); + // 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(out var target)) + target = other.GetComponentInParent(); + if (target == null) return; + if (_alreadyHit.Contains(target)) return; + + _alreadyHit.Add(target); + target.TakeDamage(_damage, _hitVelocity, _hitReactionState); + } +} diff --git a/Assets/02_Scripts/Combat/AttackHitbox.cs.meta b/Assets/02_Scripts/Combat/AttackHitbox.cs.meta new file mode 100644 index 0000000..6e063f6 --- /dev/null +++ b/Assets/02_Scripts/Combat/AttackHitbox.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 90c25ca9d3ad4c8d9e4cc0b98ff95e12 diff --git a/Assets/02_Scripts/Enemy/Enemy.cs b/Assets/02_Scripts/Enemy/Enemy.cs index ff04a36..3a1ba3b 100644 --- a/Assets/02_Scripts/Enemy/Enemy.cs +++ b/Assets/02_Scripts/Enemy/Enemy.cs @@ -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; diff --git a/Assets/02_Scripts/Player/PlayerController.cs b/Assets/02_Scripts/Player/PlayerController.cs index 0cabf47..7679c2f 100644 --- a/Assets/02_Scripts/Player/PlayerController.cs +++ b/Assets/02_Scripts/Player/PlayerController.cs @@ -34,24 +34,17 @@ public class PlayerController : MonoBehaviour [SerializeField] private ComboNode _rollRootNode; private readonly Dictionary _motionCooldownTimers = new(); private readonly List _motionCooldownKeys = new(); - private readonly List _ignoredLayerCollisions = new(); - private readonly List _overlapResults = new(); - private readonly List _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 _castResults = new(); + private Collider2D[] _bodyColliders; private Rigidbody2D _rb; private Animator _anim; private SpriteRenderer _spriteRenderer; @@ -84,14 +79,13 @@ private void Awake() _anim = GetComponent(); _spriteRenderer = GetComponentInChildren(); _bodyColliders = GetComponentsInChildren(); - 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(); - - 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(); - - 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(); - - 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(true); + if (_attackHitbox != null) + { + SetAttackHitboxLayer(); + return; + } + + GameObject hitboxObject = new GameObject("AttackHitbox"); + hitboxObject.transform.SetParent(transform, false); + hitboxObject.AddComponent(); + _attackHitbox = hitboxObject.AddComponent(); + 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(); - 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 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(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(); + + 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; - } - } } diff --git a/Assets/05_Data/Attack/Kick_A.asset b/Assets/05_Data/Attack/Kick_A.asset index bddc55e..55b6cf3 100644 --- a/Assets/05_Data/Attack/Kick_A.asset +++ b/Assets/05_Data/Attack/Kick_A.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85865e7243cbf924a44378c57d46bb4d7bc620a1115148958b3deeb4cdfd99c5 -size 1397 +oid sha256:e72e439b75af2ddbb67e3fb9297346bff5087d49fe2fabc63615de817fdce1ff +size 1296 diff --git a/Assets/05_Data/Attack/Kick_B.asset b/Assets/05_Data/Attack/Kick_B.asset index 9535507..1a19813 100644 --- a/Assets/05_Data/Attack/Kick_B.asset +++ b/Assets/05_Data/Attack/Kick_B.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fb17a64df97fd6ff3d7fac22ba257b48f0a41d5fb9680c8f92c024237bc7d5a -size 1397 +oid sha256:a3e53d72c36abb9f822b0b9f832bc719c750452181f0f78f31738d7a3dd2d6ca +size 1296 diff --git a/Assets/05_Data/Attack/Kick_C.asset b/Assets/05_Data/Attack/Kick_C.asset index 6f89e66..0bec106 100644 --- a/Assets/05_Data/Attack/Kick_C.asset +++ b/Assets/05_Data/Attack/Kick_C.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77ba009af9cd1cd1d4e4d1c6709e21fc949d3f6864e376b68685d399a1f25c82 -size 1454 +oid sha256:7285d53b1d2d6af02b39da4a2bff813b9bf2d14c5ed34915b3add5becb208c60 +size 1353 diff --git a/Assets/05_Data/Attack/Punch_A.asset b/Assets/05_Data/Attack/Punch_A.asset index 4231957..faedccb 100644 --- a/Assets/05_Data/Attack/Punch_A.asset +++ b/Assets/05_Data/Attack/Punch_A.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd1fcd2a69cccb16a6c1116fd36d8bdbf7c5e38738cb29f5e2534aa33bb33a60 -size 1399 +oid sha256:077405ba2ba24d22620cf099247a56fb65079cb02e8e4f7e77e814e313349c12 +size 1298 diff --git a/Assets/05_Data/Attack/Punch_B.asset b/Assets/05_Data/Attack/Punch_B.asset index 318875e..9a0bf75 100644 --- a/Assets/05_Data/Attack/Punch_B.asset +++ b/Assets/05_Data/Attack/Punch_B.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5dcd26ba980948c6dcff5d7c726f304d3fcedfd43c17e3bcbb63de27117a80b -size 1399 +oid sha256:50f23924228d74e237250fcd69b79d2459cec18b64d93a0746b07d274391f22f +size 1298 diff --git a/Assets/05_Data/Attack/Punch_C.asset b/Assets/05_Data/Attack/Punch_C.asset index 8829500..5c89496 100644 --- a/Assets/05_Data/Attack/Punch_C.asset +++ b/Assets/05_Data/Attack/Punch_C.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:366fd5748ee99cd90fb000d43cd52136c903f7ec6e6887784bf820f9daa234d7 -size 1459 +oid sha256:83fc9e5a5da796b6f15018ee4639d761c74daf18d2e4780f14c875ea7dc585b5 +size 1358 diff --git a/Assets/05_Data/Motion/Dash.asset b/Assets/05_Data/Motion/Dash.asset index a27c4cf..9e71406 100644 --- a/Assets/05_Data/Motion/Dash.asset +++ b/Assets/05_Data/Motion/Dash.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22d4fe2447d78255aa7b8ed8aae62475b8b01b1b759d953a4f98e4a526262e13 -size 3117 +oid sha256:293c4648a4345dda661cf2a302a1844ca640e61f6b53bd29f8cb50cf65ccbd43 +size 3018 diff --git a/Assets/05_Data/Motion/Roll.asset b/Assets/05_Data/Motion/Roll.asset index 676e365..9b77175 100644 --- a/Assets/05_Data/Motion/Roll.asset +++ b/Assets/05_Data/Motion/Roll.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:931bb8aa580fecf101b41a450fba014a0012d61f3d6c0dd0924f945b4f3b8b0a -size 2462 +oid sha256:cd865f4a60abed6277663c3d8bfe89e5c125ecdd7d6f60d28c721a0b5b60f752 +size 2363 diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset index 36189c0..691d905 100644 --- a/ProjectSettings/Physics2DSettings.asset +++ b/ProjectSettings/Physics2DSettings.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3cbdbf0be15244b7b67d2f07bdb8e8981911c11a8c7fe8035f5261272fec658 -size 2028 +oid sha256:0f183f72ae5340e621daed51b23ea478a8e424786b431033d6886c5a3d2c283c +size 1862 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 30210b1..5e4eeed 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4989ce711c55e1979c0e21ba039bd806ccb5a06c7a35d91bcea65c51f3226d8e -size 569 +oid sha256:435994dc2c596790528155eddeaf5e99a0b4fcba204f181c8dd4bcf53049d4b9 +size 575