This commit is contained in:
ohgushiyuga
2026-08-27 12:51:15 +09:00
parent 1441c96f74
commit 52341100ed
32 changed files with 840 additions and 1076 deletions

View File

@@ -1,24 +1,32 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit.Interactables; // XR Toolkit用
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
public enum BlockColor { Red, Blue, Green }
public enum BlockShapeType { TShape, CShape } // ト字, コ字
public enum BlockShapeType { TShape, CShape }
public class PuzzleBlock : MonoBehaviour
{
[field: SerializeField] public BlockColor Color { get; private set; }
[field: SerializeField] public BlockShapeType ShapeType { get; private set; }
[Header("スナップ(合体)位置の設定")]
[Tooltip("相手と合体する基準位置(空のGameObject)を指定。未設定でも中心位置でスナップします")]
[SerializeField] private Transform snapPoint;
[SerializeField] private Transform snapPoint;
private PuzzleBlock nearbyPartner; // 近くにある結合対象のブロック
private bool isConnected = false; // 結合済みフラグ
public static event Action<BlockColor> OnPuzzleCompleted;
private static readonly HashSet<PuzzleBlock> allBlocks = new HashSet<PuzzleBlock>();
private PuzzleBlock nearbyPartner;
private bool isConnected;
// ★ワールド情報ではなく「親階層」と「ローカル情報」を記憶
private Transform initialParent;
private Vector3 initialLocalPosition;
private Quaternion initialLocalRotation;
private Vector3 initialLocalScale;
// リセット用の初期座標・回転保持用
private Vector3 initialPosition;
private Quaternion initialRotation;
private Rigidbody rb;
private XRGrabInteractable grabInteractable;
@@ -27,9 +35,21 @@ public class PuzzleBlock : MonoBehaviour
rb = GetComponent<Rigidbody>();
grabInteractable = GetComponent<XRGrabInteractable>();
// 初期スポーン位置・回転を記憶しておく
initialPosition = transform.position;
initialRotation = transform.rotation;
// ★開始時の「親」と「ローカル座標・回転・スケール」を保持
initialParent = transform.parent;
initialLocalPosition = transform.localPosition;
initialLocalRotation = transform.localRotation;
initialLocalScale = transform.localScale;
}
private void OnEnable()
{
allBlocks.Add(this);
}
private void OnDisable()
{
allBlocks.Remove(this);
}
private void OnTriggerEnter(Collider other)
@@ -40,7 +60,6 @@ public class PuzzleBlock : MonoBehaviour
if (partner != null && IsValidPartner(partner))
{
nearbyPartner = partner;
Debug.Log($"🧩 パートナー検知: {partner.Color} の {partner.ShapeType}");
}
}
@@ -56,8 +75,7 @@ public class PuzzleBlock : MonoBehaviour
private bool IsValidPartner(PuzzleBlock partner)
{
if (partner == null || partner.isConnected) return false;
// 同一色 & 異なる形状(ト字 + コ字)のみ許可
return partner.Color == this.Color && partner.ShapeType != this.ShapeType;
return partner.Color == Color && partner.ShapeType != ShapeType;
}
public void OnReleased()
@@ -75,7 +93,6 @@ public class PuzzleBlock : MonoBehaviour
isConnected = true;
partner.isConnected = true;
// 1. 位置・回転のスナップ補正
if (snapPoint != null && partner.snapPoint != null)
{
transform.position = partner.snapPoint.position;
@@ -87,15 +104,16 @@ public class PuzzleBlock : MonoBehaviour
transform.rotation = partner.transform.rotation;
}
// 2. 物理&VR掴み動作の完全ロック(完成後に崩れないようにする)
LockBlockState();
partner.LockBlockState();
Debug.Log($"🎉 マグネット合体成功! 色: {Color}");
OnPuzzleCompleted?.Invoke(Color);
// 3. バフ適用してCodingMode完了へ
string buffName = ConvertColorToBuffName(Color);
PlayerStatusManager.Instance.ApplyBuffsAndResume(buffName, buffName);
BuffType buff = ConvertColorToBuffType(Color);
if (PlayerStatusManager.Instance != null)
{
PlayerStatusManager.Instance.ApplyBuffsAndResume(buff, buff);
}
}
private void LockBlockState()
@@ -106,43 +124,72 @@ public class PuzzleBlock : MonoBehaviour
rb.angularVelocity = Vector3.zero;
rb.isKinematic = true;
}
// 掴みコンポーネントをオフにして手から切り離す
if (grabInteractable != null) grabInteractable.enabled = false;
}
public void ResetBlock()
{
// 1. 手で掴んでいる場合は手離し処理
ForceDrop();
isConnected = false;
nearbyPartner = null;
transform.position = initialPosition;
transform.rotation = initialRotation;
// 2. ★親オブジェクト(Canvas)の子へ戻す
if (initialParent != null && transform.parent != initialParent)
{
transform.SetParent(initialParent, false);
}
// 3. ★Canvas内のローカル位置・回転・スケールを完全復元
transform.localPosition = initialLocalPosition;
transform.localRotation = initialLocalRotation;
transform.localScale = initialLocalScale;
// 4. 物理状態の再初期化
if (rb != null)
{
rb.isKinematic = false;
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
if (grabInteractable != null) grabInteractable.enabled = true;
// 5. 掴み機能の再有効化
if (grabInteractable != null)
{
grabInteractable.enabled = true;
}
}
private void ForceDrop()
{
if (grabInteractable == null || !grabInteractable.isSelected) return;
if (grabInteractable.interactionManager != null && grabInteractable.firstInteractorSelecting != null)
{
grabInteractable.interactionManager.SelectExit(grabInteractable.firstInteractorSelecting, grabInteractable);
}
}
public static void ResetAllBlocksInScene()
{
foreach (var block in FindObjectsByType<PuzzleBlock>(FindObjectsSortMode.None))
foreach (var block in allBlocks)
{
if (block != null) block.ResetBlock();
if (block != null)
{
block.ResetBlock();
}
}
}
private string ConvertColorToBuffName(BlockColor color)
private BuffType ConvertColorToBuffType(BlockColor color)
{
return color switch
{
BlockColor.Red => "AttackUp",
BlockColor.Blue => "DefenseUp",
BlockColor.Green => "Heal",
_ => "AttackUp"
BlockColor.Red => BuffType.AttackUp,
BlockColor.Blue => BuffType.DefenseUp,
BlockColor.Green => BuffType.Heal,
_ => BuffType.AttackUp
};
}
}