Unity 中忽略图片透明度的 Image 组件的修改版本

news2024/11/15 15:38:13

只需将此组件添加到画布中的空对象即可。请注意,仅支持简单 图像类型。

在这里插入图片描述
在这里插入图片描述

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Sprites;
using UnityEngine.UI;
#if UNITY_2017_4 || UNITY_2018_2_OR_NEWER
using UnityEngine.U2D;
#endif

#if UNITY_EDITOR
using UnityEditor;

// Custom Editor to order the variables in the Inspector similar to Image component
[CustomEditor( typeof( PaddingIgnoringImage ) )]
[CanEditMultipleObjects]
public class PaddingIgnoringImageEditor : Editor
{
	private SerializedProperty colorProp, spriteProp, preserveAspectProp, useSpriteMeshProp;
	private GUIContent spriteLabel;

	private void OnEnable()
	{
		colorProp = serializedObject.FindProperty( "m_Color" );
		spriteProp = serializedObject.FindProperty( "m_Sprite" );
		useSpriteMeshProp = serializedObject.FindProperty( "m_UseSpriteMesh" );
		preserveAspectProp = serializedObject.FindProperty( "m_PreserveAspect" );

		spriteLabel = new GUIContent( "Source Image" );
	}

	public override void OnInspectorGUI()
	{
		serializedObject.Update();

		EditorGUILayout.PropertyField( colorProp );
		EditorGUILayout.PropertyField( spriteProp, spriteLabel );

		bool spriteAssigned = spriteProp.objectReferenceValue || spriteProp.hasMultipleDifferentValues;
		if( spriteAssigned )
		{
			EditorGUI.indentLevel++;
			EditorGUILayout.PropertyField( useSpriteMeshProp );
			EditorGUILayout.PropertyField( preserveAspectProp );
			EditorGUI.indentLevel--;
		}

		DrawPropertiesExcluding( serializedObject, "m_Script", "m_Color", "m_Sprite", "m_PreserveAspect", "m_UseSpriteMesh", "m_OnCullStateChanged" );

		serializedObject.ApplyModifiedProperties();

		if( spriteAssigned && GUILayout.Button( "Set Native Size", EditorStyles.miniButton ) )
		{
			foreach( Object target in targets )
			{
				PaddingIgnoringImage _target = target as PaddingIgnoringImage;
				if( _target )
				{
					Undo.RecordObject( _target.rectTransform, "Set Native Size" );
					_target.SetNativeSize();
					EditorUtility.SetDirty( _target );
				}
			}
		}
	}
}
#endif

// Most of this code is a copy&paste of Unity's UnityEngine.UI.Image.cs
[RequireComponent( typeof( CanvasRenderer ) )]
public class PaddingIgnoringImage : MaskableGraphic, ILayoutElement
{
	[SerializeField]
	private Sprite m_Sprite;
	public Sprite sprite
	{
		get { return m_Sprite; }
		set
		{
			if( m_Sprite )
			{
				if( m_Sprite != value )
				{
					m_Sprite = value;

					SetAllDirty();
					TrackImage();
				}
			}
			else if( value )
			{
				m_Sprite = value;

				SetAllDirty();
				TrackImage();
			}
		}
	}

	[SerializeField]
	private bool m_PreserveAspect;
	public bool preserveAspect
	{
		get { return m_PreserveAspect; }
		set { if( m_PreserveAspect != value ) { m_PreserveAspect = value; SetVerticesDirty(); } }
	}

	[SerializeField]
	private bool m_UseSpriteMesh;
	public bool useSpriteMesh
	{
		get { return m_UseSpriteMesh; }
		set { if( m_UseSpriteMesh != value ) { m_UseSpriteMesh = value; SetVerticesDirty(); } }
	}

	public override Texture mainTexture { get { return sprite ? sprite.texture : s_WhiteTexture; } }

	public float pixelsPerUnit
	{
		get
		{
			float spritePixelsPerUnit = 100;
			if( sprite )
				spritePixelsPerUnit = sprite.pixelsPerUnit;

			float referencePixelsPerUnit = 100;
			if( canvas )
				referencePixelsPerUnit = canvas.referencePixelsPerUnit;

			return spritePixelsPerUnit / referencePixelsPerUnit;
		}
	}

	public override Material material
	{
		get
		{
			if( m_Material != null )
				return m_Material;

			if( sprite && sprite.associatedAlphaSplitTexture != null )
			{
#if UNITY_EDITOR
				if( Application.isPlaying )
#endif
					return Image.defaultETC1GraphicMaterial;
			}

			return defaultMaterial;
		}
		set { base.material = value; }
	}

	protected override void OnEnable()
	{
		base.OnEnable();
		TrackImage();
	}

