凹みTips

C++、JavaScript、Unity、ガジェット等の Tips について雑多に書いています。

Unity 5 x WebGL について詳しく調べてみた


f:id:hecomi:20141207233422p:plain


 Unity Advent Calendar 20148

Unity 5  Build  WebGL Unity 5 


Unity 2020.2b - Unity


 3/18  GDC2014  Unity 5  WebGL  4/78 Unite 2014  WebGL 


http://japan.unity3d.com/blog/press/unity5

http://japan.unity3d.com/unite/unite2014/schedule

Unity  Web 




 Unity  Web  Unity  ealy-access 5.x  WebGL 

 Unity x WebGL  JavaScript 



Mac OS X Yosemite 10.10.1

Unity 5.0b14

Firefox Developer Edition 35.0a2

Chrome 41.0.2224.3 dev

WebGL  Web 


Unity 


http://beta.unity3d.com/jonas/DT2/

Dead Trigger 24



Unity WebGL Player - AngryBots WebGL Demo

Unity-er  AngryBots



http://unity-chan.com/events/c86/WebGL/

GitHub - unity3d-jp/unitychan-crs: Unity-Chan "Candy Rock Star" Live Demo WebGL 



Unity WebGL Benchmarks






 WebGL  Node.js  Socket.IO  3D 


http://hecom.in/lab/webgl-chat/

WASD QE Space 

2





Chrome  Firefox 


Firefox Developer Edition



<: 2014/12/24>

GitHub 


GitHub - hecomi/Unity-WebGL-3D-Chat: Unity5 WebGL x Socket.IO = Online 3D Chat on the web browser!





On the future of Web publishing in Unity | Unity Blog

Benchmarking Unity performance in WebGL | Unity Blog


Unity  Web Unity 2 Web 

Unity 


 C/C++  Unity  Clang  LLVM-IR LLVM  LLVM-IR  JavaScript  Emscripten 使 Web 

f:id:hecomi:20141207235025p:plain
 C++  JavaScript  Emscripten Vim  gnuplot  Ruby  Perl Qt


Porting Examples and Demos · emscripten-core/emscripten Wiki · GitHub


Emscripten  JavaScript  asm.js  JavaScript = asm.js JITJust-In-Time JavaScript  a|0  int +a  double 


asm.js

asm.js performance improvements in the latest version of Firefox make games fly! - Mozilla Hacks - the Web developer blog


asm.js  Firefox Chrome  asm.js  JavaScript  Chrome 


 C#  UnityScript  C#  UnityScript  CILCommon Intermediate Language.NET Mono  CIL  JIT iPhone  AOTAhead-Of-TimeMono Windows  Mac  Linux 

f:id:hecomi:20141207234926p:plain
 C# / UnityScript  JavaScript Unity  IL2CPP  C# / UnityScript  CIL C++ 2


The future of scripting in Unity | Unity Blog

Unity5C#CUP - 


 WebGL  Clang / Emscripten  C++  JavaScript 


C# / UnityScript  Mono  CIL 

CIL  IL2CPP  C++ 

C++  Clang  LLVMIR

LLVMIR Emscripten  asm.js  JavaScript 

JavaScript  minify Fast / Fastest 


f:id:hecomi:20141208000232p:plain
Unite 2014 


Unity  Web 


IL2CPP  WebGL  C++  Mono  C++  iOS 64bit  IL2CPP 使


http://japan.unity3d.com/blog/ios-64-bit-support-in-unity


 C++  Facebook  HipHop  JIT 





Benchmarking Unity performance in WebGL | Unity Blog


f:id:hecomi:20141201180326p:plain
f:id:hecomi:20141201180336p:plain
 MacBook Pro Retina 13 Late 2013Core i7 2.8GHz Alienware 17Core i7 4910MQGTX 880M Chrome  2569489835 


asm.js  Firefox  Chrome / Safari 

GPU  WebGL 

 IL2CPP 

3D  SIMD 

3D  PhysX 3.3  SIMD 

2D  Box2D 




GPU CPU 使 asm.js  SIMD  JavaScript  SIMD  Emscripten  Web 


WebGL in Web Workers, Today - and Faster than Expected! - Mozilla Research

Introducing SIMD.js - Mozilla Hacks - the Web developer blog

[webkit-dev] SIMD support in JavaScript

