HUD区域限制算是比较常用到的功能,方形的HUD区域限制多见于小地图,弧形或者椭圆多见于屏幕范围约束。

我没有研究倒角矩形做法,而是将椭圆和矩形进行插值得到一个弧度比较高的形状:

当插值为0时限制范围是椭圆,插值为1限制范围是矩形

矩形的判断使用了线段相交函数,函数来自网络收集

线段相交: http://www.cnblogs.com/hont/p/6106043.html

代码如下

using UnityEngine;
using System;
using System.Collections; public class HUDTest2 : MonoBehaviour
{
[Serializable]
public class EllipseSetting
{
public float radius = 2f;
public Vector2 scale = new Vector2(, );
} public Transform[] hudObjectArray;
public EllipseSetting ellipseSetting = new EllipseSetting();
[Range(, )]
public float lerp; void OnGUI()
{
for (int i = ; i < hudObjectArray.Length; i++)
{
var item = hudObjectArray[i]; var screenPosition = Camera.main.WorldToScreenPoint(item.transform.position);
screenPosition.z = ;
screenPosition.y = Screen.height - screenPosition.y;
screenPosition = HUDFix(screenPosition); GUI.Box(new Rect(screenPosition, Vector3.one * ), "");
}
} Vector3 HUDFix(Vector3 position)
{
var center = new Vector3(Screen.width, Screen.height, ) * 0.5f; var ellipsePoint = GetEllipsePoint(position);
var quadPoint = GetRectPoint(position); var finalPoint = Vector3.Lerp(ellipsePoint, quadPoint, lerp); if (Vector3.Distance(center, finalPoint) >= Vector3.Distance(center, position))
return position;
else
return finalPoint;
} Vector3 GetEllipsePoint(Vector3 currentPoint)
{
var center = new Vector3(Screen.width, Screen.height, ) * 0.5f;
var current = center + (currentPoint - center).normalized * ellipseSetting.radius; current.x *= ellipseSetting.scale.x;
current.y *= ellipseSetting.scale.y; return current;
} Vector3 GetRectPoint(Vector3 currentPoint)
{
var center = new Vector3(Screen.width, Screen.height, ) * 0.5f; const float INNER = ;
const float RAY = * ;
var p0 = new Vector3(INNER, INNER, );
var p1 = new Vector3(Screen.width - INNER, INNER, );
var p2 = new Vector3(INNER, Screen.height - INNER, );
var p3 = new Vector3(Screen.width - INNER, Screen.height - INNER, ); var dir = (currentPoint - center).normalized * RAY; var contractPoint = default(Vector3);
var r = GetIntersection(p0, p1, center, center + dir, out contractPoint);
if (r == )
return contractPoint; r = GetIntersection(p1, p3, center, center + dir, out contractPoint);
if (r == )
return contractPoint; r = GetIntersection(p0, p2, center, center + dir, out contractPoint);
if (r == )
return contractPoint; GetIntersection(p2, p3, center, center + dir, out contractPoint);
return contractPoint;
} int GetIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d, out Vector3 contractPoint)
{
contractPoint = new Vector3(, ); if (Mathf.Abs(b.y - a.y) + Mathf.Abs(b.x - a.x) + Mathf.Abs(d.y - c.y)
+ Mathf.Abs(d.x - c.x) == )
{
if ((c.x - a.x) + (c.y - a.y) == )
{
//Debug.Log("ABCD是同一个点!");
}
else
{
//Debug.Log("AB是一个点,CD是一个点,且AC不同!");
}
return ;
} if (Mathf.Abs(b.y - a.y) + Mathf.Abs(b.x - a.x) == )
{
if ((a.x - d.x) * (c.y - d.y) - (a.y - d.y) * (c.x - d.x) == )
{
//Debug.Log("A、B是一个点,且在CD线段上!");
}
else
{
//Debug.Log("A、B是一个点,且不在CD线段上!");
}
return ;
}
if (Mathf.Abs(d.y - c.y) + Mathf.Abs(d.x - c.x) == )
{
if ((d.x - b.x) * (a.y - b.y) - (d.y - b.y) * (a.x - b.x) == )
{
//Debug.Log("C、D是一个点,且在AB线段上!");
}
else
{
//Debug.Log("C、D是一个点,且不在AB线段上!");
}
return ;
} if ((b.y - a.y) * (c.x - d.x) - (b.x - a.x) * (c.y - d.y) == )
{
//Debug.Log("线段平行,无交点!");
return ;
} contractPoint.x = ((b.x - a.x) * (c.x - d.x) * (c.y - a.y) -
c.x * (b.x - a.x) * (c.y - d.y) + a.x * (b.y - a.y) * (c.x - d.x)) /
((b.y - a.y) * (c.x - d.x) - (b.x - a.x) * (c.y - d.y));
contractPoint.y = ((b.y - a.y) * (c.y - d.y) * (c.x - a.x) - c.y
* (b.y - a.y) * (c.x - d.x) + a.y * (b.x - a.x) * (c.y - d.y))
/ ((b.x - a.x) * (c.y - d.y) - (b.y - a.y) * (c.x - d.x)); if ((contractPoint.x - a.x) * (contractPoint.x - b.x) <=
&& (contractPoint.x - c.x) * (contractPoint.x - d.x) <=
&& (contractPoint.y - a.y) * (contractPoint.y - b.y) <=
&& (contractPoint.y - c.y) * (contractPoint.y - d.y) <= )
{ //Debug.Log("线段相交于点(" + contractPoint.x + "," + contractPoint.z + ")!");
return ; // '相交
}
else
{
//Debug.Log("线段相交于虚交点(" + contractPoint.x + "," + contractPoint.z + ")!");
return -; // '相交但不在线段上
}
}
}

