Files
VRProject/Assets/_Scripts/PuzzleBlock.cs
ohgushiyuga 9864b95a91 HPbarzissou
2026-08-27 17:59:06 +09:00

203 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
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; }
[SerializeField] private Transform snapPoint;
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 bool initialIsKinematic;
private bool initialUseGravity;
private Rigidbody rb;
private XRGrabInteractable grabInteractable;
private void Awake()
{
rb = GetComponent<Rigidbody>();
grabInteractable = GetComponent<XRGrabInteractable>();
initialParent = transform.parent;
initialLocalPosition = transform.localPosition;
initialLocalRotation = transform.localRotation;
initialLocalScale = transform.localScale;
// ★初期状態の重力・キネマティック設定を保持
if (rb != null)
{
initialIsKinematic = rb.isKinematic;
initialUseGravity = rb.useGravity;
}
}
private void OnEnable()
{
allBlocks.Add(this);
}
private void OnDisable()
{
allBlocks.Remove(this);
}
private void OnTriggerEnter(Collider other)
{
if (isConnected) return;
PuzzleBlock partner = other.GetComponentInParent<PuzzleBlock>();
if (partner != null && IsValidPartner(partner))
{
nearbyPartner = partner;
}
}
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 == Color && partner.ShapeType != ShapeType;
}
public void OnReleased()
{
if (isConnected) return;
if (nearbyPartner != null)
{
ConnectToPartner(nearbyPartner);
}
}
private void ConnectToPartner(PuzzleBlock partner)
{
isConnected = true;
partner.isConnected = true;
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;
}
LockBlockState();
partner.LockBlockState();
OnPuzzleCompleted?.Invoke(Color);
// PuzzleBlock.cs
BuffType buff = ConvertColorToBuffType(Color);
if (PlayerStatusManager.Instance != null)
{
PlayerStatusManager.Instance.ApplyBuffAndResume(buff);
}
}
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()
{
ForceDrop();
isConnected = false;
nearbyPartner = null;
if (initialParent != null && transform.parent != initialParent)
{
transform.SetParent(initialParent, false);
}
transform.localPosition = initialLocalPosition;
transform.localRotation = initialLocalRotation;
transform.localScale = initialLocalScale;
// ★修正:初期設定(記憶した値)へ正確に復元
if (rb != null)
{
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.isKinematic = initialIsKinematic;
rb.useGravity = initialUseGravity;
}
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 allBlocks)
{
if (block != null)
{
block.ResetBlock();
}
}
}
private BuffType ConvertColorToBuffType(BlockColor color)
{
return color switch
{
BlockColor.Red => BuffType.AttackUp,
BlockColor.Blue => BuffType.DefenseUp,
BlockColor.Green => BuffType.Heal,
_ => BuffType.AttackUp
};
}
}