Tencent / puerts

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.
Other
5.03k stars 700 forks source link

[Unity] Bug: JS派生C#类后,super 访问异常 #1784

Open Geequlim opened 3 months ago

Geequlim commented 3 months ago

前置阅读 | Pre-reading

Puer的版本 | Puer Version

2.0.5

Unity的版本 | Unity Version

2022.3.17

发生在哪个平台 | Platform

Editor(win)

错误信息 | Error Message

使用案例:通过TS 重写FariyGUI的GLoader实现加载并展示远程图像

通过为C# GLoader 的 url 属性赋值时调用 LoadExternal 方法,里面调用了JS的实现。JS的实现中访问 super.url 在编辑器中报错url的setter调用没有目标对象,发布程序后能够正常工作。

报错信息

Error: c# exception:Non-static method requires a target.,stack:  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00019] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 
  at Puerts.OverloadReflectionWrap.Invoke (Puerts.JSCallInfo jsCallInfo) [0x00083] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/Wrapper/ReflectionWrap.cs:319 
  at Puerts.MethodReflectionWrap.Invoke (System.IntPtr isolate, System.IntPtr info, System.IntPtr self, System.Int32 argumentsLen) [0x00070] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/Wrapper/ReflectionWrap.cs:404 
    at TinyFairyGUIGLoader.loadExternal (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/framework/unity/tiny/game/modules/fairygui/index.ts:310:42)
    at TinyFairyGUIGLoader.__loadExternal (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/framework/unity/tiny/game/modules/fairygui/index.ts:296:36)
    at LotteryDetailWindow.view.m_list.itemRenderer (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/game/main-game/lottery/LotteryDetail.window.ts:51:18)
    at LotteryDetailWindow.<anonymous> (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/game/main-game/lottery/LotteryDetail.window.ts:92:20)
    at Generator.next (<anonymous>)
    at fulfilled (/home/geequlim/Documents/work/super-playground/project/Build/scripts/bundle.js:22100:24),stack:  at Puerts.GenericDelegate.Action () [0x00032] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/JSType/GenericDelegate.cs:432 
  at FairyGUI.GLoader.LoadExternal () [0x0000f] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:490 
  at FairyGUI.GLoader.LoadContent () [0x0003c] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:405 
  at FairyGUI.GLoader.set_url (System.String value) [0x00021] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:97 
  at FairyGUI.GLoader.set_icon (System.String value) [0x00001] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:105 
  at FairyGUI.GLabel.set_icon (System.String value) [0x0000e] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLabel.cs:34 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 

问题重现 | Bug reproduce

FairyGUI.GLoade C#关键代码 ```cs namespace FairyGUI { public class GLoader : GObject, IAnimationGear, IColorGear { #if FAIRYGUI_PUERTS public Action __loadExternal; public Action __freeExternal; #endif public string url { get { return _url; } set { if (_url == value) return; ClearContent(); _url = value; LoadContent(); UpdateGear(7); } } protected void LoadContent() { ClearContent(); if (string.IsNullOrEmpty(_url)) return; if (_url.StartsWith(UIPackage.URL_PREFIX)) LoadFromPackage(_url); else LoadExternal(); } virtual protected void LoadExternal() { #if FAIRYGUI_PUERTS if (__loadExternal != null) { __loadExternal(); return; } #endif Texture2D tex = (Texture2D)Resources.Load(_url, typeof(Texture2D)); if (tex != null) onExternalLoadSuccess(new NTexture(tex)); else onExternalLoadFailed(); } } } ```
TypeScript关键代码 ```ts export class TinyFairyGUIGLoader extends FairyGUI.GLoader { static getOverrideURL(url: string): string { return url; } constructor() { super(); this.__freeExternal = this.freeExternal.bind(this); this.__loadExternal = this.loadExternal.bind(super); } public get url(): string { return this.$url || this.$internalURL; } public set url(value: string) { this.$url = value; super.url = this.$internalURL = TinyFairyGUIGLoader.getOverrideURL(this.url); } private $internalURL: string; private $url: string; protected loadExternal() { const url = super.url; // <<< 编辑器中这里报错 // TODO: 这里忽略具体加载逻辑 } } ```
chexiongsheng commented 2 months ago

首先我一向不建议ts继承c#。 其次即使我按你说的“JS派生C#类后”,super 访问并无异常。 应该你工程还有别的什么导致了问题。我从你的描述没法重现,或者你可以提供个干净的demo。