parilitest

This commit is contained in:
ohgushiyuga
2026-07-13 16:47:37 +09:00
parent 43ba4da2df
commit 568ed162fb
9 changed files with 452 additions and 98 deletions

View File

@@ -132,12 +132,14 @@ public class BossController : MonoBehaviour, IDamageble
}
}
public void TriggerParryStun()
public bool TriggerParryStun()
{
if (currentState is SpiderBiteState || currentState is SpiderChargeState)
{
ChangeState<SpiderStunState>();
return true;
}
return false;
}
public void ResetChargeCooldown()

View File

@@ -2,57 +2,110 @@ using UnityEngine;
public class VRInputPoseDetector : MonoBehaviour
{
[Header("必須コンポーネント登録")]
[SerializeField] private Transform headTransform;
[SerializeField] private Transform rightHandTransform;
[SerializeField] private Transform leftHandTransform;
[Header("構えの判定範囲設定")]
[SerializeField] private float minForwardDistance = 0.15f;
[SerializeField] private float maxForwardDistance = 0.5f;
[SerializeField] private float minHeightOffset = -0.35f;
[SerializeField] private float maxHeightOffset = -0.1f;
[SerializeField] private float requiredPoseTime = -0.3f;
[Header("タイマー・バッファ設定")]
[SerializeField] private float requiredPoseTime = 0.3f;
[SerializeField] private float poseExitDelay = 0.15f;
[Header("視覚フィードバックガイドUI設定")]
[SerializeField] private Renderer guideRenderer;
[SerializeField] private Color defaultColor = new Color(0.5f, 0.5f, 0.5f, 0.05f); // 普段(超薄いグレー)
[SerializeField] private Color chargingColor = new Color(1f, 0.8f, 0f, 0.2f); // 溜め中(うっすら黄色)
[SerializeField] private Color successColor = new Color(0f, 0.6f, 1f, 0.4f); // 構え完了(綺麗な青シールド)
private float poseTimer = 0f;
private bool isPoseMainTained = false;
public bool IsPosing => isPoseMainTained;
private float exitTimer = 0f;
private bool isPoseMaintained = false;
public bool IsPosing => isPoseMaintained;
void Update()
{
if(headTransform == null || rightHandTransform == null || leftHandTransform == null) return;
if (headTransform == null || rightHandTransform == null || leftHandTransform == null) return;
//両手の世界座標を頭を中心としたローカル座標に変換
// 両手の世界座標を頭を中心としたローカル座標に変換
Vector3 localRightHand = headTransform.InverseTransformPoint(rightHandTransform.position);
Vector3 localLeftHand = headTransform.InverseTransformPoint(leftHandTransform.position);
//両手が構え範囲に入っているかチェック
// 両手が構え範囲に入っているかチェック
bool isRightHandGuarding = CheckHandPosition(localRightHand);
bool isLeftHandGuarding = CheckHandPosition(localLeftHand);
//両手が構え範囲にある場合のタイマー処理
if(isRightHandGuarding && isLeftHandGuarding)
bool isBothHandsGuarding = isRightHandGuarding && isLeftHandGuarding;
// ─── 🛡️ チャタリング防止付き・構え判定ロジック ───
if (isBothHandsGuarding)
{
poseTimer += Time.deltaTime;
if(poseTimer >= requiredPoseTime && !isPoseMainTained)
// 範囲内に手が戻ったので、解除カウントダウンを即座にリセット
exitTimer = 0f;
if (!isPoseMaintained)
{
isPoseMainTained = true;
Debug.Log("kamaeseikou");
poseTimer += Time.deltaTime;
if (poseTimer >= requiredPoseTime)
{
isPoseMaintained = true;
Debug.Log("🛡️ 【構え成功】 パリィ受付がアクティブになりました。");
}
}
}
else
{
poseTimer = 0f;
if(isPoseMainTained)
// 範囲外に出た場合
poseTimer = 0f; // まだ構えが完了していない段階(溜め中)なら即リセット
if (isPoseMaintained)
{
isPoseMainTained = false;
Debug.Log("kamaesippai");
// すでに構えが成功している状態なら、猶予タイマーを開始(ここで即解除しない!)
exitTimer += Time.deltaTime;
if (exitTimer >= poseExitDelay)
{
isPoseMaintained = false;
exitTimer = 0f;
Debug.Log("❌ 【構え解除】 猶予時間を超えたためガードが解けました。");
}
}
}
UpdateVisualFeedback(isBothHandsGuarding);
}
//
private bool CheckHandPosition(Vector3 localHandPos)
{
bool inForwardRange = localHandPos.z >= minForwardDistance && localHandPos.z <= maxForwardDistance; //Z軸:頭より前に手があるか
bool inHeightRange = localHandPos.y >= minHeightOffset && localHandPos.y <= maxHeightOffset; //Y軸:手の高さが適切か
bool inForwardRange = localHandPos.z >= minForwardDistance && localHandPos.z <= maxForwardDistance; // Z軸:頭より前に手があるか
bool inHeightRange = localHandPos.y >= minHeightOffset && localHandPos.y <= maxHeightOffset; // Y軸:手の高さが適切か
return inForwardRange && inHeightRange;
}
}
private void UpdateVisualFeedback(bool isBothHandsGuarding)
{
if (guideRenderer == null) return;
// ボスの攻撃を見やすくするため、現在の状態に応じてガイドシールドのカラーを3段階可変させる
if (isPoseMaintained)
{
guideRenderer.material.color = successColor; // 成功:青シールド
}
else if (isBothHandsGuarding)
{
guideRenderer.material.color = chargingColor; // 溜め中:黄色
}
else
{
guideRenderer.material.color = defaultColor; // 構えなし:目立たない透明グレー
}
}
}

View File

@@ -11,17 +11,15 @@ public class VRInputPunch : MonoBehaviour
[SerializeField] private VRInputPoseDetector poseDetector;
[Header("攻撃(パンチ)設定")]
[SerializeField] private float minPunchSpeed = 2.0f; // パンチとして判定する最低速度 (m/s)
[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 minParrySpeed = 1.0f; // パリィできるパンチとして判定する最低速度 (m/s)
[SerializeField] private float parryStunDuration = 3.0f; // スタン時間(秒)
[SerializeField] private float parryHapticAmplitude = 0.9f; // パリィ成功時の振動の強さ
[SerializeField] private float parryHapticDuration = 0.25f; // パリィ成功時の振動の長さ
// ─────────────────────────────────────────
private void OnEnable()
{
@@ -72,16 +70,17 @@ public class VRInputPunch : MonoBehaviour
BossController boss = other.GetComponentInParent<BossController>();
if (boss != null)
{
boss.TriggerParryStun();
if(boss.TriggerParryStun())
{
TriggerHaptics(parryHapticAmplitude, parryHapticDuration);
Debug.Log("🛡️ 【ジャストパリィ成功!】 ボスの体勢を崩しました!");
return;
}
}
}
Debug.Log("🧱 ガード(構え不足):敵の攻撃は防いだが、弾き返せなかった。");
return;
}