Needle Engine ドキュメント
Downloads
  • What is Needle Engine?
  • お客様の声
  • Get an overview

    • Samples and Showcase
    • 私たちのビジョン 🔮
    • 機能概要
    • 技術概要
  • Resources

    • Pricing and Plans
    • Changelog
    • API Documentation
    • Support & Community
  • Integrations

    • Unity用Needle Engine
    • Blender 用 Needle Engine
    • Web ComponentとしてのNeedle Engine
    • ウェブサイトでのNeedle Engine
    • Needle Cloud
  • Topics

    • Webプロジェクトの構造
    • Everywhere Actions
    • glTFへのアセットのエクスポート
    • フレームワーク、バンドラー、HTML
    • ローカルデバイスでのテスト
    • デプロイと最適化
  • Advanced

    • ネットワーキング
    • VR & AR (WebXR)
    • HTMLからNeedle Engineを直接使用する
    • Editor Sync
  • Troubleshooting

    • デバッグの方法
    • よくある質問(FAQ)💡
    • Get Help
  • Videos

    • Tutorials on Youtube
    • Interviews on Youtube
  • Scripting Overview

    • Needle Engineでのスクリプティング
    • Scripting Introduction for Unity Developers
    • Needleコアコンポーネント
    • Everywhere Actions
  • Components and Lifecycle

    • Creating and using Components
    • @serializable およびその他のデコレーター
    • 自動コンポーネント生成
    • Scripting Examples
    • Community Contributions
    • 追加モジュール
  • Settings and APIs

    • <needle-engine> 設定
    • needle.config.json
    • Needle Engine API
    • three.js API
Help
Samples
Pricing
  • Needle Website
  • Needle Cloud
  • Support Community
  • Discord Server
  • X/Twitter
  • YouTube
  • Newsletter
  • Email
  • Feedback
  • Github
  • English
  • 简体中文
  • Español
  • Português
  • Français
  • हिन्दी
  • 日本語
  • Deutsch
  • Tiếng Việt
Downloads
  • What is Needle Engine?
  • お客様の声
  • Get an overview

    • Samples and Showcase
    • 私たちのビジョン 🔮
    • 機能概要
    • 技術概要
  • Resources

    • Pricing and Plans
    • Changelog
    • API Documentation
    • Support & Community
  • Integrations

    • Unity用Needle Engine
    • Blender 用 Needle Engine
    • Web ComponentとしてのNeedle Engine
    • ウェブサイトでのNeedle Engine
    • Needle Cloud
  • Topics

    • Webプロジェクトの構造
    • Everywhere Actions
    • glTFへのアセットのエクスポート
    • フレームワーク、バンドラー、HTML
    • ローカルデバイスでのテスト
    • デプロイと最適化
  • Advanced

    • ネットワーキング
    • VR & AR (WebXR)
    • HTMLからNeedle Engineを直接使用する
    • Editor Sync
  • Troubleshooting

    • デバッグの方法
    • よくある質問(FAQ)💡
    • Get Help
  • Videos

    • Tutorials on Youtube
    • Interviews on Youtube
  • Scripting Overview

    • Needle Engineでのスクリプティング
    • Scripting Introduction for Unity Developers
    • Needleコアコンポーネント
    • Everywhere Actions
  • Components and Lifecycle

    • Creating and using Components
    • @serializable およびその他のデコレーター
    • 自動コンポーネント生成
    • Scripting Examples
    • Community Contributions
    • 追加モジュール
  • Settings and APIs

    • <needle-engine> 設定
    • needle.config.json
    • Needle Engine API
    • three.js API
Help
Samples
Pricing
  • Needle Website
  • Needle Cloud
  • Support Community
  • Discord Server
  • X/Twitter
  • YouTube
  • Newsletter
  • Email
  • Feedback
  • Github
  • English
  • 简体中文
  • Español
  • Português
  • Français
  • हिन्दी
  • 日本語
  • Deutsch
  • Tiếng Việt
  • Getting Started

    • Downloads
    • Needle Engine for Unity
    • Needle Engine for Blender
    • Needle Engine as Web Component
    • Needle Engine on your Website
    • Needle Cloud
    • Custom integrations
    • Support and Community
  • Core Concepts

    • Webプロジェクトの構造
    • Everywhere Actions
    • glTFへのアセットのエクスポート
    • フレームワーク、バンドラー、HTML
    • ローカルデバイスでのテスト
    • デプロイと最適化
    • デバッグの方法
    • よくある質問(FAQ)💡
  • Scripting

    • Needle Engineでのスクリプティング
    • Scripting Introduction for Unity Developers
    • Creating and using Components
    • 自動コンポーネント生成
    • Scripting Examples
    • Community Contributions
  • Advanced

    • VR & AR (WebXR)
    • ネットワーキング
    • Editor Sync
  • Reference

    • 機能概要
    • 技術概要
    • Needleコアコンポーネント
    • needle.config.json
    • <needle-engine> 設定
    • @serializable およびその他のデコレーター

