开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:1963

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

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

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

[凉鞋同学] Unity 游戏框架搭建 (十八) 静态扩展 + 泛型实现transform的链式编程

[复制链接]  [移动端链接]
排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
发表于 2017-11-7 22:41:44 | 显示全部楼层 |阅读模式

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

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

x

本篇文章介绍如何实现如下代码的链式编程:
[C#] 纯文本查看 复制代码
            this.Position(Vector3.one)          
                .LocalScale(1.0f)               
                .Rotation(Quaternion.identity);

以上代码中,this为MonoBehaviour类型的对象。
如何实现?
通过上篇文章介绍的return this + 静态扩展很容易做到,实现代码如下所示:
[C#] 纯文本查看 复制代码
        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的方法。不能像如下方式使用。
[C#] 纯文本查看 复制代码
            this.Position(Vector3.one)          
                .LocalScale(1.0f)               
                .Rotation(Quaternion.identity)
                .DoSomething(); 

以上代码中,this为MonoBehaviour类型的对象。
如何解决这个问题呢?答案是引入泛型。
引入泛型
实现代码如下所示:
[C#] 纯文本查看 复制代码
        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到底是哪个类?最后找到了如下代码。
[C#] 纯文本查看 复制代码
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的属性器。 所以可以将之前的实现改为如下代码:
[C#] 纯文本查看 复制代码
        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等类,最后可以实现如下方式的链式编程。
[C#] 纯文本查看 复制代码
            Image image = null;

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

当然,去查看一个属性到底是哪个类实现的这个过程也是一个很好的学习方式 : ) ,有很多类都可以实现链式编程,不过剩下的要靠大家自己了,当然也可以参考QFramework里的实现方式,不过QFramework也只是对笔者常用的类进行了实现。
OK,本篇介绍到这里。
相关链接:
QFramework地址:https://github.com/liangxiegame/QFramework
转载请注明地址:凉鞋的笔记http://liangxiegame.com




回复

使用道具 举报

6蛮牛粉丝
1171/1500
排名
6764
昨日变化
72

2

主题

855

帖子

1171

积分

Rank: 6Rank: 6Rank: 6

UID
241666
好友
0
蛮牛币
4559
威望
0
注册时间
2017-9-6
在线时间
164 小时
最后登录
2017-11-20
发表于 2017-11-8 08:36:24 来自Mobile--- | 显示全部楼层
感谢分享

回复

使用道具 举报

排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
 楼主| 发表于 2017-11-8 09:08:49 | 显示全部楼层

谢谢支持

回复 支持 反对

使用道具 举报

7日久生情
2636/5000
排名
5558
昨日变化
3

4

主题

2186

帖子

2636

积分

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

UID
209186
好友
4
蛮牛币
3155
威望
0
注册时间
2017-3-1
在线时间
252 小时
最后登录
2017-11-17
发表于 2017-11-8 09:18:58 | 显示全部楼层
谢谢分享

回复

使用道具 举报

3偶尔光临
291/300
排名
8280
昨日变化
4

5

主题

78

帖子

291

积分

Rank: 3Rank: 3Rank: 3

UID
229395
好友
0
蛮牛币
840
威望
0
注册时间
2017-6-29
在线时间
94 小时
最后登录
2017-11-17
发表于 2017-11-8 09:39:05 | 显示全部楼层
Thanks for sharing.

回复 支持 反对

使用道具 举报

排名
2545
昨日变化
2

5

主题

58

帖子

814

积分

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

UID
146655
好友
1
蛮牛币
1233
威望
0
注册时间
2016-4-25
在线时间
299 小时
最后登录
2017-11-15
发表于 2017-11-8 09:45:56 | 显示全部楼层
不错                                    

回复 支持 反对

使用道具 举报

2初来乍到
111/150
排名
10706
昨日变化
142

0

主题

11

帖子

111

积分

Rank: 2Rank: 2

UID
238623
好友
0
蛮牛币
255
威望
0
注册时间
2017-8-20
在线时间
32 小时
最后登录
2017-11-19
发表于 2017-11-8 09:55:00 | 显示全部楼层
挺好的分享

回复

使用道具 举报

2初来乍到
123/150
排名
11383
昨日变化
6

0

主题

19

帖子

123

积分

Rank: 2Rank: 2

UID
226019
好友
0
蛮牛币
152
威望
0
注册时间
2017-6-9
在线时间
42 小时
最后登录
2017-11-16

一贫如洗

发表于 2017-11-8 09:59:28 | 显示全部楼层
谢谢分享

回复

使用道具 举报

7日久生情
1940/5000
排名
1538
昨日变化

9

主题

720

帖子

1940

积分

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

UID
68430
好友
3
蛮牛币
7331
威望
0
注册时间
2015-1-14
在线时间
505 小时
最后登录
2017-11-17
发表于 2017-11-8 10:16:27 | 显示全部楼层
我说我们项目内有个它RectTransform有个  SetWidth 函数~~  public static void SetWidth(this RectTransform rectTrans, float width) ,原来搞不明白,怎么就多出个它呢,,,这下晓得了,多谢楼主

回复 支持 反对

使用道具 举报

排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
 楼主| 发表于 2017-11-8 10:38:02 | 显示全部楼层

谢谢支持

回复 支持 反对

使用道具 举报

排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
 楼主| 发表于 2017-11-8 10:38:13 | 显示全部楼层

谢谢支持

回复 支持 反对

使用道具 举报

排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
 楼主| 发表于 2017-11-8 10:38:36 | 显示全部楼层

谢谢支持

回复 支持 反对

使用道具 举报

排名
2952
昨日变化
11

26

主题

282

帖子

1458

积分

Rank: 9Rank: 9Rank: 9

UID
148923
好友
43
蛮牛币
1629
威望
0
注册时间
2016-5-17
在线时间
446 小时
最后登录
2017-11-19

专栏作家

QQ
 楼主| 发表于 2017-11-8 10:41:42 | 显示全部楼层
绝世love情缘 发表于 2017-11-8 10:16
我说我们项目内有个它RectTransform有个  SetWidth 函数~~  public static void SetWidth(this RectTransfo ...

谢谢支持哦 UGUI里的 RectTransform 还有个 SetSizeWithCurrentAnchors() 会考虑Anchor计算的。

回复 支持 反对

使用道具 举报

5熟悉之中
749/1000
排名
4963
昨日变化
1

1

主题

340

帖子

749

积分

Rank: 5Rank: 5

UID
216583
好友
1
蛮牛币
1117
威望
0
注册时间
2017-4-7
在线时间
186 小时
最后登录
2017-11-17
发表于 2017-11-8 10:48:17 | 显示全部楼层
很好的分享,谢谢

回复

使用道具 举报

排名
16542
昨日变化
5

0

主题

11

帖子

84

积分

Rank: 2Rank: 2

UID
176890
好友
0
蛮牛币
100
威望
0
注册时间
2016-10-19
在线时间
45 小时
最后登录
2017-11-17
发表于 2017-11-8 10:51:22 | 显示全部楼层
MonoBehaviour 也是继承自component的,直接把第一种里的MonoBehaviour改为Component类型 应该就可以吧

回复 支持 反对

使用道具 举报

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

本版积分规则

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