HPbarzissou

This commit is contained in:
ohgushiyuga
2026-08-27 17:59:06 +09:00
parent 52341100ed
commit 9864b95a91
48 changed files with 3379 additions and 19467 deletions

View File

@@ -1,10 +1,20 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.XR;
public class PlayerStatusManager : MonoBehaviour
public class PlayerStatusManager : MonoBehaviour, IDamageable
{
public static PlayerStatusManager Instance { get; private set; }
[Header("HP・ステータス設定")]
[SerializeField] private float maxHp = 100f;
[SerializeField] private float currentHp = 100f;
[Tooltip("被ダメージ後の無敵時間(秒)")]
[SerializeField] private float invincibilityDuration = 0.8f;
[Header("デバッグ設定")]
[SerializeField] private bool ignoreGaugeForDebug = true;
@@ -30,30 +40,30 @@ public class PlayerStatusManager : MonoBehaviour
[SerializeField] private BuffHandler buffHandler = new BuffHandler();
private float codingTimer;
private bool isInvincible;
public bool IsCodingMode { get; private set; }
public bool IsDead { get; private set; }
public float CurrentHp => currentHp;
public float MaxHp => maxHp;
public float CurrentGauge => currentGauge;
public float MaxGauge => maxGauge;
public BuffHandler Buffs => buffHandler;
public event Action<float, float> OnHpChanged;
public event Action<float, float> OnGaugeChanged;
public event Action OnDeath;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(gameObject);
}
if (Instance == null) Instance = this;
else Destroy(gameObject);
currentHp = maxHp;
}
private void OnEnable()
{
SetActionsEnabled(true);
}
private void OnDisable()
{
SetActionsEnabled(false);
}
private void OnEnable() => SetActionsEnabled(true);
private void OnDisable() => SetActionsEnabled(false);
private void SetActionsEnabled(bool enable)
{
@@ -73,10 +83,14 @@ public class PlayerStatusManager : MonoBehaviour
private void Start()
{
if (codingModeUI != null) codingModeUI.SetActive(false);
OnHpChanged?.Invoke(currentHp, maxHp);
OnGaugeChanged?.Invoke(currentGauge, maxGauge);
}
private void Update()
{
if (IsDead) return;
CheckComboInput();
if (!IsCodingMode)
@@ -95,8 +109,85 @@ public class PlayerStatusManager : MonoBehaviour
public void AddGauge(float amount)
{
if (IsCodingMode) return;
if (IsCodingMode || IsDead) return;
currentGauge = Mathf.Clamp(currentGauge + amount, 0f, maxGauge);
OnGaugeChanged?.Invoke(currentGauge, maxGauge);
}
public void TakeDamage(DamageInfo damageInfo)
{
if (IsDead || isInvincible || IsCodingMode) return;
// 防御バフ適用(倍率を掛けて被ダメージを軽減)
float finalDamage = damageInfo.amount * buffHandler.CurrentDefenseMultiplier;
currentHp = Mathf.Max(0f, currentHp - finalDamage);
OnHpChanged?.Invoke(currentHp, maxHp);
Debug.Log($"💥 プレイヤー被ダメージ: {finalDamage:F1} (残HP: {currentHp:F1} / {maxHp})");
// コントローラーへの被弾振動フィードバック
TriggerDamageHaptics(0.6f, 0.15f);
if (currentHp <= 0f)
{
Die();
}
else
{
StartCoroutine(InvincibilityRoutine());
}
}
public void Heal(float amount)
{
if (IsDead) return;
currentHp = Mathf.Min(maxHp, currentHp + amount);
OnHpChanged?.Invoke(currentHp, maxHp);
Debug.Log($"💚 HP回復: +{amount} (現在HP: {currentHp} / {maxHp})");
}
private IEnumerator InvincibilityRoutine()
{
isInvincible = true;
yield return new WaitForSeconds(invincibilityDuration);
isInvincible = false;
}
private void Die()
{
if (IsDead) return;
IsDead = true;
Debug.LogError("☠️ プレイヤー死亡:GAME OVER");
OnDeath?.Invoke();
SetActionsEnabled(false);
if (WorldPauseManager.Instance != null)
{
WorldPauseManager.Instance.PauseWorld();
}
// 死亡後、2秒待って現在のシーンをリロード(再開)
StartCoroutine(GameOverRestartRoutine());
}
private IEnumerator GameOverRestartRoutine()
{
yield return new WaitForSecondsRealtime(2.5f);
if (WorldPauseManager.Instance != null)
{
WorldPauseManager.Instance.ResumeWorld();
}
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
private void TriggerDamageHaptics(float amplitude, float duration)
{
UnityEngine.XR.InputDevice left = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
if (left.isValid) left.SendHapticImpulse(0, amplitude, duration);
UnityEngine.XR.InputDevice right = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
if (right.isValid) right.SendHapticImpulse(0, amplitude, duration);
}
private void CheckComboInput()
@@ -131,7 +222,7 @@ public class PlayerStatusManager : MonoBehaviour
SetActionState(turnAction, false);
PuzzleBlock.ResetAllBlocksInScene();
if (WorldPauseManager.Instance != null)
{
WorldPauseManager.Instance.PauseWorld();
@@ -140,15 +231,15 @@ public class PlayerStatusManager : MonoBehaviour
if (codingModeUI != null) codingModeUI.SetActive(true);
}
public void ApplyBuffsAndResume(BuffType buff1, BuffType buff2)
// PlayerStatusManager.cs
public void ApplyBuffAndResume(BuffType buff)
{
if (successEffectPrefab != null && effectSpawnPoint != null)
{
Instantiate(successEffectPrefab, effectSpawnPoint.position, effectSpawnPoint.rotation);
}
buffHandler.ActivateBuff(buff1);
buffHandler.ActivateBuff(buff2);
buffHandler.ActivateBuff(buff);
ResumeWorldState(consumeGauge: true);
}
@@ -165,8 +256,14 @@ public class PlayerStatusManager : MonoBehaviour
SetActionState(moveAction, true);
SetActionState(turnAction, true);
PuzzleBlock.ResetAllBlocksInScene();
IsCodingMode = false;
if (codingModeUI != null) codingModeUI.SetActive(false);
if (consumeGauge) currentGauge = 0f;
if (consumeGauge)
{
currentGauge = 0f;
OnGaugeChanged?.Invoke(currentGauge, maxGauge);
}
}
}