Unity 游戏框架搭建 2017 (十八) 静态扩展 + 泛型实现transform的链式编程

6 篇文章 1 订阅
4 篇文章 1 订阅

本篇文章介绍如何实现如下代码的链式编程:

this.Position(Vector3.one)			
	.LocalScale(1.0f)				
	.Rotation(Quaternion.identity); 

以上代码中,this 为 MonoBehaviour 类型的对象。

如何实现?

通过上篇文章介绍的 return this + 静态扩展很容易做到,实现代码如下所示:

		public static MonoBehaviour Position(this MonoBehaviour selfBehaviour, Vector3 position) 
		{
			selfBehaviour.transform.position = position;
			return selfBehaviour;
		}
		
		public static MonoBehaviour LocalScale(this MonoBehaviour selfBehaviour, float xyz)
		{
			selfBehaviour.transform.localScale = Vector3.one * xyz;
			return selfBehaviour;
		}
		
		public static MonoBehaviour Rotation(this MonoBehaviour selfBehaviour, Quaternion rotation)
		{
			selfBehaviour.transform.rotation = rotation;
			return selfBehaviour;
		}

很容易实现对吧?但是这样有个问题,由于静态扩展方法返回的是 MonoBehaviour 类而不是this所属的类型,所以接下来链式方法中只能使用 MonoBehaviour 的方法。不能像如下方式使用。

			this.Position(Vector3.one)			
				.LocalScale(1.0f)				
				.Rotation(Quaternion.identity)
				.DoSomething(); 

以上代码中,this 为 MonoBehaviour 类型的对象。

如何解决这个问题呢?答案是引入泛型。

引入泛型

实现代码如下所示:

		public static T Position<T>(this T selfBehaviour, Vector3 position) where T : MonoBehaviour
		{
			selfBehaviour.transform.position = position;
			return selfBehaviour;
		}
		
		public static T LocalScale<T>(this T selfBehaviour, float xyz) where T : MonoBehaviour
		{
			selfBehaviour.transform.localScale = Vector3.one * xyz;
			return selfBehaviour;
		}
		
		public static T Rotation<T>(this T selfBehaviour, Quaternion rotation) where T : MonoBehaviour
		{
			selfBehaviour.transform.rotation = rotation;
			return selfBehaviour;
		}

实现很简单,只是把之前代码中的 MonoBehaivour 改成泛型T,然后增加一个约束: where T : MonoBehaviour。表示这个泛型一定要继承自 MonoBehaviour。这样之前例子中的this可以使用MonoBehaviour 之外的方法实现链式编程了。

进一步完善

不只是自己实现的 MonoBehaviour 脚本像 UGUI 的 Image 等都要支持 transform 的链式编程。那么就要找到transfom 到底是哪个类?最后找到了如下代码。

namespace UnityEngine
{
  /// <summary>
  ///   <para>Base class for everything attached to GameObjects.</para>
  /// </summary>
  [RequiredByNativeCode]
  public class Component : Object
  {
	/// <summary>
	///   <para>The Transform attached to this GameObject.</para>
	/// </summary>
	public extern Transform transform { [MethodImpl(MethodImplOptions.InternalCall)] get; }
	...

最终定位到,transform 是 Component 的属性器。
所以可以将之前的实现改为如下代码:

		public static T Position<T>(this T selfComponent, Vector3 position) where T : Component
		{
			selfComponent.transform.position = position;
			return selfComponent;
		}
		
		public static T LocalScale<T>(this T selfComponent, float xyz) where T : Component
		{
			selfComponent.transform.localScale = Vector3.one * xyz;
			return selfComponent;
		}
		
		public static T Rotation<T>(this T selfComponent, Quaternion rotation) where T : Component
		{
			selfComponent.transform.rotation = rotation;
			return selfComponent;
		}

通过此种方式实现 Graphfic,Component 等类,最后可以实现如下方式的链式编程。

Image image = null;

image.LocalPosition(Vector3.back)
	.ColorAlpha(0.0f)
	.Hide();

当然,去查看一个属性到底是哪个类实现的这个过程也是一个很好的学习方式 : ) ,有很多类都可以实现链式编程,不过剩下的要靠大家自己了,当然也可以参考 QFramework 里的实现方式,不过 QFramework 也只是对笔者常用的类进行了实现。

OK,本篇介绍到这里。

转载请注明地址:凉鞋的笔记:liangxiegame.com

更多内容

  • QFramework 地址:https://github.com/liangxiegame/QFramework

  • QQ 交流群:623597263

  • Unity 进阶小班

    • 主要训练内容:
      • 框架搭建训练(第一年)
      • 跟着案例学 Shader(第一年)
      • 副业的孵化(第二年、第三年)
    • 权益、授课形式等具体详情请查看《小班产品手册》:https://liangxiegame.com/master/intro
  • 关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉鞋的笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值