Unity - 与客户端 Javascript 和 ajax 通信。如何将数据从unity传回网页?

sta*_*lew 9 javascript c# wordpress unity-game-engine

我真正要问的是这个;如果存在无法编译到统一构建中的依赖项,有没有办法仍然从统一内部调用它们并简单地使用从网站加载到浏览器中的脚本并与它们通信?

相关文档没有深入解决这个问题:https : //docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html

我正在为统一应用程序创建一个网站包装器。体验按钮位于网站内,因为按钮影响网站的其余部分,而不仅仅是统一应用程序。

然而,当在统一游戏中加载某些内容时,应用程序需要能够影响网站。有没有办法以创造性的方式将数据传回网站?目前,我将网站的所有 javascript 代码都包含在统一编译中,并且出现以下错误:

gameInstance = UnityLoader.instantiate("gameContainer", "/Build/DomumProto16_Web.json", {
    onProgress: UnityProgress
}); 
Run Code Online (Sandbox Code Playgroud)

从网站向游戏发送数据:

gameInstance.SendMessage('Manager','Filter', JSON.stringify(filterActive));
Run Code Online (Sandbox Code Playgroud)

需要从统一游戏中调用这个函数。但是,ajax.ajax_url 未定义,因为它在后端使用 wp_localize_script() 进行了本地化。

function showStudentWork(studentIndex){
        
    //make sure to remove all the 
    var x = document.getElementById("studentWork");

    var studentID = studentWork[studentIndex];
    console.log(studentID);
    
    $.ajax({
        url: ajax.ajax_url,
        type: "POST",
        data: {
            action: 'getStudentPost',
            currentStudent: studentID
        },
        success: function (data) {
            x.innerHTML = "";
            x.innerHTML = data;
            x.style.display = "grid";
        },
        error: function (error) {
            console.log(`Error ${error}`);
        }
    });
    
    return false;

}
Run Code Online (Sandbox Code Playgroud)

我真正要问的是这个;如果存在无法编译到统一构建中的依赖项,有没有办法仍然从统一内部调用它们并简单地使用从网站加载到浏览器中的脚本并与它们通信?

Car*_*son 6

这里有两种方法。一个是,在我看来,更容易,但它已被弃用,你不应该~使用它。选项二是“正确”的方式,但它有点丑陋。

选项 1:Application.ExternalCall

文档

此选项允许您直接调用浏览器 javascript,但 Unity 已弃用对它的支持,从长远来看可能是个坏主意。

在使用 Unity 网络播放器工作的给定浏览器中,请考虑以下事项: 在浏览器源代码中,定义一个 javascript 函数

<other html>
<script>
function foo(msg) {
    alert(msg);
}
</script>
Run Code Online (Sandbox Code Playgroud)

在 Unity 中,每当需要时:

Application.ExternalCall( "foo", "The game says hello!" );
Run Code Online (Sandbox Code Playgroud)

这允许从 Unity 调用 Javascript。相反方向的通信也有类似的功能。

选项 2:jslibs

文档

这是统一认可的做事方式。它涉及将 javascript 库打包到您的游戏中。

首先,创建一个将与您的游戏打包在一起的 javascript 文件。这是一个示例文件:

// Unity syntactic sugar
mergeInto(LibraryManager.library, {
    // Declare all your functions that can be called from c# here
    alert_user: function (msg) {
        window.alert(msg);
    },
    other_func: function () {
     // does something else
     // etc.
     // put as many functions as you'd like in here
    }
}
Run Code Online (Sandbox Code Playgroud)

将该文件和扩展名放在项目.jslibPlugins文件夹中。

然后,在您的 c# 文件中,您需要:

// Declare a monobehavior, whatever
using UnityEngine;
using System.Runtime.InteropServices;

public class NewBehaviourScript : MonoBehaviour {

    // IMPORTANT
    // You have to declare the javascript functions you'll be calling
    // as private external function in your c# file. Additionally,
    // They need a special function decorator [DllImport("__Internal")]
    // Example:
    [DllImport("__Internal")]
    private static extern void alert_user(string msg);

    // With that unpleasantness over with, you can now call the function
    void Start() {
        alert_user("Hello, I am a bad person and I deserve to write c#");
    }
}
Run Code Online (Sandbox Code Playgroud)

等中提琴。您可以从您的 c# javascript 调用其他 javascript,并与 dom 交互,但我会将所有这些决定留给您。

另一个方向

在这两种情况下,相反方向的通信(浏览器对 Unity 说些什么)是相同的格式。

在javascript中,创建一个UnityInstance(这种方式有点冗长,可以放入这个答案,检查任一文档)。那么,只要.sendMessage

例如:c#

...
void DoSomething (string msg) {
    // this is a c# function that does something in the game
    // use your imagination
}
...
Run Code Online (Sandbox Code Playgroud)

javascript:

let game = UnityLoader // Actually load the game here
game.SendMessage('TheNameOfMyGameObject', 'DoSomething', 'This is my message');
Run Code Online (Sandbox Code Playgroud)

  • 太感谢了。这正是我一直在寻找的。我现在正在用这个。这可以完美地工作,但已被弃用。有替代品吗? (2认同)