在使用UGUI Image组件显示不规则图片、镂空图片时,Image总是会创建一个四边形网格来显示图形,渲染过程中,GPU需要对完全透明的区域进行计算,这不利于性能的优化,一个解决办法是采用多边形网格显示图形,来减少这种不必要的消耗。
下面是Image组件和多边形显示组件的网格对比
下面是Image和多边形的Overdraw对比
整个方案的实现过程包括以下几个步骤:
如果需要根据图形做射线检测,在 UIPolyImage/Image 组件上添加PolyRaycastFilter 组件。因为该组件需要读取贴图的像素,所以需要将贴图的 readAndWrite 属性勾选。
示例项目:这里
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEngine.UI
{
public class UIPolyImage : Image
{
protected override void OnPopulateMesh(VertexHelper vh)
{
if (overrideSprite == null)
{
base.OnPopulateMesh(vh);
return;
}
switch (type)
{
case Type.Simple:
case Type.Filled:
case Type.Sliced:
case Type.Tiled:
GenerateSimpleSprite(vh, preserveAspect);
break;
}
}
void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect)
{
Vector4 v = GetDrawingDimensions(lPreserveAspect);
var color32 = color;
float width = v.z - v.x;
float height = v.w - v.y;
//将sprite.pivot进行归一化
Vector2 spritePivot = new Vector2(sprite.pivot.x / sprite.rect.width, sprite.pivot.y / sprite.rect.height);
Vector2 pivotOffset = Vector2.Scale(spritePivot - rectTransform.pivot, new Vector2(width, height));
Vector3 scale = new Vector3(1, 1, 1);
scale.x = width / sprite.bounds.size.x;
scale.y = height / sprite.bounds.size.y;
Matrix4x4 trsMT = Matrix4x4.TRS(pivotOffset, Quaternion.identity, scale);
vh.Clear();
for (int i = 0; i < sprite.vertices.Length; i++)
{
vh.AddVert(trsMT.MultiplyPoint3x4(sprite.vertices[i]), color32, sprite.uv[i]);
}
for (int i = 0; i < sprite.triangles.Length; i += 3)
{
vh.AddTriangle(sprite.triangles[i], sprite.triangles[i + 1], sprite.triangles[i + 2]);
}
}
public Rect GetDrawingRect()
{
Vector4 v = GetDrawingDimensions(preserveAspect);
return Rect.MinMaxRect(v.x, v.y, v.z, v.w);
}
/// Image's dimensions used for drawing. X = left, Y = bottom, Z = right, W = top.
private Vector4 GetDrawingDimensions(bool shouldPreserveAspect)
{
var padding = overrideSprite == null ? Vector4.zero : UnityEngine.Sprites.DataUtility.GetPadding(overrideSprite);
var size = overrideSprite == null ? Vector2.zero : new Vector2(overrideSprite.rect.width, overrideSprite.rect.height);
Rect r = GetPixelAdjustedRect();
// Debug.Log(string.Format("r:{2}, size:{0}, padding:{1}", size, padding, r));
int spriteW = Mathf.RoundToInt(size.x);
int spriteH = Mathf.RoundToInt(size.y);
var v = new Vector4(
padding.x / spriteW,
padding.y / spriteH,
(spriteW - padding.z) / spriteW,
(spriteH - padding.w) / spriteH);
if (shouldPreserveAspect && size.sqrMagnitude > 0.0f)
{
var spriteRatio = size.x / size.y;
var rectRatio = r.width / r.height;
if (spriteRatio > rectRatio)
{
var oldHeight = r.height;
r.height = r.width * (1.0f / spriteRatio);
r.y += (oldHeight - r.height) * rectTransform.pivot.y;
}
else
{
var oldWidth = r.width;
r.width = r.height * spriteRatio;
r.x += (oldWidth - r.width) * rectTransform.pivot.x;
}
}
v = new Vector4(
r.x + r.width * v.x,
r.y + r.height * v.y,
r.x + r.width * v.z,
r.y + r.height * v.w
);
return v;
}
}
}
这里实现方式是通过获取像素的 Alpha 值来进行判断的,所以一个明显的缺点就是需要将贴图的 readable 设置为true。当然还有一些其他的方法也可以实现功能,比如设置多边形碰撞、多边形检测等等,后续如果有机会的话,会补充其他的方法。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace UnityEngine.UI
{
/// <summary>
/// 用于检测不规则图形的射线检测方法,由于需要进行多边形的射线检测,
/// 效率相对较低,所以,确认自己必须进行不规则射线检测时,才使用
/// 该组件。
/// </summary>
[RequireComponent(typeof(UIPolyImage))]
public class PolyRaycastFilter : MonoBehaviour, ICanvasRaycastFilter
{
private UIPolyImage image
{
get
{
if (m_Image == null)
m_Image = GetComponent<UIPolyImage>();
return m_Image;
}
}
private RectTransform rectTransform
{
get
{
if (m_RectTransform == null)
m_RectTransform = GetComponent<RectTransform>();
return m_RectTransform;
}
}
private UIPolyImage m_Image;
private RectTransform m_RectTransform;
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
if (image.sprite == null)
return false;
//首先转换到本地坐标系中,方便下面的计算
Vector2 localP = rectTransform.InverseTransformPoint(sp);
Rect pixelRect = image.GetDrawingRect();
if (!pixelRect.Contains(localP, false))
return false;
Vector2 delta = localP - pixelRect.min;
Vector2 normalizedDelta = new Vector2(delta.x / pixelRect.width, delta.y / pixelRect.height);
int x = Mathf.CeilToInt(normalizedDelta.x * image.sprite.rect.width+image.sprite.rect.xMin);
int y = Mathf.CeilToInt(normalizedDelta.y * image.sprite.rect.height+image.sprite.rect.yMin);
Color pixel = image.sprite.texture.GetPixel(x, y);
return !Mathf.Approximately(pixel.a, 0f);
}
}
}
http://blog.csdn.net/zyh821351004/article/details/52421005cartographer与karto的比较1. 两者采取的都是图优化框架。 采取的优化库不一致, karto采取的是spa(karto_slam)或g2o(nav2d), cartographer采取的是google的ceres构建problem优化。 kart
<?php $url = "http://www.kxblogs.com/n/20161108/74429879.html"; $ch = curl_init (); curl_setopt($ch, CURLOPT_URL, $url); curl_setop...
运用工具,可以大大提高我们的工作和生活效率,节省时间,下面是一些阔以白嫖的良心在线工具网站。1.docsmall实用压缩工具推荐给经常需要压缩图片、GIF、PDF文件的小伙伴。除了压缩功能,网站还支持PDF合并和分割。网站 简单美观,体验感很nice。2.创客贴平面设计作图神器用来做封面图非常方便,通过这个网站你可以制作好看的海报、简历、新媒体文章的首页图等等,甚至很多免费且好看的 PPT插件可以直接用,良心工具呀~3.奶牛快传好用的网盘工具体验还不错的网
c++构造函数种类构造函数分四类:无参数构造函数、带参数构造函数、拷贝构造函数、默认构造函数。其中,普通构造函数,分带参数与不带参数。拷贝构造函数,用一个对象去初始化另外一个对象。默认构造函数,当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空。class String{public: String(const char *str = NULL); // 普通构造函数 String(const String &other); // 拷贝构造函
一,表现形式为了明显点,我改成红色边框线,可以看到在鼠标滑动之后,这个边框线会消失。(注:这个手机号是我瞎写的,别乱打,打通了我会被打的!)二,解决办法使用table时,加上这个样式::cell-style="{background:'#fff'}"...
前言:.NET Core是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows、Mac OSX、Linux) 的应用程序开发框架(Application Framework),未来也将会支持FreeBSD与Alpine平台。.Net Core也是微软在一开始发展时就开源的软件平台,其开发目标是跨平台的 .NET 平台。.NET Core 平台的开发优势 :...
功能对比—下载地图:客户的需求就是软件的使命,我们第一时间完善客户的功能需求 功 能 点 BIGEMAP软件 演示教程 地图下载 地图下载 地图下载 地图下载 ...
目录HttpClientFormImpl层HttpClientFormimport com.alibaba.fastjson.JSONObject;import org.apache.http.Consts;import org.apache.http.HttpEntity;import org.apache.http.HttpStatus;import org.apache.http.client.ClientProtocolException;import org.apache.http.
1.顺序结构:从上到下,从左到右执行的顺序,就叫做顺序结构;2.分支结构:if语句,if-else语句,if-else if-else if…语句,switch-case语句,三元表达式语句;3.循环结构:while循环,do-while循环,for循环,后期还有一个for-in循环;
人活着就是在对抗熵增定律,生命以负熵为生。——薛定谔一、熵增定律### 1、熵增定律熵的概念最早起源于物理学,用于度量一个热力学系统的无序程度。热力学第二定律,又称“熵增定律”,表明了在自然过程中,一个孤立的系统总是从最初的集中、有序的排列状态,趋向于分散、混乱和无序;当熵达到最大时,系统就会处于一种静寂状态。通俗的讲:系统的熵增过程,就是由原始到死亡的过程。“熵”是“活跃”的反义词,代表负能量。非生命,比如物质总是向着熵增演化,屋子不收拾会变乱,手机会越来越卡,耳机线会凌乱,热水会慢慢变凉,太阳会不断燃
问题:CommandInvokationFailure: Gradle build failed. C:\ProgramFiles\Java\jdk1.8.0_131\bin\java.exe-classpath "D:\unity\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-4.0.1.ja...
就是它了 主要内容市面上以“深入理解AndroidXXX”为名的书“不计其数”,有的看着特别像相互抄袭... 然鹅,前两天在京东图书搞活动时(满100减50),我确实淘到了这本清新脱俗的讲Android系统架构的书:《最强Android书-架构大剖析》,其对于理解Android体系架构还是很有用的!此书讲解了Android个版本之间的差异及变迁,并以Linux的角度分析了Android分区和文件系...