使用UnityGetPixel来实例Image生成现有Texture2D

主要实现:

首先我们知道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[√]

脚本代码以及使用

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更改逻辑即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值