两种屏幕HUD区域限制的做法(矩形,弧形)的更多相关文章

  1. 设置一个DIV块固定在屏幕中央(两种方法)

    设置一个DIV块固定在屏幕中央(两种方法) 方法一: 对一个div进行以下设置即可实现居中. <style> #a{ position: fixed; top: 0px; left: 0p ...

  2. jqGrid中实现radiobutton的两种做法

    http://blog.sina.com.cn/s/blog_4f925fc30102e27j.html   jqGrid中实现radiobutton的两种做法 ------------------- ...

  3. SqlServer保留几位小数的两种做法

    SqlServer保留几位小数的两种做法   数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 解决: 1. 使用 Round( ...

  4. HTML5工具做屏幕自适应的两种方法

    近一两年,HTML5在中国很火,也出了不少HTML5工具和模板.别的先不说,对于不同的H5工具,解决屏幕自适应问题的区别是什么? 简单来说,感应式设计是当用不同设备访问时,能够根据设备的宽度和高度对设 ...

  5. LVS+keepalived 的DR模式的两种做法

    LVS DR模式搭建 准备工作 三台机器: dr:192.168.13.15 rs1:192.168.13.16 rs2: 192.168.13.17 vip:192.168.13.100 修改DR上 ...

  6. Android 高级UI设计笔记23:Android 夜间模式之 两种常用方法(降低屏幕亮度+替换theme)

    1. 夜间模式 所谓的夜间模式,就是能够根据不同的设定,呈现不同风格的界面给用户,而且晚上看着不伤眼睛.特别是一些新闻类App实现夜间模式是非常人性化的,增强用户体验. 2. 我根据网上的资料 以及自 ...

  7. [正经分析] DAG上dp两种做法的区别——拓扑序与SPFA

    在下最近刷了几道DAG图上dp的题目. 要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点. 第二道是洛谷上的NOI导刊题目<最长路 ...

  8. CSS实现自适应不同大小屏幕的背景大图的两种方法(转自简书)

    CSS实现自适应不同大小屏幕的背景大图的两种方法 一张清晰漂亮的背景图片能给网页加分不少,设计师也经常会给页面的背景使用大图,我们既不想图片因为不同分辨率图片变形,也不希望当在大屏的情况下,背景有一块 ...

  9. Android 截取手机屏幕两种实现方案解析

    近期在开发的过程中,遇到了一个须要截取屏幕保存为图片的需求,详细为截取webview的视图保存图片. 方法1:首先想到的思路是利用SDK提供的View.getDrawingCache()方法: pub ...

随机推荐

  1. android 安装调试第三方应用失败

    Android Studio 3.0会在debug apk的manifest文件application标签里自动添加 android:testOnly="true"属性,导致IDE ...

  2. 【PMP】十五至尊图

    以上是PMP的10大知识领域与5个过程组,在PMP考试中属于必须记忆的知识,该知识来源于PMBOK 第6版 附件为每日练习记忆模板,可以更好的记忆上图 点击下载附件

  3. RHEL7 配置临时IP 测试

    RHEL7 配置或添加临时IP地址测试: [root@rhel7 Desktop]# ip a s enp0s3 ---查看原网卡IP 为192.168.1.7 : enp0s3: <BROAD ...

  4. 给X240换上了三键触摸板

    X240自带的触摸板非常不好用, 对于我这样的指点杆重度用户, 每次要按下整块板真的是太费力了, 而且在夜里声音很吵. 在淘宝上买了三键的X250的触摸板换上了. 这是购买的触摸板的型号 换的时候, ...

  5. Highcharts X轴纵向显示

    xAxis: { categories: ['苹果', '橘子', '梨', '葡萄', '香蕉'], labels:{ rotation: 90, style:{ fontSize: '13px', ...

  6. simhash进行文本查重 Simhash算法原理和网页查重应用

    simhash进行文本查重http://blog.csdn.net/lgnlgn/article/details/6008498 Simhash算法原理和网页查重应用http://blog.jobbo ...

  7. nRF2401A/nRF24L01/nRF24L01+无线模块最常见问题汇集(转)

    俗话说:每个人一生下来什么都会的,都是通过自己努力和探索出来的,NRF系列芯片,刚开始都好奇心加兴趣才来捣鼓它的,刚开始做硬件和软件,没有收发数据弄得整个人头都快炸开了,所以在此和大家分享一下前辈的经 ...

  8. 如何在windows下安装JDK

    1:卸载 A:一定要删除注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft 项 B:最好用安装工具卸载JDK,如果没有的话就删除JDK文件夹然后用Wise Regis ...

  9. 【MyBatis】MyBatis之如何存储NULL

    如果在sql语句中,不指定jdbcType,那么在存储中遇见null就会发生错误.一般情况下应该在每一个SQL语句的参数中指定jdbcType.比如: #{loginIp,jdbcType=VARCH ...

  10. C# Deldegate的使用

    Delegate类简介 ------------------------ 命名空间:System 程序集:mscorlib(在 mscorlib.dll 中) 委托(Delegate)类是一种数据结构 ...