otamesi
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem; // Input Systemを使うために必要
|
||||
using UnityEngine.XR; // 振動機能のために必要
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.XR;
|
||||
|
||||
[RequireComponent(typeof(Collider))]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
@@ -10,37 +10,30 @@ public class VRInputPunch : MonoBehaviour
|
||||
[SerializeField] private XRNode controllerNode = XRNode.RightHand;
|
||||
[SerializeField] private VRInputPoseDetector poseDetector;
|
||||
|
||||
[Header("攻撃(パンチ)設定")]
|
||||
[SerializeField] private float minPunchSpeed = 1.0f; // パンチとして判定する最低速度 (m/s)
|
||||
[SerializeField] private float damageMultiplier = 10.0f; // ダメージ倍率
|
||||
[SerializeField] private float hapticAmplitude = 0.5f; // 通常ヒットの振動の強さ
|
||||
[SerializeField] private float hapticDuration = 0.1f; // 通常ヒットの振動の長さ
|
||||
[Header("パンチパラメータ")]
|
||||
[SerializeField] private float minPunchSpeed = 1.0f;
|
||||
[SerializeField] private float damageMultiplier = 10.0f;
|
||||
[SerializeField] private float hapticAmplitude = 0.5f;
|
||||
[SerializeField] private float hapticDuration = 0.1f;
|
||||
|
||||
[Header("パリィ設定")]
|
||||
[SerializeField] private float parryStunDuration = 3.0f; // スタン時間(秒)
|
||||
[SerializeField] private float parryHapticAmplitude = 0.9f; // パリィ成功時の振動の強さ
|
||||
[SerializeField] private float parryHapticDuration = 0.25f; // パリィ成功時の振動の長さ
|
||||
// ─── 多段ヒット・連続暴発防止用タイマー ───
|
||||
private float punchHitCooldown = 0f; // 次のパンチが当たるまでのインターバル
|
||||
private float parryTriggerCooldown = 0f; // 次のパリィが成功するまでのインターバル
|
||||
[Header("パリィパラメータ")]
|
||||
[SerializeField] private float parryStunDuration = 3.0f;
|
||||
[SerializeField] private float parryHapticAmplitude = 0.9f;
|
||||
[SerializeField] private float parryHapticDuration = 0.25f;
|
||||
|
||||
private const string EnemyFistTag = "EnemyFist";
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (velocityAction.action != null)
|
||||
{
|
||||
velocityAction.action.Enable();
|
||||
}
|
||||
if (velocityAction.action != null) velocityAction.action.Enable();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (velocityAction.action != null)
|
||||
{
|
||||
velocityAction.action.Disable();
|
||||
}
|
||||
if (velocityAction.action != null) velocityAction.action.Disable();
|
||||
}
|
||||
|
||||
void Start()
|
||||
private void Start()
|
||||
{
|
||||
Rigidbody rb = GetComponent<Rigidbody>();
|
||||
rb.isKinematic = true;
|
||||
@@ -50,104 +43,71 @@ public class VRInputPunch : MonoBehaviour
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
// コントローラーの現在の移動速度を取得
|
||||
Vector3 velocity = velocityAction.action.ReadValue<Vector3>();
|
||||
Vector3 velocity = velocityAction.action != null ? velocityAction.action.ReadValue<Vector3>() : Vector3.zero;
|
||||
float speed = velocity.magnitude;
|
||||
|
||||
// ========================================================================
|
||||
// 【パリィ判定】当たったオブジェクトが敵の拳だった場合
|
||||
// ========================================================================
|
||||
if (other.CompareTag("EnemyFist"))
|
||||
if (other.CompareTag(EnemyFistTag))
|
||||
{
|
||||
Debug.Log($"🛡️ [パリィチェック] 敵の拳と接触。構え状態: {poseDetector.IsPosing}");
|
||||
|
||||
// 自分が「構え状態」のときだけパリィの成立チェックを行う
|
||||
if (poseDetector.IsPosing)
|
||||
if (poseDetector != null && poseDetector.IsPosing)
|
||||
{
|
||||
// 1. ザコ敵(EnemyAI)へのパリィ判定
|
||||
EnemyAI enemyAI = other.GetComponentInParent<EnemyAI>();
|
||||
if (enemyAI != null)
|
||||
{
|
||||
enemyAI.TriggerParryStun(parryStunDuration);
|
||||
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
|
||||
Debug.Log($"🛡️ 【ジャストパリィ成功!】 敵の体勢を崩しました。");
|
||||
return; // ★本当のパリィ成功時のみ、ここで処理を終了する
|
||||
}
|
||||
|
||||
// 2. ボス(BossController)へのパリィ判定
|
||||
BossController boss = other.GetComponentInParent<BossController>();
|
||||
if (boss != null)
|
||||
{
|
||||
// ★リファクタリング:ボスが本当に攻撃中(Bite/Charge)で、パリィが成功した時だけ終了する
|
||||
if (boss.TriggerParryStun())
|
||||
{
|
||||
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
|
||||
Debug.Log("🛡️ 【ジャストパリィ成功!】 ボスの体勢を崩しました!");
|
||||
return; // ★本当のパリィ成功時のみ、ここで処理を終了する
|
||||
}
|
||||
}
|
||||
if (TryProcessParry(other)) return;
|
||||
}
|
||||
|
||||
// ─── ★ここが今回の核心(超重要リファクタリング) ───
|
||||
// 構え状態ではなかった場合、またはボスが攻撃中でなくパリィが不成立だった場合は、
|
||||
// 「プレイヤーが隙を狙って殴りに行った」とみなして、returnせずにそのまま下のパンチ処理へ流す!
|
||||
Debug.Log("🥊 パリィ不成立、または攻撃チャンス:通常のパンチダメージ処理へ移行します。");
|
||||
}
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// 【パンチ攻撃の処理】
|
||||
// ========================================================================
|
||||
Debug.Log($"[InputSystem接触] {other.name} に触れました。センサー速度: {speed:F2} m/s");
|
||||
|
||||
if (speed >= minPunchSpeed)
|
||||
{
|
||||
IDamageble damageble = other.GetComponentInParent<IDamageble>();
|
||||
|
||||
if (damageble != null)
|
||||
{
|
||||
DamageInfo info = new DamageInfo();
|
||||
// 構えからパンチするとダメージ2倍、ゲージ取得度2倍
|
||||
if (poseDetector.IsPosing)
|
||||
{
|
||||
info.amount = (speed * damageMultiplier) * 2f;
|
||||
info.isPoseBonus = true;
|
||||
|
||||
if (PlayerStatusManager.Instance != null) PlayerStatusManager.Instance.AddGauge(20f);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.amount = speed * damageMultiplier;
|
||||
info.isPoseBonus = false;
|
||||
|
||||
if (PlayerStatusManager.Instance != null) PlayerStatusManager.Instance.AddGauge(10f);
|
||||
}
|
||||
info.hitPosition = other.transform.position;
|
||||
info.punchDirection = velocity.normalized;
|
||||
|
||||
if (PlayerStatusManager.Instance != null)
|
||||
{
|
||||
info.amount *= PlayerStatusManager.Instance.CurrentAttackMultiplier;
|
||||
}
|
||||
|
||||
damageble.TakeDamage(info);
|
||||
|
||||
Debug.Log($"パンチ成功 ダメージ: {info.amount:F1}");
|
||||
|
||||
// 通常ヒットの振動を発生
|
||||
TriggerHaptics(hapticAmplitude, hapticDuration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"スピードが足りません。必要: {minPunchSpeed} / 現在: {speed:F2}");
|
||||
ProcessPunchAttack(other, speed, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
/// 引数に応じて指定された強さと長さでコントローラーを振動させる
|
||||
private bool TryProcessParry(Collider other)
|
||||
{
|
||||
EnemyAI enemyAI = other.GetComponentInParent<EnemyAI>();
|
||||
if (enemyAI != null)
|
||||
{
|
||||
enemyAI.TriggerParryStun(parryStunDuration);
|
||||
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
BossController boss = other.GetComponentInParent<BossController>();
|
||||
if (boss != null && boss.TriggerParryStun())
|
||||
{
|
||||
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ProcessPunchAttack(Collider other, float speed, Vector3 velocity)
|
||||
{
|
||||
IDamageable damageable = other.GetComponentInParent<IDamageable>();
|
||||
if (damageable == null) return;
|
||||
|
||||
bool isPosing = poseDetector != null && poseDetector.IsPosing;
|
||||
|
||||
DamageInfo info = new DamageInfo
|
||||
{
|
||||
amount = speed * damageMultiplier * (isPosing ? 2f : 1f),
|
||||
isPoseBonus = isPosing,
|
||||
hitPosition = other.transform.position,
|
||||
punchDirection = velocity.normalized
|
||||
};
|
||||
|
||||
if (PlayerStatusManager.Instance != null)
|
||||
{
|
||||
PlayerStatusManager.Instance.AddGauge(isPosing ? 20f : 10f);
|
||||
info.amount *= PlayerStatusManager.Instance.Buffs.CurrentAttackMultiplier;
|
||||
}
|
||||
|
||||
damageable.TakeDamage(info);
|
||||
TriggerHaptics(hapticAmplitude, hapticDuration);
|
||||
}
|
||||
|
||||
private void TriggerHaptics(float amplitude, float duration)
|
||||
{
|
||||
// 明示的に UnityEngine.XR.InputDevice と指定して型衝突を回避
|
||||
UnityEngine.XR.InputDevice device = InputDevices.GetDeviceAtXRNode(controllerNode);
|
||||
if (device.isValid)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user