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 UseInputDirection = true;
|
||||||
public bool PreserveYVelocity = true;
|
public bool PreserveYVelocity = true;
|
||||||
public bool StopHorizontalVelocityOnEnd = true;
|
public bool StopHorizontalVelocityOnEnd = true;
|
||||||
public bool IgnoreCollisionDuringAction;
|
|
||||||
public LayerMask IgnoredCollisionLayers;
|
|
||||||
|
|
||||||
[Header("Hit")]
|
[Header("Hit")]
|
||||||
public bool HasHit = true;
|
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))
|
if (_anim != null && !string.IsNullOrEmpty(hitReactionAnimationState))
|
||||||
_anim.Play(hitReactionAnimationState);
|
_anim.Play(hitReactionAnimationState);
|
||||||
|
|
||||||
|
// HitVelocity is an immediate launch/knockback velocity, not an additive force.
|
||||||
if (_rb != null)
|
if (_rb != null)
|
||||||
{
|
{
|
||||||
Vector2 nextVelocity = GetHitReactionVelocity(hitVelocity);
|
Vector2 nextVelocity = GetHitReactionVelocity(hitVelocity);
|
||||||
@@ -116,6 +117,7 @@ private void OnCollisionExit2D(Collision2D collision)
|
|||||||
|
|
||||||
private Vector2 GetHitReactionVelocity(Vector2 hitVelocity)
|
private Vector2 GetHitReactionVelocity(Vector2 hitVelocity)
|
||||||
{
|
{
|
||||||
|
// Airborne follow-up hits pop the enemy with a fixed Y velocity for stable combos.
|
||||||
if (_hitReactionTimer <= 0f || _isGrounded)
|
if (_hitReactionTimer <= 0f || _isGrounded)
|
||||||
return hitVelocity;
|
return hitVelocity;
|
||||||
|
|
||||||
@@ -139,6 +141,7 @@ private void UpdateGroundedState(Collision2D collision)
|
|||||||
|
|
||||||
private void BounceOffWall(Vector2 wallNormal)
|
private void BounceOffWall(Vector2 wallNormal)
|
||||||
{
|
{
|
||||||
|
// While in hit reaction, side-wall impacts reflect the current knockback.
|
||||||
Vector2 incomingVelocity = _lastVelocity.sqrMagnitude > _rb.linearVelocity.sqrMagnitude
|
Vector2 incomingVelocity = _lastVelocity.sqrMagnitude > _rb.linearVelocity.sqrMagnitude
|
||||||
? _lastVelocity
|
? _lastVelocity
|
||||||
: _rb.linearVelocity;
|
: _rb.linearVelocity;
|
||||||
|
|||||||
@@ -34,24 +34,17 @@ public class PlayerController : MonoBehaviour
|
|||||||
[SerializeField] private ComboNode _rollRootNode;
|
[SerializeField] private ComboNode _rollRootNode;
|
||||||
private readonly Dictionary<ActionData, float> _motionCooldownTimers = new();
|
private readonly Dictionary<ActionData, float> _motionCooldownTimers = new();
|
||||||
private readonly List<ActionData> _motionCooldownKeys = 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")]
|
[Header("Kinematic Physics")]
|
||||||
[SerializeField] private float _overlapRecoverySpeed = 8f;
|
[SerializeField] private float _gravity = -25f;
|
||||||
[SerializeField] private float _overlapRecoveryOtherBodyRatio = 0.5f;
|
[SerializeField] private float _maxFallSpeed = 20f;
|
||||||
[SerializeField] private float _bodyBlockCastDistance = 0.08f;
|
[SerializeField] private float _skinWidth = 0.02f;
|
||||||
|
|
||||||
[Header("Attack")]
|
[Header("Attack")]
|
||||||
[SerializeField] private ComboNode _punchRootNode;
|
[SerializeField] private ComboNode _punchRootNode;
|
||||||
[SerializeField] private ComboNode _kickRootNode;
|
[SerializeField] private ComboNode _kickRootNode;
|
||||||
[SerializeField] private LayerMask _enemyLayer;
|
[SerializeField] private LayerMask _enemyLayer;
|
||||||
[SerializeField] private LayerMask _bodyCollisionIgnoredLayers;
|
[SerializeField] private AttackHitbox _attackHitbox;
|
||||||
[SerializeField] private string _idleAnimationState = "Idle";
|
[SerializeField] private string _idleAnimationState = "Idle";
|
||||||
[SerializeField] private float _bufferOpenTime = 0.1f;
|
[SerializeField] private float _bufferOpenTime = 0.1f;
|
||||||
[SerializeField] private float _bufferLifetime = 0.5f;
|
[SerializeField] private float _bufferLifetime = 0.5f;
|
||||||
@@ -61,9 +54,9 @@ public class PlayerController : MonoBehaviour
|
|||||||
private ComboNode _currentNode;
|
private ComboNode _currentNode;
|
||||||
private float _comboWindowTimer;
|
private float _comboWindowTimer;
|
||||||
private CancellationTokenSource _attackCts;
|
private CancellationTokenSource _attackCts;
|
||||||
|
private CancellationTokenSource _motionCts;
|
||||||
private CancellationTokenSource _animationSpeedCts;
|
private CancellationTokenSource _animationSpeedCts;
|
||||||
private ActionData _lastAttackGizmoData;
|
private ActionData _lastAttackGizmoData;
|
||||||
private float _lastAttackGizmoTime = -1f;
|
|
||||||
[SerializeField] private float _hitGizmoFadeDuration = 0.5f;
|
[SerializeField] private float _hitGizmoFadeDuration = 0.5f;
|
||||||
private ActionData _lastHitData;
|
private ActionData _lastHitData;
|
||||||
private Vector2 _lastHitCenter;
|
private Vector2 _lastHitCenter;
|
||||||
@@ -74,6 +67,8 @@ public class PlayerController : MonoBehaviour
|
|||||||
private float _attackStartTime = -1f;
|
private float _attackStartTime = -1f;
|
||||||
private bool _hitFired;
|
private bool _hitFired;
|
||||||
|
|
||||||
|
private readonly List<RaycastHit2D> _castResults = new();
|
||||||
|
private Collider2D[] _bodyColliders;
|
||||||
private Rigidbody2D _rb;
|
private Rigidbody2D _rb;
|
||||||
private Animator _anim;
|
private Animator _anim;
|
||||||
private SpriteRenderer _spriteRenderer;
|
private SpriteRenderer _spriteRenderer;
|
||||||
@@ -84,14 +79,13 @@ private void Awake()
|
|||||||
_anim = GetComponent<Animator>();
|
_anim = GetComponent<Animator>();
|
||||||
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||||
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
_bodyColliders = GetComponentsInChildren<Collider2D>();
|
||||||
IgnoreBodyCollisions();
|
EnsureAttackHitbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
InputManager.Instance.OnMove_Event += OnMoveInput;
|
InputManager.Instance.OnMove_Event += OnMoveInput;
|
||||||
InputManager.Instance.OnJump_Event += OnJumpInput;
|
InputManager.Instance.OnJump_Event += OnJumpInput;
|
||||||
|
|
||||||
InputManager.Instance.OnPunch_Event += OnPunchInput;
|
InputManager.Instance.OnPunch_Event += OnPunchInput;
|
||||||
InputManager.Instance.OnKick_Event += OnKickInput;
|
InputManager.Instance.OnKick_Event += OnKickInput;
|
||||||
InputManager.Instance.OnDash_Event += OnDashInput;
|
InputManager.Instance.OnDash_Event += OnDashInput;
|
||||||
@@ -112,19 +106,17 @@ private void OnDestroy()
|
|||||||
|
|
||||||
_attackCts?.Cancel();
|
_attackCts?.Cancel();
|
||||||
_attackCts?.Dispose();
|
_attackCts?.Dispose();
|
||||||
_animationSpeedCts?.Cancel();
|
|
||||||
_animationSpeedCts?.Dispose();
|
|
||||||
_motionCts?.Cancel();
|
_motionCts?.Cancel();
|
||||||
_motionCts?.Dispose();
|
_motionCts?.Dispose();
|
||||||
_restoreCollisionCts?.Cancel();
|
_animationSpeedCts?.Cancel();
|
||||||
_restoreCollisionCts?.Dispose();
|
_animationSpeedCts?.Dispose();
|
||||||
RestoreIgnoredLayerCollisions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
|
// Sample collision probes first; movement, wall slide, and jump decisions all use these flags.
|
||||||
_isGrounded = Physics2D.OverlapCircle(_groundCheck.position, _groundCheckRadius, _groundLayer);
|
_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);
|
_isTouchingRightWall = Physics2D.OverlapCircle(_wallCheckRight.position, _wallCheckRadius, _groundLayer);
|
||||||
_wallDirection = _isTouchingRightWall ? 1 : (_isTouchingLeftWall ? -1 : 0);
|
_wallDirection = _isTouchingRightWall ? 1 : (_isTouchingLeftWall ? -1 : 0);
|
||||||
|
|
||||||
@@ -132,43 +124,53 @@ private void FixedUpdate()
|
|||||||
_attackCooldownTimer -= Time.fixedDeltaTime;
|
_attackCooldownTimer -= Time.fixedDeltaTime;
|
||||||
|
|
||||||
UpdateMotionCooldowns();
|
UpdateMotionCooldowns();
|
||||||
|
ExecuteBufferedInputIfReady();
|
||||||
if (_attackCooldownTimer <= 0f && _pendingInput.HasValue)
|
TickComboWindow();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_inputLockTimer > 0f)
|
if (_inputLockTimer > 0f)
|
||||||
_inputLockTimer -= Time.fixedDeltaTime;
|
_inputLockTimer -= Time.fixedDeltaTime;
|
||||||
else
|
else
|
||||||
_rb.linearVelocity = new Vector2(GetBodyBlockedXVelocity(_moveInputX * _moveSpeed), _rb.linearVelocity.y);
|
_rb.linearVelocity = new Vector2(_moveInputX * _moveSpeed, _rb.linearVelocity.y);
|
||||||
|
|
||||||
if (_facingLockTimer > 0f)
|
if (_facingLockTimer > 0f)
|
||||||
_facingLockTimer -= Time.fixedDeltaTime;
|
_facingLockTimer -= Time.fixedDeltaTime;
|
||||||
else
|
else
|
||||||
UpdateFacingFromMoveInput();
|
UpdateFacingFromMoveInput();
|
||||||
|
|
||||||
|
ApplyGravity();
|
||||||
|
|
||||||
if (IsTouchingWall && !_isGrounded && _rb.linearVelocity.y < -_wallSlideSpeed)
|
if (IsTouchingWall && !_isGrounded && _rb.linearVelocity.y < -_wallSlideSpeed)
|
||||||
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, -_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)
|
private void OnMoveInput(Vector2 value)
|
||||||
{
|
{
|
||||||
_moveInputX = value.x == 0f ? 0f : Mathf.Sign(value.x);
|
_moveInputX = value.x == 0f ? 0f : Mathf.Sign(value.x);
|
||||||
|
if (_facingLockTimer <= 0f)
|
||||||
if (_facingLockTimer > 0f) return;
|
UpdateFacingFromMoveInput();
|
||||||
|
|
||||||
UpdateFacingFromMoveInput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFacingFromMoveInput()
|
private void UpdateFacingFromMoveInput()
|
||||||
@@ -213,6 +215,7 @@ private void HandleComboInput(ComboInputType input)
|
|||||||
|
|
||||||
private void ExecuteComboInput(ComboInputType input)
|
private void ExecuteComboInput(ComboInputType input)
|
||||||
{
|
{
|
||||||
|
// Continue from the current combo node while its window is open.
|
||||||
if (_comboWindowTimer > 0f && _currentNode != null)
|
if (_comboWindowTimer > 0f && _currentNode != null)
|
||||||
{
|
{
|
||||||
foreach (var transition in _currentNode.Transitions)
|
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
|
ComboNode root = input switch
|
||||||
{
|
{
|
||||||
ComboInputType.Punch => _punchRootNode,
|
ComboInputType.Punch => _punchRootNode,
|
||||||
ComboInputType.Kick => _kickRootNode,
|
ComboInputType.Kick => _kickRootNode,
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
if (root == null || root.Action == null) return;
|
if (root == null || root.Action == null) return;
|
||||||
@@ -277,218 +281,9 @@ private bool IsMotionOnCooldown(ActionData data)
|
|||||||
private void SetMotionCooldown(ActionData data)
|
private void SetMotionCooldown(ActionData data)
|
||||||
{
|
{
|
||||||
if (data == null || data.Cooldown <= 0f) return;
|
if (data == null || data.Cooldown <= 0f) return;
|
||||||
|
|
||||||
_motionCooldownTimers[data] = data.Cooldown;
|
_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)
|
private async void PerformAttack(ActionData data, bool preserveHorizontalVelocity = false)
|
||||||
{
|
{
|
||||||
_attackCts?.Cancel();
|
_attackCts?.Cancel();
|
||||||
@@ -504,25 +299,26 @@ private async void PerformAttack(ActionData data, bool preserveHorizontalVelocit
|
|||||||
PlayActionAnimation(data);
|
PlayActionAnimation(data);
|
||||||
|
|
||||||
if (data.HasMotion)
|
if (data.HasMotion)
|
||||||
{
|
|
||||||
ApplyActionVelocity(data);
|
ApplyActionVelocity(data);
|
||||||
}
|
|
||||||
LockMovementIfNeeded(data, preserveHorizontalVelocity);
|
LockMovementIfNeeded(data, preserveHorizontalVelocity);
|
||||||
LockFacingIfNeeded(data);
|
LockFacingIfNeeded(data);
|
||||||
IgnoreCollisionsIfNeeded(data);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await HitRoutine(data, token);
|
await HitRoutine(data, token);
|
||||||
}
|
}
|
||||||
catch (System.OperationCanceledException) { }
|
catch (System.OperationCanceledException)
|
||||||
RestoreIgnoredLayerCollisionsWhenClear(data.IgnoredCollisionLayers);
|
{
|
||||||
|
_attackHitbox?.Deactivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PerformMotion(ActionData data)
|
private async void PerformMotion(ActionData data)
|
||||||
{
|
{
|
||||||
if (data == null || IsMotionOnCooldown(data)) return;
|
if (data == null || IsMotionOnCooldown(data)) return;
|
||||||
|
|
||||||
|
// Motions such as dash/roll interrupt attacks and become the new combo node.
|
||||||
CancelAttack();
|
CancelAttack();
|
||||||
_motionCts?.Cancel();
|
_motionCts?.Cancel();
|
||||||
_motionCts?.Dispose();
|
_motionCts?.Dispose();
|
||||||
@@ -530,13 +326,10 @@ private async void PerformMotion(ActionData data)
|
|||||||
CancellationToken token = _motionCts.Token;
|
CancellationToken token = _motionCts.Token;
|
||||||
|
|
||||||
SetMotionCooldown(data);
|
SetMotionCooldown(data);
|
||||||
|
|
||||||
FaceMotionDirection(data);
|
FaceMotionDirection(data);
|
||||||
PlayActionAnimation(data);
|
PlayActionAnimation(data);
|
||||||
|
|
||||||
LockMovementIfNeeded(data);
|
LockMovementIfNeeded(data);
|
||||||
LockFacingIfNeeded(data);
|
LockFacingIfNeeded(data);
|
||||||
IgnoreCollisionsIfNeeded(data);
|
|
||||||
|
|
||||||
bool completed = false;
|
bool completed = false;
|
||||||
try
|
try
|
||||||
@@ -551,7 +344,6 @@ private async void PerformMotion(ActionData data)
|
|||||||
StopActionVelocity(data);
|
StopActionVelocity(data);
|
||||||
PlayIdleAnimation();
|
PlayIdleAnimation();
|
||||||
}
|
}
|
||||||
RestoreIgnoredLayerCollisionsWhenClear(data.IgnoredCollisionLayers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Awaitable MotionRoutine(ActionData data, CancellationToken token)
|
private async Awaitable MotionRoutine(ActionData data, CancellationToken token)
|
||||||
@@ -562,7 +354,6 @@ private async Awaitable MotionRoutine(ActionData data, CancellationToken token)
|
|||||||
while (elapsed < duration)
|
while (elapsed < duration)
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
||||||
ApplyActionVelocity(data, normalizedTime);
|
ApplyActionVelocity(data, normalizedTime);
|
||||||
|
|
||||||
@@ -579,6 +370,79 @@ private void CancelAttack()
|
|||||||
_attackCts?.Cancel();
|
_attackCts?.Cancel();
|
||||||
_attackCooldownTimer = 0f;
|
_attackCooldownTimer = 0f;
|
||||||
_pendingInput = null;
|
_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)
|
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
|
float speedMultiplier = data.MotionSpeedCurve != null
|
||||||
? data.MotionSpeedCurve.Evaluate(normalizedTime)
|
? data.MotionSpeedCurve.Evaluate(normalizedTime)
|
||||||
: 1f;
|
: 1f;
|
||||||
|
|
||||||
Vector2 velocity = data.Velocity * speedMultiplier;
|
Vector2 velocity = data.Velocity * speedMultiplier;
|
||||||
velocity.x *= direction;
|
velocity.x *= direction;
|
||||||
velocity.x = GetBodyBlockedXVelocity(velocity.x, data);
|
|
||||||
|
|
||||||
if (data.PreserveYVelocity)
|
if (data.PreserveYVelocity)
|
||||||
velocity.y = _rb.linearVelocity.y;
|
velocity.y = _rb.linearVelocity.y;
|
||||||
@@ -600,22 +464,14 @@ private void ApplyActionVelocity(ActionData data, float normalizedTime = 0f)
|
|||||||
private void StopActionVelocity(ActionData data)
|
private void StopActionVelocity(ActionData data)
|
||||||
{
|
{
|
||||||
if (!data.StopHorizontalVelocityOnEnd) return;
|
if (!data.StopHorizontalVelocityOnEnd) return;
|
||||||
|
|
||||||
_rb.linearVelocity = new Vector2(0f, _rb.linearVelocity.y);
|
_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)
|
private void LockMovementIfNeeded(ActionData data, bool preserveHorizontalVelocity = false)
|
||||||
{
|
{
|
||||||
if (data.CanMoveDuringAction) return;
|
if (data.CanMoveDuringAction) return;
|
||||||
|
|
||||||
|
// Non-moving attacks should not inherit walking velocity from the previous frame.
|
||||||
if (!preserveHorizontalVelocity && !data.HasMotion)
|
if (!preserveHorizontalVelocity && !data.HasMotion)
|
||||||
_rb.linearVelocity = new Vector2(0f, _rb.linearVelocity.y);
|
_rb.linearVelocity = new Vector2(0f, _rb.linearVelocity.y);
|
||||||
|
|
||||||
@@ -625,7 +481,6 @@ private void LockMovementIfNeeded(ActionData data, bool preserveHorizontalVeloci
|
|||||||
private void LockFacingIfNeeded(ActionData data)
|
private void LockFacingIfNeeded(ActionData data)
|
||||||
{
|
{
|
||||||
if (data.CanTurnDuringAction) return;
|
if (data.CanTurnDuringAction) return;
|
||||||
|
|
||||||
_facingLockTimer = Mathf.Max(data.MotionDuration, 0.02f);
|
_facingLockTimer = Mathf.Max(data.MotionDuration, 0.02f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,7 +519,6 @@ private async void ApplyAnimationSpeedCurve(ActionData data, CancellationToken t
|
|||||||
while (elapsed < duration)
|
while (elapsed < duration)
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
float normalizedTime = Mathf.Clamp01(elapsed / duration);
|
||||||
_anim.speed = GetAnimationSpeed(data, normalizedTime);
|
_anim.speed = GetAnimationSpeed(data, normalizedTime);
|
||||||
|
|
||||||
@@ -701,71 +555,6 @@ private void FaceMotionDirection(ActionData data)
|
|||||||
_facingLockTimer = 0f;
|
_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)
|
private Vector2 GetHitVelocity(Vector2 hitVelocity)
|
||||||
{
|
{
|
||||||
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||||
@@ -773,19 +562,19 @@ private Vector2 GetHitVelocity(Vector2 hitVelocity)
|
|||||||
return 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)
|
private string GetActionName(ActionData data)
|
||||||
{
|
{
|
||||||
if (data == null) return string.Empty;
|
if (data == null) return string.Empty;
|
||||||
return string.IsNullOrEmpty(data.ActionName) ? data.name : data.ActionName;
|
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)
|
private void ApplyForwardStep(float distance, float duration)
|
||||||
{
|
{
|
||||||
if (distance <= 0f) return;
|
if (distance <= 0f) return;
|
||||||
@@ -798,6 +587,98 @@ private void ApplyForwardStep(float distance, float duration)
|
|||||||
_inputLockTimer = safeDuration;
|
_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()
|
private void OnDrawGizmos()
|
||||||
{
|
{
|
||||||
if (_lastHitData == null || _lastHitTime < 0f) return;
|
if (_lastHitData == null || _lastHitTime < 0f) return;
|
||||||
@@ -833,34 +714,6 @@ private void OnDrawGizmosSelected()
|
|||||||
Gizmos.color = _isTouchingRightWall ? Color.green : Color.red;
|
Gizmos.color = _isTouchingRightWall ? Color.green : Color.red;
|
||||||
Gizmos.DrawWireSphere(_wallCheckRight.position, _wallCheckRadius);
|
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()
|
private void OnGUI()
|
||||||
@@ -919,7 +772,7 @@ private void DrawTimelineBar(ActionData data, float elapsed)
|
|||||||
GUI.color = new Color(0f, 0f, 0f, 0.6f);
|
GUI.color = new Color(0f, 0f, 0f, 0.6f);
|
||||||
GUI.DrawTexture(new Rect(barX, barY, barW, barH), Texture2D.whiteTexture);
|
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;
|
float hitEndX = barX + ((data.HitTiming + data.HitDuration) / totalTime) * barW;
|
||||||
GUI.color = new Color(1f, 0.3f, 0.3f, 0.5f);
|
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);
|
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;
|
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