主要实现:
首先我们知道GetPixel方法能够通过(int,int)坐标来读取材质上的颜色,
这个X,Y是什么呢?这里我用aseprite生成3X4的图片(12像素)并在ps中加入坐标轴
原理解释
由此可见,我们读取像素只需要从(0,0)读到(2,0),然后y轴+1从(0,1)再读取,也就是只需要两个for循环即可。
for (int Y = 0; Y <4; Y++)
{
for (int X = 0; X < 3; X++)
{
Color insPixelColor = textureTarget.GetPixel(X, Y);
if (insPixelColor.a != 0)
{
insPixel = Instantiate(pixelImage, this.transform);
insPixel.GetComponent<Image>().color = insPixelColor;
insPixel.transform.localPosition = new Vector3(X-textureTarget.width/2, Y-textureTarget.height/2);
}
}
}
接着看最后一行,在生成实例image之后,又改变了生成实例的本地坐标,这是因为正常为了方便,我们都习惯Image中心就在红色轴,但是我们生成的图片的中心并不是红色轴,而是蓝色轴,所以只要需要将生成的图片整体下移2/材质高度,左移2/材质宽度.
insPixel.transform.localPosition = new Vector3(X-textureTarget.width/2, Y-textureTarget.height/2);
于是通过协程来按照顺序读取Texture2D的每个像素颜色然后用普通Image生成实例,来用大量Image还原出所选的Texture2D,接着对Image实例加脚本来实现各种效果.
普通效果&&更多效果
脚本以及使用准备
1.准备像素实例,也就是每一步生成的像素点
只需要一个无缩放的1x1的Image,然后添加为预设体
2.准备要生成的Texture2D,并勾选Read/Write Enabled[√]
![](https://i-blog.csdnimg.cn/blog_migrate/e4613b7aff1eddf2f83955fafe86aeab.png)
脚本代码以及使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class pixelParticle : MonoBehaviour
{
public Texture2D textureTarget;
public int particlePercent;
public GameObject pixelImage;
public float loadTime;
private GameObject insPixel;
private Color insPixelColor;
public bool pixelFinish;
void Start()
{
StartCoroutine(insPixelImage());
}
IEnumerator insPixelImage()
{
for (int Y = 0; Y < textureTarget.height; Y++)
{
for (int X = 0; X < textureTarget.width; X++)
{
insPixelColor = textureTarget.GetPixel(X, Y);
if (insPixelColor.a != 0)
{
if (Random.Range(0f, 100f) < (particlePercent))
{
insPixel = Instantiate(pixelImage, this.transform);
insPixel.GetComponent<Image>().color = insPixelColor;
insPixel.transform.localPosition = new Vector3(X - textureTarget.width / 2, Y - textureTarget.height / 2);
}
}
}
yield return new WaitForSeconds(loadTime / textureTarget.height);
}
pixelFinish = true;
yield break;
}
}
将代码挂到Canvas下的空物体上,添加脚本
脚本主要参数
textureTarget 要生成的Texture2D
particlePercent 生成粒子的概率,填101就是100%生成粒子,填30就是30%的几率生成
(particlePercent=100) (particlePercent=80) (particlePercent=30)
pixelImage 上一步的1X1的image预设体
loadTime 加载时间,不要太短或者太长(3-5S最佳)
更多效果的实现方法以及实例脚本
想要更多效果只需要给实例image加上脚本即可,以下是实例脚本(仅供参考)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class pixelControl : MonoBehaviour
{
public bool randomBack;
public bool randomDisappear;
private Vector3 startPos;
private Vector3 randomDir;
private pixelParticle pixelParticle;
private float alphaTimer=1f;
private Image imageThis;
private bool SetDestroy;
// Start is called before the first frame update
void Start()
{
pixelParticle = this.GetComponentInParent<pixelParticle>();
imageThis = this.GetComponent<Image>();
if (randomBack)
{
startPos = this.transform.position;
this.transform.Translate(new Vector3(Random.Range(-3F, 3F), Random.Range(-3F, 3F), 0), Space.World);
}
else if (randomDisappear)
{
randomDir = new Vector3(Random.Range(-1F, 1F), Random.Range(-1F, 1F), 0);
}
}
// Update is called once per frame
void Update()
{
if (pixelParticle.pixelFinish)
{
if (randomBack)
{
transform.position = Vector3.MoveTowards(this.transform.position, startPos, Time.deltaTime * 3f);
}
else if (randomDisappear)
{
if (!SetDestroy)
{
imageThis.color = new Color(imageThis.color.r, imageThis.color.g, imageThis.color.b, alphaTimer);
Destroy(this.gameObject, Random.Range(0.6F, 0.9F));
}
alphaTimer -= Time.deltaTime;
transform.Translate(randomDir*Time.deltaTime*20f);
imageThis.color = new Color(imageThis.color.r, imageThis.color.g, imageThis.color.b,alphaTimer);
}
}
}
}
勾选randomBack是由分散到复合
勾选randomDisappear是随机消散
自定义也是比较简单,只需要对一个image更改逻辑即可。