拼图块脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ItemPuzzle : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler//IPointerDownHandler, IPointerUpHandler
{
[Header("正确位置下标")]
public int CorrectIndex;
[Header("当前位置下标")]
[HideInInspector]
public int CurrIndex;
/// <summary>
/// 交换下标
/// </summary>
private int ExchangeIndex;
/// <summary>
/// 开始拖拽位置(用于判断拖拽方向,防止斜着拖动)
/// </summary>
private Vector2 startDragPosition;
/// <summary>
/// 拖拽中位置(用于判断拖拽方向,防止斜着拖动)
/// </summary>
private Vector2 endDragPosition;
/// <summary>
/// 原始交换坐标
/// </summary>
private Vector3 m_ExchangePosition;
private Transform startParent;
/// <summary>
/// 交换的
/// </summary>
private ItemPuzzle m_ExchangePiece;
/// <summary>
/// 检查
/// </summary>
private Action OnCheck;
public void OnBeginDrag(PointerEventData eventData)
{
startDragPosition = eventData.position;
startParent = transform.parent;
transform.SetParent(transform.root);
GetComponent<CanvasGroup>().blocksRaycasts = false;
}
public void OnDrag(PointerEventData eventData)
{
endDragPosition = eventData.position;
if (!DetectDragDirection()) return;
m_ExchangePiece = GetExchangePiece(eventData);
if (m_ExchangePiece == null) return;
if (eventData.pointerEnter.layer != 6 || m_ExchangePiece.CorrectIndex != 0)
{
transform.position = m_ExchangePosition;
return;
}
//Vector2 offset = (Vector2)startPosition - eventData.position;
//float X = Mathf.Clamp(offset.x, -100, 100);
//float Y = Mathf.Clamp(offset.y, -100, 100);
//offset = new Vector2(X, Y);
//Debug.Log(eventData.pointerEnter.tag);
//transform.position = (Vector2)startPosition - offset;
//被交换的交换 给当前的当前
transform.position = m_ExchangePiece.m_ExchangePosition;
CurrIndex = m_ExchangePiece.ExchangeIndex;
//当前的交换 给 交换的当前
m_ExchangePiece.transform.position = m_ExchangePosition;
m_ExchangePiece.CurrIndex = ExchangeIndex;
//当前的当前 给当前的交换
m_ExchangePosition = transform.position;
ExchangeIndex = CurrIndex;
//交换的当前 给 交换的交换
m_ExchangePiece.m_ExchangePosition = m_ExchangePiece.transform.position;
m_ExchangePiece.ExchangeIndex = m_ExchangePiece.CurrIndex;
}
public void OnEndDrag(PointerEventData eventData)
{
transform.SetParent(startParent);
GetComponent<CanvasGroup>().blocksRaycasts = true;
//检查拼图块是否到达正确位置
if (OnCheck != null) OnCheck();
}
private ItemPuzzle GetExchangePiece(PointerEventData eventData)
{
ItemPuzzle m_ExchangePiece = eventData.pointerCurrentRaycast.gameObject.GetComponent<ItemPuzzle>();
return m_ExchangePiece;
}
#region SetUI 设置当前下标和交换下标
/// <summary>
/// 设置当前下标和交换下标
/// </summary>
/// <param name="index">下标</param>
/// <param name="pos">位置</param>
public void SetUI(int index, Vector3 pos, Action onCheck)
{
ExchangeIndex = CurrIndex = index;
m_ExchangePosition = transform.position = pos;
OnCheck = onCheck;
Debug.Log("下标=" + index);
Debug.Log("位置=" + pos);
}
#endregion
#region DetectDragDirection 计算拖拽的方向并将其转换为角度。通过判断角度的范围,可以确定拖拽的主要方向(上、下、左、右)
/// <summary>
/// 计算拖拽的方向并将其转换为角度。通过判断角度的范围,可以确定拖拽的主要方向(上、下、左、右)
/// </summary>
/// <returns></returns>
private bool DetectDragDirection()
{
Vector2 direction = endDragPosition - startDragPosition;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (angle < 0) angle += 360; // Convert negative angles to positive
//Debug.Log($"Drag Angle: {angle}");
//if (angle >= 45 && angle < 135)
//{
// Debug.Log("Dragged Upward");
//}
//else if (angle >= 135 && angle < 225)
//{
// Debug.Log("Dragged Leftward");
//}
//else if (angle >= 225 && angle < 315)
//{
// Debug.Log("Dragged Downward");
//}
//else
//{
// Debug.Log("Dragged Rightward");
//}
if (angle >= 70 && angle < 110)
{
//Debug.Log("Dragged Upward");
return true;
}
else if (angle >= 160 && angle < 200)
{
//Debug.Log("Dragged Leftward");
return true;
}
else if (angle >= 250 && angle < 290)
{
//Debug.Log("Dragged Downward");
return true;
}
else if (angle >= 340 || angle < 20)
{
//Debug.Log("Dragged Rightward");
return true;
}
else
{
//Debug.Log("不能");
return false;
}
}
#endregion
}
生成拼图随机位置脚本
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public class PuzzlePiece : MonoBehaviour
{
[Header("拼图块")]
[SerializeField]
private ItemPuzzle[] m_ItemPuzzles;
[Header("拼图块位置")]
[SerializeField]
private Vector3[] m_Position;
private void Start()
{
LoadRandomPos();
}
/// <summary>
/// 加载随机位置
/// </summary>
private void LoadRandomPos()
{
if (m_ItemPuzzles == null || m_ItemPuzzles.Length == 0 || m_Position == null || m_Position.Length == 0) return;
List<int> m_IndexList = GenerateUniqueRandomNumbers(9, 0, 8);
for (int i = 0; i < m_IndexList.Count; ++i)
{
int index = m_IndexList[i];
ItemPuzzle item = m_ItemPuzzles[i];
Vector3 pos = m_Position[index];
if (item != null)
{
item.SetUI(index, pos, OnCheckCallBack);
}
}
}
/// <summary>
/// 检查回调
/// </summary>
private void OnCheckCallBack()
{
if (m_ItemPuzzles == null || m_ItemPuzzles.Length == 0) return;
bool isSuccess = true;
for (int i = 0; i < m_ItemPuzzles.Length; ++i)
{
ItemPuzzle item = m_ItemPuzzles[i];
if (item != null)
{
if (item.CorrectIndex != item.CurrIndex)
{
isSuccess = false;
break;
}
}
}
if (isSuccess)
{
//成功
Debug.Log("拼图成功");
}
else
{
//失败
Debug.Log("拼图失败");
}
}
/// <summary>
/// 生成不重复的随机数
/// </summary>
/// <param name="count">数组长度</param>
/// <param name="minValue">最小(包括最小)</param>
/// <param name="maxValue">最大(包括最大)</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public List<int> GenerateUniqueRandomNumbers(int count, int minValue, int maxValue)
{
if (count > (maxValue - minValue + 1))
{
throw new ArgumentException("The count is too large for the given range.");
}
HashSet<int> uniqueNumbers = new HashSet<int>();
System.Random random = new System.Random();
while (uniqueNumbers.Count < count)
{
int number = random.Next(minValue, maxValue + 1);
uniqueNumbers.Add(number);
}
return new List<int>(uniqueNumbers);
}
}
成功样式