20191126のCSSに関する記事は9件です。

要素の表示非表示は visibility:hidden の方が display:none よりも高速

はじめに

ACCESS Advent Calendar 2019 の25日目最終日です。

初めまして、今年一番ハマったソシャゲはドラクエウォークの @naohikowatanabe です。

HTML 的要素の表示非表示の基本

一般的には HTML 的に要素の表示非表示を行う際、以下のように言われます。
・要素の非表示は display:none か visibility:hidden で実現出来る
・visibility:hidden は「見えない+要素自体は存在する」
・display:none は「見えない+要素自体無し」
・visibility:hidden の方が要素の削除が無いので高速

本記事ではどの程度速度に差があるのか、を見ていきます。
#組込ブラウザのお仕事をやっているとお客さんからこの質問が非常に多い。。
#なのでまとめてしまう。

測定

display:none と visibility:hidden の違い の HTML をベースに、
「display:none による表示非表示100万回」
「visibility:hidden による表示非表示100万回」
を行うようにコードを変更し、測定します。

html

<!doctype html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>difference between visibility hidden and display none</title>
    <link rel="stylesheet" href="css/style.css">
    <script>
    const loop_count = 1000000;

    function visibilityhidden () {
      const two = document.getElementById("two");
      const startTime = Date.now();
      for (i = 0; i < loop_count; i++) {
        two.style.visibility = "hidden";
        two.style.visibility = "visible";
      }
      const endTime = Date.now();
      console.log("visibility:hidden " + (endTime - startTime) + " [msec]");
    }

    function displaynone () {
      const three = document.getElementById("three");
      const startTime = Date.now();
      for (i = 0; i < loop_count; i++) {
        three.style.display = "none";
        three.style.display = "inline";
      }
      const endTime = Date.now();
      console.log("display:none " + (endTime - startTime) + " [msec]");
    }
    </script>
</head>
<body>
    <div id="one" class="box"></div>
    <div id="two" class="box">
        <h3>Visibility:hidden</h3>
        エレメント描画されず。けど、表示エリアは「残る」。背景色で塗りつぶした感じ。
    </div>
    <div id="three" class="box">
        <h3>display:none</h3>
        エレメントが表示エリアから消える。DOMとして存在はするけど描画されない。
    </div>
    <div id="four" class="box"></div>

    <button onclick="visibilityhidden()">visibility:hidden * 100万回</button>
    <button onclick="displaynone()">display:none * 100万回</button>
</body>
</html>

CSS

オリジナルから変えてません。

@charset "UTF-8";

.box{
  width:150px;
  height:150px;
  margin:10px;
  border-radius: 10px;        /* CSS3草案 */
  -webkit-border-radius: 10px;    /* Safari,Google Chrome用 */
  -moz-border-radius: 10px;   /* Firefox用 */
  float:left;
  padding:20px;
}

#one{

  background:#000;
}

#two{
  /*visibility:hidden;*/
  background:#9eccb3;
}

#three{
  background:#f47d44;
  /*display:none;*/
}

#four{
  background:#000;
  clear:right;
}

表示結果

Screenshot2019-11-26_1.png

測定結果

やり方 時間[msec]
display:none 100万回 1000
visibility:hidden 100万回 888

visibility:hidden の方が1割程度高速です。
PC 環境ではあまり気にならないですが、
組込環境ではマシンパワーが非力な場合が多いのでこういうところで少しずつ気を付けるのが良いですね。

Screenshot2019-11-26.png

まとめ

要素の表示非表示は visibility:hidden の方が display:none よりも1割程度高速。

参考

display:none と visibility:hidden の違い

終わりに

本記事で ACCESS Advent Calendar 2019 無事終了です。
ここまで見ていただいた皆様に感謝です。

それでは皆様、良いお年を!
来年もよろしくお願いします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

大きい画像をスマホで見たときに縮小する方法

趣味とポートフォリオを兼ねて自分が主催しているダンスイベントのサイトを作っています。

 

 

 

 

 

 

配置は基本的な構成なのですが、トップ画像で問題発生。

 

縦長のサイズのトップ画像が、PCサイズからスマホサイズに可変しない。

 

 

 

 

 

Googleで調べてみると

 

 

 

 

 

img{

width: 100%;

height: auto;

}

 

とあったんですが、これだとスマホサイズにはなるんですが、今度はPCサイズに可変しなくなりました。

 

 

 

 

 

色々と試行錯誤した結果

 

 

 

.main-view .top-img{
  width: 100%;
height: 0;
padding-top: 50%;
padding-bottom: 80%;
background-image: url("画像のファイル");
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
} 

 

 

これでスマホサイズにもPCサイズにも可変するようになりました。

 

 

 

ヘッダー下にdivタグを作成して、CSSにバックグラウンドとして画像を挿入。

 

パディングの余白を%で追加することで縦長のフライヤーも出現しました。

 

 

 

 

画像の出し方一つでも色々な要素が出てくるので、一つずつ理解していきたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 169日目

100日チャレンジの169日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

169日目は

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チュートリアル - 3D空間を使った簡単webサイト 5/5

前回

Publishして誰でも見れるように公開!

プロジェクトを作成してビルドまでやってくれるのもPlayCanvasのすごいところ。

