事件接口
IDragHandler(常用):鼠标按下拖动时执行(只要鼠标在拖动就一直执行)
IDropHandler:对象拖动结束时,如果鼠标在物体的范围内,执行一次(依赖于IDragHandler存在)
(结束时鼠标必须在图片范围内)
IBeginDragHandler:开始拖动时执行一次
IEndDragHandler:拖动结束时执行一次(结束时对鼠标在哪没有要求)
IScrollHandler:监控鼠标滚轮
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; public class EventDrag : MonoBehaviour, IDragHandler, IDropHandler, IBeginDragHandler, IEndDragHandler, IPointerEnterHandler, IPointerUpHandler, IPointerClickHandler { public void OnDrag(PointerEventData eventData) { Debug.Log("IDragHandler.OnDrag"); //Debug.Log("eventData.delta:" + eventData.delta);//上次执行与本次执行的鼠标偏移量 Debug.Log("eventData.scrollDelta:" + eventData.scrollDelta);//上次执行与本次执行的鼠标偏移量 } public void OnDrop(PointerEventData eventData) { Debug.Log("IDropHandler.OnDrop"); } public void OnBeginDrag(PointerEventData eventData) { Debug.Log("IBeginDragHandler.OnBeginDrag"); } public void OnEndDrag(PointerEventData eventData) { Debug.Log("IEndDragHandler.OnEndDrag"); } public void OnPointerEnter(PointerEventData eventData) { //Debug.Log("eventData.delta.name" + eventData.pointerDrag.name);//报错:在鼠标进入的事件接口里,无法获得拖动的物体 } public void OnPointerUp(PointerEventData eventData) { Debug.Log("当前的结果:" + eventData.pointerCurrentRaycast.gameObject.name); Debug.Log("按下的结果:" + eventData.pointerPressRaycast.gameObject.name); } public void OnPointerClick(PointerEventData eventData) { Debug.Log("点击次数:" + eventData.clickCount); } // Use this for initialization void Start() { } // Update is called once per frame void Update() { } }
PointerEventData:
button:鼠标按下时判断左右键
clickCount:点击次数(时间间隔固定)
delta:拖动时鼠标的偏移量(一般用在拖动的事件接口中)
dragging:是否处于拖动状态
enterEventCamera:鼠标进入时的事件相机
pressEventCamera:鼠标按下时的事件相机
pointerDrag:拖动的物体(一般用在拖动接口里)
pointerEnter:进入的物体
pointerPress:
pointerCurrentRaycast:鼠标当前的射线检测结果
pointerPressRaycast:鼠标按下时的射线检测结果
scrollDelta:鼠标滚轮的
使用EvenData类的参数时,首先要考虑有无意义
例如,在鼠标进入的事件接口里,无法获得拖动的物体
public void OnPointerEnter(PointerEventData eventData) { //Debug.Log("eventData.delta.name" + eventData.pointerDrag.name);//报错:在鼠标进入的事件接口里,无法获得拖动的物体 }
射线检测结果:按下结果和当前结果是有差别的
public void OnPointerUp(PointerEventData eventData) { Debug.Log("当前的结果:" + eventData.pointerCurrentRaycast.gameObject.name); Debug.Log("按下的结果:" + eventData.pointerPressRaycast.gameObject.name); }
RaycastResult - gameObject:一般情况下,判断检测结果是谁的(常用)
连续点击的次数,在一定时间间隔内,会累积计数,超过时间间隔则归零重新计数
public void OnPointerClick(PointerEventData eventData) { Debug.Log("点击次数:" + eventData.clickCount); }
鼠标有球形滚轮,数值是二维的
虚拟摇杆案例
画布设置1280x720
轮盘功能
轮盘的代码逻辑
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; //1、鼠标在摇杆背景下按下的时候,需要把摇杆移动到鼠标按下的位置 //2、鼠标在拖动的时候,摇杆需要跟随鼠标移动 //3、鼠标松开的时候,摇杆回到中心位置 //4、摇杆的拖动范围是一个圆形区域 //1)、鼠标在圆形区域内,摇杆跟着鼠标移动 //2)、鼠标超出圆形区域,摇杆要在圆的边缘 //5、默认情况摇杆是隐藏的,当鼠标按下时显示,只有在屏幕左下方有效 //创建一张透明图片,在屏幕的左下方 //当在这个透明图片的区域内按下时,整个摇杆的轮盘到鼠标的位置,并且显示 //松开鼠标时,隐藏轮盘 public class Rocker : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler { private GameObject handler;//摇杆的句柄,也就是跟随鼠标移动的物体 private GameObject rocker;//摇杆的轮盘 private float r = 90f;//圆形区域的半径 private RectTransform handlerParent;//句柄的父物体的Rect Transform private RectTransform rockerParent;//轮盘的父物体的Rect Transform private Vector2 outPos;//转换之后的位置坐标 private void Awake() { handler = GameObject.Find("HandlerBig/HandlerSmall"); rocker = GameObject.Find("HandlerBig"); ; //找到父物体的Rect Transform handlerParent = handler.transform.parent as RectTransform; rockerParent = handler.transform.parent as RectTransform; } public void OnDrag(PointerEventData eventData) { //拖动时,遥感句柄跟随鼠标移动 MoveHandler(eventData); } public void OnPointerDown(PointerEventData eventData) { PlayerMove.movespeed = 0.1f; //按下时,轮盘显示,轮盘到鼠标的位置,同时轮盘在鼠标的位置 rocker.SetActive(true); //转换轮盘的坐标 if (RectTransformUtility.ScreenPointToLocalPointInRectangle( rockerParent, eventData.position, eventData.pressEventCamera, out outPos )) { rocker.transform.localPosition = outPos; } //按下时,遥感句柄移到鼠标位置 MoveHandler(eventData); } public void OnPointerUp(PointerEventData eventData) { //抬起时,轮盘隐藏 rocker.SetActive(false); //抬起时,遥感句柄回到中心位置 rocker.transform.localPosition = Vector3.zero; PlayerMove.movespeed = 0f; } /// <summary> /// 封装好的移动句柄的方法 /// </summary> /// <param name="eventData"></param> void MoveHandler(PointerEventData eventData) { if (RectTransformUtility.ScreenPointToLocalPointInRectangle( handlerParent, eventData.position, eventData.pressEventCamera, out outPos )) { //判断鼠标在圆内还是圆外,通过圆的中心点指向鼠标点的向量的模长来判断 //1、计算圆心指向鼠标向量的模长 //Vector2 temp = outPos - Vector.zero;//outPos就是从圆心指向鼠标的向量 if (outPos.magnitude >= r) { //计算圆心指向鼠标的方向 outPos.normalized //最终位置 - 原点位置 + 在圆心指向鼠标的方向上,移动半径个距离的向量 //Vector2 temp = outPos.normalized * r + Vector3.zero; Vector2 temp = outPos.normalized * r; handler.transform.localPosition = temp; } else { handler.transform.localPosition = outPos; } } } // Use this for initialization void Start() { rocker.SetActive(false);//默认隐藏 } // Update is called once per frame void Update() { } }
在C#中,<summary> 标记应当用于描述类型或类型成员。 生成<summary>注释的方法很简单,在方法之前输入 /// 就会自动生成。
移动的功能
移动的代码逻辑
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMove : MonoBehaviour { public static float movespeed = 0.1f; public GameObject handler;//遥感句柄 private Vector3 moveDir; // Use this for initialization void Start () { } // Update is called once per frame void Update () { //计算圆心指向摇杆的向量 //Vector3 temp = handler.transform.localPosition - Vector3.zero; //temp = handler.transform.localPosition moveDir.x = handler.transform.localPosition.x; moveDir.y = 0; moveDir.z = handler.transform.localPosition.y; transform.Translate(moveDir * Time.deltaTime * movespeed); } }
层级管理
代码操作层级
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LayerManager : MonoBehaviour { private GameObject red; private GameObject yellow; private GameObject blue; // Use this for initialization void Start () { red = GameObject.Find("Red"); yellow = GameObject.Find("Yellow"); blue = GameObject.Find("Blue"); //red.transform.SetSiblingIndex(2); int temp = red.transform.GetSiblingIndex(); red.transform.SetSiblingIndex(blue.transform.GetSiblingIndex()); blue.transform.SetSiblingIndex(temp); } // Update is called once per frame void Update () { } }
背包案例
Grid Layout Group(网格自动布局)
Padding:距离边界的距离
Cell Size:子物体元素的大小
Spacing:元素间的间隔、
Start Corner:第一个元素的位置,起点位置
Start Axis:排列的轴向
Child Alignment:对其方式
Constraint:约束,没有约束,
----Fixed Row Count:约束行数
----Fixed Column Count:约束列数
注意:9元素,3行4行一样,拿走1个会缺一块,整列拿走重排又会多出第5行
背包布局
背包拖动
拖动的代码逻辑
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; using UnityEngine.EventSystems; //1、控制物品的拖动 //2、显示物品 public class GridUI : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler { public Transform tempParent;//临时的父节点 public string imageName;//物体图片的名字,如果名字不为“”时有物品,为“”时没有物品 private Image image;//显示物品的组件,拖动的也是他 private RectTransform imageParent; private Vector2 outPos; private Vector2 offSet;//鼠标开始拖动时,距离图片中心点的偏移量 private void Awake() { image = transform.Find("Image").GetComponent<Image>(); image.raycastTarget = false;//关闭image的射线检测,避免挡住Grid imageParent = tempParent as RectTransform; } public void OnDrag(PointerEventData eventData) { if (imageName == "") { return; } if (RectTransformUtility.ScreenPointToLocalPointInRectangle( imageParent, eventData.position, eventData.enterEventCamera, out outPos )) { image.transform.localPosition = outPos - offSet; } } public void OnBeginDrag(PointerEventData eventData) { if (imageName == "") { return; } //开始时,把图片放在临时的父节点上,保证拖动的图片永远显示在最前面 image.transform.parent = tempParent; if (RectTransformUtility.ScreenPointToLocalPointInRectangle( imageParent, eventData.position, eventData.enterEventCamera, out outPos )) { //计算鼠标距离图片中心点的偏移量 offSet = outPos - new Vector2(image.transform.localPosition.x, image.transform.localPosition.y); } } public void OnEndDrag(PointerEventData eventData) { if (imageName == "") { return; } //结束时,需要把图片的父节点还原,位置也需要归零 image.transform.parent = transform; //image.transform.SetParent(transform); image.transform.localPosition = Vector3.zero; //拖动结束时,判断当前的鼠标位置是否在格子上 if (eventData.pointerCurrentRaycast.gameObject != null && eventData.pointerCurrentRaycast.gameObject.CompareTag("Grid")) { Debug.Log("格子:" + eventData.pointerCurrentRaycast.gameObject.name); //把自己的图片给对方,把对方的拿过来 GridUI target = eventData.pointerCurrentRaycast.gameObject.GetComponent<GridUI>(); //把自己的图片名字设置给目标,temp就是对方的图片名字 string temp = target.SetSpriteName(this.imageName); //然后把对方的图片名字设置给自己 this.SetSpriteName(temp); } else { Debug.Log("不是格子"); } } void UpdateItem() { if (imageName == "") { image.enabled = false; } else { image.enabled = true; if (image.sprite.name != imageName) { Sprite sp = Resources.Load<Sprite>("Backpack/ICon/" + imageName); image.sprite = sp; } } } //设置自己图片的名字,返回值是之前的名字 public string SetSpriteName(string str) { string before = imageName; imageName = str; UpdateItem(); return before; } // Use this for initialization void Start() { UpdateItem(); } // Update is called once per frame void Update() { } }
拖动的临时父节点,保证图片在最上方显示
添加Grid标签
给图片添加名字