カスタムコンポーネントの作成

スクリプトに慣れていない場合は、まず以下のガイドを読むことを強くお勧めします。

  • Typescript Essentials
  • Unity開発者向けNeedle Engine

何をしているか分かっている場合は、Needle Engine APIドキュメントを直接参照してください。


Needle Engineのランタイムコードは、TypeScript(推奨)またはJavaScriptで記述されています。これらからC#スタブコンポーネントが自動生成され、エディタでGameObjectsに追加できます。C#コンポーネントとそのデータは、ランタイムによって同じデータを持つJavaScriptコンポーネントとして再作成され、three.jsオブジェクトにアタッチされます。

カスタムコンポーネントと組み込みのUnityコンポーネントの両方を、この方法でJavaScriptコンポーネントにマッピングできます。たとえば、アニメーション、レンダリング、物理学に関連する多くの組み込みコンポーネントのマッピングは、Needle Engineにすでに含まれています。

以下の例をインストールせずにコードで追いたい場合は、以下のリンクをクリックするだけです。

  • コード追従用の仮想ワークスペースを作成する。

当社のウェブランタイムエンジンは、Unityに類似したコンポーネントモデルを採用しており、馴染みのある多くの機能を提供します。 threeのObject3Dオブジェクトにアタッチされたコンポーネントには、awake、start、onEnable、onDisable、update、lateUpdateといったライフサイクルメソッドを実装できます。また、コルーチンを使用することもできます。


コードを書く必要がない場合

多くの場合、Unityのイベントと組み込みコンポーネントのメソッド呼び出しを使用してインタラクティブなシーンを実現できます。典型的な例は、ボタンクリック時のアニメーション再生です。ボタンを作成し、インスペクターにClickイベントを追加し、Animator.SetTriggerなどを呼び出して特定のアニメーションを再生します。

Needle EngineはUnityのイベントをJavaScriptメソッド呼び出しに翻訳するため、これは非常に高速で柔軟なワークフローになります。イベントを通常通り設定すれば、呼び出されたときにUnityと同じように動作します。

imageNeedle Engineでそのまま動作するButton Clickイベントの例 — コードは不要です。

新しいコンポーネントの作成

スクリプトはTypeScript(推奨)またはJavaScriptで記述されます。 カスタムスクリプトをプロジェクトに追加するには2つの方法があります。

  • 生成されたプロジェクトディレクトリのsrc/scripts/内に.tsまたは.js拡張子のファイルをシンプルに追加します。たとえば、src/scripts/MyFirstScript.tsのように。

  • Unity固有: コードをNPM Definition Files(npmパッケージ)に整理します。これらはプロジェクト間でコードをモジュール化して再利用するのに役立ちます。Web開発に慣れている場合、これらは実際にはローカルにインストールされる通常のnpmパッケージです。 Unityでは、Create > NPM DefinitionからNpmDefファイルを作成し、NpmDefファイルを右クリックしてCreate > TypeScriptを選択することでTypeScriptファイルを追加できます。詳細については、この章を参照してください。

どちらの方法でも、ソースディレクトリは変更が監視され、変更が検出されるたびにC#スタブコンポーネントまたはBlenderパネルが再生成されます。 ソースファイルの変更は、実行中のウェブサイトのホットリロードも引き起こします。C#コンポーネントの再コンパイルをUnityが待つ必要はありません。これにより、コードの反復がほぼ瞬時に行えます。

1つのファイル内に複数のコンポーネントタイプを含めることもできます(例:同じTypescriptファイル内でexport class MyComponent1とexport class MyOtherComponentを宣言できます)。

