NGUI源码解析之UIPanel(二)自定义Panel

文章说明

本篇文章基于NGUI (3.12.0)版本源码下的代码分析,如果代码和大家自己的不同,可能是版本不同。如果文章中分析有误希望大神看见指点迷津,大家好,我就是一个勤勤恳恳爱偷懒的码农,希望和大家一起学习研究。

自定义Panel

看这篇文章之前希望你把之前文章看过了,今天这一篇文章就是来做个实践操作吧,把之前关于 Panel 裁剪 的部分拆出来实现一个 demo,加深下对其的理解。

功能目标

我实现的功能非常简单,利用一张贴图模拟实现 UIPanel 如下功能:
1.实现 UIPanel 裁剪的 Soft Clip 功能,并且只实现单裁剪;
2.实现层级设置;
3.shader 直接使用 “Hidden/Unlit/Transparent Colored 1” ;

这里面涉及到功能主要有: mesh 创建,材质创建,给 shader 传递裁剪参数,将融合 UIPanel 和 UIDrawcall 部分功能。

代码

public static class ToolClass
{
	public static T AddOrGetComponent<T>(this GameObject obj) where T : Component
	{
		T component = obj.GetComponent<T>();
		if (null == component)
		{
			component = obj.AddComponent<T>();
		}
		return component;
	}
}

public class NGUI_TestPanel : MonoBehaviour {

	//外部属性
	public Vector4 _ClipRange = new Vector4(0, 0, 300f, 200f);
	public Vector2 _softness = new Vector2(5f, 5f);
	public int depth = 0;
	public Texture _tex;

	//内部属性
	private Vector4 _ShowRange = new Vector4(0, 0, 500f, 300f);
	private MeshFilter _filter;
	private MeshRenderer _render;
	private Mesh _mesh;
	private Material _mDynamicMat;

	// Use this for initialization
	void Start () {
		
	}

	private void OnEnable()
	{
		InitPanel();
	}

	private void InitPanel()
	{
		_filter = ToolClass.AddOrGetComponent<MeshFilter>(gameObject);
		_render = ToolClass. AddOrGetComponent<MeshRenderer>(gameObject);
		SetGeometryInfo();
		SetMaterials();
		SetClipping();
	}

	//只渲染一个面
	private void SetGeometryInfo()
	{
		if (_mesh == null)
		{
			_mesh = new Mesh();
		}
		_mesh.hideFlags = HideFlags.DontSave;
		_mesh.name = "NGUI_TestPanelMesh";
		//设置几何信息
		Vector3[] ver = { new Vector3(_ShowRange.x, _ShowRange.y),
			new Vector3(_ShowRange.x, _ShowRange.w + _ShowRange.y, 0),
			new Vector3(_ShowRange.z + _ShowRange.x, _ShowRange.w + _ShowRange.y, 0),
			new Vector3(_ShowRange.z + _ShowRange.x, _ShowRange.y, 0)};

		//int[] triangle = { 0, 1, 3, 1, 2, 3 };

		int vertexCount = (ver.Length >> 1) * 3;
		int[] triangle = new int[vertexCount];
		int index = 0;

		for (int i = 0; i < ver.Length; i += 4)
		{
			triangle[index++] = i;
			triangle[index++] = i + 1;
			triangle[index++] = i + 2;

			triangle[index++] = i + 2;
			triangle[index++] = i + 3;
			triangle[index++] = i;
		}

		Vector2[] uv = { Vector2.zero, Vector2.up, new Vector2(1, 1), Vector2.right };
		Vector3[] normal = { Vector3.back, Vector3.back, Vector3.back, Vector3.back };
		//也可以不设置颜色
		//Color[] color = { Color.white, Color.white, Color.white, Color.white};
		_mesh.vertices = ver;
		_mesh.uv = uv;
		_mesh.triangles = triangle;
		_mesh.normals = normal;
		//_mesh.colors = color;

		_filter.mesh = _mesh;
	}

	private void SetMaterials()
	{
		string shadername = "Hidden/Unlit/Transparent Colored 1";
		Shader shader = Shader.Find(shadername);
		if (_mDynamicMat == null)
		{
			_mDynamicMat = new Material(shader);
			_mDynamicMat.name = "[NGUI] " + shadername;
			_mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
		}
		_mDynamicMat.mainTexture = _tex;
		_mDynamicMat.renderQueue = 3000;
		_render.sharedMaterials = new Material[] { _mDynamicMat };
		_render.sortingOrder = depth;
	}

	private void SetClipping()
	{
		float angle = 0f;
		angle*= -Mathf.Deg2Rad;


		Vector2 sharpness = new Vector2(1000.0f, 1000.0f);
		if (_softness.x > 0f) sharpness.x = _ClipRange.z / _softness.x;
		if (_softness.y > 0f) sharpness.y = _ClipRange.w / _softness.y;

		_mDynamicMat.SetVector("_ClipRange0", new Vector4(-_ClipRange.x / _ClipRange.z, -_ClipRange.y / _ClipRange.w,
			1f/ _ClipRange.z, 1f/ _ClipRange.w));
		_mDynamicMat.SetVector("_ClipArgs0", new Vector4(sharpness.x, sharpness.y, Mathf.Sin(angle), Mathf.Cos(angle)));
	}

}

实际效果

我们分别创建了两个对象,分别挂载了 “NGUI_TestPanel” 这个组件,然后设置的参数如下:

在这里插入图片描述
在这里插入图片描述
最终运行后的效果如图所示:

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值