ここまで作成したものをPlayCanvasの公開環境に公開してみましょう。

左のメニュー、またはシーンの左上のManage Scenesから以下のPublish画面を開きます。

スクリーンショット 2019-06-21 11.15.25.png

PUBLISH TO PLAYCANVASを選択して、一番下のPUBLISH NOWをクリックしてビルドは完了です。
URLでPC、スマホ、他ユーザーにもログインすることなく共有することができます。

スクリーンショット 2019-06-21 11.18.57.png

以上がチュートリアルの大枠となる説明でした。
おつかれさまでした。

以降はWebサイトとして追加したいものを説明するおまけです。


おまけ

SCENEの名前を変更する

sceneの名前もUntitledのままじゃカッコがつかないですね。
これはPlayCanvasの設定から変更ができます。

左上のPlayCanvasのロゴをクリックするとメニューが開きます。
その中のSettingsでインスペクター上にSETTINGSを開き、上のScene Nameから名前を変更できます。

スクリーンショット 2019-06-24 19.35.21.png


headerの処理

headerのhtmlも追加しているので、同じようにglobal変数を使って同じように実装していきます。

addhtml.jsのinitializeに以下に書き換えます。
さらに、headerのナビゲーションをクリックするためgnavClickのイベントの処理も追加します。
headerのナビゲーションではどのsceneを選択したのかを、data-scene属性を作成して参照します。

Addhtml.prototype.initialize = function() { // init

    globalPc.scene = 0; // どのシーンページを開いているか保管

    var htmlNameArr = []; // attributesのデータの名前を配列にします
    var arrIndex = Addhtml.attributes.index;
    for(var i = 0; i < Object.keys(arrIndex).length; i++){ // attributesのデータを取得してfor文で回す
        if(!Object.keys(arrIndex)[i].indexOf("scene")){ // 名前にhtmlが入っているデータをif文
            htmlNameArr.push(Object.keys(arrIndex)[i]); // htmlデータの名前だけ配列化する
        }
    }

    var head = document.getElementsByTagName("head")[0]; // headタグ取得
    var body = document.getElementsByTagName("body")[0]; // bodyタグ取得

    var wrapper = document.createElement("div"); // DOMを囲う要素を作成
    wrapper.className = "wrapper"; // クラス名指定
    body.appendChild(wrapper); // bodyタグの最後に要素を追加

    container = document.createElement("main"); // DOMを囲う要素を作成
    container.className = "container"; // クラス名指定
    wrapper.appendChild(container); // bodyタグの最後に要素を追加

    var style = document.createElement("style"); // cssのstyleタグ

    wrapper.insertAdjacentHTML("afterbegin", this.header.resource); // attrで追加したヘッダーを追加

    // ヘッダー内のgnaviを取得
    var gnavLists = document.querySelector(".gnav_lists"); 
    gnavLists.innerHTML = ""; // .gnav_lists内のhtmlを空っぽに
    var gnavItem = document.createElement("div"); // gnavの各リンクのdivを作成
    gnavItem.className = "gnav_item"; // gnavリンク要素のclass名を指定
    var gnavItemCl = []; // gnav_itemを整理する

    style.append(this.css._resources[0]);
    head.appendChild(style); // headの最後にstyleを追加

    for(var i = 0; i < htmlNameArr.length; i++){

        container.insertAdjacentHTML("beforeend", this[htmlNameArr[i]].resource); // アセットから取得したhtmlを追加

        // 今回はgnavのリンクの数とhtmlのアセットの数が同じなのでどう処理を行う。
        gnavItemCl[i] = gnavItem.cloneNode(true); // gnavItemのクローンを作成
        gnavItemCl[i].innerHTML = '<label for="menu"><span>' + htmlNameArr[i] + '</span></label>'; // innerHTMLを作成
        gnavItemCl[i].setAttribute("data-scene",i+1); // scene1,scene2,scene3を切り替えるため数値をdata-sceneに追加
        gnavLists.append(gnavItemCl[i]); // gnav_lists内に追加
        gnavItemCl[i].addEventListener("click", gnavClick, false); // gnav_item各々にイベントをセット
    }
};
function gnavClick(e){ // gnav_itemをクリックしたら発火
    if(globalPc.scene === 0)  {
        globalPc.scene = this.getAttribute("data-scene"); // クリックしたgnav_itemのdata-sceneを取得
    }
}

ホバーとクリックのアクションを追加

クリックでhtmlにイベントを取得させましたが、アニメーションを追加します。
ホバーすればscaleが少し大きくなり、クリックすればワイヤーフレームになるといった感じです。
このアクションではもっと色んな広がりを見せることができます。
PlayCanvasではアニメーションを作れるTweenライブラリが公開されていますのでご参照ください。
https://developer.playcanvas.com/en/tutorials/tweening/

hotspot.jsを以下にまるっと書き換えます。

var Hotspot = pc.createScript('hotspot');

// canvasのclickやhoverなどの処理を行う

Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのentityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // entityのヒットエリアの範囲を指定

