ialex32x / unity-jsb

It brings Javascript runtime capability to Unity3D by integrating QuickJS.
MIT License
337 stars 41 forks source link

Vector3 PropertyType #54

Closed lorenalexm closed 3 years ago

lorenalexm commented 3 years ago

I am attempting to extend the decorators to allow having proper Vector3 editing within an inspector window, instead of having to have three float properties and constructing my own Vector3 objects from these values in the script.

I cannot seem to get around the error [native] no overload method matched for EditorGUILayout.Vector3Field [2] though; the complete debug log can be found at bottom. This could be with my unfamiliarity of the unity-jsb code base and not knowing where all additions must be made.

I have made changes to the editor_decorators.ts, JSInspectorBase.cs, and the JSScriptProperties.cs files. Are there more places that I am missing? I have included my changes below, and would greatly appreciate any guidance in moving forward with this. Thank you!

// editor_decorators.ts

[..]

type PropertyTypeID = "integer" | "float" | "string" | "object" | "vector3";

[..]

export function ScriptVector3(meta?: WeakPropertyMetaInfo) {
    let meta_t = <PropertyMetaInfo>meta;
    if (typeof meta_t === "undefined") {
        meta_t = { type: "vector3" }
    } else {
        meta_t.type = "vector3";
    }
    return ScriptProperty(meta_t);
}

[..]
    /**
    * 默认编辑器绘制行为
    */
    static draw(target: any, extra?: any) {
        SerializationUtil.forEach(target, extra, (propertyKey, slot, self, extra) => {
            if (slot.visible) {
                        [..]
                            case "vector3": {
                            let oldValue: Vector3 = self[propertyKey];
                            if(editablePE) {
                                let newValue = EditorGUILayout.Vector3Field(label, oldValue);
                                if (newValue != oldValue) {
                                    self[propertyKey] = newValue;
                                    EditorUtility.SetDirty(self);
                                }
                            } else {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.Vector3Field(label, oldValue);
                                EditorGUI.EndDisabledGroup();
                            }
                        }
                        [..]
// JSInspectorBase.cs

[..]

        private void DrawPrimitiveView()
        {
            [..]
            ps.ForEach((string key, Vector3 value) =>
            {
                // unsafe
                EditorGUILayout.Vector3Field(key, value);
            });
        }

[..]
// JSScriptProperties.cs

[..]

        [Serializable]
        public class Vector3KeyValuePair
        {
            public string key;
            public Vector3 value;
        }

        [SerializeField]
        private List<Vector3KeyValuePair> _vector3s;

[..]
        public void ForEach(Action<string, Vector3> cb)
        {
            if(_vector3s != null)
            {
                for(int i = 0, count = _vector3s.Count; i < count; i++)
                {
                    var pair = _vector3s[i];
                    cb(pair.key, pair.value);
                }
            }
        }

        public void SetVector3(string key, Vector3 value)
        {
            if(_vector3s == null)
            {
                _vector3s = new List<Vector3KeyValuePair>();
            }

            var found = _vector3s.Find(pair => pair.key == key);
            if(found == null)
            {
                _vector3s.Add(new Vector3KeyValuePair { key = key, value = value });
            }
            else
            {
                found.value = value;
            }
        }

        public Vector3 GetVector3(string key)
        {
            return _vector3s?.Find(pair => pair.key == key)?.value ?? Vector3.zero;
        }
[..]

[native] no overload method matched for EditorGUILayout.Vector3Field [2] Javascript stack: at Vector3Field (native) at (Scripts/out/plover/editor/editor_decorators.js:190) at forEach (Scripts/out/plover/editor/editor_decorators.js:273) at draw (Scripts/out/plover/editor/editor_decorators.js:264) at OnInspectorGUI (Scripts/out/plover/editor/editor_decorators.js:144)

UnityEngine.Debug:LogErrorFormat (string,object[]) QuickJS.Utils.DefaultScriptLogger:Write (QuickJS.Utils.LogLevel,string,object[]) (at Assets/Jsb/Source/Utils/DefaultScriptLogger.cs:67) QuickJS.Native.JSContext:print_exception (QuickJS.Utils.IScriptLogger,QuickJS.Utils.LogLevel,string) (at Assets/Jsb/Source/Native/JSContext.cs:59) QuickJS.Native.JSContext:print_exception (QuickJS.Utils.LogLevel,string) (at Assets/Jsb/Source/Native/JSContext.cs:27) QuickJS.Unity.JSInspectorBase1<QuickJS.Unity.JSBehaviour>:DrawScriptingView () (at Assets/Jsb/Source/Unity/Editor/JSInspectorBase.cs:433) QuickJS.Unity.JSInspectorBase1:OnInspectorGUI () (at Assets/Jsb/Source/Unity/Editor/JSInspectorBase.cs:480) UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:189)

ialex32x commented 3 years ago

It's because the default property value is undefined, there is no type information for the type matching mechanism to guess a proper overloading member to use.

let oldValue: Vector3 = self[propertyKey] || Vector3.zero; // it should fix this issue 

Thank you for finding out this problem. I've pushed a submission to fix it.

lorenalexm commented 3 years ago

Wonderful! Thank you so much @ialex32x. d4490eb should close this issue!