HPbarzissou
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user