Hotspot.prototype.initialize = function() { // init
    this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
    this.ray = new pc.Ray(); // cameraからentityへ直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)

    this.directionToCamera = new pc.Vec3(); // Vector座標の型を取得

    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時

    this.localScale = this.entity.getLocalScale().clone(); // 初期のscaleを保持
    this.hoverScale = this.localScale.clone().scale(1.2); // ホバー時のentityのscaleを保持

};

Hotspot.prototype.update = function(dt) { // update
    this.cameraPosition = this.cameraEntity.getPosition(); // cameraのポジション(座標)を取得
    this.directionToCamera.sub2(this.cameraPosition, this.entity.getPosition()); // 2つの3次元ベクトルの値を互いに減算
    this.directionToCamera.normalize(); // 3次元ベクトルを単位ベクトルに変換

    if(globalPc.scene === 0){ // sceneが選択されていない場合
        for (var i = 0; i < this.entity.model.meshInstances.length; i++) {
            this.entity.model.meshInstances[i].renderStyle = pc.RENDERSTYLE_SOLID; // レンダラーのスタイルをソリッドに変更
        }
    }
    if(this.entity.tags._list[0].replace(/[^0-9]/g, '') === globalPc.scene) { // gnav_itemから選択されたsceneを参照
        this.entity.model._model.generateWireframe(); // モデルのワイヤーフレームを準備
        for (var j = 0; j < this.entity.model.meshInstances.length; j++) { // モデルのメッシュを取得
            this.entity.model.meshInstances[j].renderStyle = pc.RENDERSTYLE_WIREFRAME; // ワイヤーフレームにレンダリング
        }
    }
};

Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) {
        globalPc.scene = this.entity.tags._list[0].replace(/[^0-9]/g, ''); // entityで設定したタグを取得し、s1、s2...の数字以外をreplaceで削除し数字のみ代入
        this.entity.model._model.generateWireframe(); // モデルのワイヤーフレームを準備
        for (var i = 0; i < this.entity.model.meshInstances.length; i++) { // モデルのメッシュを取得
            this.entity.model.meshInstances[i].renderStyle = pc.RENDERSTYLE_WIREFRAME; // ワイヤーフレームにレンダリング
        }
    }
};

Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
    this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
    this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換

    if (this.hitArea.intersectsRay(this.ray) && globalPc.scene === 0) { // sceneが選択されていなくて、ヒットエリアとレイが交差した場合
        this.entity.setLocalScale(this.hoverScale); // entityのスケールを大きく
    }else{
        this.entity.setLocalScale(this.localScale); // entityのスケールを小さく
    }
};

Hotspot.prototype.onMouseDown = function(event) { // クリックが押されている時
    if (event.button == pc.MOUSEBUTTON_LEFT) { // 左クリックが押された時
        this.doRayCast(event); // レイキャストを呼ぶ
    }
};

さらにおまけで、マウスのクリックボタンの判定を以下のように取っていましたが、

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

以下のようにもっと簡単に左・中・右クリックのbooleanを取ることもできます。

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.buttons[0]) {} // 左クリック
    if (event.buttons[1]) {} // 中クリック
    if (event.buttons[2]) {} // 右クリック
};

3Dオブジェクトのモデルを変えたい!

PlayCanvasにはAssets Storeなるものがあり、ここから指定のプロジェクトのAssetsライブラリにアセットを追加することができます。
http://store.playcanvas.com/

スクリーンショット 2019-06-21 10.53.49.png

アセットを選択し、Downloadをするとログインしているアカウントが所有しているプロジェクトの一覧が表示されますので、指定のプロジェクトを選択することでアセットが使用できます。

スクリーンショット 2019-06-21 10.56.58.png

スクリーンショット 2019-06-21 10.59.01.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チュートリアル - 3D空間を使った簡単webサイト 4/5

前回

3Dオブジェクトに応じたHTMLのページを表示させる

マウスからイベントが取得できたので、クリックしたらHTMLを表示するようにします。

予めAssetsにmarkupというディレクトリ内に使用されるhtmlとcssのサンプルがあります。
事前にサンプルを用意していますが、作る際には自分のローカルで作成する必要があるのでご注意ください。

今回は3つの3Dオブジェクトと3つのhtmlを関係を持たせて、
「3Dオブジェクトがクリックされたら、それにリンクするhtmlが表示される」 までを作ります。

ここで使用するscriptはaddhtml.jsですが、これもまたEntityにADD SCRIPTする必要があります。
使用するaddhtml.jsは特定のEntityにADD SCRIPTする必要はありません。
今回はcharaというグループのEntityにADD SCRIPTします。

スクリーンショット 2019-07-10 20.13.04.png

addhtml.jsをADD SCRIPTしたら、コードエディターを開きます。

以下のコードを追加します。

Addhtml.attributes.add("css", {type: 'asset', assetType:'css', title: 'CSS Style'}); // アセットのcss読み込み
Addhtml.attributes.add("header", {type: 'asset', assetType:'html', title: 'HTML Header'}); // アセットのhtmlのheader読み込み
Addhtml.attributes.add("scene1", {type: 'asset', assetType:'html', title: 'HTML Scene1'}); // アセットのhtmlのscene1読み込み
Addhtml.attributes.add("scene2", {type: 'asset', assetType:'html', title: 'HTML Scene2'}); // アセットのhtmlのscene2読み込み
Addhtml.attributes.add("scene3", {type: 'asset', assetType:'html', title: 'HTML Scene3'}); // アセットのhtmlのscene3読み込み

早速、markupディレクトリのファイルを登録していきます。

下のアセットからmarkupというディレクトリに登録するファイルがあります。

スクリーンショット 2019-07-10 20.16.05.png

スクリーンショット 2019-07-31 12.19.50.png

htmlとcssを登録していきます。

登録したコードを追加するために

とのエレメントを取得する必要があります。
なぜ取得するのかというと、取得したheadやbodyに対して、appendChild()やinnerHTML、insertAdjacentHTML()などでhtmlを追加するからです。

以下のコードを追加していきます。

var container;

Addhtml.prototype.initialize = function() { // init
    var htmlNameArr = []; // attributesのデータの名前を配列にします
    var arrIndex = Addhtml.attributes.index;
    for(var i = 0; i < Object.keys(arrIndex).length; i++){ // attributesのデータを取得してfor文で回す
        if(!Object.keys(arrIndex)[i].indexOf("scene")){ // 名前にhtmlが入っているデータをif文
            htmlNameArr.push(Object.keys(arrIndex)[i]); // htmlデータの名前だけ配列化する
        }
    }

    var head = document.getElementsByTagName("head")[0]; // headタグ取得
    var body = document.getElementsByTagName("body")[0]; // bodyタグ取得

    var wrapper = document.createElement("div"); // DOMを囲う要素を作成
    wrapper.className = "wrapper"; // クラス名指定
    body.appendChild(wrapper); // bodyタグの最後に要素を追加

    container = document.createElement("main"); // DOMを囲う要素を作成
    container.className = "container"; // クラス名指定
    wrapper.appendChild(container); // bodyタグの最後に要素を追加

        var style = document.createElement("style"); // cssのstyleタグ

    wrapper.insertAdjacentHTML("afterbegin", this.header.resource); // attrで追加したヘッダーを追加

    style.append(this.css._resources[0]);
    head.appendChild(style); // headの最後にstyleを追加

    for(var i = 0; i < htmlNameArr.length; i++){ // htmlのアセットを配列管理するためにfor文でattrの名前の配列を回す

        container.insertAdjacentHTML("beforeend", this[htmlNameArr[i]].resource); // アセットから取得したhtmlを追加

    }
};

これでhtmlとcssの情報を追加できました。
headの中にcssのスタイルが入り()、bodyの中にhtmlの要素が入っています。

スクリーンショット 2019-06-20 18.05.48.png

次にオブジェクトをクリックしたらそれに連動したhtmlを表示するやり方です。

attributesで登録したhtmlでscene1、scene2、scene3とありました。
この数字を3Dオブジェクトとの関係性に使います。

Editorから3DオブジェクトのModelを選択し、インスペクターからTagsを登録します。
tagの名前は任意のもので大丈夫です。数字をそれぞれに入れるのを忘れないように。

スクリーンショット 2019-06-20 18.11.03.png

登録したtagをクリックした時に取得できるか確認します。
hotspot.jsのdoRayCastでtagを確認します。

Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("click!! : ",this.entity.tags._list[0]);
    }
};

クリックした3Dオブジェクトから各々のtagが取得できたと思います。
これを使ってhtmlとリンクさせます。

addhtml.jsに以下を追加します。

globalPc = {}; // グローバルな変数(オブジェクト)

Addhtml.prototype.update = function(dt) { // update
    if(Number(globalPc.scene) > 0) { // いずれかのsceneが選択されている場合
        if(!container.classList.contains("is-open")){ // 追加したアセットのhtmlにis-openのclassが追加されていない場合(どのhtmlも表示されていない)
            container.classList.add("is-open"); // is-openのclass名をcontainerに追加
            var sectionElements = document.getElementsByClassName("section"); // sectionを取得
            for(var i = 0; i < sectionElements.length; i++){ // sectionをループ処理
                if(sectionElements[i].classList.contains("is-current")){ // sectionにis-currentのclass名を持つかif処理
                    sectionElements[i].classList.remove("is-current"); // is-currentを削除
                }
            }
            sectionElements[globalPc.scene-1].classList.add("is-current"); // 選択されたsceneにis-currentのclass名を追加
            document.getElementsByClassName("section_close")[globalPc.scene-1].addEventListener("click", btnClose, false); // 選択されたsceneの閉じるボタンにイベントをセット
        }
    }

};

function btnClose(e){ // 閉じるボタンが押されたら発火
    e.preventDefault();
    globalPc.scene = 0; // 閉じるボタンなので選択されたsceneはnullにするので、0を代入
    container.classList.remove("is-open"); // containerのis-openのclass名を削除
    var sectionElements = document.getElementsByClassName("section"); // sectionを取得
    for(var i = 0; i < sectionElements.length; i++){ // sectionをループ処理
        if(sectionElements[i].classList.contains("is-current")){ // sectionにis-currentのclass名を持つかif処理
            sectionElements[i].classList.remove("is-current"); // is-currentを削除
        }
    }
}

リンクさせる方法として、global変数のglobalPcで今開いているページを管理できるようにします。

initializeには以下を追加します。

globalPc.scene = 0; // どのシーンページを開いているか保管

