游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2348

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 1946|回复: 17

[海莉zhe] 【每日一记】Unity3D 实战练习-实现物体的镜像 (十四)

[复制链接]  [移动端链接]
排名
568
昨日变化
2

68

主题

238

帖子

3148

积分

Rank: 9Rank: 9Rank: 9

UID
76890
好友
90
蛮牛币
4472
威望
0
注册时间
2015-3-4
在线时间
1144 小时
最后登录
2018-11-12

专栏作家

发表于 2018-9-12 21:25:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 海莉zhe 于 2018-9-12 21:22 编辑

   
             最近在学习如何实现物体的镜像,练习了一个简单的例子,然后和大家一起探讨一下哈!物体镜像的操作实际上是通过一个模型的MeshFilter 和 MeshRenderer 来获取模型的顶点和网格的信息,按指定的轴向、指定的距离来克隆一个新对象,简单来讲,就是克隆了一个含有MeshRenderer的对象。                            
             好吧!废话不多讲,我们直接进入实战吧!

            1. 需要新建一个含有Mesh Filter组件和Mesh Renderer 组件的对象;

                1_0.jpeg


            2. 直接增加 MeshMirrorManager.cs 组件类,并且附加对象上;
               具体代码如下:

            
[C#] 纯文本查看 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/// <summary>
/// 镜像方向
/// </summary>
public enum MeshMirrorDir
{
	X,
	Y,
	Z
}

/// <summary>
/// 显示的模式
/// </summary>
public enum MeshRendererMode
{
	Opaque,//不透明
	Cutout,//镂空
	Fade,//淡入淡出
	Transparent,//透明
}

/// <summary>
/// 对象镜像管理类
/// </summary>
public class MeshMirrorManager : MonoBehaviour {

	/// <summary>
	/// 镜像方向
	/// </summary>
	public MeshMirrorDir m_mirrorDir;

	/// <summary>
	/// 镜像与对象距离
	/// </summary>
	public float m_mirrorDistance=2.0f;

	/// <summary>
	/// 镜像材质透明度
	/// </summary>
	[Range(0.1f, 1.0f)]
	public float m_mirrorMaterialAlpha = 0.5f;

	/// <summary>
	/// 镜像材质颜色
	/// </summary>
	public Color m_mirrorMaterialColor = Color.white;

	MeshFilter _meshFilter;
	MeshRenderer _meshRenderer;

	void Start () 
	{
		_meshFilter = GetComponent<MeshFilter> ();
		_meshRenderer = GetComponent<MeshRenderer> ();

		GenerateMirror();
	}


	private void GenerateMirror()
	{
		if ( _meshFilter== null &&  _meshRenderer== null)
		{
			Debug.Log("请确认对象已附加MeshFilter或MeshRenderer组件");
		}

		GameObject mirror = new GameObject("Mirror");
		mirror.transform.position = this.transform.position;
		mirror.transform.rotation = this.transform.rotation;
		mirror.transform.localScale = this.transform.localScale;
		mirror.transform.SetParent(this.transform);

		mirror.AddComponent<MeshFilter>();
		mirror.AddComponent<MeshRenderer>();

		//镜像的网格
		Mesh mesh = new Mesh();
		mesh.Clear();
		mesh.vertices = GenerateVertices(_meshFilter.mesh.vertices);
		mesh.triangles = GenerateTriangles(_meshFilter.mesh.triangles);
		mesh.uv=GetComponent<MeshFilter>().mesh.uv;
		mesh.name = "mirror";
		//重新计算发现(刷新显示)
		mesh.RecalculateNormals();
		mirror.GetComponent<MeshFilter>().mesh = mesh;
		mirror.GetComponent<MeshRenderer>().material = GenerateMaterial(_meshRenderer.material);
	}

	/// <summary>
	/// 生成镜像顶点
	/// </summary>
	/// <param name="backVertices">原游戏对象的顶点</param>
	/// <returns></returns>
	private Vector3[] GenerateVertices(Vector3[] backVertices)
	{
		Vector3[] newVertices = backVertices;

		switch(m_mirrorDir)
		{
		case MeshMirrorDir.X:
			for (int i = 0; i <= newVertices.Length - 1;i++ )
			{
				newVertices[i].x = newVertices[i].x * -1 + m_mirrorDistance;
			}
			break;
		case MeshMirrorDir.Y:
			for (int i = 0; i <= newVertices.Length - 1; i++)
			{
				newVertices[i].y = newVertices[i].y * -1 + m_mirrorDistance;
			}
			break;
		case MeshMirrorDir.Z:
			for (int i = 0; i <= newVertices.Length - 1; i++)
			{
				newVertices[i].z = newVertices[i].z * -1 + m_mirrorDistance;
			}
			break;
		default:
			break;
		}

		return newVertices;
	}



	/// <summary>
	/// 生成镜像三角面
	/// </summary>
	/// <param name="backTriangles">各个顶点的渲染顺序</param>
	/// <returns></returns>
	int[] GenerateTriangles(int[] backTriangles)
	{
		int[] newTriangles = new int[backTriangles.Length];
		//将所有面的顶点渲染顺序颠倒
		for (int i = 0; i < newTriangles.Length; i++)
		{
			newTriangles[newTriangles.Length - i - 1] = backTriangles[i];
		}

		return newTriangles;
	}

	/// <summary>
	/// 生成材质球
	/// </summary>
	/// <returns>原材质球</returns>
	/// <param name="backMeterial">复制后的材质球</param>
	private Material GenerateMaterial(Material backMeterial)
	{
		Material newMaterial = new Material(backMeterial);
		//不透明
		if (m_mirrorMaterialAlpha >= 1.0f)
		{
			SetMaterialRenderingMode(newMaterial, MeshRendererMode.Opaque);
			if (newMaterial.HasProperty("_Color"))
			{
				newMaterial.SetColor("_Color", m_mirrorMaterialColor);
			}
		}
		//透明
		else
		{
			SetMaterialRenderingMode(newMaterial, MeshRendererMode.Fade);
			if (newMaterial.HasProperty("_Color"))
			{
				m_mirrorMaterialColor.a = m_mirrorMaterialAlpha;
				newMaterial.SetColor("_Color", m_mirrorMaterialColor);
			}
		}

		return newMaterial;
	}


	/// <summary>
	/// 设置纹理渲染模式
	/// </summary>
	/// <param name="material"></param>
	/// <param name="renderingMode"></param>
	private void SetMaterialRenderingMode(Material material, MeshRendererMode renderingMode)
	{
		switch (renderingMode)
		{
		case MeshRendererMode.Opaque:
			material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
			material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
			material.SetInt("_ZWrite", 1);
			material.DisableKeyword("_ALPHATEST_ON");
			material.DisableKeyword("_ALPHABLEND_ON");
			material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			material.renderQueue = -1;
			break;
		case MeshRendererMode.Cutout:
			material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
			material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
			material.SetInt("_ZWrite", 1);
			material.EnableKeyword("_ALPHATEST_ON");
			material.DisableKeyword("_ALPHABLEND_ON");
			material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			material.renderQueue = 2450;
			break;
		case MeshRendererMode.Fade:
			material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
			material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
			material.SetInt("_ZWrite", 0);
			material.DisableKeyword("_ALPHATEST_ON");
			material.EnableKeyword("_ALPHABLEND_ON");
			material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			material.renderQueue = 3000;
			break;
		case MeshRendererMode.Transparent:
			material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
			material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
			material.SetInt("_ZWrite", 0);
			material.DisableKeyword("_ALPHATEST_ON");
			material.DisableKeyword("_ALPHABLEND_ON");
			material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
			material.renderQueue = 3000;
			break;
		}
	}
}

            3.运行项目看效果哈!

             2_0.jpeg
               


            题外小窗:一代动捕,一代神。《虚拟偶像》在各大安卓应用市场(以及苹果商店App Store)都可以直接搜索下载噢!期待大家来关注! ------来自努努的自白






回复

使用道具 举报

6蛮牛粉丝
1282/1500
排名
2595
昨日变化
11

5

主题

407

帖子

1282

积分

Rank: 6Rank: 6Rank: 6

UID
54335
好友
1
蛮牛币
1958
威望
0
注册时间
2014-11-9
在线时间
342 小时
最后登录
2018-11-12
发表于 2018-9-13 08:46:41 | 显示全部楼层

回复

使用道具 举报

7日久生情
1938/5000
排名
2877
昨日变化
15

0

主题

1144

帖子

1938

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
189581
好友
0
蛮牛币
2755
威望
0
注册时间
2016-12-5
在线时间
310 小时
最后登录
2018-11-12
发表于 2018-9-13 09:26:10 | 显示全部楼层
给力啊强大啊

回复

使用道具 举报

3偶尔光临
174/300
排名
12235
昨日变化
189

1

主题

60

帖子

174

积分

Rank: 3Rank: 3Rank: 3

UID
292646
好友
0
蛮牛币
174
威望
0
注册时间
2018-8-6
在线时间
43 小时
最后登录
2018-11-12
发表于 2018-9-13 09:26:36 | 显示全部楼层
很赞的小功能

回复

使用道具 举报

6蛮牛粉丝
1231/1500
排名
1590
昨日变化
5

0

主题

163

帖子

1231

积分

Rank: 6Rank: 6Rank: 6

UID
137070
好友
0
蛮牛币
2451
威望
0
注册时间
2016-2-20
在线时间
300 小时
最后登录
2018-11-12
发表于 2018-9-13 09:46:55 | 显示全部楼层
666666
感谢楼主分享!

回复 支持 反对

使用道具 举报

排名
23322
昨日变化
14

0

主题

5

帖子

30

积分

Rank: 1

UID
278081
好友
0
蛮牛币
75
威望
0
注册时间
2018-4-20
在线时间
9 小时
最后登录
2018-11-8
发表于 2018-9-13 18:46:23 | 显示全部楼层
感谢楼主分享

回复

使用道具 举报

3偶尔光临
250/300
排名
9970
昨日变化
5

0

主题

77

帖子

250

积分

Rank: 3Rank: 3Rank: 3

UID
203296
好友
2
蛮牛币
146
威望
0
注册时间
2017-1-19
在线时间
71 小时
最后登录
2018-10-19
发表于 2018-9-13 22:02:18 | 显示全部楼层
vrey nice!

回复

使用道具 举报

5熟悉之中
613/1000
排名
4734
昨日变化
23

0

主题

181

帖子

613

积分

Rank: 5Rank: 5

UID
267103
好友
0
蛮牛币
1298
威望
0
注册时间
2018-1-31
在线时间
142 小时
最后登录
2018-11-12
发表于 2018-9-14 08:34:43 | 显示全部楼层

回复

使用道具 举报

排名
46446
昨日变化
65

0

主题

12

帖子

18

积分

Rank: 1

UID
293230
好友
0
蛮牛币
6
威望
0
注册时间
2018-8-11
在线时间
2 小时
最后登录
2018-9-15
发表于 2018-9-14 18:41:49 | 显示全部楼层
很好很强大

回复

使用道具 举报

7日久生情
2471/5000
排名
648
昨日变化
3

0

主题

345

帖子

2471

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
8899
好友
0
蛮牛币
4139
威望
0
注册时间
2013-11-25
在线时间
850 小时
最后登录
2018-11-12
发表于 2018-9-15 12:10:50 | 显示全部楼层
谢谢分享

回复

使用道具 举报

4四处流浪
403/500
排名
5919
昨日变化
3

0

主题

75

帖子

403

积分

Rank: 4

UID
282652
好友
1
蛮牛币
2363
威望
0
注册时间
2018-5-24
在线时间
108 小时
最后登录
2018-11-8

迈向小康

发表于 2018-9-17 09:44:11 | 显示全部楼层
镜像可以的

回复

使用道具 举报

5熟悉之中
560/1000
排名
7151
昨日变化
5

1

主题

214

帖子

560

积分

Rank: 5Rank: 5

UID
258102
好友
1
蛮牛币
624
威望
0
注册时间
2017-12-6
在线时间
173 小时
最后登录
2018-11-2

一贫如洗

发表于 2018-9-17 10:23:26 | 显示全部楼层

回复

使用道具 举报

7日久生情
2205/5000
排名
2742
昨日变化
4

1

主题

1419

帖子

2205

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
119154
好友
0
蛮牛币
2385
威望
0
注册时间
2015-8-21
在线时间
279 小时
最后登录
2018-11-9
发表于 2018-9-17 13:20:53 | 显示全部楼层
谢谢楼主大大。

回复

使用道具 举报

排名
33683
昨日变化
42

0

主题

30

帖子

81

积分

Rank: 2Rank: 2

UID
282476
好友
0
蛮牛币
107
威望
0
注册时间
2018-5-23
在线时间
43 小时
最后登录
2018-10-26
发表于 2018-9-17 13:53:49 | 显示全部楼层
66666666666666666

回复 支持 反对

使用道具 举报

排名
14748
昨日变化
7

0

主题

28

帖子

94

积分

Rank: 2Rank: 2

UID
289333
好友
0
蛮牛币
201
威望
0
注册时间
2018-7-10
在线时间
18 小时
最后登录
2018-11-8
发表于 2018-9-17 23:16:36 | 显示全部楼层
镜像   好像挺有意思的
[发帖际遇]: 苦瓜公子 发帖时在路边捡到 2 蛮牛币,偷偷放进了口袋. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 返回顶部 返回列表