	protected override void OnDisable()
	{
		base.OnDisable();

		if( m_Tracked )
			UnTrackImage();
	}

	private Vector4 GetDrawingDimensions()
	{
		Vector4 padding = sprite ? DataUtility.GetPadding( sprite ) : Vector4.zero;
		Vector2 size = sprite ? sprite.rect.size : Vector2.zero;
		size -= new Vector2( padding.x + padding.z, padding.y + padding.w );

		Rect r = GetPixelAdjustedRect();

		if( preserveAspect && size.sqrMagnitude > 0f )
		{
			float spriteRatio = size.x / size.y;
			float rectRatio = r.width / r.height;

			if( spriteRatio > rectRatio )
			{
				float oldHeight = r.height;
				r.height = r.width * ( 1f / spriteRatio );
				r.y += ( oldHeight - r.height ) * rectTransform.pivot.y;
			}
			else
			{
				float oldWidth = r.width;
				r.width = r.height * spriteRatio;
				r.x += ( oldWidth - r.width ) * rectTransform.pivot.x;
			}
		}

		return new Vector4( r.x, r.y, r.x + r.width, r.y + r.height );
	}

	protected override void OnPopulateMesh( VertexHelper vh )
	{
		vh.Clear();

		Vector4 v = GetDrawingDimensions();
		Vector4 uv = sprite ? DataUtility.GetOuterUV( sprite ) : Vector4.zero;
		Color32 color32 = color;

		if( !sprite || !useSpriteMesh )
		{
			vh.AddVert( new Vector3( v.x, v.y ), color32, new Vector2( uv.x, uv.y ) );
			vh.AddVert( new Vector3( v.x, v.w ), color32, new Vector2( uv.x, uv.w ) );
			vh.AddVert( new Vector3( v.z, v.w ), color32, new Vector2( uv.z, uv.w ) );
			vh.AddVert( new Vector3( v.z, v.y ), color32, new Vector2( uv.z, uv.y ) );

			vh.AddTriangle( 0, 1, 2 );
			vh.AddTriangle( 2, 3, 0 );
		}
		else
		{
			Vector4 spritePadding = DataUtility.GetPadding( sprite );
			Vector2 spriteRectSize = sprite.rect.size;
			Vector2 spriteNonPaddingSize = spriteRectSize - new Vector2( spritePadding.x + spritePadding.z, spritePadding.y + spritePadding.w );
			Vector2 spritePivot = sprite.pivot;
			Vector2 spriteNormalizedPivot = new Vector2( ( spritePivot.x - spritePadding.x ) / spriteNonPaddingSize.x, ( spritePivot.y - spritePadding.y ) / spriteNonPaddingSize.y );
			Vector2 spriteBoundSize = Vector2.Scale( sprite.bounds.size, new Vector2( spriteNonPaddingSize.x / spriteRectSize.x, spriteNonPaddingSize.y / spriteRectSize.y ) );

			Vector2 drawingSize = new Vector2( v.z - v.x, v.w - v.y );
			Vector2 drawOffset = Vector2.Scale( rectTransform.pivot - spriteNormalizedPivot, drawingSize );

			Vector2[] vertices = sprite.vertices;
			Vector2[] uvs = sprite.uv;
			ushort[] triangles = sprite.triangles;

			for( int i = 0; i < vertices.Length; ++i )
				vh.AddVert( new Vector3( ( vertices[i].x / spriteBoundSize.x ) * drawingSize.x - drawOffset.x, ( vertices[i].y / spriteBoundSize.y ) * drawingSize.y - drawOffset.y ), color32, new Vector2( uvs[i].x, uvs[i].y ) );
			for( int i = 0; i < triangles.Length; i += 3 )
				vh.AddTriangle( triangles[i + 0], triangles[i + 1], triangles[i + 2] );
		}
	}

	public override void SetNativeSize()
	{
		if( sprite != null )
		{
			Vector4 padding = DataUtility.GetPadding( sprite );
			Vector2 size = sprite.rect.size;
			size -= new Vector2( padding.x + padding.z, padding.y + padding.w );

			float w = size.x / pixelsPerUnit;
			float h = size.y / pixelsPerUnit;

			rectTransform.anchorMax = rectTransform.anchorMin;
			rectTransform.sizeDelta = new Vector2( w, h );

			SetAllDirty();
		}
	}

	int ILayoutElement.layoutPriority { get { return 0; } }
	float ILayoutElement.minWidth { get { return 0f; } }
	float ILayoutElement.minHeight { get { return 0f; } }
	float ILayoutElement.flexibleWidth { get { return -1; } }
	float ILayoutElement.flexibleHeight { get { return -1; } }
	float ILayoutElement.preferredWidth { get { return sprite ? ( sprite.rect.size.x / pixelsPerUnit ) : 0f; } }
	float ILayoutElement.preferredHeight { get { return sprite ? ( sprite.rect.size.y / pixelsPerUnit ) : 0f; } }
	void ILayoutElement.CalculateLayoutInputHorizontal() { }
	void ILayoutElement.CalculateLayoutInputVertical() { }

	// Whether this is being tracked for Atlas Binding
	private bool m_Tracked = false;

#if UNITY_2017_4 || UNITY_2018_2_OR_NEWER
	private static List<PaddingIgnoringImage> m_TrackedTexturelessImages = new List<PaddingIgnoringImage>();
	private static bool s_Initialized;
#endif

	private void TrackImage()
	{
		if( sprite != null && sprite.texture == null )
		{
#if UNITY_2017_4 || UNITY_2018_2_OR_NEWER
			if( !s_Initialized )
			{
				SpriteAtlasManager.atlasRegistered += RebuildImage;
				s_Initialized = true;
			}

			m_TrackedTexturelessImages.Add( this );
#endif
			m_Tracked = true;
		}
	}