先ほど確認したhotspot.jsのdoRayCastでもglobal変数に数字を与えます。
数字のみを代入するようにします。

Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        globalPc.scene = this.entity.tags._list[0].replace(/[^0-9]/g, ''); // entityで設定したタグを取得し、scene1、scene2...の数字以外をreplaceで削除し数字のみ代入
    }
};

Launch画面でリロードして3Dオブジェクトをクリックすると、それぞれ該当したhtmlが表示されるようになります。

これで簡単なwebの大枠はできました。

[ hotspot.jsのコード ]

var Hotspot = pc.createScript('hotspot');

// canvasのclickやhoverなどの処理を行う

Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのentityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // entityのヒットエリアの範囲を指定

Hotspot.prototype.initialize = function() { // init
    this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
    this.ray = new pc.Ray(); // cameraからentityへ直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)

    this.directionToCamera = new pc.Vec3(); // Vector座標の型を取得

    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
};


Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        globalPc.scene = this.entity.tags._list[0].replace(/[^0-9]/g, ''); // entityで設定したタグを取得し、s1、s2...の数字以外をreplaceで削除し数字のみ代入
    }
};


Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
    this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
    this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換

    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("hover");
    }
};

Hotspot.prototype.onMouseDown = function(event) { // クリックが押されている時
    if (event.button == pc.MOUSEBUTTON_LEFT) { // 左クリックが押された時
        this.doRayCast(event); // レイキャストを呼ぶ
    }
};

[ addhtml.js のコード ]

var Addhtml = pc.createScript('addhtml');

// htmlを追加などする処理を記入

Addhtml.attributes.add("css", {type: 'asset', assetType:'css', title: 'CSS Style'}); // アセットのcss読み込み
Addhtml.attributes.add("header", {type: 'asset', assetType:'html', title: 'HTML Header'}); // アセットのhtmlのheader読み込み
Addhtml.attributes.add("scene1", {type: 'asset', assetType:'html', title: 'HTML Scene1'}); // アセットのhtmlのscene1読み込み
Addhtml.attributes.add("scene2", {type: 'asset', assetType:'html', title: 'HTML Scene2'}); // アセットのhtmlのscene2読み込み
Addhtml.attributes.add("scene3", {type: 'asset', assetType:'html', title: 'HTML Scene3'}); // アセットのhtmlのscene3読み込み

globalPc = {}; // グローバルな変数(オブジェクト)
var container;

Addhtml.prototype.initialize = function() { // init
    globalPc.scene = 0; // どのシーンページを開いているか保管

    var htmlNameArr = []; // attributesのデータの名前を配列にします
    var arrIndex = Addhtml.attributes.index;
    for(var i = 0; i < Object.keys(arrIndex).length; i++){ // attributesのデータを取得してfor文で回す
        if(!Object.keys(arrIndex)[i].indexOf("scene")){ // 名前にhtmlが入っているデータをif文
            htmlNameArr.push(Object.keys(arrIndex)[i]); // htmlデータの名前だけ配列化する
        }
    }

    var head = document.getElementsByTagName("head")[0]; // headタグ取得
    var body = document.getElementsByTagName("body")[0]; // bodyタグ取得

    var wrapper = document.createElement("div"); // DOMを囲う要素を作成
    wrapper.className = "wrapper"; // クラス名指定
    body.appendChild(wrapper); // bodyタグの最後に要素を追加

    container = document.createElement("main"); // DOMを囲う要素を作成
    container.className = "container"; // クラス名指定
    wrapper.appendChild(container); // bodyタグの最後に要素を追加

    var style = document.createElement("style"); // cssのstyleタグ

    wrapper.insertAdjacentHTML("afterbegin", this.header.resource); // attrで追加したヘッダーを追加

    style.append(this.css._resources[0]);
    head.appendChild(style); // headの最後にstyleを追加

    for(var i = 0; i < htmlNameArr.length; i++){ // htmlのアセットを配列管理するためにfor文でattrの名前の配列を回す

        container.insertAdjacentHTML("beforeend", this[htmlNameArr[i]].resource); // アセットから取得したhtmlを追加

    }
};

Addhtml.prototype.update = function(dt) { // update
    if(Number(globalPc.scene) > 0) { // いずれかのsceneが選択されている場合
        if(!container.classList.contains("is-open")){ // 追加したアセットのhtmlにis-openのclassが追加されていない場合(どのhtmlも表示されていない)
            container.classList.add("is-open"); // is-openのclass名をcontainerに追加
            var sectionElements = document.getElementsByClassName("section"); // sectionを取得
            for(var i = 0; i < sectionElements.length; i++){ // sectionをループ処理
                if(sectionElements[i].classList.contains("is-current")){ // sectionにis-currentのclass名を持つかif処理
                    sectionElements[i].classList.remove("is-current"); // is-currentを削除
                }
            }
            sectionElements[globalPc.scene-1].classList.add("is-current"); // 選択されたsceneにis-currentのclass名を追加
            document.getElementsByClassName("section_close")[globalPc.scene-1].addEventListener("click", btnClose, false); // 選択されたsceneの閉じるボタンにイベントをセット
        }
    }

};

