2026-05-15 공격과 피격
This commit is contained in:
BIN
Assets/01_Scenes/GameScene.unity
LFS
BIN
Assets/01_Scenes/GameScene.unity
LFS
Binary file not shown.
8
Assets/02_Scripts/Combat.meta
Normal file
8
Assets/02_Scripts/Combat.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 66c32bbc793f98d49adc0346594251e9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
17
Assets/02_Scripts/Combat/AttackData.cs
Normal file
17
Assets/02_Scripts/Combat/AttackData.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[CreateAssetMenu(fileName = "AttackData", menuName = "Combat/AttackData")]
|
||||||
|
public class AttackData : ScriptableObject
|
||||||
|
{
|
||||||
|
public string AttackName;
|
||||||
|
public string AnimationState;
|
||||||
|
public Vector2 Offset = new Vector2(0.5f, 0f);
|
||||||
|
public float Radius = 0.5f;
|
||||||
|
public int Damage = 10;
|
||||||
|
public float Cooldown = 0.3f;
|
||||||
|
|
||||||
|
[Header("Timing")]
|
||||||
|
public float HitTiming = 0.15f;
|
||||||
|
public float HitDuration = 0f;
|
||||||
|
public float MotionDuration = 0.3f;
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Combat/AttackData.cs.meta
Normal file
2
Assets/02_Scripts/Combat/AttackData.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 526ebe3dc7ff32e4faa2cfcdc1670638
|
||||||
26
Assets/02_Scripts/Combat/ComboNode.cs
Normal file
26
Assets/02_Scripts/Combat/ComboNode.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public enum ComboInputType
|
||||||
|
{
|
||||||
|
Punch,
|
||||||
|
Kick
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class ComboTransition
|
||||||
|
{
|
||||||
|
public ComboInputType Trigger;
|
||||||
|
public ComboNode Next;
|
||||||
|
public float ForwardStep = 0f;
|
||||||
|
public float ForwardStepDuration = 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CreateAssetMenu(fileName = "ComboNode", menuName = "Combat/ComboNode")]
|
||||||
|
public class ComboNode : ScriptableObject
|
||||||
|
{
|
||||||
|
public string NodeName;
|
||||||
|
public AttackData Attack;
|
||||||
|
public float ComboWindow = 0.8f;
|
||||||
|
public ComboTransition[] Transitions;
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Combat/ComboNode.cs.meta
Normal file
2
Assets/02_Scripts/Combat/ComboNode.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d4d02e4d65b341140b34a24e39798ff6
|
||||||
4
Assets/02_Scripts/Combat/IDamageable.cs
Normal file
4
Assets/02_Scripts/Combat/IDamageable.cs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
public interface IDamageable
|
||||||
|
{
|
||||||
|
void TakeDamage(int amount);
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Combat/IDamageable.cs.meta
Normal file
2
Assets/02_Scripts/Combat/IDamageable.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 48f6e522039b1f44f8cce75191bcefec
|
||||||
8
Assets/02_Scripts/Enemy.meta
Normal file
8
Assets/02_Scripts/Enemy.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 48e440de30939c14d9f50089d72d7c9e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
58
Assets/02_Scripts/Enemy/Enemy.cs
Normal file
58
Assets/02_Scripts/Enemy/Enemy.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[RequireComponent(typeof(Collider2D))]
|
||||||
|
public class Enemy : MonoBehaviour, IDamageable
|
||||||
|
{
|
||||||
|
[Header("Stats")]
|
||||||
|
[SerializeField] private int _maxHealth = 30;
|
||||||
|
|
||||||
|
[Header("Hit Feedback")]
|
||||||
|
[SerializeField] private float _hitFlashDuration = 0.1f;
|
||||||
|
[SerializeField] private Color _hitFlashColor = Color.red;
|
||||||
|
|
||||||
|
private int _currentHealth;
|
||||||
|
private SpriteRenderer _spriteRenderer;
|
||||||
|
private Color _originalColor;
|
||||||
|
private float _flashTimer;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_currentHealth = _maxHealth;
|
||||||
|
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||||
|
if (_spriteRenderer != null)
|
||||||
|
_originalColor = _spriteRenderer.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_flashTimer > 0f)
|
||||||
|
{
|
||||||
|
_flashTimer -= Time.deltaTime;
|
||||||
|
if (_flashTimer <= 0f && _spriteRenderer != null)
|
||||||
|
_spriteRenderer.color = _originalColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TakeDamage(int amount)
|
||||||
|
{
|
||||||
|
if (_currentHealth <= 0) return;
|
||||||
|
|
||||||
|
_currentHealth -= amount;
|
||||||
|
Debug.Log($"{name} 피격: -{amount} (HP: {_currentHealth}/{_maxHealth})");
|
||||||
|
|
||||||
|
if (_spriteRenderer != null)
|
||||||
|
{
|
||||||
|
_spriteRenderer.color = _hitFlashColor;
|
||||||
|
_flashTimer = _hitFlashDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentHealth <= 0)
|
||||||
|
Die();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Die()
|
||||||
|
{
|
||||||
|
Debug.Log($"{name} 사망");
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/02_Scripts/Enemy/Enemy.cs.meta
Normal file
2
Assets/02_Scripts/Enemy/Enemy.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 945e2c8fc675cb64c97b4eff6d2e8d56
|
||||||
@@ -109,6 +109,24 @@ public @GameInput()
|
|||||||
""processors"": """",
|
""processors"": """",
|
||||||
""interactions"": """",
|
""interactions"": """",
|
||||||
""initialStateCheck"": false
|
""initialStateCheck"": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
""name"": ""Punch"",
|
||||||
|
""type"": ""Button"",
|
||||||
|
""id"": ""3dcb1343-a166-469d-990e-24ccedf2d09e"",
|
||||||
|
""expectedControlType"": """",
|
||||||
|
""processors"": """",
|
||||||
|
""interactions"": """",
|
||||||
|
""initialStateCheck"": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
""name"": ""Kick"",
|
||||||
|
""type"": ""Button"",
|
||||||
|
""id"": ""1af50460-846d-4f2a-8030-f9712ad7df6b"",
|
||||||
|
""expectedControlType"": """",
|
||||||
|
""processors"": """",
|
||||||
|
""interactions"": """",
|
||||||
|
""initialStateCheck"": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
""bindings"": [
|
""bindings"": [
|
||||||
@@ -177,6 +195,28 @@ public @GameInput()
|
|||||||
""action"": ""Jump"",
|
""action"": ""Jump"",
|
||||||
""isComposite"": false,
|
""isComposite"": false,
|
||||||
""isPartOfComposite"": false
|
""isPartOfComposite"": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
""name"": """",
|
||||||
|
""id"": ""9f28cd37-d35c-4f36-8af0-a0020d508486"",
|
||||||
|
""path"": ""<Keyboard>/z"",
|
||||||
|
""interactions"": """",
|
||||||
|
""processors"": """",
|
||||||
|
""groups"": """",
|
||||||
|
""action"": ""Punch"",
|
||||||
|
""isComposite"": false,
|
||||||
|
""isPartOfComposite"": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
""name"": """",
|
||||||
|
""id"": ""43e56be6-df9b-4845-ba12-cd109ac1ffa0"",
|
||||||
|
""path"": ""<Keyboard>/x"",
|
||||||
|
""interactions"": """",
|
||||||
|
""processors"": """",
|
||||||
|
""groups"": """",
|
||||||
|
""action"": ""Kick"",
|
||||||
|
""isComposite"": false,
|
||||||
|
""isPartOfComposite"": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -187,6 +227,8 @@ public @GameInput()
|
|||||||
m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
|
m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
|
||||||
m_Player_Move = m_Player.FindAction("Move", throwIfNotFound: true);
|
m_Player_Move = m_Player.FindAction("Move", throwIfNotFound: true);
|
||||||
m_Player_Jump = m_Player.FindAction("Jump", throwIfNotFound: true);
|
m_Player_Jump = m_Player.FindAction("Jump", throwIfNotFound: true);
|
||||||
|
m_Player_Punch = m_Player.FindAction("Punch", throwIfNotFound: true);
|
||||||
|
m_Player_Kick = m_Player.FindAction("Kick", throwIfNotFound: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
~@GameInput()
|
~@GameInput()
|
||||||
@@ -269,6 +311,8 @@ public int FindBinding(InputBinding bindingMask, out InputAction action)
|
|||||||
private List<IPlayerActions> m_PlayerActionsCallbackInterfaces = new List<IPlayerActions>();
|
private List<IPlayerActions> m_PlayerActionsCallbackInterfaces = new List<IPlayerActions>();
|
||||||
private readonly InputAction m_Player_Move;
|
private readonly InputAction m_Player_Move;
|
||||||
private readonly InputAction m_Player_Jump;
|
private readonly InputAction m_Player_Jump;
|
||||||
|
private readonly InputAction m_Player_Punch;
|
||||||
|
private readonly InputAction m_Player_Kick;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides access to input actions defined in input action map "Player".
|
/// Provides access to input actions defined in input action map "Player".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -289,6 +333,14 @@ public struct PlayerActions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public InputAction @Jump => m_Wrapper.m_Player_Jump;
|
public InputAction @Jump => m_Wrapper.m_Player_Jump;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Provides access to the underlying input action "Player/Punch".
|
||||||
|
/// </summary>
|
||||||
|
public InputAction @Punch => m_Wrapper.m_Player_Punch;
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to the underlying input action "Player/Kick".
|
||||||
|
/// </summary>
|
||||||
|
public InputAction @Kick => m_Wrapper.m_Player_Kick;
|
||||||
|
/// <summary>
|
||||||
/// Provides access to the underlying input action map instance.
|
/// Provides access to the underlying input action map instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public InputActionMap Get() { return m_Wrapper.m_Player; }
|
public InputActionMap Get() { return m_Wrapper.m_Player; }
|
||||||
@@ -320,6 +372,12 @@ public void AddCallbacks(IPlayerActions instance)
|
|||||||
@Jump.started += instance.OnJump;
|
@Jump.started += instance.OnJump;
|
||||||
@Jump.performed += instance.OnJump;
|
@Jump.performed += instance.OnJump;
|
||||||
@Jump.canceled += instance.OnJump;
|
@Jump.canceled += instance.OnJump;
|
||||||
|
@Punch.started += instance.OnPunch;
|
||||||
|
@Punch.performed += instance.OnPunch;
|
||||||
|
@Punch.canceled += instance.OnPunch;
|
||||||
|
@Kick.started += instance.OnKick;
|
||||||
|
@Kick.performed += instance.OnKick;
|
||||||
|
@Kick.canceled += instance.OnKick;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -337,6 +395,12 @@ private void UnregisterCallbacks(IPlayerActions instance)
|
|||||||
@Jump.started -= instance.OnJump;
|
@Jump.started -= instance.OnJump;
|
||||||
@Jump.performed -= instance.OnJump;
|
@Jump.performed -= instance.OnJump;
|
||||||
@Jump.canceled -= instance.OnJump;
|
@Jump.canceled -= instance.OnJump;
|
||||||
|
@Punch.started -= instance.OnPunch;
|
||||||
|
@Punch.performed -= instance.OnPunch;
|
||||||
|
@Punch.canceled -= instance.OnPunch;
|
||||||
|
@Kick.started -= instance.OnKick;
|
||||||
|
@Kick.performed -= instance.OnKick;
|
||||||
|
@Kick.canceled -= instance.OnKick;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -391,5 +455,19 @@ public interface IPlayerActions
|
|||||||
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
|
||||||
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
|
||||||
void OnJump(InputAction.CallbackContext context);
|
void OnJump(InputAction.CallbackContext context);
|
||||||
|
/// <summary>
|
||||||
|
/// Method invoked when associated input action "Punch" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
|
||||||
|
void OnPunch(InputAction.CallbackContext context);
|
||||||
|
/// <summary>
|
||||||
|
/// Method invoked when associated input action "Kick" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
|
||||||
|
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
|
||||||
|
void OnKick(InputAction.CallbackContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public class InputManager : MonoBehaviour, GameInput.IPlayerActions
|
|||||||
|
|
||||||
public event Action<Vector2> OnMove_Event;
|
public event Action<Vector2> OnMove_Event;
|
||||||
public event Action OnJump_Event;
|
public event Action OnJump_Event;
|
||||||
|
public event Action OnPunch_Event;
|
||||||
|
public event Action OnKick_Event;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -38,4 +40,18 @@ public void OnJump(InputAction.CallbackContext ctx)
|
|||||||
if (ctx.phase == InputActionPhase.Started)
|
if (ctx.phase == InputActionPhase.Started)
|
||||||
OnJump_Event?.Invoke();
|
OnJump_Event?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnPunch(InputAction.CallbackContext ctx)
|
||||||
|
{
|
||||||
|
if (ctx.phase == InputActionPhase.Started)
|
||||||
|
OnPunch_Event?.Invoke();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnKick(InputAction.CallbackContext ctx)
|
||||||
|
{
|
||||||
|
if (ctx.phase == InputActionPhase.Started)
|
||||||
|
OnKick_Event?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,76 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class PlayerController : MonoBehaviour
|
public class PlayerController : MonoBehaviour
|
||||||
{
|
{
|
||||||
[Header("Movement")]
|
[Header("Movement")]
|
||||||
[SerializeField] private float moveSpeed = 5f;
|
[SerializeField] private float _moveSpeed = 5f;
|
||||||
|
private float _moveInputX = 0f;
|
||||||
|
|
||||||
[Header("Jump")]
|
[Header("Jump")]
|
||||||
[SerializeField] private float jumpForce = 12f;
|
[SerializeField] private float _jumpForce = 8f;
|
||||||
[SerializeField] private Transform groundCheck;
|
[SerializeField] private Transform _groundCheck;
|
||||||
[SerializeField] private float groundCheckRadius = 0.1f;
|
[SerializeField] private float _groundCheckRadius = 0.1f;
|
||||||
[SerializeField] private LayerMask groundLayer;
|
[SerializeField] private LayerMask _groundLayer;
|
||||||
|
private bool _isGrounded;
|
||||||
|
|
||||||
private Rigidbody2D rb;
|
[Header("WallSlide")]
|
||||||
private float moveInputX = 0f;
|
[SerializeField] private Transform _wallCheckLeft;
|
||||||
private bool isGrounded;
|
[SerializeField] private Transform _wallCheckRight;
|
||||||
|
[SerializeField] private float _wallCheckRadius = 0.1f;
|
||||||
|
[SerializeField] private float _wallSlideSpeed = 2f;
|
||||||
|
[SerializeField] private Vector2 _wallJumpForce = new Vector2(4f, 5f);
|
||||||
|
[SerializeField] private float _wallJumpInputLockDuration = 0.15f;
|
||||||
|
private bool _isTouchingLeftWall;
|
||||||
|
private bool _isTouchingRightWall;
|
||||||
|
private bool IsTouchingWall => _isTouchingLeftWall || _isTouchingRightWall;
|
||||||
|
private int _wallDirection;
|
||||||
|
private float _inputLockTimer;
|
||||||
|
|
||||||
|
[Header("Attack")]
|
||||||
|
[SerializeField] private ComboNode _punchRootNode;
|
||||||
|
[SerializeField] private ComboNode _kickRootNode;
|
||||||
|
[SerializeField] private LayerMask _enemyLayer;
|
||||||
|
[SerializeField] private string _idleAnimationState = "Idle";
|
||||||
|
[SerializeField] private float _bufferOpenTime = 0.1f;
|
||||||
|
[SerializeField] private float _bufferLifetime = 0.5f;
|
||||||
|
private ComboInputType? _pendingInput;
|
||||||
|
private float _pendingInputTime = -1f;
|
||||||
|
private float _attackCooldownTimer;
|
||||||
|
private ComboNode _currentNode;
|
||||||
|
private float _comboWindowTimer;
|
||||||
|
private CancellationTokenSource _attackCts;
|
||||||
|
private AttackData _lastAttackGizmoData;
|
||||||
|
private float _lastAttackGizmoTime = -1f;
|
||||||
|
[SerializeField] private float _hitGizmoFadeDuration = 0.5f;
|
||||||
|
private AttackData _lastHitData;
|
||||||
|
private Vector2 _lastHitCenter;
|
||||||
|
private float _lastHitTime = -1f;
|
||||||
|
|
||||||
|
[Header("Debug")]
|
||||||
|
[SerializeField] private bool _showAttackDebug = true;
|
||||||
|
private float _attackStartTime = -1f;
|
||||||
|
private bool _hitFired;
|
||||||
|
|
||||||
|
private Rigidbody2D _rb;
|
||||||
|
private Animator _anim;
|
||||||
|
private SpriteRenderer _spriteRenderer;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
rb = GetComponent<Rigidbody2D>();
|
_rb = GetComponent<Rigidbody2D>();
|
||||||
|
_anim = GetComponent<Animator>();
|
||||||
|
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
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.OnKick_Event += OnKickInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
@@ -32,30 +79,356 @@ private void OnDestroy()
|
|||||||
{
|
{
|
||||||
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.OnKick_Event -= OnKickInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_attackCts?.Cancel();
|
||||||
|
_attackCts?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FixedUpdate()
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer);
|
_isGrounded = Physics2D.OverlapCircle(_groundCheck.position, _groundCheckRadius, _groundLayer);
|
||||||
rb.linearVelocity = new Vector2(moveInputX * moveSpeed, rb.linearVelocity.y);
|
_isTouchingLeftWall = Physics2D.OverlapCircle(_wallCheckLeft.position, _wallCheckRadius, _groundLayer);
|
||||||
|
_isTouchingRightWall = Physics2D.OverlapCircle(_wallCheckRight.position, _wallCheckRadius, _groundLayer);
|
||||||
|
_wallDirection = _isTouchingRightWall ? 1 : (_isTouchingLeftWall ? -1 : 0);
|
||||||
|
|
||||||
|
if (_attackCooldownTimer > 0f)
|
||||||
|
_attackCooldownTimer -= Time.fixedDeltaTime;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_inputLockTimer > 0f)
|
||||||
|
_inputLockTimer -= Time.fixedDeltaTime;
|
||||||
|
else
|
||||||
|
_rb.linearVelocity = new Vector2(_moveInputX * _moveSpeed, _rb.linearVelocity.y);
|
||||||
|
|
||||||
|
if (IsTouchingWall && !_isGrounded && _rb.linearVelocity.y < -_wallSlideSpeed)
|
||||||
|
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, -_wallSlideSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (_moveInputX != 0f && _spriteRenderer != null)
|
||||||
|
_spriteRenderer.flipX = _moveInputX < 0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnJumpInput()
|
private void OnJumpInput()
|
||||||
{
|
{
|
||||||
if (isGrounded)
|
if (_isGrounded)
|
||||||
rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce);
|
{
|
||||||
|
_rb.linearVelocity = new Vector2(_rb.linearVelocity.x, _jumpForce);
|
||||||
|
}
|
||||||
|
else if (IsTouchingWall)
|
||||||
|
{
|
||||||
|
_rb.linearVelocity = new Vector2(-_wallDirection * _wallJumpForce.x, _wallJumpForce.y);
|
||||||
|
_inputLockTimer = _wallJumpInputLockDuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPunchInput() => HandleComboInput(ComboInputType.Punch);
|
||||||
|
private void OnKickInput() => HandleComboInput(ComboInputType.Kick);
|
||||||
|
|
||||||
|
private void HandleComboInput(ComboInputType input)
|
||||||
|
{
|
||||||
|
if (_attackCooldownTimer > 0f)
|
||||||
|
{
|
||||||
|
float elapsed = Time.time - _attackStartTime;
|
||||||
|
if (_lastAttackGizmoData != null && elapsed >= _bufferOpenTime)
|
||||||
|
{
|
||||||
|
_pendingInput = input;
|
||||||
|
_pendingInputTime = Time.time;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecuteComboInput(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteComboInput(ComboInputType input)
|
||||||
|
{
|
||||||
|
if (_comboWindowTimer > 0f && _currentNode != null)
|
||||||
|
{
|
||||||
|
foreach (var transition in _currentNode.Transitions)
|
||||||
|
{
|
||||||
|
if (transition.Trigger != input) continue;
|
||||||
|
if (transition.Next == null || transition.Next.Attack == null) continue;
|
||||||
|
|
||||||
|
ApplyForwardStep(transition.ForwardStep, transition.ForwardStepDuration);
|
||||||
|
PerformAttack(transition.Next.Attack);
|
||||||
|
_currentNode = transition.Next;
|
||||||
|
_comboWindowTimer = transition.Next.ComboWindow;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboNode root = input switch
|
||||||
|
{
|
||||||
|
ComboInputType.Punch => _punchRootNode,
|
||||||
|
ComboInputType.Kick => _kickRootNode,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
if (root == null || root.Attack == null) return;
|
||||||
|
|
||||||
|
PerformAttack(root.Attack);
|
||||||
|
_currentNode = root;
|
||||||
|
_comboWindowTimer = root.ComboWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void PerformAttack(AttackData data)
|
||||||
|
{
|
||||||
|
_attackCts?.Cancel();
|
||||||
|
_attackCts?.Dispose();
|
||||||
|
_attackCts = CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken);
|
||||||
|
CancellationToken token = _attackCts.Token;
|
||||||
|
|
||||||
|
_attackCooldownTimer = data.Cooldown;
|
||||||
|
_lastAttackGizmoData = data;
|
||||||
|
_attackStartTime = Time.time;
|
||||||
|
_hitFired = false;
|
||||||
|
|
||||||
|
if (_anim != null && !string.IsNullOrEmpty(data.AnimationState))
|
||||||
|
_anim.Play(data.AnimationState);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await HitRoutine(data, token);
|
||||||
|
}
|
||||||
|
catch (System.OperationCanceledException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Awaitable HitRoutine(AttackData data, CancellationToken token)
|
||||||
|
{
|
||||||
|
float attackStartTime = Time.time;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (_anim != null && !string.IsNullOrEmpty(_idleAnimationState))
|
||||||
|
_anim.Play(_idleAnimationState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyDamageInArea(AttackData 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
float safeDuration = Mathf.Max(duration, 0.02f);
|
||||||
|
float facing = _spriteRenderer != null && _spriteRenderer.flipX ? -1f : 1f;
|
||||||
|
float vx = facing * (distance / safeDuration);
|
||||||
|
|
||||||
|
_rb.linearVelocity = new Vector2(vx, _rb.linearVelocity.y);
|
||||||
|
_inputLockTimer = safeDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (_lastHitData == null || _lastHitTime < 0f) return;
|
||||||
|
|
||||||
|
float since = Time.time - _lastHitTime;
|
||||||
|
if (since < 0f || since > _hitGizmoFadeDuration) return;
|
||||||
|
|
||||||
|
float t = Mathf.Clamp01(since / _hitGizmoFadeDuration);
|
||||||
|
float alpha = Mathf.Lerp(0.85f, 0f, t);
|
||||||
|
float radius = _lastHitData.Radius;
|
||||||
|
|
||||||
|
Gizmos.color = new Color(1f, 0.2f, 0.2f, alpha * 0.35f);
|
||||||
|
Gizmos.DrawSphere(_lastHitCenter, radius);
|
||||||
|
|
||||||
|
Gizmos.color = new Color(1f, 0f, 0f, alpha);
|
||||||
|
Gizmos.DrawWireSphere(_lastHitCenter, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDrawGizmosSelected()
|
private void OnDrawGizmosSelected()
|
||||||
{
|
{
|
||||||
if (groundCheck == null) return;
|
if (_groundCheck != null)
|
||||||
Gizmos.color = isGrounded ? Color.green : Color.red;
|
{
|
||||||
Gizmos.DrawWireSphere(groundCheck.position, groundCheckRadius);
|
Gizmos.color = _isGrounded ? Color.green : Color.red;
|
||||||
|
Gizmos.DrawWireSphere(_groundCheck.position, _groundCheckRadius);
|
||||||
|
}
|
||||||
|
if (_wallCheckLeft != null)
|
||||||
|
{
|
||||||
|
Gizmos.color = _isTouchingLeftWall ? Color.green : Color.red;
|
||||||
|
Gizmos.DrawWireSphere(_wallCheckLeft.position, _wallCheckRadius);
|
||||||
|
}
|
||||||
|
if (_wallCheckRight != null)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
AttackData 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()
|
||||||
|
{
|
||||||
|
if (!_showAttackDebug || _lastAttackGizmoData == null) return;
|
||||||
|
|
||||||
|
AttackData data = _lastAttackGizmoData;
|
||||||
|
float elapsed = Time.time - _attackStartTime;
|
||||||
|
|
||||||
|
string status = _hitFired
|
||||||
|
? (elapsed < data.HitTiming + Mathf.Max(data.HitDuration, 0.01f) ? "HIT" : "DONE")
|
||||||
|
: "WINDUP";
|
||||||
|
string cooldownText = _attackCooldownTimer > 0f
|
||||||
|
? $"{_attackCooldownTimer:F3}s left"
|
||||||
|
: "READY";
|
||||||
|
|
||||||
|
string bufferText = _pendingInput.HasValue
|
||||||
|
? $"<color=#ffcc00>BUFFERED: {_pendingInput.Value}</color>"
|
||||||
|
: (elapsed >= _bufferOpenTime && _attackCooldownTimer > 0f ? "ready to buffer" : "-");
|
||||||
|
|
||||||
|
string info =
|
||||||
|
$"<b>{(string.IsNullOrEmpty(data.AttackName) ? data.name : data.AttackName)}</b> [{status}]\n" +
|
||||||
|
$"Elapsed : {elapsed:F3} s\n" +
|
||||||
|
$"HitTiming : {data.HitTiming:F3} s\n" +
|
||||||
|
$"HitDuration : {data.HitDuration:F3} s\n" +
|
||||||
|
$"Cooldown : {data.Cooldown:F3} s ({cooldownText})\n" +
|
||||||
|
$"ComboWindow : {_comboWindowTimer:F3} s\n" +
|
||||||
|
$"Buffer : {bufferText}";
|
||||||
|
|
||||||
|
GUIStyle style = new GUIStyle(GUI.skin.box)
|
||||||
|
{
|
||||||
|
fontSize = 26,
|
||||||
|
alignment = TextAnchor.UpperLeft,
|
||||||
|
richText = true,
|
||||||
|
padding = new RectOffset(16, 16, 12, 12),
|
||||||
|
normal = { textColor = Color.white }
|
||||||
|
};
|
||||||
|
|
||||||
|
GUI.Box(new Rect(10, 10, 520, 282), info, style);
|
||||||
|
|
||||||
|
DrawTimelineBar(data, elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTimelineBar(AttackData data, float elapsed)
|
||||||
|
{
|
||||||
|
float barX = 10f;
|
||||||
|
float barY = 302f;
|
||||||
|
float barW = 520f;
|
||||||
|
float barH = 36f;
|
||||||
|
float totalTime = Mathf.Max(
|
||||||
|
data.HitTiming + Mathf.Max(data.HitDuration, 0.05f),
|
||||||
|
data.Cooldown,
|
||||||
|
data.MotionDuration,
|
||||||
|
0.3f);
|
||||||
|
|
||||||
|
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 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);
|
||||||
|
|
||||||
|
float bufferX = barX + Mathf.Clamp01(_bufferOpenTime / totalTime) * barW;
|
||||||
|
GUI.color = new Color(0.2f, 1f, 0.4f, 0.9f);
|
||||||
|
GUI.DrawTexture(new Rect(bufferX - 2f, barY, 4f, barH), Texture2D.whiteTexture);
|
||||||
|
|
||||||
|
float cdEndX = barX + Mathf.Clamp01(data.Cooldown / totalTime) * barW;
|
||||||
|
GUI.color = new Color(0.3f, 0.7f, 1f, 0.9f);
|
||||||
|
GUI.DrawTexture(new Rect(cdEndX - 2f, barY, 4f, barH), Texture2D.whiteTexture);
|
||||||
|
|
||||||
|
float cursorX = barX + Mathf.Clamp01(elapsed / totalTime) * barW;
|
||||||
|
GUI.color = Color.yellow;
|
||||||
|
GUI.DrawTexture(new Rect(cursorX - 2f, barY - 4f, 4f, barH + 8f), Texture2D.whiteTexture);
|
||||||
|
|
||||||
|
GUI.color = Color.white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
Assets/03_Character/WhiteMan/Physics.meta
Normal file
8
Assets/03_Character/WhiteMan/Physics.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ed10d659a73ec5646a3c118373bbfea7
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!62 &6200000
|
||||||
|
PhysicsMaterial2D:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Player_NoFriction
|
||||||
|
serializedVersion: 2
|
||||||
|
friction: 0
|
||||||
|
bounciness: 0
|
||||||
|
m_FrictionCombine: 3
|
||||||
|
m_BounceCombine: 3
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d6340da9be911d04bb908e5c78fea72c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 6200000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
Assets/05_Data.meta
Normal file
8
Assets/05_Data.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 874c09e27a1996a488f4c8fcc0463f1c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/05_Data/Attack.meta
Normal file
8
Assets/05_Data/Attack.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0c30e407ce5cfbd4ca6ad0704d9d03c6
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Kick_A.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Kick_A.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Kick_A.asset.meta
Normal file
8
Assets/05_Data/Attack/Kick_A.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: edf7db29ac692e346969f62ba6affb99
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Kick_B.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Kick_B.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Kick_B.asset.meta
Normal file
8
Assets/05_Data/Attack/Kick_B.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9eab77b3aa491b14082559d7670fb8fa
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Kick_C.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Kick_C.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Kick_C.asset.meta
Normal file
8
Assets/05_Data/Attack/Kick_C.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 66ae598bd05e97a4b87b3f49a06eed1d
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Punch_A.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Punch_A.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Punch_A.asset.meta
Normal file
8
Assets/05_Data/Attack/Punch_A.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: df671596c8a54114789564d1ae9e7b58
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Punch_B.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Punch_B.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Punch_B.asset.meta
Normal file
8
Assets/05_Data/Attack/Punch_B.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7bd5ebeb5044dfb44864673343c5b63f
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Attack/Punch_C.asset
LFS
Normal file
BIN
Assets/05_Data/Attack/Punch_C.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Attack/Punch_C.asset.meta
Normal file
8
Assets/05_Data/Attack/Punch_C.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 961b750a6648ff24d88f8cf5dbcfe9c3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/05_Data/Combo.meta
Normal file
8
Assets/05_Data/Combo.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f208be54919bfa4cb1feb32daaf1c9e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Kick_A.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Kick_A.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Kick_A.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Kick_A.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e868141c61f9d3c41ab8c631d68e5058
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Kick_B.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Kick_B.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Kick_B.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Kick_B.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4c94ebe82d46ebf4d88a17ce859ebd55
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Kick_C.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Kick_C.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Kick_C.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Kick_C.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e6bcd60837177ac458507946d733c3dd
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Punch_A.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Punch_A.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Punch_A.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Punch_A.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 62ff3f93ff39de341ab516bb3dfe4b75
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Punch_B.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Punch_B.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Punch_B.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Punch_B.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 979e8f13c305e1c4bbdeb2ab83add475
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/05_Data/Combo/Combo_Punch_C.asset
LFS
Normal file
BIN
Assets/05_Data/Combo/Combo_Punch_C.asset
LFS
Normal file
Binary file not shown.
8
Assets/05_Data/Combo/Combo_Punch_C.asset.meta
Normal file
8
Assets/05_Data/Combo/Combo_Punch_C.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 460f8d2a9a57dd14999125a99069a485
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -23,6 +23,24 @@
|
|||||||
"processors": "",
|
"processors": "",
|
||||||
"interactions": "",
|
"interactions": "",
|
||||||
"initialStateCheck": false
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Punch",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "3dcb1343-a166-469d-990e-24ccedf2d09e",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kick",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "1af50460-846d-4f2a-8030-f9712ad7df6b",
|
||||||
|
"expectedControlType": "",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"bindings": [
|
"bindings": [
|
||||||
@@ -91,6 +109,28 @@
|
|||||||
"action": "Jump",
|
"action": "Jump",
|
||||||
"isComposite": false,
|
"isComposite": false,
|
||||||
"isPartOfComposite": false
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "9f28cd37-d35c-4f36-8af0-a0020d508486",
|
||||||
|
"path": "<Keyboard>/z",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Punch",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "43e56be6-df9b-4845-ba12-cd109ac1ffa0",
|
||||||
|
"path": "<Keyboard>/x",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Kick",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
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