CodingMode難しい

This commit is contained in:
ohgushiyuga
2026-06-10 16:27:28 +09:00
parent 14ebaa11be
commit c6b593805b
4 changed files with 325 additions and 91 deletions

View File

@@ -0,0 +1,109 @@
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);
}
}
}