在image上找到一个点,并显示在canvas上
- 一、功能
- 介绍
- 效果图
- 二、满足功能的必要条件
- 三、排除可能存在的问题
- 四、功能实现以及原理
- 1、初始版本
- 2、简化版本
- 五、实现
- 先来张场景图
- 测试功能的脚本
- 总结与下节
一、功能
介绍
起初此功能的作用是为了满足这样一个需求:
- 前端页面点击图片上的某个位置,将数值传递过来,在unity内相应图片位置上生成一个物体
效果图
二、满足功能的必要条件
- 前端使用的图片与unity内图片必须一致(尤其是长宽)
三、排除可能存在的问题
- 图片在unity内可以随意拉伸
- 图片在屏幕可视范围内与可视范围外不影响此功能的使用
四、功能实现以及原理
1、初始版本
/// <summary>
/// 传入一个image 和 图片上Image的XY点,返回一个在canvas上图片点位置的坐标
/// </summary>
/// <param name="image">基础的image 图片</param>
/// <param name="inputX">要生成位置的X轴坐标</param>
/// <param name="InputY">要生成位置的X轴坐标</param>
/// <returns></returns>
public static Vector2 GetPointPos(this Image image,float inputX,float InputY)
{
Vector3[] v3 =new Vector3[4];//定义一个数组,接收image在屏幕中四个点的位置,顺序是左下、左上、右下、右上
image.gameObject.GetComponent<RectTransform>().GetWorldCorners(v3);//这一步就是得到了四个角的位置
float RealityW = image.sprite.texture.width;//得到精灵图片的真实宽度
float RealityH = image.sprite.texture.height;//得到精灵图片的真实宽度
float w = Mathf.Abs(v3[0].x - v3[3].x);//用image在屏幕内的左下角减去右下角的绝对值就是image 在图片在屏幕中的宽度
float h = Mathf.Abs(v3[0].y - v3[1].y);//与宽度同理
float RatioW = RealityW / w;//真实宽度大小除屏幕内的图片大小得到宽度的比例
float RatioH = RealityH / h;//高度同理(考虑到图片在unity内拉伸不一定是等比例的拉伸,这一步少不了)
float IamgeW = inputX / RatioW;//要生成位置的X轴坐标(传入的参数)除 比例 得到要生成的点在unity image上的相应位置
float IamgeY = InputY / RatioH;//Y轴同理
float ScreneX = IamgeW + v3[0].x;//相应位置的X加上image左下角在屏幕中的X轴位置得到传入值应该在屏幕中的位置
float ScreneY = IamgeY + v3[0].y;//Y轴同理
return new Vector2(IamgeW + v3[0].x, IamgeY + v3[0].y);//返回的就是你传入的XY轴在屏幕中图片的相应位置
}
2、简化版本
为什么有简化版本,如果我一开始扔上来,我自己看时都会一脸懵逼,所以先有过程,才有简化的
/// <summary>
/// 传入一个image 和 图片上Image的XY点,返回一个在canvas上图片点位置的坐标
/// </summary>
/// <param name="image"></param>
/// <param name="inputX"></param>
/// <param name="InputY"></param>
/// <returns></returns>
public static Vector2 GetPointPos(this Image image,float inputX,float InputY)
{
Vector3[] v3 =new Vector3[4];
image.gameObject.GetComponent<RectTransform>().GetWorldCorners(v3);
float ScreneX = (inputX / (image.sprite.texture.width / Mathf.Abs(v3[0].x - v3[3].x))) + v3[0].x;
float ScreneY = (InputY / (image.sprite.texture.height / Mathf.Abs(v3[0].y - v3[1].y))) + v3[0].y;
return new Vector2(ScreneX, ScreneY);
}
五、实现
先来张场景图
测试功能的脚本
因为是测试,所以直接将方法拖拽到按钮上的,UI拖在脚本上的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using QFrameWork;
public class Text2Dtest : MonoBehaviour
{
public Image image;//图片
public InputField XInput;//X轴输入框
public InputField YInput;//Y轴输入框
public Button ConfirmBut;//确定按钮
public Canvas canvas;//Canvas物体
private void Start()
{
}
public void OnConfirmClick()//按钮点击事件,
{
float X = float.Parse(XInput.text);//获取输入框内的X轴坐标
float Y = float.Parse(YInput.text);//获取输入框内的Y轴坐标
//调用刚才写的方法(注意我上面原理内的方法使用的是this关键字,因为是工具类,所以这里我可以直接通过Image点出来GetPoint这个方法)
Vector2 v2 = image.GetPointPos(X, Y);
//下面就是生成物体并赋值的了,不用说了吧,要注意的是,生成的是UI,要放在Canvas的下面
GameObject Area = Instantiate(Resources.Load<GameObject>("image/Area"));
Area.transform.SetParent(canvas.transform);
Area.transform.position = new Vector3(v2.x, v2.y);
}
}
总结与下节
因为此功能我是放在自己的库中的,所以一开始设计就是按照扩展类的方式去设计的
还有一个功能是在世界坐标下Sprite的相同点位置的查找,功能已经出来了,和这个原理基本相同,为什么要两个功能都做呢!因为需求改了………………下次再说!
更新后我会将连接直接放在这篇文章的下面,敬请期待。