function btnClose(e){ // 閉じるボタンが押されたら発火
    e.preventDefault();
    globalPc.scene = 0; // 閉じるボタンなので選択されたsceneはnullにするので、0を代入
    container.classList.remove("is-open"); // containerのis-openのclass名を削除
    var sectionElements = document.getElementsByClassName("section"); // sectionを取得
    for(var i = 0; i < sectionElements.length; i++){ // sectionをループ処理
        if(sectionElements[i].classList.contains("is-current")){ // sectionにis-currentのclass名を持つかif処理
            sectionElements[i].classList.remove("is-current"); // is-currentを削除
        }
    }
}

次はここまで作成したSceneをPublishして公開します。

次回

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チュートリアル - 3D空間を使った簡単webサイト 3/5

前回

3Dオブジェクトでマウスのイベントを起こす

3Dオブジェクトとマウスカーソルとの関係性を作ります。

ヒエラルキーからchara->Modelを選択。
ADD COMPONENTからScriptを選択し、hotspotのscriptを登録します。
このModelを一つずつ選択する動作は面倒ですが、複数選択して設定を行うこともできます。

スクリーンショット 2019-07-31 12.05.20.png

hotspotの中身をコードエディターで開きます。

配置された3Dオブジェクトとマウスカーソルとの関係を持たせるにはレイキャストと呼ばれるものを使用します。
レイキャストとは、特定の地点から特定の方向へ直線の線を引き、その線上のどこかでぶつかるものがあるか検知するものです。
ここでのレイキャストは、「マウスがクリックされた時、カメラから見て、3Dオブジェクトとそのマウスカーソルが重なっているか」を取得するような処理を作ります。

ここから以下の処理を追加していきます

  • 3Dオブジェクトにレイキャストの線が当たるヒットエリアを作成
  • 使用するカメラのEntityとヒットエリアの大きさをAttributesでEditorから設定
  • ヒットエリアにマウスホバーしてイベントが取れる

以下のコードをhotspot.jsに書き換えます。

var Hotspot = pc.createScript('hotspot');

Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのEntityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // Entityのヒットエリアの範囲を指定

Hotspot.prototype.initialize = function() { // init
    this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
    this.ray = new pc.Ray(); // cameraからentityへ直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)

    this.directionToCamera = new pc.Vec3(); // Vector座標の型を取得

    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時

};

Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
    this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
    this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換

    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("hover");
    }
};

新しくattributesというのが言葉がありますが、これは属性設定ができ、PlayCanvasのEditorからデータを変更することができるようになります。
ここではカメラのEntityの選択と、対象の3Dオブジェクトのヒットエリアの大きさを指定できます。

Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのEntityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // Entityのヒットエリアの範囲を指定

以下画像のように入力エリアが表示されていない場合は、Editアイコン横のParseで更新され表示されます。

スクリーンショット 2019-06-20 12.00.58.png

initializeではヒットエリア、レイキャストのRayの設定、マウス移動のイベントを取得しています。

Hotspot.prototype.initialize = function() {
    this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
    this.ray = new pc.Ray(); // 直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)

    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時
};

マウス移動のイベントで3Dオブジェクトとカメラから見てホバーしているかonMouseHoverで取得しています。

Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
    this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
    this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換

    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("hover");
    }
};

マウス移動のイベントで3Dオブジェクトとカメラから見てホバーしているかonMouseHoverで取得しています。

これでマウスオーバー(ホバー)のイベントを取得できました。
次はクリックのイベントです。

initializeに以下を追加

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時

クリックイベントの左クリックを取得

Hotspot.prototype.onMouseDown = function(event) { // クリックが押されている時
    if (event.button == pc.MOUSEBUTTON_LEFT) { // 左クリックが押された時
        this.doRayCast(event); // レイキャストを呼ぶ
    }
};

クリックしたらレイキャストを走らせる

Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("click!!");
    }
};

Launch画面をリロードしてコンソールから確認ができます。

ここまでのコードは以下になります。(hotspot.js)

var Hotspot = pc.createScript('hotspot');

// canvasのclickやhoverなどの処理を行う

Hotspot.attributes.add("cameraEntity", {type: "entity", title: "Camera Entity"}); // カメラのentityを取得
Hotspot.attributes.add("radius", {type: "number", title: "Radius"}); // entityのヒットエリアの範囲を指定

Hotspot.prototype.initialize = function() { // init
    this.hitArea = new pc.BoundingSphere(this.entity.getPosition(), this.radius); // ヒットエリアを作成。BoundingSphereがentityの境界エリアを作成(Photoshopでいうバウンディングボックス的な)
    this.ray = new pc.Ray(); // cameraからentityへ直進する線のデータを作成。(Rayは光線の意でstart pointからentityまでの距離を測ったりすることが可能)

    this.directionToCamera = new pc.Vec3(); // Vector座標の型を取得

    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseHover, this); // マウスカーソルがホバーした時
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
};


Hotspot.prototype.doRayCast = function (screenPosition) { // レイキャスト処理(ある地点から特定方向に直線で線を引いて、その線上で物体があるか検知する処理)
    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("click!!");
    }
};


Hotspot.prototype.onMouseHover = function(screenPosition) { // マウスホバー時
    this.cameraEntity.camera.screenToWorld(screenPosition.x, screenPosition.y, this.cameraEntity.camera.farClip, this.ray.direction); // ポジションを2Dスクリーンから3D空間へ変換
    this.ray.origin.copy(this.cameraEntity.getPosition()); // レイのオリジナルのポジションにカメラのポジションをコピー
    this.ray.direction.sub(this.ray.origin).normalize(); // 3次元ベクトルを他の場所から減算し、単位ベクトルに変換

    if (this.hitArea.intersectsRay(this.ray)) { // ヒットエリアとレイが交差した場合
        console.log("hover");
    }
};

Hotspot.prototype.onMouseDown = function(event) { // クリックが押されている時
    if (event.button == pc.MOUSEBUTTON_LEFT) { // 左クリックが押された時
        this.doRayCast(event); // レイキャストを呼ぶ
    }
};

次は3Dオブジェクトに応じてHTMLのページを表示させるようにします。

次回

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チュートリアル - 3D空間を使った簡単webサイト 2/5

前回

カメラを移動させる

まずはドラッグして3D空間を移動させます。

事前に用意している scripts ディレクトリ内の cameraMove.js を開きます。

ファイル内のコードはファイル作成時にデフォルトで書かれているもので、上から以下になります。

  • initialize : 初回読み込み
  • update : 毎フレームごと
  • swap : scriptファイル更新時(hot reloading)

マウスイベントを取得

PlayCanvasにはエンジンのRootのネームスペースがあります。
https://developer.playcanvas.com/en/api/pc.html

pc.MOUSEBUTTON_LEFTなどからイベントを取得し判別することができます。
以下のコードを追加します。

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) {} // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
  console.log(event);
};

上記で追加した関数を使いたいので、initializeでイベントを取得できるようにします。

this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時

ここのon()はjQueryのon()と同じようなもので、イベント処理を行い、関数を呼び出します。

このままではこのscriptは呼び出されません。対象となるEntityに登録する必要があります。
ヒエラルキーからCameraを選択し、インスペクターのADD COMPONENTからScriptを選択。

スクリーンショット 2019-06-19 15.37.45.png

SCRIPTSの設定のADD SCRIPTからcameraMoveを選択します。
cameraMoveが設定されたらOKです。
ちなみに、名前の横のEditをクリックするとコードエディターを開きます。
そのさらに横のParseをクリックすると設定した scriptを再読み込みします。

スクリーンショット 2019-06-19 15.41.26.png

Lauch画面をリロードしConsoleを確認するとonMouseMoveのconsole.logがマウスが動くたびに呼び出されています。

これをクリックしている間だけに変更し、ドラッグしたら呼び出すようにします。
initializeにクリックしているか判定するフラッグを用意します。

this.f_click = false;

これに合わせて、onMouseDownとonMouseUpに適当なものを追加します。
追加すると以下のようなコードになると思います。

var CameraMove = pc.createScript('cameraMove');

// カメラ移動などの処理

CameraMove.prototype.initialize = function() {
    this.f_click = false;

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
    this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時
};

CameraMove.prototype.update = function(dt) {};

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = true; } // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = false; } // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
  if(this.f_click){
    console.log(event);
  }
};

これでクリックしドラッグした時だけconsole.logが呼ばれるようになりました。
ここで呼ばれているデータからカメラも移動するようにします。

initializeで以下を設定。
カメラのEntityの情報を取得しています。ここではカメラのPositionを取得します。
https://developer.playcanvas.com/en/api/pc.Entity.html

    this.cameraEntity = this.entity; // このjsを受けているEntityを取得(カメラであることを前提に)
    this.pos = this.cameraEntity.getPosition(); // カメラの座標を取得 

onMouseMoveの中身を以下に差し替えます。
クリックされていない場合はreturnするように変更。
eventからベクトル量を取得します。取得したベクトル量からカメラのポジションを再設定します。

    if(!this.f_click) return; // クリックが押されている時
    var posDX = event.dx/500; // x座標の変化量
    var posDY = event.dy/500; // y座標の変化量

    var posX = this.pos.x - posDX; // ドラッグ量からカメラの座標を計算
    var posZ = this.pos.z - posDY; // ドラッグ量からカメラの座標を計算

    this.cameraEntity.setPosition(posX,this.pos.y,posZ); // カメラの座標をセット

これでカメラの移動ができるようになりました。

最終的にコードは以下のようになります。

var CameraMove = pc.createScript('cameraMove');

// カメラ移動などの処理

CameraMove.prototype.initialize = function() {
    this.f_click = false;

    this.cameraEntity = this.entity; // このjsを受けているEntityを取得(カメラであることを前提に)
    this.pos = this.cameraEntity.getPosition(); // カメラの座標を取得 

    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this); // クリックが押された時
    this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // クリックを押している状態から離れる時
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスカーソルが動いている時
};

CameraMove.prototype.update = function(dt) {};