	private void UnTrackImage()
	{
#if UNITY_2017_4 || UNITY_2018_2_OR_NEWER
		m_TrackedTexturelessImages.Remove( this );
#endif
		m_Tracked = false;
	}

#if UNITY_2017_4 || UNITY_2018_2_OR_NEWER
	private static void RebuildImage( SpriteAtlas spriteAtlas )
	{
		for( int i = m_TrackedTexturelessImages.Count - 1; i >= 0; i-- )
		{
			PaddingIgnoringImage image = m_TrackedTexturelessImages[i];
			if( spriteAtlas.CanBindTo( image.sprite ) )
			{
				image.SetAllDirty();
				m_TrackedTexturelessImages.RemoveAt( i );
			}
		}
	}
#endif
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1133766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分类预测 | MATLAB实现SSA-CNN-BiGRU-Attention数据分类预测(SE注意力机制)

分类预测 | MATLAB实现SSA-CNN-BiGRU-Attention数据分类预测&#xff08;SE注意力机制&#xff09; 目录 分类预测 | MATLAB实现SSA-CNN-BiGRU-Attention数据分类预测&#xff08;SE注意力机制&#xff09;分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MATLA…

微信小程序如何跳转页面

1.wx.navigateTo&#xff1a;用于跳转到其他页面&#xff0c;并保留当前页面。通过该 API 跳转后&#xff0c;可以通过返回按钮回到原页面。 wx.navigateTo({url: /pages/otherPage/otherPage })2.wx.redirectTo&#xff1a;用于跳转到其他页面&#xff0c;并关闭当前页面。通…

上初三的小伙子做了个windows12网页版

某天逛GitHub突然刷到这个仓库&#xff0c;好奇的点了进去&#xff0c;读完md我懵了&#xff0c;作者才初三&#xff1f;wtf&#xff0c;现在内卷到这个程度了吗&#xff01;而且start还不低有5.2k。 效果展示 新的版本有很多变化&#xff0c;仅供参考&#xff0c;请以实物为准…

SpringBoot 自动配置@EnableAutoConfiguration

自动配置vs自动装配 Spring有两个名字听起来相似的概念&#xff1a;一个是自动装配&#xff0c;一个是自动配置。他们两个只是听起来相似&#xff0c;实际根本不同。自动装配是autowire&#xff0c;自动配置是autoconfiguration&#xff0c;他们之间没有任何关系&#xff0c;概…

ARM 版 OpenEuler 22.03 部署 KubeSphere v3.4.0 不完全指南

作者&#xff1a;运维有术 前言 知识点 定级&#xff1a;入门级KubeKey 安装部署 ARM 版 KubeSphere 和 KubernetesARM 版 KubeSphere 和 Kubernetes 常见问题 实战服务器配置 (个人云上测试服务器) 主机名IPCPU内存系统盘数据盘用途ks-master-1172.16.33.1661650200KubeSp…

翻页电子相册如何制作?看到就是赚到

在日常生活中&#xff0c;我们拿起手机随手一拍&#xff0c;即可记录美丽瞬间。但随着手机里的照片越来越多&#xff0c;这时该怎么办呢&#xff1f;相信很多小伙伴会选择把照片装订成相册&#xff0c;不过&#xff0c;时间一长也都成了压箱底&#xff0c;无人翻看。但除了这一…

sheng的学习笔记-【中】【吴恩达课后测验】Course 3 - 结构化机器学习项目 - 第一周测验

课程3_第1周_测验题 目录&#xff1a;目录 要解决的问题 ① 这个例子来源于实际项目&#xff0c;但是为了保护机密性&#xff0c;我们会对细节进行保护。 ② 现在你是和平之城的著名研究员&#xff0c;和平之城的人有一个共同的特点&#xff1a;他们害怕鸟类。 ③ 为了保护…

MyBatis-Plus 通过updateById更新日期null

date类型的字段为 一、需求&#xff1a; 有时候需要将页面日期重新赋值空&#xff0c;但是Mybatis Plus 默认情况下&#xff0c;baseMapper.updateById方法&#xff0c;当doman中字段值为null&#xff0c;后端并会不更新这个字段 解决方法&#xff1a; 对应的实体类的属性加…

浅谈智能制造

智能制造 如今&#xff0c;同一版本同一型号的手机&#xff0c;几乎是一模一样的。当我们说去选购商品&#xff0c;其实是在有限的型号中选择我们需要的那一款。可是&#xff0c;人的需求千变万化&#xff0c;为什么偏偏要归结到几个固定的型号上去呢&#xff1f;每个人不应该…

2023/10/25MySQL学习

外键约束 在子表添加外键后,不能在主表删除或更新记录,因为存在外键关联 删除外键,注意外键名称时我们添加外键时起的名称 使用cascade操作后,可以操作主表数据,并且子表的外键也会对应改变 set null的话,删除主表对应主键信息后,子表对应外键信息变为空 多表关系 创建中间表 可…

JavaScript进阶 第四天笔记——深浅拷贝、this绑定、防抖节流

JavaScript 进阶 - 第4天 深浅拷贝 浅拷贝 首先浅拷贝和深拷贝只针对引用类型 浅拷贝&#xff1a;拷贝的是地址 常见方法&#xff1a; 拷贝对象&#xff1a;Object.assgin() / 展开运算符 {…obj} 拷贝对象拷贝数组&#xff1a;Array.prototype.concat() 或者 […arr] 如…

NSSCTF做题第9页(3)

[GKCTF 2020]CheckIN 代码审计 这段代码定义了一个名为ClassName的类&#xff0c;并在脚本的最后创建了一个ClassName类的实例。 在ClassName类的构造函数中&#xff0c;首先通过调用$this->x()方法获取了请求参数$_REQUEST中的值&#xff0c;并将其赋值给$this->code属性…

Android [SPI,AutoSerivce,ServiceLoader]

记录一下在Android中使用SPI的过程。 1.项目gralde文件。 plugins {id kotlin-kapt } dependencies {implementation com.google.auto.service:auto-service:1.0-rc7 kapt "com.google.auto.service:auto-service:1.0-rc7" } 这个AutoServ…

【Qt】绘图与绘图设备

文章目录 绘图设备QPainter绘图实例案例1案例2-高级设置案例3&#xff1a;利用画家画资源图片 点击按钮移动图片 QtPaintDevice实例Pixmap绘图设备QImage 绘图设备QPicture 绘图设备 QPainter绘图 Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系…

外卖跑腿小程序开发如何满足不断变化的用户需求?

外卖跑腿小程序市场竞争激烈&#xff0c;用户需求不断演变。为了保持竞争力&#xff0c;开发团队需要不断适应变化&#xff0c;提供新功能和改进用户体验。本文将讨论如何通过技术手段来满足不断变化的用户需求。 1. 灵活的后端服务 后端服务是外卖跑腿小程序的核心&#xf…

Sui主网升级至V1.12.2版本

其他升级要点如下所示&#xff1a; #14305 使Sui能够验证zkLogin历史地址&#xff08;通过已填充的address_seed派生&#xff09;。升级协议版本至29&#xff0c;以启用对历史地址的验证。 #14100 修复了verify_zklogin_id函数中的错误&#xff0c;该函数按预期返回一个Ver…

Flutter extended_image库设置内存缓存区大小与缓存图片数

ExtendedImage ExtendedImage 是一个Flutter库&#xff0c;用于提供高级图片加载和显示功能。这个库使用了 image 包来进行图片的加载和缓存。如果你想修改缓存大小&#xff0c;你可以通过修改ImageCache的配置来实现。 1. 获取ImageCache实例: 你可以通过PaintingBinding…

Ansible简介

环境 控制节点&#xff1a;Ubuntu 22.04Ansible 2.10.8管理节点&#xff1a;CentOS 8 组成 Ansible环境主要由三部分组成&#xff1a; 控制节点&#xff08;Control node&#xff09;&#xff1a;安装Ansible的节点&#xff0c;在此节点上运行Ansible命令管理节点&#xff…

【剑指Offer】38.字符串的排列

题目 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数据范围&#xff1a;n<10 要求&#xff1a;空间复…