Bringing SIMD to JavaScript | 01.org


 WebGL 


 Build Settings  Platform  WebGL (Preview) 

f:id:hecomi:20141201171853p:plain
C++ JSNative Compile to JS...

f:id:hecomi:20141201172157p:plain
<>.js JSjs Unity 便 Unity  .data  .mem 

Apache  nginx index.html 

f:id:hecomi:20141201173203p:plain
 CDN  FileSystem API AssetBundle gzip 

WebPlayer  WebPlayerTemplates  WebGL 

Optimization Level


Optimization Level 3

f:id:hecomi:20141201185530p:plain

Slow (fast builds)

Fast

Fastest (very slow builds)


 Slow Fastest  FastestFastSlow 


Edit > Project Settings > Player HTML5 

f:id:hecomi:20141206012223p:plain
 WebGL  Run In Background 



使Preview  Web 


On the future of Web publishing in Unity | Unity Blog





Runtime generation of Substance textures



http://docs-jp.unity3d.com/Documentation/Manual/ProceduralMaterials.html



MovieTextures

MovieTexture 



Networking other then WWW class (a WebSockets plug-in is available)

WWW 

...



Support for WebCam and Microphone access



getUserMedia 



Hardware cursor support





Most of the non-basic audio features







Script debugging



Chrome ...



Threads



WebWorker 使



Any .NET features requiring dynamic code generation

 .NET 

System.Reflection.Emit  CSharpCodeProvider 




 DLL  WebPlayer 

JavaScript  Unity 

Unity  JavaScript 


Unity Unite 2014 


You can just write a plugin directly in JavaScript and call functions from that from your C# scripts.

You can also just add C++ source files to your project, and call functions from them from your game scripts.

You can use Application.ExternalCallorApplication.ExternalEval, like you would do in the Web Player.



231


Unity - Scripting API: Application.ExternalCall

Unity - Scripting API: Application.ExternalEval


Application.ExternalCall() 1 JavaScript 2Application.ExternalEval()  JavaScript  eval() WebPlayer 使 WebGL 使
using UnityEngine;
using System.Collections;

public class ExternalCallTest : MonoBehaviour 
{
    void Update() 
    {
        if (Input.GetKeyDown(KeyCode.C)) {
            Application.ExternalCall("console.log", "hogehoge", 100, 123.456f);
        }
    
        if (Input.GetKeyDown(KeyCode.E)) {
            Application.ExternalEval("document.body.bgColor = '#000'");
        }
    }
}

C / E 

f:id:hecomi:20141202223814p:plain
eval() console.log() 

 jslib  [DllImport("__Internal")] attribute 


Question : WEBGL calling external js function - Unity Forum

JavaScript  Unity 


JavaScript  Unity WebPlayer  UnityObject2  SendMessage() 


http://docs.unity3d.com/Manual/UnityWebPlayerandbrowsercommunication.html

http://docs.unity3d.com/Manual/WorkingwithUnityObject.html


WebGL  SendMessage()  UnityConfig.js 使


 Browser to Unity WebGL communication - Unity Answers


 Unity 
using UnityEngine;
using System.Collections;

public class CubeGenerator : MonoBehaviour 
{
    public GameObject cube;

    void Generate()
    {
        var pos = Vector3.up * 10f + Random.onUnitSphere;
        Instantiate(cube, pos, Quaternion.identity);
    }
}

 GameObject  Main Camera  Prefab  cube JS
document.addEventListener("keydown", function() {
    SendMessage("Main Camera", "Generate");
});

SendMessage() 1 GameObject 23 Generate 

f:id:hecomi:20141202234424p:plain


 Unity 便 HTML5 使JS Unity  Web  Twitter WebSocket 

Application.ExternalCall()  SendMessage() Unity 2 WebPlayer  Unity  JavaScript Application.ExternalCall()  SendMessage() 便


Main Camera  Directional Light  Slow  132 MB JSData/PROJECT_NAME.js 110 MB Slow JS minify Fastest  minify  35 MB JS 23 MB  WebPlayer 




WebGL build size for empty scene is huge. Optimisation tips and tricks? - Unity Forum


 Data  Compressed 2 .htaccess  .htaccess 
Options +FollowSymLinks
RewriteEngine on