JavascriptまたはTypescriptの記述に慣れていない場合は、このガイドを続ける前にTypescript Essentialsガイドを読むことをお勧めします。

例: オブジェクトを回転させるコンポーネントの作成
  • オブジェクトを回転させるコンポーネントを作成するsrc/scripts/Rotate.tsを作成し、以下のコードを追加します。
import { Behaviour, serializable } from "@needle-tools/engine";

export class Rotate extends Behaviour
{
    @serializable()
    speed : number = 1;

    start(){
        // logging this is useful for debugging in the browser.
        // You can open the developer console (F12) to see what data your component contains
        console.log(this);
    }

    // update will be called every frame
    update(){
        this.gameObject.rotateY(this.context.time.deltaTime * this.speed);
    }
}

これでUnity内にRotate.csという新しいスクリプトが自動的に生成されます。新しいUnityコンポーネントをCubeに追加し、シーンを保存します。 Cubeがブラウザ内で回転するようになります。 Chrome開発者コンソールをF12で開き、Rotate.startメソッドからのログを確認してください。これは、エクスポートされているフィールドと現在割り当てられているデータを学習およびデバッグするのに役立つ実践です。一般的に、すべてのpublicおよびserializableなフィールドとすべてのpublicプロパティがエクスポートされます。

次に、Unityコンポーネントに新しいフィールドpublic float speed = 5を追加し、保存します。Rotateコンポーネントのインスペクターに編集可能なspeedフィールドが表示されます。シーンを保存(またはBuildボタンをクリック)すると、javascriptコンポーネントにエクスポートされたspeed値が割り当てられていることに注意してください。

カスタム関数を持つコンポーネントの作成

構文と言語について詳しくは、Typescript Essentialsガイドを参照してください。

import { Behaviour } from "@needle-tools/engine";

export class PrintNumberComponent extends Behaviour
{
    start(){
      this.printNumber(42);
    }

    private printNumber(myNumber : number){
        console.log("My Number is: " + myNumber);
    }
}
バージョン管理とUnity

生成されたC#コンポーネントはタイプ名を使用して安定したGUIDを生成しますが、良い習慣として生成されたコンポーネントをバージョン管理でチェックインすることをお勧めします。

コンポーネントアーキテクチャ

コンポーネントはthree.jsのObject3Dに追加されます。これはUnityでコンポーネントがGameObjectに追加される方法に似ています。したがって、three.jsのObject3Dにアクセスしたい場合は、コンポーネントがアタッチされているObject3Dを返すthis.gameObjectとしてアクセスできます。

注意: Object3Dのvisibleをfalseに設定すると、UnityのSetActive(false)のように動作します。つまり、このオブジェクトとその子オブジェクト上のすべての現在のコンポーネントも無効になります。非アクティブなコンポーネントのUpdateイベントは、visibleが再びtrueに設定されるまで呼び出されません。コンポーネントに影響を与えずにオブジェクトを非表示にしたい場合は、Needle EngineのRendererコンポーネントを無効にするだけです。

ライフサイクルメソッド

ライフサイクルメソッドは、宣言されている場合にのみ呼び出されることに注意してください。したがって、実際に必要な場合にのみupdateライフサイクルメソッドを宣言してください。そうしないと、何も行わないアップデートループを持つコンポーネントが多数ある場合にパフォーマンスが低下する可能性があります。

メソッド名説明
awake()新しいコンポーネントが作成されたときに最初に呼び出されるメソッド。
onEnable()コンポーネントが有効になったとき(例:enabledがfalseからtrueに変わったとき)に呼び出される。
onDisable()コンポーネントが無効になったとき(例:enabledがtrueからfalseに変わったとき)に呼び出される。
onDestroy()Object3Dまたはコンポーネントが破棄されているときに呼び出される。
start()コンポーネントが作成された後の最初のフレームの開始時に呼び出される。
earlyUpdate()最初のUpdateイベント。
update()デフォルトのUpdateイベント。
lateUpdate()Updateの後に呼び出される。
onBeforeRender()Render呼び出し前の最後のUpdateイベント。
onAfterRender()Renderイベントの後に呼び出される。

物理イベントメソッド

メソッド名説明
onCollisionEnter(col : Collision)
onCollisionStay(col : Collision)
onCollisionExit(col : Collision)
onTriggerEnter(col : Collision)
onTriggerStay(col : Collision)
onTriggerExit(col : Collision)

