326 lines
12 KiB
C#
326 lines
12 KiB
C#
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
||
|
|
using Newtonsoft.Json;
|
||
|
|
using UnityEngine;
|
||
|
|
using DG.Tweening;
|
||
|
|
using LoveLegend;
|
||
|
|
|
||
|
|
public class level2 : MonoBehaviour
|
||
|
|
{
|
||
|
|
|
||
|
|
public GameObject item_parent;
|
||
|
|
public GameObject item_parent_big;
|
||
|
|
private List<ItemState_2> _itemList;
|
||
|
|
public Camera cam;
|
||
|
|
private GameObject selected;
|
||
|
|
private Vector3 offset;
|
||
|
|
private int out_layers = 30;
|
||
|
|
public GameObject empty_parent;
|
||
|
|
|
||
|
|
private List<Vector3> originalPositions = new List<Vector3>();
|
||
|
|
void Awake()
|
||
|
|
{
|
||
|
|
Camera orthoCamera = GameObject.Find("Main Camera").GetComponent<Camera>();
|
||
|
|
|
||
|
|
float size = (float)System.Math.Round(5.5f / ((float)Screen.width / Screen.height), 4);
|
||
|
|
// string type = SystemInfo.deviceModel.ToLower().Trim();
|
||
|
|
// // Debug.Log($"type==========={type}");
|
||
|
|
// if (type.Substring(0, 3) == "ipa")
|
||
|
|
// {//iPad机型
|
||
|
|
// size = 49.9f;
|
||
|
|
// }
|
||
|
|
orthoCamera.orthographicSize = size;
|
||
|
|
}
|
||
|
|
void Start()
|
||
|
|
{
|
||
|
|
|
||
|
|
_itemList = new List<ItemState_2>();
|
||
|
|
|
||
|
|
int index_ = 0;
|
||
|
|
foreach (Transform child in item_parent.transform)
|
||
|
|
{
|
||
|
|
// Debug.Log("子物体: " + child.name);
|
||
|
|
// Debug.Log("子物体: " + child.tag);
|
||
|
|
_itemList.Add(new ItemState_2()
|
||
|
|
{
|
||
|
|
_position = positionList[index_],
|
||
|
|
_orderInLayer = child.GetComponent<SpriteRenderer>().sortingOrder,
|
||
|
|
_tag = child.tag,
|
||
|
|
_isFull = false,
|
||
|
|
type = 1,
|
||
|
|
});
|
||
|
|
index_++;
|
||
|
|
|
||
|
|
}
|
||
|
|
foreach (Transform child in empty_parent.transform)
|
||
|
|
{
|
||
|
|
// Debug.Log("子物体: " + child.name);
|
||
|
|
// Debug.Log("子物体: " + child.tag);
|
||
|
|
_itemList.Add(new ItemState_2()
|
||
|
|
{
|
||
|
|
_position = positionList[index_],
|
||
|
|
_orderInLayer = child.GetComponent<SpriteRenderer>().sortingOrder,
|
||
|
|
_tag = child.tag,
|
||
|
|
_isFull = false,
|
||
|
|
type = 2
|
||
|
|
});
|
||
|
|
index_++;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// foreach (Transform child in item_parent.transform)
|
||
|
|
// {
|
||
|
|
// float randomX = Random.Range(-3f, 3f); // X 在 -2 ~ 2
|
||
|
|
// float randomY = 14f + Random.Range(-2f, 2f); // Y 在 -16 ~ -12
|
||
|
|
// child.position = new Vector3(randomX, randomY, child.position.z);
|
||
|
|
// }
|
||
|
|
|
||
|
|
// DOVirtual.DelayedCall(2.5f, () =>
|
||
|
|
// {
|
||
|
|
// StartCoroutine(MoveChildrenCoroutine());
|
||
|
|
// });
|
||
|
|
|
||
|
|
// Debug.Log(JsonConvert.SerializeObject(_itemList));
|
||
|
|
// foreach (var pos in positionList)
|
||
|
|
// {
|
||
|
|
// Debug.Log("Position: " + pos);
|
||
|
|
// }
|
||
|
|
}
|
||
|
|
List<Vector3> positionList = new List<Vector3>()
|
||
|
|
{
|
||
|
|
new Vector3(0.44f, 1.30f, 0.00f),
|
||
|
|
new Vector3(1.34f, -1.84f, 0.00f),
|
||
|
|
new Vector3(-0.46f, -1.38f, 0.00f),
|
||
|
|
new Vector3(-1.36f, 0.39f, 0.00f),
|
||
|
|
new Vector3(1.17f, 2.46f, 0.00f),
|
||
|
|
new Vector3(5.10f, 1.39f, 0.00f),
|
||
|
|
new Vector3(1.06f, 1.38f, 0.00f),
|
||
|
|
new Vector3(-1.48f, -1.30f, 0.00f),
|
||
|
|
new Vector3(-6.83f, -0.40f, 0.00f),
|
||
|
|
new Vector3(-2.82f, -0.40f, 0.00f),
|
||
|
|
new Vector3(2.80f, 2.46f, 0.00f),
|
||
|
|
new Vector3(-1.90f, -0.40f, 0.00f),
|
||
|
|
new Vector3(-1.39f, -2.17f, 0.00f),
|
||
|
|
new Vector3(0.83f, -0.41f, 0.00f),
|
||
|
|
new Vector3(-5.81f, 0.49f, 0.00f),
|
||
|
|
new Vector3(-6.61f, -1.29f, 0.00f),
|
||
|
|
new Vector3(-0.31f, 0.49f, 0.00f),
|
||
|
|
new Vector3(6.27f, -2.18f, 0.00f),
|
||
|
|
new Vector3(-2.58f, 1.39f, 0.00f)
|
||
|
|
};
|
||
|
|
|
||
|
|
// IEnumerator MoveChildrenCoroutine()
|
||
|
|
// {
|
||
|
|
// foreach (Transform child in item_parent.transform)
|
||
|
|
// {
|
||
|
|
// // 随机目标 Y 在 -5 ~ 5
|
||
|
|
// float targetY = Random.Range(-5f, 5f);
|
||
|
|
// Vector3 targetPos = new Vector3(child.position.x, targetY, child.position.z);
|
||
|
|
|
||
|
|
// // DOTween 缓动到目标位置
|
||
|
|
// child.DOMove(targetPos, 1.7f).SetEase(Ease.InCubic);
|
||
|
|
|
||
|
|
// // 每个间隔 0.1s
|
||
|
|
// yield return new WaitForSeconds(0.05f);
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
// IEnumerator MoveBackCoroutine()
|
||
|
|
// {
|
||
|
|
// int index = 0;
|
||
|
|
// foreach (Transform child in plate_parent.transform)
|
||
|
|
// {
|
||
|
|
// // 缓动到原始位置
|
||
|
|
// child.DOMove(originalPositions[index], 0.5f).SetEase(Ease.OutQuad);
|
||
|
|
|
||
|
|
// index++;
|
||
|
|
// // 每隔 0.3s 执行一个
|
||
|
|
// yield return new WaitForSeconds(0.2f);
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
private GameObject Popup;
|
||
|
|
void Update()
|
||
|
|
{
|
||
|
|
// 鼠标按下时检测
|
||
|
|
if (Input.GetMouseButtonDown(0))
|
||
|
|
{
|
||
|
|
if (Popup == null) Popup = GameObject.Find("Popup");
|
||
|
|
if (Popup != null && Popup.transform.childCount != 0) return;
|
||
|
|
Vector2 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
|
||
|
|
RaycastHit2D[] hits = Physics2D.RaycastAll(mousePos, Vector2.zero);
|
||
|
|
|
||
|
|
if (hits.Length > 0)
|
||
|
|
{
|
||
|
|
selected = GetTopSprite(hits);
|
||
|
|
if (selected != null)
|
||
|
|
{
|
||
|
|
if (selected.tag == "bg")
|
||
|
|
{
|
||
|
|
// bg 不做缩放和旋转,只记录偏移
|
||
|
|
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
|
||
|
|
offset = selected.transform.position - new Vector3(pos.x, selected.transform.position.y, selected.transform.position.z);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// ✅ 如果该物体已经在 _itemList 中,释放槽位
|
||
|
|
foreach (var item in _itemList)
|
||
|
|
{
|
||
|
|
if (item._inGameobject == selected)
|
||
|
|
{
|
||
|
|
item._isFull = false;
|
||
|
|
item._inGameobject = null;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
selected.GetComponent<SpriteRenderer>().sortingLayerName = "layer_4_drag";
|
||
|
|
|
||
|
|
// 点击时强制修正为 0 度旋转
|
||
|
|
selected.transform.DORotate(Vector3.zero, 0.2f).SetEase(Ease.OutQuad);
|
||
|
|
|
||
|
|
// DOTween 缩放到固定 1.1 倍
|
||
|
|
selected.transform.DOScale(Vector3.one * 1.1f, 0.2f).SetEase(Ease.OutBack);
|
||
|
|
|
||
|
|
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
|
||
|
|
offset = selected.transform.position - new Vector3(pos.x, pos.y, selected.transform.position.z);
|
||
|
|
selected.GetComponent<SpriteRenderer>().sortingOrder = out_layers;
|
||
|
|
out_layers++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 拖拽中
|
||
|
|
if (Input.GetMouseButton(0) && selected != null)
|
||
|
|
{
|
||
|
|
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
|
||
|
|
|
||
|
|
if (selected.tag == "bg")
|
||
|
|
{
|
||
|
|
// 只允许 X 方向拖拽,限制在 [-2.3, 2.3]
|
||
|
|
float newX = pos.x + offset.x;
|
||
|
|
newX = Mathf.Clamp(newX, -2.8f, 2.8f);
|
||
|
|
selected.transform.position = new Vector3(newX, selected.transform.position.y, selected.transform.position.z);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
selected.transform.position = new Vector3(pos.x, pos.y, selected.transform.position.z) + offset;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 鼠标松开
|
||
|
|
if (Input.GetMouseButtonUp(0) && selected != null)
|
||
|
|
{
|
||
|
|
if (selected.tag != "bg")
|
||
|
|
{
|
||
|
|
// DOTween 缩放还原到固定 1 倍
|
||
|
|
selected.transform.DOScale(Vector3.one, 0.2f).SetEase(Ease.InOutSine);
|
||
|
|
|
||
|
|
bool snapped = false;
|
||
|
|
|
||
|
|
// 吸附逻辑:检查标签和位置
|
||
|
|
string tag = selected.tag;
|
||
|
|
foreach (var item in _itemList)
|
||
|
|
{
|
||
|
|
if (item._isFull) continue;
|
||
|
|
if (item._tag == tag)
|
||
|
|
{
|
||
|
|
float dist = 0;
|
||
|
|
if (item.type == 1)
|
||
|
|
{
|
||
|
|
dist = Vector3.Distance(selected.transform.localPosition, item._position);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Vector3 localPosInTarget = item_parent_big.transform.InverseTransformPoint(selected.transform.position);
|
||
|
|
dist = Vector3.Distance(localPosInTarget, item._position);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (dist < 0.5f)
|
||
|
|
{
|
||
|
|
// selected.SetParent(item_parent_big);
|
||
|
|
if (item.type == 2) selected.transform.SetParent(item_parent_big.transform, true);
|
||
|
|
|
||
|
|
// 吸附过去并旋转归零
|
||
|
|
selected.transform.DOLocalMove(item._position, 0.2f).SetEase(Ease.OutQuad);
|
||
|
|
selected.transform.DORotate(Vector3.zero, 0.2f).SetEase(Ease.OutQuad);
|
||
|
|
selected.GetComponent<SpriteRenderer>().sortingLayerName = "layer_2_inslot";
|
||
|
|
selected.GetComponent<SpriteRenderer>().sortingOrder = item._orderInLayer;
|
||
|
|
item._isFull = true;
|
||
|
|
item._inGameobject = selected;
|
||
|
|
snapped = true;
|
||
|
|
selected.GetComponent<PolygonCollider2D>().enabled = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 如果吸附成功 → 检查整个列表
|
||
|
|
if (snapped)
|
||
|
|
{
|
||
|
|
bool allFull = true;
|
||
|
|
foreach (var item in _itemList)
|
||
|
|
{
|
||
|
|
if (!item._isFull)
|
||
|
|
{
|
||
|
|
allFull = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (allFull)
|
||
|
|
{
|
||
|
|
Debug.Log("所有物体都已吸附完成!");
|
||
|
|
GameDispatcher.Instance.Dispatch(GameMsg.GameSuccess);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// 如果没有吸附成功 → 随机旋转 ±8°
|
||
|
|
selected.GetComponent<SpriteRenderer>().sortingLayerName = "layer_3_out";
|
||
|
|
int randomChoice = Random.Range(0, 2); // 0 或 1
|
||
|
|
float randomAngle = (randomChoice == 0) ? -8f : 8f;
|
||
|
|
selected.transform.DORotate(new Vector3(0, 0, randomAngle), 0.3f).SetEase(Ease.OutQuad);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
selected = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private GameObject GetTopSprite(RaycastHit2D[] hits)
|
||
|
|
{
|
||
|
|
GameObject top = null;
|
||
|
|
int topLayer = int.MinValue;
|
||
|
|
int topOrder = int.MinValue;
|
||
|
|
|
||
|
|
foreach (var hit in hits)
|
||
|
|
{
|
||
|
|
SpriteRenderer sr = hit.collider.GetComponent<SpriteRenderer>();
|
||
|
|
if (sr != null)
|
||
|
|
{
|
||
|
|
int layerID = SortingLayer.GetLayerValueFromID(sr.sortingLayerID);
|
||
|
|
int order = sr.sortingOrder;
|
||
|
|
|
||
|
|
if (layerID > topLayer || (layerID == topLayer && order > topOrder))
|
||
|
|
{
|
||
|
|
top = sr.gameObject;
|
||
|
|
topLayer = layerID;
|
||
|
|
topOrder = order;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return top;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ItemState_2
|
||
|
|
{
|
||
|
|
[JsonIgnore]
|
||
|
|
public Vector2 _position;
|
||
|
|
public int _orderInLayer;
|
||
|
|
public string _tag;
|
||
|
|
public bool _isFull;
|
||
|
|
public GameObject _inGameobject;
|
||
|
|
public int type;
|
||
|
|
}
|