148 lines
4.5 KiB
C#
148 lines
4.5 KiB
C#
using UnityEngine;
|
||
using UnityEngine.XR.Interaction.Toolkit.Interactables; // XR Toolkit用
|
||
|
||
public enum BlockColor { Red, Blue, Green }
|
||
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;
|
||
|
||
private PuzzleBlock nearbyPartner; // 近くにある結合対象のブロック
|
||
private bool isConnected = false; // 結合済みフラグ
|
||
|
||
// リセット用の初期座標・回転保持用
|
||
private Vector3 initialPosition;
|
||
private Quaternion initialRotation;
|
||
private Rigidbody rb;
|
||
private XRGrabInteractable grabInteractable;
|
||
|
||
private void Awake()
|
||
{
|
||
rb = GetComponent<Rigidbody>();
|
||
grabInteractable = GetComponent<XRGrabInteractable>();
|
||
|
||
// 初期スポーン位置・回転を記憶しておく
|
||
initialPosition = transform.position;
|
||
initialRotation = transform.rotation;
|
||
}
|
||
|
||
private void OnTriggerEnter(Collider other)
|
||
{
|
||
if (isConnected) return;
|
||
|
||
PuzzleBlock partner = other.GetComponentInParent<PuzzleBlock>();
|
||
if (partner != null && IsValidPartner(partner))
|
||
{
|
||
nearbyPartner = partner;
|
||
Debug.Log($"🧩 パートナー検知: {partner.Color} の {partner.ShapeType}");
|
||
}
|
||
}
|
||
|
||
private void OnTriggerExit(Collider other)
|
||
{
|
||
PuzzleBlock partner = other.GetComponentInParent<PuzzleBlock>();
|
||
if (partner == nearbyPartner)
|
||
{
|
||
nearbyPartner = null;
|
||
}
|
||
}
|
||
|
||
private bool IsValidPartner(PuzzleBlock partner)
|
||
{
|
||
if (partner == null || partner.isConnected) return false;
|
||
// 同一色 & 異なる形状(ト字 + コ字)のみ許可
|
||
return partner.Color == this.Color && partner.ShapeType != this.ShapeType;
|
||
}
|
||
|
||
public void OnReleased()
|
||
{
|
||
if (isConnected) return;
|
||
|
||
if (nearbyPartner != null)
|
||
{
|
||
ConnectToPartner(nearbyPartner);
|
||
}
|
||
}
|
||
|
||
private void ConnectToPartner(PuzzleBlock partner)
|
||
{
|
||
isConnected = true;
|
||
partner.isConnected = true;
|
||
|
||
// 1. 位置・回転のスナップ補正
|
||
if (snapPoint != null && partner.snapPoint != null)
|
||
{
|
||
transform.position = partner.snapPoint.position;
|
||
transform.rotation = partner.snapPoint.rotation;
|
||
}
|
||
else
|
||
{
|
||
transform.position = partner.transform.position;
|
||
transform.rotation = partner.transform.rotation;
|
||
}
|
||
|
||
// 2. 物理&VR掴み動作の完全ロック(完成後に崩れないようにする)
|
||
LockBlockState();
|
||
partner.LockBlockState();
|
||
|
||
Debug.Log($"🎉 マグネット合体成功! 色: {Color}");
|
||
|
||
// 3. バフ適用してCodingMode完了へ
|
||
string buffName = ConvertColorToBuffName(Color);
|
||
PlayerStatusManager.Instance.ApplyBuffsAndResume(buffName, buffName);
|
||
}
|
||
|
||
private void LockBlockState()
|
||
{
|
||
if (rb != null)
|
||
{
|
||
rb.linearVelocity = Vector3.zero;
|
||
rb.angularVelocity = Vector3.zero;
|
||
rb.isKinematic = true;
|
||
}
|
||
// 掴みコンポーネントをオフにして手から切り離す
|
||
if (grabInteractable != null) grabInteractable.enabled = false;
|
||
}
|
||
|
||
public void ResetBlock()
|
||
{
|
||
isConnected = false;
|
||
nearbyPartner = null;
|
||
|
||
transform.position = initialPosition;
|
||
transform.rotation = initialRotation;
|
||
|
||
if (rb != null)
|
||
{
|
||
rb.isKinematic = false;
|
||
rb.linearVelocity = Vector3.zero;
|
||
rb.angularVelocity = Vector3.zero;
|
||
}
|
||
if (grabInteractable != null) grabInteractable.enabled = true;
|
||
}
|
||
|
||
public static void ResetAllBlocksInScene()
|
||
{
|
||
foreach (var block in FindObjectsByType<PuzzleBlock>(FindObjectsSortMode.None))
|
||
{
|
||
if (block != null) block.ResetBlock();
|
||
}
|
||
}
|
||
|
||
private string ConvertColorToBuffName(BlockColor color)
|
||
{
|
||
return color switch
|
||
{
|
||
BlockColor.Red => "AttackUp",
|
||
BlockColor.Blue => "DefenseUp",
|
||
BlockColor.Green => "Heal",
|
||
_ => "AttackUp"
|
||
};
|
||
}
|
||
} |