入力イベントメソッド

メソッド名説明
onPointerEnter(args : PointerEventData)カーソルがオブジェクト(またはその子オブジェクト)の上にホバーを開始したときに呼び出される。
onPointerMove(args : PointerEventData)カーソルがオブジェクト(またはその子オブジェクト)の上を移動したときに呼び出される。
onPointerExit(args : PointerEventData)カーソルがオブジェクトから離れたとき(ホバーを停止したとき)に呼び出される。
onPointerDown(args : PointerEventData)カーソルがオブジェクト上で押されたときに呼び出される。
onPointerUp(args : PointerEventData)カーソルがオブジェクト上で離されたときに呼び出される。
onPointerClick(args : PointerEventData)カーソルがオブジェクト上でクリックされたときに呼び出される。

XRイベントメソッド

Needle Engine >= 3.32.0が必要です

メソッド名説明
supportsXR(mode: XRSessionMode)immersive-vrやimmersive-arなどの特定のXRモードのコールバックのみを受け取りたい場合に任意で実装します。渡されたモードのコールバックを受け取りたいことをシステムに通知するためにtrueを返します。
onBeforeXR(mode: XRSessionMode, init: XRSessionInit)XRSessionが要求される直前に呼び出され、XRSessionInitオブジェクトを変更するために使用できます。
onEnterXR(args: NeedleXREventArgs)このコンポーネントがXRセッションに参加したとき(または実行中のXRセッションでアクティブになったとき)のコールバック。
onUpdateXR(args: NeedleXREventArgs)XRセッションが更新されたとき(XRセッション中にアクティブである間)のコールバック。
onLeaveXR(args: NeedleXREventArgs)このコンポーネントがXRセッションを終了したとき(または実行中のXRセッションで非アクティブになったとき)のコールバック。
onControllerAdded(args: NeedleXRControllerEventArgs)XRセッション中にコントローラーが接続/追加されたとき、またはコンポーネントがすでに接続されているコントローラーを持つ実行中のXRセッションに参加したとき、または実行中のXRセッション中にコンポーネントがアクティブになったときのコールバック。
onControllerRemoved(args: NeedleXRControllerEventArgs)XRセッション中にコントローラーが削除されたとき、または実行中のXRセッション中にコンポーネントが非アクティブになったときのコールバック。

追加のXRイベント

メソッド名説明
window.addEventListener("needle-xrsession-start")XRSessionが開始されたときに呼び出されるCustomEventです。detailsにNeedleXRSessionが含まれます。
window.addEventListener("needle-xrsession-end")XRSessionが開始されたときに呼び出されるCustomEventです。detailsにNeedleXRSessionが含まれます。
onXRSessionStart(args: { session:NeedleXRSession } )グローバルイベントフックです。購読解除にはoffXRSessionStartを使用します。

コルーチン

コルーチンはJavaScript Generator構文を使用して宣言できます。 コルーチンを開始するには、this.startCoroutine(this.myRoutineName());を呼び出します。

例

import { Behaviour, FrameEvent } from "@needle-tools/engine";

export class Rotate extends Behaviour {

    start() {
        // the second argument is optional and allows you to specifiy
        // when it should be called in the current frame loop
        // coroutine events are called after regular component events of the same name
        // for example: Update coroutine events are called after component.update() functions
        this.startCoroutine(this.rotate(), FrameEvent.Update);
    }

    // this method is called every frame until the component is disabled
    *rotate() {
        // keep looping forever
        while (true) {
            yield;
        }
    }
}

コルーチンを停止するには、ルーチンからreturnして終了するか、startCoroutineの戻り値をキャッシュしてthis.stopCoroutine(<...>)を呼び出します。すべてのコルーチンはonDisable時/コンポーネント無効時に停止されます。

特殊なライフサイクルフック

Needle Engineは、コンポーネント全体を記述することなく更新ループにフックするために使用できるいくつかのライフサイクルフックも公開しています。 これらのフックは、Webアプリケーションの任意の場所(たとえば、トップレベルのスコープやsvelteコンポーネント内)に挿入できます。

