【unity框架开发13】unity静态扩展 this 关键字,实现类似DOTween / LINQ的链式写法

文章目录

前言

⼤家应该都接触过 DOTween / LINQ 等等概念了吧?其中的链式写法真的是很惊艳。

比如:

csharp 复制代码
transform.DOMove().SetEase().OnComplete();

这种方式在写的过程中体验是⾮常友好的。那么它的原理是什么呢?

答案是静态扩展 this 关键字。

一、如何实现静态 this 扩展

静态 this 扩展,仅仅是 C# 的⼀种语法关键字。要实现其实⾮常简单,我们直接看代码就能明⽩。

代码如下:

csharp 复制代码
public static class Test
{
	//调用
	static void MenuClicked()
	{
		 new object().Log();
		"string".Log();
	}
	
	//静态 this 扩展
	static void Log(this object data)
	{
		Debug.Log(data);
	}
}

先看下 我们的 Log⽅法,Log的第⼀个参数是 object 类型的,但是前边有个 this 关键字,有了这个this 关键字,我们的 object 对象就可以像调⽤⾃⼰的⽅法⼀样调⽤ Test ⽅法

也就是说,我们可以扩展已有的类,⽽不⽤去修改已有类内部的源码。这简直⽐ partial 还厉害。这就是 C# 语法的强⼤之处。

这⾥注意⼀下,实现静态 this 扩展⽅法的类,必须是静态类

二、应⽤静态 this 扩展到框架中

我们了解了静态 this 扩展之后,⾸先我们要思考⼀下它⽤在哪⾥⽐较合适呢?

静态 this 扩展,本质上其实还是静态⽅法,这些⽅法都是独⽴的,并不需要借助对象才可以调⽤的。

GameObject扩展⽅法

只需要把类变为静态的,并在每个⽅法的第⼀个参数上加上 this 关键字,增加后的代码如下:

csharp 复制代码
/// <summary>
/// GameObject扩展⽅法
/// </summary>
public static partial class GameObjectExtension
{
    public static void Show(this GameObject gameObj)
    {
        gameObj.SetActive(true);
    }
    public static void Hide(this GameObject gameObj)
    {
        gameObj.SetActive(false);
    }

    public static void Show(this Transform transform)
    {
        transform.gameObject.SetActive(true);
    }
    public static void Hide(this Transform transform)
    {
        transform.gameObject.SetActive(false);
    }
    public static void Show(this MonoBehaviour monoBehaviour)
    {
        monoBehaviour.gameObject.SetActive(true);
    }
    public static void Hide(this MonoBehaviour monoBehaviour)
    {
        monoBehaviour.gameObject.SetActive(false);
    }
}

测试调用

csharp 复制代码
# 按gameObject隐藏对象
gameObject.Hide();

# 按gameObject显示对象
gameObject.Show();

# 按transform隐藏对象
transform.Hide();

# 按transform显示对象
transform.Show();

# 按MonoBehaviour隐藏对象
this.Hide();

# 按MonoBehaviour显示对象
this.Show();

TransformExtension扩展方法

csharp 复制代码
/// <summary>
/// Transform扩展⽅法
/// </summary>
public static partial class TransformExtension
{
    #region 重置操作
    public static void Identity(this MonoBehaviour monoBehaviour)
    {
        monoBehaviour.transform.Identity();
    }
    public static void Identity(this Transform trans)
    {
        trans.localPosition = Vector3.zero;
        trans.localScale = Vector3.one;
        trans.localRotation = Quaternion.identity;
    }

    public static void Identity(this GameObject gameObject)
    {
        gameObject.transform.localPosition = Vector3.zero;
        gameObject.transform.localScale = Vector3.one;
        gameObject.transform.localRotation = Quaternion.identity;
    }
    #endregion

    #region 快捷设置localPosition的值
    public static void SetLocalPosX(this Transform transform, float x)
    {
        var localPos = transform.localPosition;
        localPos.x = x;
        transform.localPosition = localPos;
    }

    public static void SetLocalPosY(this Transform transform, float y)
    {
        var localPos = transform.localPosition;
        localPos.y = y;
        transform.localPosition = localPos;
    }

    public static void SetLocalPosZ(this Transform transform, float z)
    {
        var localPos = transform.localPosition;
        localPos.z = z;
        transform.localPosition = localPos;
    }

    public static void SetLocalPosXY(this Transform transform, float x, float y)
    {
        var localPos = transform.localPosition;
        localPos.x = x;
        localPos.y = y;
        transform.localPosition = localPos;
    }

    public static void SetLocalPosXZ(this Transform transform, float x, float z)
    {
        var localPos = transform.localPosition;
        localPos.x = x;
        localPos.z = z;
        transform.localPosition = localPos;
    }

    public static void SetLocalPosYZ(this Transform transform, float y, float z)
    {
        var localPos = transform.localPosition;
        localPos.y = y;
        localPos.z = z;
        transform.localPosition = localPos;
    }
    #endregion
}

调用

csharp 复制代码
# 按MonoBehaviour重置操作
this.Identity();

# 按transform重置操作
transform.Identity();
            
# 按gameObject重置操作
gameObject.Identity();

# 快捷设置localPosition的x值
transform.SetLocalPosX(1);
            
# 快捷设置localPosition的y值
transform.SetLocalPosY(1);
            
# 快捷设置localPosition的z值
transform.SetLocalPosZ(1);
            
# 快捷设置localPosition的xy值
transform.SetLocalPosXY(1, 2);
            
# 快捷设置localPosition的yz值
transform.SetLocalPosYZ(1, 2);
            
# 快捷设置localPosition的yz值
transform.SetLocalPosYZ(1, 2);

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
EIP低代码平台4 小时前
EIP 低代码平台 - 角色维护
低代码·c#·权限·工作流·netcore
码智社5 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海5 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖5 小时前
JDK 26 新特性详解
java·开发语言
马优晨6 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区8 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大8 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai9 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜9 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript