Files
VRProject/Assets/Scripts/CodingPazzleManager.cs
2026-06-10 16:27:28 +09:00

109 lines
4.8 KiB
C#
Raw 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.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
/// <summary>
/// 3D空間上の2つのソケットスロットにバフモジュールがハメ込まれたかを監視し、
/// 連結完了時にバフを発動させるパズル管理クラス
/// </summary>
public class CodingPuzzleManager : MonoBehaviour
{
[Header("ソケットスロットの設定")]
[Tooltip("台座に配置した Slot_A の XRSocketInteractor を指定してください")]
[SerializeField] private XRSocketInteractor socketA;
[Tooltip("台座に配置した Slot_B の XRSocketInteractor を指定してください")]
[SerializeField] private XRSocketInteractor socketB;
private void OnEnable()
{
// ソケットにオブジェクトが「ハメ込まれた瞬間」のイベントを登録
if (socketA != null) socketA.selectEntered.AddListener(OnSocketAEntered);
if (socketB != null) socketB.selectEntered.AddListener(OnSocketBEntered);
}
private void OnDisable()
{
// イベントの登録解除
if (socketA != null) socketA.selectEntered.RemoveListener(OnSocketAEntered);
if (socketB != null) socketB.selectEntered.RemoveListener(OnSocketBEntered);
}
// Slot_A に何かがハメ込まれた時のコールバック
private void OnSocketAEntered(SelectEnterEventArgs args)
{
CheckPuzzleCompletion();
}
// Slot_B に何かがハメ込まれた時のコールバック
private void OnSocketBEntered(SelectEnterEventArgs args)
{
CheckPuzzleCompletion();
}
/// <summary>
/// 両方のスロットが埋まっているかチェックし、埋まっていれば連結バフを発動する
/// </summary>
private void CheckPuzzleCompletion()
{
if (socketA == null || socketB == null) return;
// 両方のソケットがオブジェクトを保持hasSelectionしているか確認
if (socketA.hasSelection && socketB.hasSelection)
{
// ハメ込まれているオブジェクトInteractableを取得
var objA = socketA.firstInteractableSelected;
var objB = socketB.firstInteractableSelected;
if (objA != null && objB != null)
{
// オブジェクトの名前から、どのバフ四角形かを判別する文字列を抽出
string buff1 = GetBuffNameFromObjectName(objA.transform.gameObject.name);
string buff2 = GetBuffNameFromObjectName(objB.transform.gameObject.name);
Debug.Log($"💻 パズル連結完了! 検出されたコンボ: [{buff1}] + [{buff2}]");
// ★ソケットにハマっているオブジェクトを強制的に解放・リセット
// (これをしないと、次回Codingモードを開いた時にスロットが埋まったままになります)
ClearSockets();
// PlayerStatusManagerにバフを適用させ、時間停止を解除してプレイ画面に戻る
if (PlayerStatusManager.Instance != null)
{
PlayerStatusManager.Instance.ApplyBuffsAndResume(buff1, buff2);
}
}
}
}
/// <summary>
/// オブジェクト名に含まれるキーワードから、ステータスマネージャーに渡す用の正確なバフ名を返すヘルパー
/// </summary>
private string GetBuffNameFromObjectName(string objName)
{
if (objName.Contains("AttackUp")) return "AttackUp";
if (objName.Contains("DefenseUp")) return "DefenseUp";
if (objName.Contains("Heal")) return "Heal";
return "Unknown";
}
/// <summary>
/// 次回起動時のために、ソケットの選択状態を内部的・物理的に安全にクリアする
/// </summary>
private void ClearSockets()
{
// 開発環境のSDKバージョンによって挙動が異なる場合があるため、
// ハハマっているモジュールを一度ソケットの子供から外し、初期位置付近に戻すか、
// あるいは単純に非アクティブ(または位置リセット)にする処理が推奨されます。
// ここでは安全のため、ハマっていたオブジェクトの座標を台座の手前に逃がします。
if (socketA.firstInteractableSelected != null)
{
socketA.firstInteractableSelected.transform.position = transform.position + (transform.forward * -0.2f);
}
if (socketB.firstInteractableSelected != null)
{
socketB.firstInteractableSelected.transform.position = transform.position + (transform.forward * -0.2f) + (transform.right * 0.1f);
}
}
}