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