メソッド名説明
onInitialized(cb, options)新しいコンテキストが初期化されたとき(最初のフレームの前)に呼び出されます。
onClear(cb, options)エンジンコンテキストがクリアされる前にコールバックを登録します。
onDestroy(cb, options)エンジンコンテキストが破棄される前にコールバックを登録します。
onStart(cb, options)コンポーネントのstartの直後、フレームの開始時に呼び出されます。
onUpdate(cb, options)コンポーネントのupdateの直後に呼び出されます。
onBeforeRender(cb, options)render呼び出し前に呼び出されます。
onAfterRender(cb, options)render呼び出し後に呼び出されます。

例(stackblitzの例を参照)

// this can be put into e.g. main.ts or a svelte component (similar to onMount)
import { onStart, onUpdate, onBeforeRender, onAfterRender } from "@needle-tools/engine"

onStart(ctx => console.log("Hello Scene", ctx.scene));

onUpdate(ctx => {
    // do something... e.g. access the frame # or deltatime via ctx.time
    console.log("UPDATE", ctx.time.frame);
});

onBeforeRender(ctx => {
    // this event is only called once because of the { once: true } argument
    console.log("ON BEFORE RENDER", ctx.time.frame);
}, { once: true } );

// Every event hook returns a method to unsubscribe from the event
const unsubscribe = onAfterRender(ctx => {
    console.log("ON AFTER RENDER", ctx.time.frame);
});
// Unsubscribe from the event at any time
setTimeout(()=> unsubscribe(), 1000);

コンポーネントの検索、追加、削除

他のコンポーネントにアクセスするには、GameObjectまたはthis.gameObjectの静的メソッドを使用します。たとえば、親のRendererコンポーネントにアクセスするには、GameObject.getComponentInParent(this.gameObject, Renderer)またはthis.gameObject.getComponentInParent(Renderer)を使用します。

例:

import { Behaviour, GameObject, Renderer } from "@needle-tools/engine";

export class MyComponent extends Behaviour {

    start() {
        const renderer = GameObject.getComponentInParent(this.gameObject, Renderer);
        console.log(renderer);
    }
}

利用可能なメソッドの一部:

メソッド
GameObject.instantiate(Object3D, InstantiateOptions)このオブジェクトの新しいインスタンスを、すべてのコンポーネントの新しいインスタンスを含めて作成します。
GameObject.destroy(Object3D | Component)コンポーネントまたはObject3D(とそのコンポーネント)を破棄します。
GameObject.addNewComponent(Object3D, Type)指定されたオブジェクトに、タイプに応じた新しいコンポーネントを追加(および作成)します。コンポーネントが返されるときには、awakeおよびonEnableは既に呼び出されていることに注意してください。
GameObject.addComponent(Object3D, Component)コンポーネントインスタンスを指定されたオブジェクトに移動します。例えばnew MyComponent()でコンポーネントを作成し、それをオブジェクトにアタッチする場合など、インスタンスが既にある場合に便利です。
GameObject.removeComponent(Component)gameObjectからコンポーネントを削除します。
GameObject.getComponent(Object3D, Type)指定されたオブジェクト上で、タイプに一致する最初のコンポーネントを返します。
GameObject.getComponents(Object3D, Type)指定されたオブジェクト上で、タイプに一致するすべてのコンポーネントを返します。
GameObject.getComponentInChildrengetComponentと同じですが、子オブジェクト内も検索します。
GameObject.getComponentsInChildrengetComponentsと同じですが、子オブジェクト内も検索します。
GameObject.getComponentInParentgetComponentと同じですが、親オブジェクト内も検索します。
GameObject.getComponentsInParentgetComponentsと同じですが、親オブジェクト内も検索します。
GameObject.findObjectOfTypeシーン全体でタイプを検索します。
GameObject.findObjectsOfTypeシーン全体で一致するすべてのタイプを検索します。

Three.jsとHTML DOM

コンテキストとは、Web Component内のランタイムを指します。 three.jsのシーンは、<needle-engine>というカスタムHTMLコンポーネント内に存在します(プロジェクトのindex.htmlを参照)。this.context.domElementを使用して<needle-engine> Web Componentにアクセスできます。

このアーキテクチャにより、同じウェブページ上に複数のNeedle WebGLシーンを配置することが可能になります。これらのシーンは単独で実行することも、ウェブページの一部として互いに通信することもできます。

シーンにアクセスする

コンポーネントから現在のシーンにアクセスするには、this.sceneを使用します。これはthis.context.sceneと同等で、three.jsのルートシーンオブジェクトを取得します。

