您的位置:首页 > 移动开发 > Unity3D

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

2016-12-07 21:15 543 查看
制作弹痕主要用到粒子系统的贴图融合,通俗的说就是把墙壁的纹理和子弹的纹理融合在一起。实现这个效果需要知道:

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 bullet
4000
Pexis = 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 );
//方法是调用方法,几秒调用


如果有些错的地方欢迎大家指出来,共同指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: