1. 点击屏幕选中物体
// 核心是坐标转化:屏幕坐标 -> 世界坐标 -> 射线碰撞
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);
RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);
2. 多个血条显示
// 核心是坐标转换:世界坐标转为屏幕坐标
// GameObject所在的世界坐标转为屏幕坐标
Vector3 position = Camera.main.WorldToScreenPoint(transform.position);
// 设置血条的位置,并调整偏移量
bloodGameObject.gameObject.transform.position = new Vector3(position.x-35, position.y + 110, position.z);
// 设置血条长度
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, originalSize \* percent);
3. 移动
// 刚体移动使用rig.MovePosition,防止物体抖动
// 使用MoveTowards计算移动的新位置, 防止速度过快时总是偏离目标位置
if( Vector3.Distance(rig.position, targetPosition) > Mathf.Epsilon)
{
float distance = attackMoveSpeed \* Time.deltaTime;
Vector3 newPosition = Vector3.MoveTowards(rig.position, targetPosition, distance);
rig.MovePosition(newPosition);
}
4. 拖拽物品
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ItemDrag : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
// 鼠标起点
private Vector2 originalLocalPointerPosition;
// 面板起点
private Vector3 originalLocalPanelPosition;
// 当前物体
private RectTransform panelRectTransform;
// 父节点
private RectTransform parentRectTransform;
// 格子列表, 在gridList上一层添加一个新的空对象作为父节点
private GameObject gridManager;
// 记录物品拖拽前的位置
private GameObject originalGrid;
private static int siblingIndex = 0;
void Awake()
{
panelRectTransform = transform as RectTransform;
parentRectTransform = GameObject.FindGameObjectWithTag("ScrollRect").GetComponent<RectTransform>() as RectTransform;
gridManager = GameObject.Find("GridManager");
}
// 按下鼠标
public void OnPointerDown(PointerEventData eventData)
{
// 记录物品当前所在格子信息
originalGrid = panelRectTransform.parent.gameObject;
// 将物品设置在gridManager下,并设置层级,保证物品显示在整个背包之上
panelRectTransform.SetParent(parentRectTransform.transform);
siblingIndex = 10;
panelRectTransform.SetSiblingIndex(siblingIndex);
// 记录当前物品的起点位置
originalLocalPanelPosition = panelRectTransform.localPosition;
// 通过屏幕中的鼠标点,获取在父节点中的鼠标点
// parentRectTransform 父节点
// data.position当前鼠标位置
// data.pressEventCamera当前事件的摄像机
// originalLocalPointerPosition获取当前鼠标起点
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRectTransform, eventData.position, eventData.pressEventCamera,
out originalLocalPointerPosition);
Debug.Log(originalLocalPointerPosition.x + " : " + originalLocalPointerPosition.y);
}
// 拖动
public void OnDrag(PointerEventData eventData)
{
if(panelRectTransform == null parentRectTransform == null)
{
return;
}
Vector2 localPointerPosition;
// 获取鼠标本地位置
if( RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRectTransform, eventData.position, eventData.pressEventCamera,
out localPointerPosition))
{
// 移动位置 = 本地鼠标位置 - 鼠标起点位置
Vector3 offsetToOriginal = localPointerPosition - originalLocalPointerPosition;
// 当前物品位置 = 当前物品起点位置 + 移动位置
panelRectTransform.transform.localPosition = originalLocalPanelPosition + offsetToOriginal;
}
}
public void OnPointerUp(PointerEventData eventData)
{
RaycastHit2D hit = Physics2D.Raycast(Input.mousePosition, -Vector2.up);
if( hit.collider != null)
{
GameObject g = hit.transform.gameObject;
Debug.Log(" hit " + g.tag + " ");
Debug.Log(g.transform.Find("Item(Clone)"));
if ( hit.collider.gameObject.tag == "Grid" && hit.collider.gameObject.transform.Find("Item(Clone)")==null)
{
transform.SetParent(hit.transform);
}
else
{
transform.SetParent(originalGrid.transform);
}
}
else
{
Debug.Log("not hit");
transform.SetParent(originalGrid.transform);
}
// 重置物品位置
transform.localPosition = Vector3.zero;
}
}