コンポーネントから階層をたどるには、オブジェクトの子をforループで反復処理できます。

for(let i = 0; i < this.gameObject.children; i++)
    console.log(this.gameObject.children[i]);

または、foreachと同等の方法で反復処理できます。

for(const child of this.gameObject.children) {
    console.log(child);
}

three.js固有のメソッドを使用して、traverseメソッドでオブジェクトを再帰的に素早く反復処理することもできます。

import { Object3D } from "three";
this.gameObject.traverse((obj: Object3D) => console.log(obj));

または、表示可能なオブジェクトのみをたどる場合は、traverseVisibleを使用してください。

もう1つの便利なオプションは、レンダリング可能なオブジェクトのみを反復処理したい場合に、すべてのrendererコンポーネメントをクエリして以下のように反復処理することです。

import { Renderer } from "@needle-tools/engine";
for(const renderer of this.gameObject.getComponentsInChildren(Renderer))
    console.log(renderer);

コンポーネントの取得について詳しくは、次のセクションを参照してください。

時間

時間データにアクセスするには、this.context.timeを使用します。

  • this.context.time.time はアプリケーションの開始からの時間です。
  • this.context.time.deltaTime は前回のフレームから経過した時間です。
  • this.context.time.frameCount はアプリケーションの開始から経過したフレーム数です。
  • this.context.time.realtimeSinceStartup はアプリケーションの開始からのスケールされていない時間です。

また、this.context.time.timeScaleを使用して、例えばスローモーション効果のために時間を意図的に遅くすることも可能です。

入力

コンポーネントが存在するオブジェクトの入力データを受け取ります。

import { Behaviour } from "@needle-tools/engine";
export class MyScript extends Behaviour
{
    onPointerDown() {
        console.log("POINTER DOWN on " + this.gameObject.name);
    }
}

また、以下のようにInputEvents enumのグローバルイベントを購読することもできます。

import { Behaviour, InputEvents, NEPointerEvent } from "@needle-tools/engine";

export class MyScript extends Behaviour
{
    onEnable() {
        this.context.input.addEventListener(InputEvents.PointerDown, this.inputPointerDown);
    }

    onDisable() {
        // it is recommended to also unsubscribe from events when your component becomes inactive
        this.context.input.removeEventListener(InputEvents.PointerDown, this.inputPointerDown);
    }

    // @nonSerialized
    inputPointerDown = (evt: NEPointerEvent) => { console.log("POINTER DOWN anywhere on the <needle-engine> element"); }
}

または、毎フレーム入力状態をポーリングしたい場合はthis.context.inputを使用します。

import { Behaviour } from "@needle-tools/engine";
export class MyScript extends Behaviour
{
    update() {
        if(this.context.input.getPointerDown(0)){
            console.log("POINTER DOWN anywhere")
        }
    }
}

自分で入力を処理したい場合は、ブラウザが提供するすべてのイベント(非常にたくさんあります)を購読することもできます。例えば、ブラウザのクリックイベントを購読するには、以下のように記述します。

import { Behaviour } from "@needle-tools/engine";
export class MyScript extends Behaviour
{
    onEnable() {
        window.addEventListener("click", this.windowClick);
    }

    onDisable() {
        // unsubscribe again when the component is disabled
        window.removeEventListener("click", this.windowClick);
    }

    windowClick = () => { console.log("CLICK anywhere on the page, not just on <needle-engine>"); }
}

この場合、すべてのケースを自分で処理する必要があることに注意してください。たとえば、ユーザーがデスクトップ、モバイル、VRデバイスのいずれでウェブサイトを訪問しているかによって、異なるイベントを使用する必要がある場合があります。これらのケースは、Needle Engineの入力イベント(例:PointerDownはマウスダウン、タッチダウン、およびVRコントローラーのボタンダウンの両方で発生します)によって自動的に処理されます。

レイキャスト

レイキャストを実行し、交差のリストを取得するには、this.context.physics.raycast()を使用します。オプションを渡さない場合、レイキャストは画面空間のマウス位置(または最初のタッチ位置)から、現在アクティブなmainCameraを使用して実行されます。maxDistance、使用するカメラ、テストするレイヤーなどのさまざまな設定を持つRaycastOptionsオブジェクトを渡すこともできます。

