Files
VRProject/Assets/Scripts/PlayerStatusManager.cs
ohgushiyuga e77200862d atu
2026-07-07 12:32:32 +09:00

209 lines
7.5 KiB
C#
Raw Permalink 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;
using System.Collections;
using System.Collections.Generic; // Listを使うために追加
/// <summary>
/// プレイヤーの共通ゲージ、時間停止Codingモード、UI、および各種バフの制限時間を管理するクラス
/// </summary>
public class PlayerStatusManager : MonoBehaviour
{
public static PlayerStatusManager Instance { get; private set; }
[Header("Codingモード用 入力設定")]
[SerializeField] private InputActionProperty zlButtonAction;
[SerializeField] private InputActionProperty zrButtonAction;
[Header("ゲージ設定")]
[SerializeField] private float maxGauge = 100f;
[SerializeField] private float currentGauge = 0f;
[Header("表示UI設定")]
[Tooltip("画面全体を追従させる親オブジェクトWorld Space Canvasや3D台座を指定してください")]
[SerializeField] private GameObject codingModeUI;
[Header("バフパラメータ設定")]
[Tooltip("攻撃力UP・防御力UPの持続時間 (秒)")]
[SerializeField] private float buffDuration = 10f;
[Tooltip("攻撃力UP時のダメージ倍率 (例: 1.5倍)")]
[SerializeField] private float attackBuffMultiplier = 1.5f;
[Tooltip("防御力UP時の被ダメージ軽減率 (例: 0.5ならダメージ50%カット)")]
[SerializeField] private float defenseBuffMultiplier = 0.5f;
[Tooltip("HP回復バフ発動時の回復量")]
[SerializeField] private float hpHealAmount = 30f;
// 各バフの残り時間を管理するタイマー0より大きければバフ有効
private float attackBuffTimer = 0f;
private float defenseBuffTimer = 0f;
// 現在Codingモード時間停止中かどうかのフラグ
private bool isCodingMode = false;
// 【新設】一時停止させた敵のアニメーターを記憶しておくためのリスト
private List<Animator> pausedAnimators = new List<Animator>();
#region
public bool IsAttackBuffActive => attackBuffTimer > 0f;
public bool IsDefenseBuffActive => defenseBuffTimer > 0f;
public float CurrentAttackMultiplier => IsAttackBuffActive ? attackBuffMultiplier : 1.0f;
public float CurrentDefenseMultiplier => IsDefenseBuffActive ? defenseBuffMultiplier : 1.0f;
#endregion
private void Awake()
{
if (Instance == null) { Instance = this; }
else { Destroy(gameObject); }
}
private void OnEnable()
{
if (zlButtonAction.action != null) zlButtonAction.action.Enable();
if (zrButtonAction.action != null) zrButtonAction.action.Enable();
}
private void OnDisable()
{
if (zlButtonAction.action != null) zlButtonAction.action.Disable();
if (zrButtonAction.action != null) zrButtonAction.action.Disable();
}
private void Start()
{
if (codingModeUI != null) codingModeUI.SetActive(false);
}
private void Update()
{
CheckComboInput();
// ゲームプレイ中(時間停止中でないとき)のみ、バフのタイマーを減算する
if (!isCodingMode)
{
UpdateBuffTimers();
}
}
public void AddGauge(float amount)
{
if (isCodingMode) return;
currentGauge += amount;
currentGauge = Mathf.Clamp(currentGauge, 0f, maxGauge);
Debug.Log($"🔋 共通ゲージ増加: {currentGauge} / {maxGauge}");
}
private void CheckComboInput()
{
if (zlButtonAction.action == null || zrButtonAction.action == null) return;
bool zlPressed = zlButtonAction.action.triggered && zlButtonAction.action.ReadValue<float>() > 0.5f;
bool zrPressed = zrButtonAction.action.triggered && zrButtonAction.action.ReadValue<float>() > 0.5f;
if (!isCodingMode && currentGauge >= maxGauge)
{
if ((zlPressed && zrButtonAction.action.ReadValue<float>() > 0.5f) ||
(zrPressed && zlButtonAction.action.ReadValue<float>() > 0.5f))
{
StartCodingMode();
}
}
}
/// <summary>
/// Codingモード時間停止を開始する
/// </summary>
private void StartCodingMode()
{
isCodingMode = true;
// 【変更】Time.timeScaleは弄らず、シーン内のAnimatorを検索して停止させる
Animator[] allAnimators = FindObjectsByType<Animator>(FindObjectsSortMode.None);
pausedAnimators.Clear();
foreach (var anim in allAnimators)
{
if (anim == null) continue;
// ⚠️ プレイヤー自身のアニメーターまで止めないように除外する
// (このマネージャーがプレイヤーオブジェクトについている、またはPlayerタグを想定)
if (anim.gameObject == this.gameObject || anim.CompareTag("Player")) continue;
// 元のスピードに関わらず、0に上書きしてアニメーションを完全停止
anim.speed = 0f;
pausedAnimators.Add(anim); // 記憶リストに保存
}
if (codingModeUI != null) codingModeUI.SetActive(true);
Debug.Log("⏳ Codingモード敵の時間アニメーションを停止しました。");
}
/// <summary>
/// バフを適用してゲームを再開する
/// </summary>
public void ApplyBuffsAndResume(string buff1, string buff2)
{
// 1. 選択された2つのバフをそれぞれ発動
ActivateBuffByName(buff1);
ActivateBuffByName(buff2);
// 【変更】2. 停止させていた敵のアニメーターを元の速度1.0f)に戻す
foreach (var anim in pausedAnimators)
{
if (anim != null)
{
anim.speed = 1f;
}
}
pausedAnimators.Clear(); // リストを空にする
// 3. Codingモードの終了処理
isCodingMode = false;
if (codingModeUI != null) codingModeUI.SetActive(false);
currentGauge = 0f; // ゲージを消費
Debug.Log("▶ Codingモード終了敵の時間を再開しました。");
}
private void ActivateBuffByName(string buffName)
{
switch (buffName)
{
case "AttackUp":
attackBuffTimer = buffDuration;
Debug.Log($"⚔️ 攻撃力UPバフ発動 倍率: {attackBuffMultiplier} / 効果時間: {buffDuration}秒");
break;
case "DefenseUp":
defenseBuffTimer = buffDuration;
Debug.Log($"🛡️ 防御力UPバフ発動 被ダメージ倍率: {defenseBuffMultiplier} / 効果時間: {buffDuration}秒");
break;
case "Heal":
ExecuteHeal();
break;
default:
Debug.LogWarning($"未定義のバフ名が検出されました: {buffName}");
break;
}
}
private void ExecuteHeal()
{
Debug.Log($"💚 HP回復バフ発動 回復量: {hpHealAmount}");
}
private void UpdateBuffTimers()
{
if (attackBuffTimer > 0f)
{
attackBuffTimer -= Time.deltaTime;
if (attackBuffTimer <= 0f) Debug.Log("⚔️ 攻撃力UPバフの効果が終了しました。");
}
if (defenseBuffTimer > 0f)
{
defenseBuffTimer -= Time.deltaTime;
if (defenseBuffTimer <= 0f) Debug.Log("🛡️ 防御力UPバフの効果が終了しました。");
}
}
}