CameraMove.prototype.onMouseDown = function (event) { // クリックダウンしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = true; } // 左クリックのとき
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseUp = function (event) { // クリックアップしたら
    if (event.button === pc.MOUSEBUTTON_LEFT) { this.f_click = false; } // 左クリック
    if (event.button === pc.MOUSEBUTTON_MIDDLE) {} // 中クリック
    if (event.button === pc.MOUSEBUTTON_RIGHT) {} // 右クリック
};

CameraMove.prototype.onMouseMove = function (event) { // マウスカーソルが動いたら
    if(!this.f_click) return; // クリックが押されている時
    var posDX = event.dx/500; // deltaX
    var posDY = event.dy/500; // deltaY

    var posX = this.pos.x - posDX; // ドラッグ量からカメラの座標を計算
    var posZ = this.pos.z - posDY; // ドラッグ量からカメラの座標を計算

    this.cameraEntity.setPosition(posX,this.pos.y,posZ); // カメラの座標をセット
};

次は3Dオブジェクトをクリックしてイベントを取得する処理です。

次回

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チュートリアル - 3D空間を使った簡単webサイト 1/5

※このチュートリアルはPlayCanvas運営事務局で使用しているハンズオンの資料です。

PlayCanvasでWebサイトを作る

ゲームエンジンでwebサイトを作る?

PlayCanvasはWebGL/HTML5ゲームエンジンであり、ゲームだけでなくwebへの展開もできます。
そこでPlayCanvasを使ってどんなwebサイトが作れるのか、実際に作っていきたいと思います。

このチュートリアルでは、PlayCanvasを使って3D空間のコンテンツを作成し、その上にhtmlの要素を配置して、LPページ(ランディングページ)やキャンペーンサイトのようなwebサイトを作成していきたいと思います。

できるページは以下のようなページができます。
https://playcanv.as/p/uQN2hNcm/

3Dオブジェクトをクリックするとそれに応じたhtmlが表示されるサイト。
ドラッグするとカメラの位置も変わり、3Dオブジェクトを好きな位置に配置して探す、といったこともできます。

今回は上記のものを作成するべく、チュートリアルを始めましょう。


Projectをforkする

チュートリアル用に準備したProjectがあるので、こちらをforkしてチュートリアルを始めます。

以下のProjectからforkします。
https://playcanvas.com/project/623766/

スクリーンショット 2019-06-17 17.50.27.png

forkしたProjectのページに飛ぶので、forkしたプロジェクトのEDITORボタンからエディット画面に飛びます。

スクリーンショット 2019-06-17 18.00.17.png

エディット画面のGUIの説明

まずSCENESの画面からeditするsceneを選びます。
Untitledしかないのでこちらを選択。(新規にプロジェクトを作る際もUntitledのsceneがあります)

スクリーンショット 2019-06-17 18.03.12.png

Untitledをクリックすると以下の画面になります。

スクリーンショット 2019-06-17 18.14.26.png

上の画像を基に、GUIを簡単に説明していきます。

  • メニュー(MENU)
    Photoshopなどでいうツールバーとメニューバーが合わさっている感じ。
    プロジェクトの設定やシーンの設定などもここで操作できます。
  • ヒエラルキー(HIERARCHY)
    シーン内に存在するオブジェクトの一覧が表示されます。
    このシーンではどんなentityが使われているのかなどここで管理。
    まとめてグループ化や名前の変更などもできる。
  • シーン(SCENE)
    3D空間が表示され、自由な位置・角度から眺めることができます。
    3DコンテンツやカメラのPositionやRotateなどを弄ることができます。
  • アセット(ASSETS)
    プロジェクトhtmlやcss、imgといったファイルや3Dモデルのデータなどもここで表示され、ここに入れて使われるデータたちは合わせてアセットと呼ばれています。
    ディレクトリで分けたり名前を変更することもできます。各ファイルはアップロード時にIDが付与され管理されるため、同じ名前のファイル名をアップロードしても上書きアップロードにはならないことがあるので注意。
  • インスペクター(INSPECTOR)
    ヒエラルキーやシーンで選択中のオブジェクトの設定を編集できます。
    3Dモデルのメッシュや衝突判定、物理制御に関するパラメータもここで定義することが可能。

コードエディター

基本的なGUIはこの5つで、他にコードエディターがあります。

コードエディターはメニューの下の方にあります。

スクリーンショット 2019-06-17 18.34.30.png

スクリーンショット 2019-06-17 18.33.35.png

コードエディターは普段使用されているであろうエディターと基本同じです。

JavaScriptのsnippetやコードのhighlightなども基本付いています。

基本ここでコードを書いて反映していきます。

Lauch実行

右上の再生ボタン的な矢印のボタンをクリックすると、Launch実行されます。

スクリーンショット 2019-06-19 13.35.05.png

Sceneの現状をLaunch実行してくれるため、開発しながら確認ができます。

Launch画面を開いたままにしておくと、Editor画面とライブリンクが持続した状態になり、Editor画面でPositionmの数値などを変更するとリアルタイムでLaunch画面でもプレビューされます。

スクリーンショット 2019-06-19 13.41.03.png

プロジェクトを確認できたところで、次はカメラ移動の処理をつけていきます。

次回

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cssメモ

チートシート

//スクロールしてもついてくる要素の設定
position: -webkit-sticky;
position: sticky;

//要素寄せ
//左
float: left;
//右
float: right;
//クリア
clear: both;

//要素の重なりの優先順位をつける
//優先順位1の場合
z-index: 1;

//アイコンの円形化
border-radius: 50%;

//text中央寄せ
text-align: center;

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む