RewriteCond %{HTTP:Accept-encoding} gzip
RewriteRule (.*)Data(.*)\.js $1Compressed$2\.jsgz [L]
RewriteRule (.*)Data(.*)\.data $1Compressed$2\.datagz [L]
RewriteRule (.*)Data(.*)\.mem $1Compressed$2\.memgz [L]
RewriteRule (.*)Data(.*)\.unity3d $1Compressed$2\.unity3dgz [L]
AddEncoding gzip .jsgz
AddEncoding gzip .datagz
AddEncoding gzip .memgz
AddEncoding gzip .unity3dgz

 gzip  gzip 使


:  | Web Design Leaves


 gzip  Data  .js.data.mem.unity3d 

gzip  Mac & Apache  /private/etc/apache2/httpd.conf 2RewriteCond / RwriteRule  mod_rewrite 
# 以下のコメントを外す
LoadModule rewrite_module libexec/apache2/mod_rewrite.so

.htaccess 使 AllowOverride  All 
DocumentRoot "PATH_TO_YOUR_WWW_DIR"
<Directory "PATH_TO_YOUR_WWW_DIR">
    ...
    # AllowOverride None を All にする
    AllowOverride All 
    ...
</Directory>

 Content-Encoding  gzip 

f:id:hecomi:20141202015424p:plain
2304

f:id:hecomi:20141202015539p:plain
Data  Rwrite Slow  16.5 MB  1/8 Fastest  6.2 MB 

gzip  .htaccess Dropbox  Data  Compressed 


Node.js  Socket.IO Unity  WebGL  Application.ExternalCall  JavaScript  Socket.IO  SendMessage()  Unity  WebGL 




f:id:hecomi:20141206162527p:plain

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PlayerController : MonoBehaviour 
{
    public Text textUi;

    private Vector3 prePosition_;
    private Quaternion preRotation_;

    void Update() 
    {
        // ...(略: プレイヤーを動かす処理)

        EmitPosition();
        EmitRotation();
    }

    void EmitPosition()
    {
        // 位置が更新されていたらサーバに伝える
        var pos = transform.position;
        if (pos != prePosition_) {
            prePosition_ = pos;
            Application.ExternalCall("socket.emit", "move", pos.x, pos.y, pos.z); 
        }
    }

    void EmitRotation()
    {
        // 向きが更新されていたらサーバに伝える
        var rot = transform.rotation;
        if (rot != preRotation_) {
            preRotation_ = rot;
            Application.ExternalCall("socket.emit", "rotate", rot.x, rot.y, rot.z, rot.w); 
        }
    }

    void Talk(string message)
    {
        // メッセージを更新してサーバに伝える
        textUi.text = message;
        Application.ExternalCall("socket.emit", "talk", message); 
    }
}

socket.emit JavaScript  Socket.IO  socket 
var socket = io() || {};

Unity  socket socket.emit() 


Node.js 
var io = require('socket.io')(3000);

io.on('connection', function(socket) {
    var id = socket.id;

    socket.on('move', function(x, y, z) {
        socket.broadcast.emit('move', id, x, y, z);
    });

    socket.on('rotate', function(x, y, z, w) {
        socket.broadcast.emit('rotate', id, x, y, z, w);
    });

    socket.on('talk', function(message) {
        socket.broadcast.emit('talk', id, message);
    });

    socket.on('disconnect', function(message) {
        socket.broadcast.emit('destroy', id);
    });
});

 socket.id 使




f:id:hecomi:20141206162557p:plain
 Unity  socket 
var socket = io() || {};
socket.isReady = false; // <-- Awake() のタイミングで true になる

window.addEventListener('load', function() {
    var execInUnity = function(method) {
        // シーンがロードされるまでデータの同期はしない
        if (!socket.isReady) return;
        // "Network Player Manager" ゲームオブジェクトに SendMessage(method, args) する
        //  引数は1つしか取れないので , 区切りの文字列で引き渡す
        var args = Array.prototype.slice.call(arguments, 1);
        SendMessage('Network Player Manager', method, args.join(','));
    };

    socket.on('move', function(id, x, y, z) {
        execInUnity('Move', id, x, y, z);
    });

    socket.on('rotate', function(id, x, y, z ,w) {
        execInUnity('Rotate', id, x, y, z, w);
    });

    socket.on('talk', function(id, message) {
        execInUnity('Talk', id, message);
    });

    socket.on('destroy', function(id) {
        execInUnity('DestroyPlayer', id);
    });
});

 Unity  SendMessage() isReady 

 SendMessage() SendMessage / Network Player Manager  Unity  SendMessage()  Unity 
