找回密码
 注册帐号

扫一扫,访问微社区

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

18
回复
2649
查看
[ 复制链接 ]
排名
526
昨日变化

68

主题

247

帖子

3330

积分

Rank: 9Rank: 9Rank: 9

UID
76890
好友
96
蛮牛币
4610
威望
0
注册时间
2015-3-4
在线时间
1219 小时
最后登录
2019-4-19

专栏作家

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)都可以直接搜索下载噢!期待大家来关注! ------来自努努的自白





回复

使用道具 举报

7日久生情
1709/5000
排名
1990
昨日变化

5

主题

516

帖子

1709

积分

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

UID
54335
好友
2
蛮牛币
5531
威望
0
注册时间
2014-11-9
在线时间
506 小时
最后登录
2019-4-25
2018-9-13 08:46:41 显示全部楼层
回复

使用道具 举报

7日久生情
2295/5000
排名
2248
昨日变化

0

主题

1286

帖子

2295

积分

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

UID
189581
好友
0
蛮牛币
3447
威望
0
注册时间
2016-12-5
在线时间
383 小时
最后登录
2019-4-25
2018-9-13 09:26:10 显示全部楼层
给力啊强大啊
回复

使用道具 举报

4四处流浪
406/500
排名
8010
昨日变化

3

主题

129

帖子

406

积分

Rank: 4

UID
292646
好友
0
蛮牛币
457
威望
0
注册时间
2018-8-6
在线时间
120 小时
最后登录
2019-4-17
2018-9-13 09:26:36 显示全部楼层
很赞的小功能
回复

使用道具 举报

7日久生情
1581/5000
排名
1199
昨日变化

0

主题

216

帖子

1581

积分

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

UID
137070
好友
0
蛮牛币
3207
威望
0
注册时间
2016-2-20
在线时间
389 小时
最后登录
2019-4-25
2018-9-13 09:46:55 显示全部楼层
666666
感谢楼主分享!
回复 支持 反对

使用道具 举报

排名
24126
昨日变化

0

主题

6

帖子

35

积分

Rank: 1

UID
278081
好友
0
蛮牛币
85
威望
0
注册时间
2018-4-20
在线时间
12 小时
最后登录
2019-1-25
2018-9-13 18:46:23 显示全部楼层
感谢楼主分享
回复

使用道具 举报

3偶尔光临
269/300
排名
10342
昨日变化

0

主题

77

帖子

269

积分

Rank: 3Rank: 3Rank: 3

UID
203296
好友
2
蛮牛币
198
威望
0
注册时间
2017-1-19
在线时间
88 小时
最后登录
2019-4-22
2018-9-13 22:02:18 显示全部楼层
vrey nice!
回复

使用道具 举报

5熟悉之中
877/1000
排名
3156
昨日变化

0

主题

201

帖子

877

积分

Rank: 5Rank: 5

UID
267103
好友
0
蛮牛币
2902
威望
0
注册时间
2018-1-31
在线时间
206 小时
最后登录
2019-4-25
2018-9-14 08:34:43 显示全部楼层
回复

使用道具 举报

排名
48129
昨日变化

0

主题

11

帖子

17

积分

Rank: 1

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

使用道具 举报

7日久生情
2571/5000
排名
641
昨日变化

0

主题

347

帖子

2571

积分

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

UID
8899
好友
0
蛮牛币
4385
威望
0
注册时间
2013-11-25
在线时间
879 小时
最后登录
2019-3-19
2018-9-15 12:10:50 显示全部楼层
谢谢分享
回复

使用道具 举报

5熟悉之中
590/1000
排名
4499
昨日变化

0

主题

91

帖子

590

积分

Rank: 5Rank: 5

UID
282652
好友
1
蛮牛币
3204
威望
0
注册时间
2018-5-24
在线时间
173 小时
最后登录
2019-4-24
2018-9-17 09:44:11 显示全部楼层
镜像可以的
回复

使用道具 举报

5熟悉之中
848/1000
排名
5174
昨日变化

1

主题

295

帖子

848

积分

Rank: 5Rank: 5

UID
258102
好友
1
蛮牛币
1100
威望
0
注册时间
2017-12-6
在线时间
274 小时
最后登录
2019-4-25
2018-9-17 10:23:26 显示全部楼层
回复

使用道具 举报

7日久生情
2695/5000
排名
2230
昨日变化

1

主题

1721

帖子

2695

积分

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

UID
119154
好友
0
蛮牛币
2778
威望
0
注册时间
2015-8-21
在线时间
343 小时
最后登录
2019-4-23
2018-9-17 13:20:53 显示全部楼层
谢谢楼主大大。
回复

使用道具 举报

2初来乍到
134/150
排名
22151
昨日变化

0

主题

45

帖子

134

积分

Rank: 2Rank: 2

UID
282476
好友
0
蛮牛币
156
威望
0
注册时间
2018-5-23
在线时间
68 小时
最后登录
2019-3-26
2018-9-17 13:53:49 显示全部楼层
66666666666666666
回复 支持 反对

使用道具 举报

3偶尔光临
208/300
排名
10001
昨日变化

0

主题

38

帖子

208

积分

Rank: 3Rank: 3Rank: 3

UID
289333
好友
0
蛮牛币
421
威望
0
注册时间
2018-7-10
在线时间
60 小时
最后登录
2019-4-25
2018-9-17 23:16:36 显示全部楼层
镜像   好像挺有意思的
回复 支持 反对

使用道具 举报

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

本版积分规则