游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5038|回复: 6

一起讨论下腾讯平台上的u3d游戏所用的各种技术吧

[复制链接]

1

主题

8

帖子

58

积分

注册会员

Rank: 2

积分
58
发表于 2015-5-4 14:43:17 | 显示全部楼层 |阅读模式
      个人感觉腾讯把关的游戏质量还是很严格的,而且确实越来越好。比如去年我还能破解那些游戏,看看源代码,今年新发布的腾讯上的游戏全部都加密过了。用的方法应该和以前说过的一样,幸好我可以去小平台下载游戏的老版本去看源代码。
      先说一个我现在正在研究的问题吧,android上的代码热更新。我看过我叫MT2,盗梦英雄,酷酷爱魔兽等,只要使用U3d的,我都会去稍微看下,除了今天新看的天天传奇,暂时没有发现任何热更新代码的策略和逻辑。百度上所说的啥lua啊,C#脚本啊,腾讯平台上应该没有采用这种手段的,个人也觉得lua性能吃不消。而另一种就是将逻辑抽出到一个dll里面,然后利用反射实现代码的更新。
      然后今天看了下天天传奇的,首先他确实将逻辑抽出来了。一般游戏逻辑dll都有3M以上,它只有500k。所以肯定还有其他逻辑放到了另一个dll。果然我检查了下,发现Assembly-CSharp-firstpass.dll特别大,反编译后里面确实有全部的游戏逻辑。
      但我看了下代码,它有这样一个类:
      

public class NgAssembly { // Fields
public static BindingFlags m_bindingAttr = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); // Methods
private static object GetField(object inObj, string fieldName)
    { object obj2 = null; FieldInfo field = inObj.GetType().GetField(fieldName); if (field != null)
        { obj2 = field.GetValue(inObj);
        } return obj2;
    }
public static object GetProperty(object srcObj, string fieldName)
    { PropertyInfo property = srcObj.GetType().GetProperty(fieldName, m_bindingAttr); if (((property != null) && property.CanRead) && (property.GetIndexParameters().[url=http://127.0.0.1/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.5.0:7cec85d7bea7798e/System.Array/propertyength:Int32]Length[/url] == 0))
        { return property.GetValue(srcObj, null);
        } ssLogger.LogWarning(property.Name + " could not be read."); return null;
    }
public static T GetReference<T>(object inObj, string fieldName) where T: class { return (GetField(inObj, fieldName) as T);
    }
public static T GetValue<T>(object inObj, string fieldName) where T: struct { return (T) GetField(inObj, fieldName);
    }
public static void LogFieldsPropertis(Object srcObj)
    {
    }
public static void SetField(object inObj, string fieldName, object newValue)
    { FieldInfo field = inObj.GetType().GetField(fieldName); if (field != null)
        { field.SetValue(inObj, newValue);
        }
    }
public static void SetProperty(object srcObj, string fieldName, object newValue)
    {
PropertyInfo property = srcObj.GetType().GetProperty(fieldName, m_bindingAttr); if ((property != null) && property.CanWrite)
        {
property.SetValue(srcObj, newValue, null);
        }
else { ssLogger.LogWarning(property.Name + " could not be write.");
        }
    }
}

对于反射我不是很了解,但应该就是它去取dll里面的类定义吧。另一个问题在于我看到大部分的逻辑依然还是直接用类本身,也就是说,我感觉他虽然抽出了dll,但实际上是没有实现代码热更新的功能,
我也举得覆盖Assembly-CSharp-firstpass.dll应该不太可能吧。
不知道有没有人也感兴趣的,一起研究讨论下?

4

主题

129

帖子

423

积分

中级会员

Rank: 3Rank: 3

积分
423
发表于 2015-5-4 18:31:08 | 显示全部楼层
反射性能非常差,unity3d自己底层都没有用,而是自己实现了一套类似的功能。u3d暴露出来的基本都是些逻辑接口,真没有什么好看的东西。C#脚本就是普通文件跟普通文件更新是一样的,ios不能更新是因为苹果基于安全考虑不让app生成和释放脚本代码,在代码层是支持更新的。

1

主题

8

帖子

58

积分

注册会员

Rank: 2

积分
58
 楼主| 发表于 2015-5-5 14:25:31 | 显示全部楼层
okyuyu 发表于 2015-5-4 18:31
反射性能非常差,unity3d自己底层都没有用,而是自己实现了一套类似的功能。u3d暴露出来的基本都是些逻辑接口 ...

恩 但据说直接覆盖代码文件实际逻辑并不会更新,所以网上的人都说用反射,但我又无法再哪个大型游戏的源代码中找到类似用法,所以比较困惑。。。。我还没有和任何安卓平台合作过,不知道是不是平台的后台可以直接支持增量更新?或者平台SDK本身就有增量更新的相关内容?

4

主题

129

帖子

423

积分

中级会员

Rank: 3Rank: 3

积分
423
发表于 2015-5-5 21:50:56 | 显示全部楼层
这是我的安卓demo:http://pan.baidu.com/s/1nt1Ldfr,脚本也是用的C#但是引擎不是用的unity3d而是Ogre,app运行的时候会检测可写空间是否有脚本代码,如果没有则先把脚本从只读空间拷贝到可写空间,然后游戏运行的时候加载脚本是从可写空间加载的,加个版本号验证应该可以很容易实现脚本代码的更新。ps:更新这块我还真没有做过测试,所以不能保证自己的做法100%对。

0

主题

2

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2015-5-25 15:43:52 | 显示全部楼层
okyuyu 发表于 2015-5-4 18:31
反射性能非常差,unity3d自己底层都没有用,而是自己实现了一套类似的功能。u3d暴露出来的基本都是些逻辑接口 ...

您好,我是易信科技的小彭,如果有需要服务器托管与租用随时可以联系QQ:613878563,一手资源物美价廉。~~~

0

主题

2

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2015-5-25 15:45:09 | 显示全部楼层
您好,我是易信科技的小彭,如果有需要服务器托管与租用随时可以联系QQ:613878563,一手资源物美价廉。~~~

0

主题

12

帖子

26

积分

注册会员

Rank: 2

积分
26
发表于 2015-7-12 09:44:39 | 显示全部楼层
要好好补充下c#基础。类似这种东西,一般是定义一个接口,然后动态加载dll作为assembly,然后反射遍历这个assembly,拿到接口的实现。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-25 17:10

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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