three.jsのRayを使用してレイキャストを実行するには、this.context.physics.raycastFromRay(your_ray)を使用します。

注意: このタイプのレイキャストは、シーン内のすべての可視オブジェクトに対してレイをキャストします。物理エンジンは必要ありません。これは、オブジェクトにヒットするために常にコライダーが必要なUnityの挙動とは異なります。物理コライダーのみに対してキャストしたい場合は、以下のphysics.engine.raycastメソッドを使用してください。

パフォーマンスに関する考慮事項

デフォルトのNeedle圧縮設定を使用する場合、メッシュの単純化されたバージョンが自動的に作成され、レイキャストにも使用されます。それでも、一部のタイプのメッシュは遅いです。例えば、スキンメッシュやブレンドシェイプを持つメッシュは、正確なヒットを判断するために高価な計算が必要です。それらのオブジェクトをUnityのIgnore Raycastレイヤーに設定して、それらに対するレイキャストを避けることを検討してください。

物理ベースのレイキャスト

もう1つのオプションは、物理レイキャストメソッドを使用することです。これにより、シーン内のコライダーとのヒットのみが返されます。

const hit = this.context.physics.engine?.raycast();

物理レイキャストの編集可能な例はこちら。

ネットワーク

ネットワーク関連のメソッドにはthis.context.connection経由でアクセスできます。詳細については、ネットワークドキュメントを参照してください。

どこからでもNeedle Engineとコンポーネントにアクセスする

コンポーネント内にない通常のJavaScriptコードから上記で説明したすべての機能にアクセスすることが可能です。Needleランタイムのすべてのコンポーネントと機能はグローバルなNeedle名前空間経由でアクセスできます(console.log(Needle)と記述すると概要を確認できます)。

たとえば、Needle.findObjectOfType(Needle.AudioSource)を使用してコンポーネントを見つけることができます。シーン全体を繰り返し検索するのは高コストであるため、これらの参照をキャッシュすることをお勧めします。上記のコンポーネントの検索、追加、削除のリストを参照してください。

最初のシーンロードのコールバックを取得するには、以下の例を参照してください。

<needle-engine loadstart="loadingStarted" progress="loadingProgress" loadfinished="loadingFinished"></needle-engine>

<script type="text/javascript">
function loadingStarted() { console.log("START") }
function loadingProgress() { console.log("LOADING...") }
function loadingFinished() { console.log("FINISHED!") }
</script>

また、グローバルなNeedleEngine(「ContextRegistry」と呼ばれることもあります)を購読して、Needle Engineコンテキストが作成されたときのコールバックを受け取ったり、利用可能なすべてのコンテキストにアクセスしたりすることもできます。

class YourComponentType extends Behaviour {}
//---cut---
import { NeedleEngine, GameObject, Behaviour } from "@needle-tools/engine";

NeedleEngine.addContextCreatedCallback((args) => {
  const context = args.context;
  const scene = context.scene;
  const myInstance = GameObject.getComponentInChildren(scene, YourComponentType);
});

もう1つのオプションは、onInitialized(ctx => {}) ライフサイクルフックを使用することです。

また、NeedleEngine.Registered経由で利用可能なすべてのコンテキストにアクセスすることも可能です。これは内部配列を返します。(ただし、この配列は変更されるべきではなく、すべての aktif コンテキストを反復処理して設定を変更するために使用できます。例:すべてのコンテキストをcontext.isPaused = trueに設定するなど)

以下に、静的NeedleEngineタイプで利用可能なイベントのリストを示します。 NeedleEngine.registerCallback(ContextEvent.ContextCreated, (args) => {})経由でこれらのイベントを購読できます。

ContextEventオプション
ContextEvent.ContextRegisteredコンテキストがレジストリに登録されたときに呼び出されます。
ContextEvent.ContextCreationStart最初のglbがロードされる前に呼び出され、物理エンジンの初期化に使用できます。Promiseを返すことも可能です。
ContextEvent.ContextCreated最初のフレームの前にコンテキストが作成されたときに呼び出されます。
ContextEvent.ContextDestroyedコンテキストが破棄されたときに呼び出されます。
ContextEvent.MissingCameraコンテキストがカメラを見つけられなかったときに呼び出されます。現在、作成時のみ呼び出されます。
ContextEvent.ContextClearingコンテキストがクリアされているときに呼び出されます。シーン内のすべてのオブジェクトが破棄され、内部状態がリセットされます。
ContextEvent.ContextClearedコンテキストがクリアされた後に呼び出されます。