using UnityEngine;
using System.Collections.Generic;

public class NetworkPlayerManager : MonoBehaviour 
{
    public GameObject networkPlayerPrefab;

    private Dictionary<string, NetworkPlayerController> players_ = 
        new Dictionary<string, NetworkPlayerController>();
    static private readonly char[] Delimiter = new char[] {','};

    void Awake()
    {
        Application.ExternalEval("socket.isReady = true;");
    }

    void Move(string argsStr) 
    {
        var args = argsStr.Split(Delimiter);
        GetPlayer(args[0]).Move(new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])));
    }

    void Rotate(string argsStr) 
    {
        var args = argsStr.Split(Delimiter);
        GetPlayer(args[0]).Rotate(new Quaternion(
            float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]), float.Parse(args[4])));
    }

    void Talk(string argsStr)
    {
        var args = argsStr.Split(Delimiter);
        GetPlayer(args[0]).Talk(args[1]);
    }

    NetworkPlayerController GetPlayer(stringid)
    {
        return players_.ContainsKey(id) ? players_[id] : CreatePlayer(id);
    }

    NetworkPlayerController CreatePlayer(stringid)
    {
        var obj = Instantiate(networkPlayerPrefab) as GameObject;
        obj.name = id;
        var player = obj.GetComponent<NetworkPlayerController>();
        players_.Add(id, player);
        return player;
    }

    void DestroyPlayer(stringid)
    {
        var player = GetPlayer(id);
        player.Talk("[LOGOUT] Good by!");
        players_.Remove(id);
        Destroy(player.gameObject, 3f);
    }
}

 idid = 

 NetworkPlayerController  Prefab 
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class NetworkPlayerController : MonoBehaviour 
{
    public Text textUi;

    public void Move(Vector3 position) 
    {
        transform.position = position;
    }
    
    public void Rotate(Quaternion rotation) 
    {
        transform.rotation = rotation;
    }

    public void Talk(string message)
    {
        textUi.text = message;
    }
}

 Rigidbody 使 Is Kinematic Use Gravity 

 WebGL  Editor 

 WebGL 

Unreal Engine


 Unreal Engine3 Mozilla  WebGL 


Chrome 31Opera 18asm.jsWebGLUnreal Engine 3  Publickey

WebGL.com - Beauty at the intersection of Math, Code & Design


 Unreal Engine4 WebGL 


(Unreal Engine):WebGL

Demos of open web technologies | MDN


 HTML5 


(Unreal Engine):WebGL


Emscripten  asm.js JS Unreal Engine  Unity  Mono  C++ / Blueprint  Unity 

Esenthel Engine


Esenthel Engine  WebGL 


Esenthel EngineWebGLIE - Qiita


C++  JavaScript  Emscripten Emscripten  Wiki 


Porting Examples and Demos · emscripten-core/emscripten Wiki · GitHub

WebGL 2.0


 WebGL  OpenGL ES 2.0 WebGL 2.0  OpenGL ES 3.0  Unity 5.x  Unite 2014 


Unity  Web 

WebVR


Oculus Rift  Morpheus  Google CardboardGearVR  VR Chrome  Firefox  WebVR 


http://blog.bitops.com/blog/2014/06/26/first-steps-for-vr-on-the-web/

WebVR(VR使API) - Qiita

Oculus Rift3D - GIGAZINE


 WebGL 

Chrome  NPAPI  WebPlayer 


2015/1  Chrome  NPAPI  Google 


GoogleChromeNPAPI | TechCrunch Japan


Chrome  NPAPI  WebPlayer Firefox / Safari / IEChrome Unite 2014  NPAPI ... WebGL 


The future of Web publishing in Unity  an update | Unity Blog

.NET 


Microsoft  .NET 


.NET Core Framework.NET Core Distribution for Linux/OSXVisual Studio Community (1/2)CodeZine


 Unity 


A New Era for .NET: .NET Core 5 Open Source - Unity Forum

.NET Core is Open Source : Unity3D


 Microsoft  .NET 


The future of scripting in Unity | Unity Blog


使



Unite Japan 2014UnityWebGL - GAME Watch

MozillaWebGLWeb姿






 WebGL Three.js  Web  3D  Web 

 12/9 @kiruroboKinectMMD * KinectMMD