From 69f5891a149c2cafe4e57f8d38293ead2037dc84 Mon Sep 17 00:00:00 2001 From: KawakamiKento Date: Wed, 3 Jun 2026 16:35:15 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B9=E3=82=BF=E3=83=B3=E7=8A=B6=E6=85=8B?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Animation/EnemyAnim.controller | 145 ++++++++++++++++++ Assets/Scenes/GameScene.unity | 80 +++++++++- Assets/Scripts/EnemyAI.cs | 75 +++++++-- Assets/Scripts/EnemyHealth.cs | 19 ++- Assets/Scripts/VRPunchAttack.cs | 87 ++++++++--- .../XR/Settings/OpenXRPackageSettings.asset | 6 +- ProjectSettings/TagManager.asset | 1 + 7 files changed, 369 insertions(+), 44 deletions(-) diff --git a/Assets/Animation/EnemyAnim.controller b/Assets/Animation/EnemyAnim.controller index a6f095f..a114ef7 100644 --- a/Assets/Animation/EnemyAnim.controller +++ b/Assets/Animation/EnemyAnim.controller @@ -1,5 +1,32 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: +--- !u!1102 &-9213843072455903201 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Stun + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: + - {fileID: 551695996419535402} + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 3094330708855449807, guid: 6bc3ab383df35674db1c49d5c09cf9f3, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: --- !u!1101 &-4617766861655133771 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -104,6 +131,31 @@ AnimatorState: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: +--- !u!1101 &-2177191287041199040 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Dead + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 3858776489725453322} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.75 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1101 &-1087799933439154294 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -247,6 +299,18 @@ AnimatorController: m_DefaultInt: 0 m_DefaultBool: 0 m_Controller: {fileID: 9100000} + - m_Name: Dead + m_Type: 9 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} + - m_Name: Stun + m_Type: 9 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} m_AnimatorLayers: - serializedVersion: 5 m_Name: Base Layer @@ -260,6 +324,28 @@ AnimatorController: m_IKPass: 0 m_SyncedLayerAffectsTiming: 0 m_Controller: {fileID: 9100000} +--- !u!1101 &551695996419535402 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: [] + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: 5198712320388512128} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.75 + m_HasExitTime: 1 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1101 &2869564516383402369 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -285,6 +371,32 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1102 &3858776489725453322 +AnimatorState: + serializedVersion: 6 + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Death + m_Speed: 1 + m_CycleOffset: 0 + m_Transitions: [] + m_StateMachineBehaviours: [] + m_Position: {x: 50, y: 50, z: 0} + m_IKOnFeet: 0 + m_WriteDefaultValues: 1 + m_Mirror: 0 + m_SpeedParameterActive: 0 + m_MirrorParameterActive: 0 + m_CycleOffsetParameterActive: 0 + m_TimeParameterActive: 0 + m_Motion: {fileID: 5957932628511814003, guid: b09be4f98e05fa7489d148a376fc0f1c, type: 3} + m_Tag: + m_SpeedParameter: + m_MirrorParameter: + m_CycleOffsetParameter: + m_TimeParameter: --- !u!1102 &4274158951045771678 AnimatorState: serializedVersion: 6 @@ -385,9 +497,17 @@ AnimatorStateMachine: - serializedVersion: 1 m_State: {fileID: 4274158951045771678} m_Position: {x: 300, y: -100, z: 0} + - serializedVersion: 1 + m_State: {fileID: 3858776489725453322} + m_Position: {x: 300, y: -200, z: 0} + - serializedVersion: 1 + m_State: {fileID: -9213843072455903201} + m_Position: {x: 300, y: -300, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: - {fileID: -4617766861655133771} + - {fileID: -2177191287041199040} + - {fileID: 8508030687789852846} m_EntryTransitions: [] m_StateMachineTransitions: {} m_StateMachineBehaviours: [] @@ -396,3 +516,28 @@ AnimatorStateMachine: m_ExitPosition: {x: 600, y: 100, z: 0} m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} m_DefaultState: {fileID: 5198712320388512128} +--- !u!1101 &8508030687789852846 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Stun + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -9213843072455903201} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.25 + m_TransitionOffset: 0 + m_ExitTime: 0.75 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 diff --git a/Assets/Scenes/GameScene.unity b/Assets/Scenes/GameScene.unity index 3e38c79..fd9da1e 100644 --- a/Assets/Scenes/GameScene.unity +++ b/Assets/Scenes/GameScene.unity @@ -3707,6 +3707,7 @@ MonoBehaviour: attackDamage: 10 attackCooldown: 2 telegraphDuration: 0.8 + rightHandCollider: {fileID: 1991158664} comboInterval: 0.8 wanderRadius: 8 minWaitTime: 2 @@ -17497,6 +17498,10 @@ MonoBehaviour: damageMultiplier: 10 hapticAmplitude: 0.5 hapticDuration: 0.1 + minParrySpeed: 1 + parryStunDuration: 3 + parryHapticAmplitude: 0.9 + parryHapticDuration: 0.25 --- !u!65 &938850979 BoxCollider: m_ObjectHideFlags: 0 @@ -651973,33 +651978,57 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 7357282918100144696, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.x + value: 0.0019 + objectReference: {fileID: 0} + - target: {fileID: 7357282918100144696, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.y + value: -0.00478 + objectReference: {fileID: 0} + - target: {fileID: 7357282918100144696, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.z + value: 0.00012 + objectReference: {fileID: 0} + - target: {fileID: 7357282918100144728, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.x + value: 0.00794 + objectReference: {fileID: 0} + - target: {fileID: 7357282918100144728, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.y + value: 0.00156 + objectReference: {fileID: 0} + - target: {fileID: 7357282918100144728, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_LocalPosition.z + value: 0.0004 + objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalPosition.x - value: -38.33 + value: -35.87 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalPosition.y - value: 26.042007 + value: 26 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalPosition.z - value: 12.68 + value: -1.29 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalRotation.w - value: 1 + value: -0.72334737 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalRotation.x - value: 0 + value: -0.024862813 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalRotation.y - value: 0 + value: 0.6896066 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalRotation.z - value: 0 + value: -0.024355074 objectReference: {fileID: 0} - target: {fileID: 7357282918100144838, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_LocalEulerAnglesHint.x @@ -652013,6 +652042,14 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 7357282918100569688, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_TagString + value: EnemyFist + objectReference: {fileID: 0} + - target: {fileID: 7357282918100569720, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + propertyPath: m_TagString + value: Untagged + objectReference: {fileID: 0} - target: {fileID: 7357282918100569830, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} propertyPath: m_Name value: Skin_1 @@ -652052,6 +652089,9 @@ PrefabInstance: - targetCorrespondingSourceObject: {fileID: 7357282918100569830, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} insertIndex: -1 addedObject: {fileID: 438681048} + - targetCorrespondingSourceObject: {fileID: 7357282918100569688, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + insertIndex: -1 + addedObject: {fileID: 1991158664} m_SourcePrefab: {fileID: 100100000, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} --- !u!114 &1927926602 MonoBehaviour: @@ -652739,6 +652779,32 @@ MonoBehaviour: m_ShadowLayerMask: 1 m_RenderingLayers: 1 m_ShadowRenderingLayers: 1 +--- !u!1 &1991158661 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 7357282918100569688, guid: 935264455f4b40f4ab5ea045bf9d7a3c, type: 3} + m_PrefabInstance: {fileID: 1924402715} + m_PrefabAsset: {fileID: 0} +--- !u!135 &1991158664 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1991158661} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 1 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 3 + m_Radius: 1 + m_Center: {x: 0, y: 0, z: 0} --- !u!1 &1997079592 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/EnemyAI.cs b/Assets/Scripts/EnemyAI.cs index 5bc4704..dbc4013 100644 --- a/Assets/Scripts/EnemyAI.cs +++ b/Assets/Scripts/EnemyAI.cs @@ -12,7 +12,8 @@ public class EnemyAI : MonoBehaviour { Wander, // 徘徊 Chase, // 追跡 - Attack // 攻撃 + Attack, // 攻撃 + Stun // 怯み } [Header("現在の状態")] @@ -32,6 +33,7 @@ public class EnemyAI : MonoBehaviour [SerializeField] private float attackCooldown = 2.0f; [Tooltip("攻撃の予兆時間 (秒)")] [SerializeField] private float telegraphDuration = 0.6f; + [SerializeField] private Collider rightHandCollider; [Header("ループ攻撃の調整")] [Tooltip("連続攻撃の間に挟む最低限のインターバル (秒)")] @@ -57,6 +59,8 @@ public class EnemyAI : MonoBehaviour { agent = GetComponent(); anim = GetComponent(); + + SetFistCollider(false); // AIのメインループコルーチンを開始 StartCoroutine(AILoop()); @@ -87,7 +91,7 @@ public class EnemyAI : MonoBehaviour } // 攻撃、のけぞりアニメーションの再生中でない場合のみ、ステートに応じた行動を実行 - if (!isAttacking && !isKnockbacking) + if (!isAttacking && !isKnockbacking && currentState != AIState.Stun) { switch (currentState) { @@ -211,7 +215,7 @@ public class EnemyAI : MonoBehaviour float targetSpeed = 0f; // 攻撃中でなく、経路が存在し、かつ実際に一定以上の速度で移動している場合のみSpeedを1にする - if (!isAttacking && !isKnockbacking && agent.hasPath && agent.velocity.magnitude > 0.1f) + if (!isAttacking && !isKnockbacking && currentState != AIState.Stun && agent.hasPath && agent.velocity.magnitude > 0.1f) { targetSpeed = 1f; } @@ -223,7 +227,7 @@ public class EnemyAI : MonoBehaviour /// 攻撃ステートの際、プレイヤーの方向へ滑らかに旋回させる private void UpdateRotationOnAttack() { - if (currentState == AIState.Attack && playerTransform != null && !isKnockbacking) + if (currentState == AIState.Attack && playerTransform != null && !isKnockbacking && currentState != AIState.Stun) { Vector3 direction = (playerTransform.position - transform.position).normalized; direction.y = 0; // 上下方向の傾き(ピッチ回転)を無視 @@ -242,6 +246,7 @@ public class EnemyAI : MonoBehaviour { if(isDead) return; + SetFistCollider(false); StopAllCoroutines(); isAttacking = false; isWandering = false; @@ -255,6 +260,21 @@ public class EnemyAI : MonoBehaviour StartCoroutine(KnockbackRoutine(duration)); } + public void TriggerParryStun(float duration) + { + if(isDead) return; + + Debug.Log($"{gameObject.name}: parry = true Stunnow"); + + SetFistCollider(false); + StopAllCoroutines(); + isAttacking = false; + isWandering = false; + isKnockbacking = false; + + StartCoroutine(ParryStunRoutine(duration)); + } + public void DisableAIOnDeath() { isDead = true; @@ -266,6 +286,31 @@ public class EnemyAI : MonoBehaviour } } + private IEnumerator ParryStunRoutine(float duration) + { + currentState = AIState.Stun; + + if(agent.isOnNavMesh) + { + agent.isStopped = true; + agent.ResetPath(); + } + + anim.SetTrigger("Stun"); + + yield return new WaitForSeconds(duration); + + if(agent.isOnNavMesh) + { + agent.isStopped = false; + } + + currentState = AIState.Chase; + isCooldown = false; + + StartCoroutine(AILoop()); + } + private IEnumerator KnockbackRoutine(float duration) { isKnockbacking = true; @@ -379,21 +424,17 @@ public class EnemyAI : MonoBehaviour /// 攻撃アニメーションのヒットフレームで実行されるヒット判定(Animation Eventから呼び出し) public void OnPunchHit() { - if (isKnockbacking || playerTransform == null) return; + if (isKnockbacking || currentState == AIState.Stun) return; - float distanceToPlayer = Vector3.Distance(transform.position, playerTransform.position); - - // ヒット判定の瞬間、プレイヤーが射程内に残っているか判定(猶予として0.3m加算) - if (distanceToPlayer <= attackRange + 0.3f) - { - Debug.Log($"💥 敵のパンチがヒット!"); - } + SetFistCollider(true); } /// Recovery(硬直)アニメーションの終了時に実行される処理(Animation Eventから呼び出し) public void OnRecoveryEnd() { - if(isKnockbacking) return; + if(isKnockbacking || currentState == AIState.Stun) return; + + SetFistCollider(false); isAttacking = false; if (playerTransform == null) @@ -423,6 +464,14 @@ public class EnemyAI : MonoBehaviour #region ヘルパー・デバッグ用メソッド /// 指定された中心座標の範囲内から、NavMesh上の有効なランダム座標を取得する + + private void SetFistCollider(bool enabledState) + { + if(rightHandCollider != null) + { + rightHandCollider.enabled = enabledState; + } + } private Vector3 GetRandomNavMeshPoint(Vector3 center, float radius) { Vector3 randomDirection = UnityEngine.Random.insideUnitSphere * radius; diff --git a/Assets/Scripts/EnemyHealth.cs b/Assets/Scripts/EnemyHealth.cs index 749b3e2..05b15be 100644 --- a/Assets/Scripts/EnemyHealth.cs +++ b/Assets/Scripts/EnemyHealth.cs @@ -9,6 +9,8 @@ public class EnemyHealth : MonoBehaviour, IDamageble [SerializeField] private float knockbackDuration = 0.5f; private EnemyAI enemyAI; + private bool isDead = false; + void Start() { currentHealth = maxHealth; //HPを代入 @@ -41,11 +43,26 @@ public class EnemyHealth : MonoBehaviour, IDamageble private void Die() { + if(isDead) return; + isDead = true; + + Animator anim = GetComponent(); + if(anim != null) + { + anim.SetTrigger("Dead"); + } + + Collider col = GetComponent(); + if(col != null) + { + col.enabled = false; + } + if(enemyAI != null) { enemyAI.DisableAIOnDeath(); } - Destroy(gameObject, 0.5f); + Destroy(gameObject, 3.0f); } } diff --git a/Assets/Scripts/VRPunchAttack.cs b/Assets/Scripts/VRPunchAttack.cs index 5cb8367..21dc712 100644 --- a/Assets/Scripts/VRPunchAttack.cs +++ b/Assets/Scripts/VRPunchAttack.cs @@ -7,17 +7,25 @@ using UnityEngine.XR; // 振動機能のために必要 public class VRInputPunch : MonoBehaviour { [SerializeField] private InputActionProperty velocityAction; - [SerializeField] private XRNode controllerNode = XRNode.RightHand; - [SerializeField] private VRInputPoseDetector poseDetector; - [SerializeField] private float minPunchSpeed = 2.0f; //パンチとして判定する最低速度 (m/s) - - [SerializeField] private float damageMultiplier = 10.0f; //ダメージ倍率 + [Header("攻撃(パンチ)設定")] + [SerializeField] private float minPunchSpeed = 2.0f; // パンチとして判定する最低速度 (m/s) + [SerializeField] private float damageMultiplier = 10.0f; // ダメージ倍率 + [SerializeField] private float hapticAmplitude = 0.5f; // 通常ヒットの振動の強さ + [SerializeField] private float hapticDuration = 0.1f; // 通常ヒットの振動の長さ - [SerializeField] private float hapticAmplitude = 0.5f; //振動の強さ - [SerializeField] private float hapticDuration = 0.1f; //振動の長さ + [Header("パリィ設定")] + [Tooltip("パリィを成立させるために必要な最低限の手の速度 (m/s) ※構え中は速度に関係なく成功します")] + [SerializeField] private float minParrySpeed = 1.0f; + [Tooltip("パリィ成功時に敵がスタン(行動不能)になる時間 (秒)")] + [SerializeField] private float parryStunDuration = 3.0f; + [Tooltip("パリィ成功時の強力な振動の強さ (0.0 ~ 1.0)")] + [SerializeField] private float parryHapticAmplitude = 0.9f; + [Tooltip("パリィ成功時の強力な振動の長さ (秒)")] + [SerializeField] private float parryHapticDuration = 0.25f; + // ───────────────────────────────────────── private void OnEnable() { @@ -45,10 +53,42 @@ public class VRInputPunch : MonoBehaviour private void OnTriggerEnter(Collider other) { + // コントローラーの現在の移動速度を取得 Vector3 velocity = velocityAction.action.ReadValue(); - float speed = velocity.magnitude; + // ─── ★新設:【パリィ判定】当たったオブジェクトが「敵の拳」だった場合 ─── + if (other.CompareTag("EnemyFist")) + { + Debug.Log($"🛡️ [パリィチェック] 敵の拳と接触。プレイヤーの手の速度: {speed:F2} m/s / 構え状態: {poseDetector.IsPosing}"); + + // 条件:構え状態(IsPosing)である、もしくは、弾くための速度が一定以上出ている場合 + if (poseDetector.IsPosing || speed >= minParrySpeed) + { + // 敵の親オブジェクトからEnemyAIスクリプトを検索 + EnemyAI enemyAI = other.GetComponentInParent(); + if (enemyAI != null) + { + // 敵の攻撃コンボを強制中断し、スタン状態にする + enemyAI.TriggerParryStun(parryStunDuration); + + // パリィ成功用の強力な振動(手応え)をプレイヤーに返す + TriggerHaptics(parryHapticAmplitude, parryHapticDuration); + + Debug.Log($"🛡️ 【ジャストパリィ成功!】 敵の体勢を崩しました。スタン時間: {parryStunDuration}秒"); + return; // パリィが成立した場合は以降のパンチ処理は行わない + } + } + else + { + Debug.Log("🧱 ガード(または速度不足):敵の攻撃は防いだが、弾き返せなかった。"); + return; + } + } + // ──────────────────────────────────────────────────────────────────────── + + + // ─── 以下は従来の【パンチ攻撃】の処理(変更なし・ログのバグ修正のみ) ─── Debug.Log($"[InputSystem接触] {other.name} に触れました。センサー速度: {speed:F2} m/s"); if (speed >= minPunchSpeed) @@ -58,7 +98,7 @@ public class VRInputPunch : MonoBehaviour if (damageble != null) { DamageInfo info = new DamageInfo(); - if(poseDetector.IsPosing) + if (poseDetector.IsPosing) { info.amount = (speed * damageMultiplier) * 2f; info.isPoseBonus = true; @@ -69,26 +109,33 @@ public class VRInputPunch : MonoBehaviour info.isPoseBonus = false; } info.hitPosition = other.transform.position; - info.punchDirection = velocity.normalized; //パンチの進む向き - damageble.TakeDamage(info); - Debug.Log("パンチ成功 ダメージ: {damage:F1}"); + info.punchDirection = velocity.normalized; - TriggerHaptics(); - } - else - { - Debug.Log("スピードが足りません。必要: {minPunchSpeed} / 現在: {speed:F2}"); + damageble.TakeDamage(info); + + // ※元のコードのログ出力の記述バグ($の付け忘れ)を修正しました + Debug.Log($"パンチ成功 ダメージ: {info.amount:F1}"); + + // 通常ヒットの振動を発生 + TriggerHaptics(hapticAmplitude, hapticDuration); } } + else + { + // ※元のコードのログ出力の記述バグ($の付け忘れ)を修正しました + Debug.Log($"スピードが足りません。必要: {minPunchSpeed} / 現在: {speed:F2}"); + } } - // コントローラーを振動させる処理 - private void TriggerHaptics() + /// + /// 引数に応じて指定された強さと長さでコントローラーを振動させる + /// + private void TriggerHaptics(float amplitude, float duration) { UnityEngine.XR.InputDevice device = InputDevices.GetDeviceAtXRNode(controllerNode); if (device.isValid) { - device.SendHapticImpulse(0, hapticAmplitude, hapticDuration); + device.SendHapticImpulse(0, amplitude, duration); } } } \ No newline at end of file diff --git a/Assets/XR/Settings/OpenXRPackageSettings.asset b/Assets/XR/Settings/OpenXRPackageSettings.asset index 312c3cc..7154d7e 100644 --- a/Assets/XR/Settings/OpenXRPackageSettings.asset +++ b/Assets/XR/Settings/OpenXRPackageSettings.asset @@ -1179,8 +1179,8 @@ MonoBehaviour: features: - {fileID: 7011443450567333355} - {fileID: -671281728444007487} - - {fileID: -901939997048047619} - - {fileID: -1734471456787174204} + - {fileID: 6956056911768161135} + - {fileID: -6387251413244805544} - {fileID: 8980318060753866109} - {fileID: -6559185765804338520} - {fileID: -4756202077021157709} @@ -1191,7 +1191,7 @@ MonoBehaviour: - {fileID: 348827886137839178} - {fileID: -7499073031166464939} - {fileID: 7666556398442971420} - - {fileID: -7343570946846779558} + - {fileID: -142859899272520151} - {fileID: 3985858319333531581} - {fileID: -6511185071715886993} - {fileID: -4363231183632145407} diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index fbf971c..76ec59f 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -6,6 +6,7 @@ TagManager: tags: - Anchor - Enemy + - EnemyFist layers: - Default - TransparentFX