ギズモ

静的クラスGizmosを使用して、線、形状、テキストを描画できます。これは主にデバッグに役立ちます。 すべてのギズモ関数には、色やシーンに表示される期間など、複数のオプションがあります。内部的にはキャッシュされて再利用されます。

ギズモ
Gizmos.DrawLabelオプションで背景付きのラベルを描画します。オブジェクトにアタッチできます。テキストを更新するために使用できるLabelハンドルを返します。
Gizmos.DrawRayワールド空間の原点と方向を受け取り、無限のレイラインを描画します。
Gizmos.DrawDirectionワールド空間の原点と方向を受け取り、方向を描画します。
Gizmos.DrawLineワールド空間の2つのvec3ポイントを受け取り、線を描画します。
Gizmos.DrawWireSphereワールド空間にワイヤーフレームの球体を描画します。
Gizmos.DrawSphereワールド空間にソリッドな球体を描画します。
Gizmos.DrawWireBoxワールド空間にワイヤーフレームのボックスを描画します。
Gizmos.DrawWireBox3ワイヤーフレームのbox3を描画します。
Gizmos.DrawArrowワールド空間の2つのポイントを受け取り、矢印を描画します。

シリアライゼーション / glTFファイル内のコンポーネント

コンポーネントを埋め込み、それらを正しいタイプでglTFで再作成するために、非プリミティブ型(Number、Boolean、String以外のすべて)も保存する必要があります。これは、フィールドまたはプロパティの上に@serializable(<type>)デコレータを追加することで行えます。

例:

import { Behaviour, serializable, Camera } from "@needle-tools/engine";
import { Object3D } from "three"

export class MyClass extends Behaviour {
    // this will be a "Transform" field in Unity
    @serializable(Object3D) 
    myObjectReference: Object3D | null = null;
    
    // this will be a "Transform" array field in Unity
    // Note that the @serializable decorator contains the array content type! (Object3D and not Object3D[])
    @serializable(Object3D) 
    myObjectReferenceList: Object3D[] | null = null;

    // for component or other objects use the object's type
    @serializable(Camera)
    myCameraComponent: Camera | null = null;
}

カスタム形式でシリアライズおよびデシリアライズするには、TypeSerializerクラスを拡張してインスタンスを作成することが可能です。サポートされているタイプを登録するために、コンストラクタでsuper()を使用します。

注意: 一致するフィールドに加えて、typescriptファイル内のフィールドと一致するプロパティもエクスポートされます。

シーンのロード

Unityで参照されているPrefabs、SceneAssets、およびAssetReferences(UnityのAddressable System)は、自動的にglTFファイルとしてエクスポートされます(Export Prefabsドキュメントを参照してください)。

これらのエクスポートされたglTFファイルは、プレーンな文字列URIとしてシリアライズされます。これらのファイルをTypeScriptコンポーネントから簡単にロードするために、AssetReferenceタイプの概念が追加されました。これらはランタイムにロードできるため、アプリの一部や外部コンテンツのロードを遅延させることが可能です。

例:

import { Behaviour, serializable, AssetReference } from "@needle-tools/engine";

export class MyClass extends Behaviour {

    // if you export a prefab or scene as a reference from Unity you'll get a path to that asset
    // which you can de-serialize to AssetReference for convenient loading
    @serializable(AssetReference)
    myPrefab?: AssetReference;
    
    async start() {
      // directly instantiate
      const myInstance = await this.myPrefab?.instantiate();

      // you can also just load and instantiate later
      // const myInstance = await this.myPrefab.loadAssetAsync();
      // this.gameObject.add(myInstance)
      // this is useful if you know that you want to load this asset only once because it will not create a copy
      // since ``instantiate()`` does create a copy of the asset after loading it
    }  
}

AssetReferenceはURIごとにキャッシュされるため、複数のコンポーネント/スクリプトで同じエクスポートされたglTF/Prefabを参照しても、一度だけロードされて再利用されます。

次のステップ


AIによって自動翻訳されたページ

Suggest changes
最終更新:: 2025/04/22 17:38
Prev
Scripting Introduction for Unity Developers
Next
自動コンポーネント生成