Files
VRProject/Assets/Scripts/VRPunchAttack.cs
2026-06-03 16:35:15 +09:00

141 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using UnityEngine.InputSystem; // Input Systemを使うために必要
using UnityEngine.XR; // 振動機能のために必要
[RequireComponent(typeof(Collider))]
[RequireComponent(typeof(Rigidbody))]
public class VRInputPunch : MonoBehaviour
{
[SerializeField] private InputActionProperty velocityAction;
[SerializeField] private XRNode controllerNode = XRNode.RightHand;
[SerializeField] private VRInputPoseDetector poseDetector;
[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; // 通常ヒットの振動の長さ
[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()
{
if (velocityAction.action != null)
{
velocityAction.action.Enable();
}
}
private void OnDisable()
{
if (velocityAction.action != null)
{
velocityAction.action.Disable();
}
}
void Start()
{
Rigidbody rb = GetComponent<Rigidbody>();
rb.isKinematic = true;
rb.useGravity = false;
GetComponent<Collider>().isTrigger = true;
}
private void OnTriggerEnter(Collider other)
{
// コントローラーの現在の移動速度を取得
Vector3 velocity = velocityAction.action.ReadValue<Vector3>();
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<EnemyAI>();
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)
{
IDamageble damageble = other.GetComponentInParent<IDamageble>();
if (damageble != null)
{
DamageInfo info = new DamageInfo();
if (poseDetector.IsPosing)
{
info.amount = (speed * damageMultiplier) * 2f;
info.isPoseBonus = true;
}
else
{
info.amount = speed * damageMultiplier;
info.isPoseBonus = false;
}
info.hitPosition = other.transform.position;
info.punchDirection = velocity.normalized;
damageble.TakeDamage(info);
// ※元のコードのログ出力の記述バグ($の付け忘れ)を修正しました
Debug.Log($"パンチ成功 ダメージ: {info.amount:F1}");
// 通常ヒットの振動を発生
TriggerHaptics(hapticAmplitude, hapticDuration);
}
}
else
{
// ※元のコードのログ出力の記述バグ($の付け忘れ)を修正しました
Debug.Log($"スピードが足りません。必要: {minPunchSpeed} / 現在: {speed:F2}");
}
}
/// <summary>
/// 引数に応じて指定された強さと長さでコントローラーを振動させる
/// </summary>
private void TriggerHaptics(float amplitude, float duration)
{
UnityEngine.XR.InputDevice device = InputDevices.GetDeviceAtXRNode(controllerNode);
if (device.isValid)
{
device.SendHapticImpulse(0, amplitude, duration);
}
}
}