我的Unity(5)一点一滴 利用贴图制作弹痕

制作弹痕主要用到粒子系统的贴图融合,通俗的说就是把墙壁的纹理和子弹的纹理融合在一起。实现这个效果需要知道:
1UV坐标,
//对UV坐标的理解:
//1.UV坐标就是图片在屏幕上像素点的位置,【相当于x、y坐标】
//2.范围一般是[0,1].左下角是(0.0),右上角是(1.1)。
//3.U坐标=第U个像素点/图片的宽;
V坐标=第V个像素点/图片的高;
2 要知道队列的知识 ,使用空间是using System.Collections.Generic;入队列和出队列。

这个代码的功能是实现在屏幕上点击任意位置,在Plane上出现弹痕,过3秒后消失。

消失的时候需要用到队列知识。Queue
每一步都有注释,慢慢写,慢慢看

//命名空间
using System.Collections.Generic;
public class konglian : MonoBehaviour
{


    public Texture2D m_oldWallTexture;
    Texture2D m_newWallTexture;
    public Texture2D m_bulletTexture;

    //定义纹理的高宽,
    float m_wallTextureWidth;
    float m_wallTextureHeight;

    float m_bulletTextureWidth;
    float m_bulletTextureHeight;
    //创建一个队列。注意他的命名空间。
    Queue <Vector2> qua = new Queue<Vector2> ();

    void Start ()
    {
        m_oldWallTexture = GetComponent <MeshRenderer> ().material.mainTexture as Texture2D;
        //调用旧的纹理作为效果图   不然最后的图渲染完之后,不能更改。
        m_newWallTexture = Instantiate (m_oldWallTexture);
        //使用这个纹理  理解为壁纸  
        GetComponent <MeshRenderer> ().material.mainTexture = m_oldWallTexture;
        //获得墙和子弹贴图的宽度和高度
        m_wallTextureWidth = m_newWallTexture.width;
        m_wallTextureHeight = m_newWallTexture.height;

        m_bulletTextureWidth = m_bulletTexture.width;
        m_bulletTextureHeight = m_bulletTexture.height;


    }

    Ray m_ray;
    RaycastHit m_hit;

    void Update ()
    {
        //屏幕发射射线
        if (Input.GetMouseButtonDown (0)) {
            m_ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            if (Physics.Raycast (m_ray, out m_hit)) {
                if (m_hit.transform.name == "Plane") {
                    Vector2 UV = m_hit.point;
                    //把射击的位置入队列
                    qua.Enqueue (UV);
                    //找到子弹贴图的原点位置,进行融合   需要定义   UV的位置是射击到的位置,以他为中心。i  j是子弹的贴图大小。
                    for (int i = 0; i < m_bulletTextureWidth; i++) {
                        for (int j = 0; j < m_bulletTextureHeight; j++) {
                            //注意i j是墙的整体像素的行和列,需要乘墙的宽度和高度  谁的坐标乘谁的。
                            float w = (UV.x * m_wallTextureWidth - m_bulletTextureWidth / 2) + i;
                            float h = (UV.y * m_wallTextureHeight - m_bulletTextureHeight / 2) + j;
                            //获得像素,子弹在墙壁上的需要融合的位置,
                            Color bulletPexis = m_bulletTexture.GetPixel (i, j);
                            Color wallPexis = m_newWallTexture.GetPixel ((int)w, (int)h);

                            //开始融合  像素之间相乘
                            m_newWallTexture.SetPixel ((int)w, (int)h, wallPexis * bulletPexis);

                        }
                    }
                }
                //需要提交一下。融合完成后进行。
                m_newWallTexture.Apply ();
                Invoke("ReBack",3f);
            }
        }
    }
}


下面是让弹痕消失,原理一样,用旧的纹理,来补全有弹痕的纹理。

void ReBack ()
    {
        //你想你射击,肯定是先射击出现的弹痕先消失,后出现的设计弹痕后消失,所以这里需要用到队列的知识。
        //取出第一个元素,并返回到UV,这个就是第一弹痕,需要让他消失,出队列。
        Vector2 UV = qua.Dequeue ();
        //同样的方法找到UV原点,得到子弹的像素点,只不过是和原来的贴图融合,
        for (int i = 0; i < m_bulletTextureWidth; i++) {
            for (int j = 0; j < m_bulletTextureHeight; j++) {
                float w = (UV.x * m_wallTextureWidth - m_bulletTextureWidth / 2) + i;
                float h = (UV.y * m_wallTextureHeight - m_bulletTextureHeight / 2) + j;
                //看清楚是旧的纹理,因为旧的没有修改过,读取,不能修改。
                Color wallPexis = m_oldWallTexture.GetPixel ((int)w, (int)h);
                显示的图是新修改的图。set方法。
                m_newWallTexture.SetPixel ((int)w, (int)h, wallPexis);
            }
        }
        //完成后记得提交
        m_newWallTexture.Apply ();
    }

同时 出现弹痕时提交的时候 ,调用ReBack方法,弹痕就会在3f。后消失。

Invoke(string name,float );
//方法是调用方法,几秒调用

如果有些错的地方欢迎大家指出来,共同指教。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值