从今天开始写博客啦,把自己觉得有用的记录下来,供自己以后使用。
最近做项目遇到的一个需求,简单的实现了一下,大佬们有更好的方法恳请留言告诉我。
下图为UI的层级结构,Anchors下的四个物体为UI的四个角,注意物体的锚点要设置成对应的位置,而Communication的锚点要设置为stretch、stretch
具体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class LeftTop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform; //当前预制体的坐标信息
public RectTransform rootRectTransform; //UI窗口
public Transform content; //消息显示对话框
// Start is called before the first frame update
void Start()
{
rectTransform = this.GetComponent();
rootRectTransform = transform.parent.parent.GetComponent();
}
// Update is called once per frame
void Update()
{
}
#region 拖拽逻辑
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("开始拖拽左上角锚点");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 pos;
Vector2 mousePos = eventData.position;
if (eventData.position.x < 0)
mousePos.x = 0;
else if (eventData.position.x > Screen.width)
mousePos.x = Screen.width;
if (eventData.position.y < 0)
mousePos.y = 0;
else if (eventData.position.y > Screen.height)
mousePos.y = Screen.height;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, mousePos, eventData.enterEventCamera, out pos);
//Debug.Log(rootRectTransform.offsetMin + " " + rootRectTransform.offsetMax + " " + rootRectTransform.sizeDelta + " " + Screen.width + " " + Screen.height);
//防止缩的太小把UI缩没了
if (Mathf.Abs(pos.x - rootRectTransform.offsetMax.x) < Screen.width - 100 && Mathf.Abs(pos.y - Screen.height - rootRectTransform.offsetMin.y) < Screen.height - 100)
{
rectTransform.position = pos; //当前鼠标坐标赋给锚点
rootRectTransform.offsetMin = new Vector2(pos.x, rootRectTransform.offsetMin.y); //设置UI的rectTransform组件的left bottom参数
rootRectTransform.offsetMax = new Vector2(rootRectTransform.offsetMax.x, pos.y - Screen.height); //设置rectTransform的right top
int children = content.childCount;
for (int i = 0; i < children; i++)
{
content.GetChild(i).GetComponent().sizeDelta = new Vector2(Screen.width - Mathf.Abs(rootRectTransform.sizeDelta.x) - 40, 20);//消息显示对话框里的文本跟随窗口伸缩保持原有的相对位置不变
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("结束拖拽左上角锚点");
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class LeftBottom : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform; //当前预制体的坐标信息
public RectTransform rootRectTransform; //UI窗口
public Transform content; //消息显示对话框
// Start is called before the first frame update
void Start()
{
rectTransform = this.GetComponent();
rootRectTransform = transform.parent.parent.GetComponent();
}
// Update is called once per frame
void Update()
{
}
#region 拖拽逻辑
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("开始拖拽左下角锚点");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 pos;
Vector2 mousePos = eventData.position;
if (eventData.position.x < 0)
mousePos.x = 0;
else if (eventData.position.x > Screen.width)
mousePos.x = Screen.width;
if (eventData.position.y < 0)
mousePos.y = 0;
else if (eventData.position.y > Screen.height)
mousePos.y = Screen.height;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, mousePos, eventData.enterEventCamera, out pos);
//Debug.Log(rootRectTransform.offsetMin + " " + rootRectTransform.offsetMax + " " + rootRectTransform.sizeDelta + " " + Screen.width + " " + Screen.height);
if (Mathf.Abs(pos.x - rootRectTransform.offsetMax.x) < Screen.width - 100 && Mathf.Abs(pos.y - rootRectTransform.offsetMax.y) < Screen.height - 100)
{
rectTransform.position = pos; //当前鼠标坐标赋给锚点
rootRectTransform.offsetMin = new Vector2(pos.x, pos.y); //设置rectTransform的left bottom
rootRectTransform.offsetMax = new Vector2(rootRectTransform.offsetMax.x, rootRectTransform.offsetMax.y); //设置rectTransform的right top
int children = content.childCount;
for (int i = 0; i < children; i++)
{
content.GetChild(i).GetComponent().sizeDelta = new Vector2(Screen.width - Mathf.Abs(rootRectTransform.sizeDelta.x)-40, 20);//消息显示对话框里的文本跟随窗口伸缩保持原有的相对位置不变
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("结束拖拽左下角锚点");
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class RightTop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform; //当前预制体的坐标信息
public RectTransform rootRectTransform; //UI窗口
public Transform content; //消息显示对话框
// Start is called before the first frame update
void Start()
{
rectTransform = this.GetComponent();
rootRectTransform = transform.parent.parent.GetComponent();
}
// Update is called once per frame
void Update()
{
}
#region 拖拽逻辑
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("开始拖拽右上角锚点");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 pos;
Vector2 mousePos = eventData.position;
if (eventData.position.x < 0)
mousePos.x = 0;
else if (eventData.position.x > Screen.width)
mousePos.x = Screen.width;
if (eventData.position.y < 0)
mousePos.y = 0;
else if (eventData.position.y > Screen.height)
mousePos.y = Screen.height;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, mousePos, eventData.enterEventCamera, out pos);
//Debug.Log(rootRectTransform.offsetMin + " " + rootRectTransform.offsetMax + " " + rootRectTransform.sizeDelta + " " + Screen.width + " " + Screen.height);
if (Mathf.Abs(pos.x - Screen.width - rootRectTransform.offsetMin.x) < Screen.width - 100 && Mathf.Abs(pos.y - Screen.height - rootRectTransform.offsetMin.y) < Screen.height - 100)
{
rectTransform.position = pos; //当前鼠标坐标赋给锚点
rootRectTransform.offsetMin = new Vector2(rootRectTransform.offsetMin.x, rootRectTransform.offsetMin.y); //设置rectTransform的left bottom
rootRectTransform.offsetMax = new Vector2(pos.x - Screen.width, pos.y - Screen.height); //设置rectTransform的right top
int children = content.childCount;
for (int i = 0; i < children; i++)
{
content.GetChild(i).GetComponent().sizeDelta = new Vector2(Screen.width - Mathf.Abs(rootRectTransform.sizeDelta.x) - 40, 20); //消息显示对话框里的文本跟随窗口伸缩保持原有的相对位置不变
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("结束拖拽右上角锚点");
}
#endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class RightBottom : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform; //当前预制体的坐标信息
public RectTransform rootRectTransform; //UI窗口
public Transform content; //消息显示对话框
// Start is called before the first frame update
void Start()
{
rectTransform = this.GetComponent();
rootRectTransform = transform.parent.parent.GetComponent();
}
// Update is called once per frame
void Update()
{
}
#region 拖拽逻辑
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("开始拖拽右下角锚点");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 pos;
Vector2 mousePos = eventData.position;
if (eventData.position.x < 0)
mousePos.x = 0;
else if (eventData.position.x > Screen.width)
mousePos.x = Screen.width;
if (eventData.position.y < 0)
mousePos.y = 0;
else if (eventData.position.y > Screen.height)
mousePos.y = Screen.height;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, mousePos, eventData.enterEventCamera, out pos);
//Debug.Log(rootRectTransform.offsetMin + " " + rootRectTransform.offsetMax + " " + rootRectTransform.sizeDelta + " " + Screen.width + " " + Screen.height);
if (Mathf.Abs(pos.x - Screen.width - rootRectTransform.offsetMin.x) < Screen.width - 100 && Mathf.Abs(pos.y - rootRectTransform.offsetMax.y) < Screen.height - 100)
{
rectTransform.position = pos; //当前鼠标坐标赋给锚点
rootRectTransform.offsetMin = new Vector2(rootRectTransform.offsetMin.x, pos.y); //设置rectTransform的left bottom
rootRectTransform.offsetMax = new Vector2(pos.x - Screen.width, rootRectTransform.offsetMax.y); //设置rectTransform的right top
int children = content.childCount;
for (int i = 0; i < children; i++)
{
content.GetChild(i).GetComponent().sizeDelta = new Vector2(Screen.width - Mathf.Abs(rootRectTransform.sizeDelta.x) - 40, 20);//消息显示对话框里的文本跟随窗口伸缩保持原有的相对位置不变
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("结束拖拽右下角锚点");
}
#endregion
}
Communication下的子物体根据需要设置锚点,横向或者纵向需要跟随根节点变化的就将锚点设置为stretch。
需要注意的是,当子物体为Scroll View时,content下的物体无法设置锚点,我的content下是text组件,不管怎么拉伸UI文字始终维持到左上角的距离不变,所以我只好在每次拖拽时都设置text的位置,来控制text在UI中的相对位置,不要问为什么设置为那个值,我试出来的。
我的第一篇博客新鲜出炉啦,请各路大神不吝赐教!