Needle Engine
  • README
  • Code Of Conduct
  • HOW TO
  • documentation
    • SUMMARY
    • _backlog-mermaid
    • _backlog
    • _meta-test
    • Automatic Component Generation
    • Needle Core Components
    • How To Debug
    • Deployment and Optimization
    • embedding
    • Everywhere Actions
    • Example Projects ✨
    • Exporting Assets, Animations, Prefabs, Materials, Lightmaps...
    • Questions and Answers (FAQ) 💡
    • Feature Overview
    • This page has been moved: continue here
    • getting-started
    • Frameworks, Bundlers, HTML
    • index
    • Additional Modules
    • Networking
    • Needle Engine Project Structure
    • Samples Projects
    • Scripting Examples
    • Creating and using Components
    • Live
    • Live
    • About
    • Live
    • Live
    • Live
    • Live
    • Support, Community & AI
    • Technical Overview
    • Testimonials
    • Testing on local devices
    • Using Needle Engine directly from HTML
    • vision
    • VR & AR (WebXR)
    • blender
      • Needle Engine for Blender
    • cloud
      • Needle Cloud
    • custom-integrations
      • index
    • getting-started
      • Scripting Introduction for Unity Developers
      • Getting Started & Installation
      • Scripting in Needle Engine
    • reference
      • needle.config.json
      • <needle-engine> Configuration
      • @serializable and other decorators
    • three
      • index
    • unity
      • Editor Sync
      • Needle Engine for Unity
    • lang
      • de
        • 404
        • SUMMARY
        • Automatische Komponenten-Generierung
        • Needle-Kernkomponenten
        • Debugging
        • Bereitstellung und Optimierung
        • embedding
        • Everywhere Actions
        • Beispielprojekte ✨
        • Assets, Animationen, Prefabs, Materialien, Lightmaps exportieren...
        • Fragen und Antworten (FAQ) 💡
        • Funktionsübersicht
        • Diese Seite wurde verschoben: hier fortfahren
        • getting-started
        • Frameworks, Bundler, HTML
        • index
        • Zusätzliche Module
        • Netzwerkfunktionen
        • Needle Engine Projektstruktur
        • Beispielprojekte
        • Scripting Beispiele
        • Erstellen und Verwenden von Komponenten
        • Live
        • Live
        • Über
        • Live
        • Live
        • Live
        • Live
        • Support und Community
        • Technischer Überblick
        • Erfahrungsberichte
        • Testen auf lokalen Geräten
        • Needle Engine direkt aus HTML verwenden
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine für Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Einführung in das Scripting für Unity-Entwickler
          • Erste Schritte & Installation
          • Scripting in Needle Engine
        • reference
          • needle.config.json
          • <needle-engine> Konfiguration
          • @serializable und andere Decorators
        • three
          • index
        • unity
          • Editor Synchronisierung
          • Needle Engine für Unity
      • es
        • SUMMARY
        • Generación Automática de Componentes
        • Componentes principales de Needle
        • Cómo Depurar
        • Despliegue y optimización
        • embedding
        • Acciones Everywhere
        • Proyectos de Ejemplo ✨
        • Exportación de Assets, Animaciones, Prefabs, Materiales, Lightmaps...
        • Preguntas Frecuentes (FAQ) 💡
        • Resumen de Características
        • Esta página ha sido movida: continúe aquí
        • getting-started
        • Frameworks, Bundlers, HTML
        • index
        • Módulos Adicionales
        • Redes
        • Estructura de Proyecto de Needle Engine
        • Proyectos de ejemplo
        • Ejemplos de scripting
        • Crear y usar Components
        • En vivo
        • En Vivo
        • Acerca de
        • En vivo
        • En vivo
        • En vivo
        • En vivo
        • Soporte y Comunidad
        • Resumen técnico
        • Testimonios
        • Testing on local devices
        • Usando Needle Engine directamente desde HTML
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine para Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Introducción al Scripting para Desarrolladores de Unity
          • Primeros pasos e instalación
          • Scripting in Needle Engine
        • reference
          • needle.config.json
          • Configuración de <needle-engine>
          • @serializable y otros decoradores
        • three
          • index
        • unity
          • Editor Sync
          • Needle Engine para Unity
      • fr
        • SUMMARY
        • Génération automatique de composants
        • Composants principaux de Needle
        • Comment déboguer
        • Déploiement et Optimisation
        • embedding
        • Everywhere Actions
        • Exemples de Projets ✨
        • Exporter des Assets, des Animations, des Prefabs, des Matériaux, des Lightmaps...
        • Questions et Réponses (FAQ) 💡
        • Aperçu des fonctionnalités
        • Cette page a été déplacée : continuez ici
        • getting-started
        • Frameworks, Bundlers, HTML
        • index
        • Modules supplémentaires
        • Réseau
        • Structure du projet Needle Engine
        • Projets d'exemples
        • Exemples de Scripting
        • Créer et utiliser des Components
        • showcase-bike
        • En direct
        • À propos
        • En direct
        • Jouer
        • En direct
        • En direct
        • Support et Communauté
        • Vue d'ensemble technique
        • Témoignages
        • Tester sur les appareils locaux
        • Utiliser Needle Engine directement depuis HTML
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine pour Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Introduction au Scripting pour les Développeurs Unity
          • Premiers pas et installation
          • Scripting in Needle Engine
        • reference
          • needle.config.json
          • <needle-engine> Configuration
          • @serializable et autres décorateurs
        • three
          • index
        • unity
          • Synchronisation de l'Editor (Editor Sync)
          • Needle Engine pour Unity
      • hi
        • SUMMARY
        • कंपोनेंट का स्वतः जनरेशन
        • नीडल कोर कंपोनेंट्स
        • How To Debug
        • Deployment and Optimization
        • embedding
        • Everywhere Actions
        • उदाहरण प्रोजेक्ट ✨
        • एसेट, एनिमेशन, प्रीफैब, मटेरियल, लाइटमैप्स... को एक्सपोर्ट करना
        • प्रश्न और उत्तर (FAQ) 💡
        • सुविधा अवलोकन
        • यह पृष्ठ स्थानांतरित कर दिया गया है: यहां जारी रखें
        • getting-started
        • Frameworks, Bundlers, HTML
        • index
        • अतिरिक्त मॉड्यूल
        • नेटवर्किंग
        • Needle Engine प्रोजेक्ट स्ट्रक्चर
        • samples-and-modules
        • स्क्रिप्टिंग उदाहरण
        • कंपोनेंट बनाना और उपयोग करना
        • लाइव
        • लाइव
        • परिचय
        • लाइव
        • लाइव
        • लाइव
        • लाइव
        • समर्थन और समुदाय
        • तकनीकी अवलोकन
        • प्रशंसापत्र
        • Testing on local devices
        • HTML से सीधे Needle Engine का उपयोग करना
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine for Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Unity डेवलपर्स के लिए स्क्रिप्टिंग परिचय
          • आरंभ करना और इंस्टॉलेशन
          • Needle Engine में स्क्रिप्टिंग
        • reference
          • needle.config.json
          • <needle-engine> कॉन्फ़िगरेशन
          • @serializable and other decorators
        • three
          • index
        • unity
          • Editor Sync
          • Unity के लिए Needle Engine
      • ja
        • SUMMARY
        • 自動コンポーネント生成
        • Needleコアコンポーネント
        • デバッグの方法
        • デプロイと最適化
        • embedding
        • Everywhere Actions
        • サンプルプロジェクト ✨
        • アセット、アニメーション、Prefab、マテリアル、ライトマップなどのエクスポート
        • よくある質問(FAQ)💡
        • 機能概要
        • このページは移動しました: こちらからどうぞ
        • getting-started
        • フレームワーク、バンドラー、HTML
        • index
        • 追加モジュール
        • ネットワーキング
        • Needle Engineプロジェクトの構造
        • サンプルプロジェクト
        • スクリプティング例
        • Creating and using Components
        • ライブ
        • showcase-castle
        • 概要
        • ライブ
        • ライブ
        • ライブ
        • ライブ
        • サポートとコミュニティ
        • 技術概要
        • お客様の声
        • ローカルデバイスでのテスト
        • HTMLからNeedle Engineを直接使用する
        • vision
        • VR & AR (WebXR)
        • blender
          • Blender 用 Needle Engine
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Scripting Introduction for Unity Developers
          • はじめに & インストール
          • Needle Engineでのスクリプティング
        • reference
          • needle.config.json
          • <needle-engine> 設定
          • @serializable およびその他のデコレーター
        • three
          • index
        • unity
          • Editor Sync
          • Unity用Needle Engine
      • pt
        • SUMMARY
        • Automatic Component Generation
        • Componentes Principais do Needle
        • Como Depurar
        • Implementação e Otimização
        • embedding
        • Everywhere Actions
        • Projetos de Exemplo ✨
        • Exportar Recursos, Animações, Prefabs, Materiais, Lightmaps...
        • Perguntas e Respostas (FAQ) 💡
        • Visão Geral dos Recursos
        • Esta página foi movida: continue aqui
        • getting-started
        • Frameworks, Bundlers, HTML
        • index
        • Módulos Adicionais
        • Redes
        • Estrutura do Projeto Needle Engine
        • Projetos de Exemplo
        • Exemplos de Scripting
        • Criar e usar Componentes
        • Ao Vivo
        • Ao Vivo
        • Sobre
        • Ao Vivo
        • Ao Vivo
        • Ao Vivo
        • Ao Vivo
        • Suporte e Comunidade
        • Visão Geral Técnica
        • Depoimentos
        • Testar em dispositivos locais
        • vanilla-js
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine para Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Introdução à Scripting para Developers Unity
          • Começar e Instalação
          • Scripting no Needle Engine
        • reference
          • needle.config.json
          • needle-engine-attributes
          • @serializable e outros decorators
        • three
          • index
        • unity
          • Sincronização do Editor
          • Needle Engine para Unity
      • vn
        • 404
        • SUMMARY
        • Automatic Component Generation
        • Các Component Cốt lõi của Needle
        • Cách gỡ lỗi
        • Triển khai và Tối ưu hóa
        • embedding
        • Hành động ở mọi nơi (Everywhere Actions)
        • Các Dự Án Ví Dụ ✨
        • Xuất Tài sản, Hoạt ảnh, Prefab, Vật liệu, Lightmap...
        • Câu hỏi thường gặp (FAQ) 💡
        • Tổng quan tính năng
        • Trang này đã được di chuyển: tiếp tục tại đây
        • getting-started
        • Frameworks, Bundlers, HTML
        • index
        • Các Module Bổ Sung
        • Kết nối mạng
        • Cấu trúc dự án Needle Engine
        • samples-and-modules
        • Ví dụ về Scripting
        • Tạo và sử dụng Component
        • Trực tiếp
        • Trực tiếp
        • Giới thiệu
        • Trực tiếp
        • Chơi thử
        • Trực tiếp
        • Demo trực tiếp
        • Hỗ trợ và Cộng đồng
        • Tổng quan kỹ thuật
        • Lời chứng thực
        • Testing on local devices
        • Sử dụng Needle Engine trực tiếp từ HTML
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine cho Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Giới thiệu về Scripting cho các nhà phát triển Unity
          • Getting Started & Installation
          • Scripting trong Needle Engine
        • reference
          • needle.config.json
          • Cấu hình <needle-engine>
          • @serializable và các decorator khác
        • three
          • index
        • unity
          • Editor Sync
          • Needle Engine cho Unity
      • zh
        • SUMMARY
        • 自动生成组件
        • Needle 核心组件
        • 如何调试
        • 部署与优化
        • embedding
        • Everywhere Actions
        • 示例项目 ✨
        • 导出资源、动画、预制体、材质、光照贴图...
        • 常见问题 (FAQ) 💡
        • 功能概览
        • 此页面已移动:请在此处继续
        • getting-started
        • 框架、打包器、HTML
        • index
        • 附加模块
        • 网络
        • Needle Engine 项目结构
        • 示例项目
        • Scripting Examples
        • Creating and using Components
        • 实时示例
        • 实时
        • 关于
        • 实时演示
        • 在线试玩
        • 实时演示
        • 现场演示
        • 支持与社区
        • 技术概述
        • 用户评价
        • Testing on local devices
        • 使用 Needle Engine 直接从 HTML
        • vision
        • VR & AR (WebXR)
        • blender
          • Needle Engine for Blender
        • cloud
          • Needle Cloud
        • custom-integrations
          • index
        • getting-started
          • Scripting Introduction for Unity Developers
          • 入门与安装
          • 在 Needle Engine 中编写脚本
        • reference
          • needle.config.json
          • <needle-engine> 配置
          • @serializable and other decorators
        • three
          • index
        • unity
          • 编辑器同步
          • Unity 版 Needle Engine
Powered by GitBook
On this page
  • The Basics
  • Creating a Component
  • Script Fields
  • GameObjects and the Scene
  • Components
  • Renamed Unity Types
  • Transform
  • Time
  • Raycasting
  • Input
  • InputSystem Callbacks
  • Debug.Log
  • Gizmos
  • Useful Utility Methods
  • The Web project
  • Installing packages & dependencies
  • Learning more
Edit on GitHub
  1. documentation
  2. getting-started

Scripting Introduction for Unity Developers

Previousgetting-startedNextGetting Started & Installation

Last updated 2 months ago

Needle Engine provides a tight integration into the Unity Editor. This allows developers and designers alike to work together in a familiar environment and deliver fast, performant and lightweight web-experiences.

The following guide is mainly aimed at developers with a Unity3D background but it may also be useful for developers with a web or three.js background. It covers topics regarding how things are done in Unity vs in three.js or Needle Engine.

If you are all new to Typescript and Javascript and you want to dive into writing scripts for Needle Engine then we also recommend reading the for a basic understanding between the differences between C# and Javascript/Typescript.

If you want to code-along you can to create a small project that you can edit in the browser ⚡

The Basics

Needle Engine is a 3d web engine running on-top of . Three.js is one of the most popular 3D webgl based rendering libraries for the web. Whenever we refer to a gameObject in Needle Engine we are actually also talking about a three.js Object3D, the base type of any object in three.js. Both terms can be used interchangeably. Any gameObject is a Object3D.

This also means that - if you are already familiar with three.js - you will have no problem at all using Needle Engine. Everything you can do with three.js can be done in Needle Engine as well. If you are already using certain libraries then you will be able to also use them in a Needle Engine based environment.

Note: Needle Engine's Exporter does NOT compile your existing C# code to Web Assembly. While using Web Assembly may result in better performance at runtime, it comes at a high cost for iteration speed and flexibility in building web experiences. Read more about our and .

:::details How to create a new Unity project with Needle Engine? (Video) :::

Creating a Component

In Unity you create a new component by deriving from MonoBehaviour:

using UnityEngine;
public class MyComponent : MonoBehaviour { 
}

A custom component in Needle Engine on the other hand is written as follows:

import { Behaviour } from "@needle-tools/engine"
export class MyComponent extends Behaviour { 
}

Script Fields

serializable

If you have seen some Needle Engine scripts then you might have noticed that some variables are annotated with @serializable above their declaration. This is a Decorator in Typescript and can be used to modify or annotate code. In Needle Engine this is used for example to let the core serialization know which types we expect in our script when it converts from the raw component information stored in the glTF to a Component instance. Consider the following example:

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

class SomeClass extends Behaviour{
    @serializable(Behaviour)
    myOtherComponent?: Behaviour;
    @serializable(Object3D)
    someOtherObject?: Object3D;
}

This tells Needle Engine that myOtherComponent should be of type Behaviour. It will then automatically assign the correct reference to the field when your scene is loaded. The same is true for someOtherObject where we want to deserialize to an Object3D reference.

import { Behaviour, serializable } from "@needle-tools/engine";
class SomeClass {
    @serializable() // < no type is needed here because the field type is a primitive
    myString?: string;
}

public vs private

Field without any accessor modified like private, public or protected will by default be public in javascript

import { Behaviour, serializable } from "@needle-tools/engine";
class SomeClass {
    /// no accessor means it is public:
    myNumber?: number;
    // explicitly making it private:
    private myPrivateNumber?: number;
    protected myProtectedNumber?: number;
}

The same is true for methods as well.

GameObjects and the Scene

To access the current scene from a component you use this.scene which is equivalent to this.context.scene, this gives you the root three.js scene object.

To traverse the hierarchy from a component you can either iterate over the children of an object with a for loop:

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

or you can iterate using the foreach equivalent:

for (const child of this.gameObject.children) {
    console.log(child);
}
import { GameObject } from "@needle-tools/engine";
//---cut-before---
this.gameObject.traverse((obj: GameObject) => console.log(obj))

Another option that is quite useful when you just want to iterate objects being renderable you can query all renderer components and iterate over them like so:

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

for(const renderer of this.gameObject.getComponentsInChildren(Renderer))
    console.log(renderer);

For more information about getting components see the next section.

Components

Finding Components in the Scene

For getting component you can use the familiar methods similar to Unity. Note that the following uses the Animator type as an example but you can as well use any component type that is either built-in or created by you.

Method name
Desciption

this.gameObject.getComponent(Animator)

Get the Animator component on a GameObject/Object3D. It will either return the Animator instance if it has an Animator component or null if the object has no such componnent.

this.gameObject.getComponentInChildren(Animator)

Get the first Animator component on a GameObject/Object3D or on any of its children

this.gameObject.getComponentsInParents(Animator)

Get all animator components in the parent hierarchy (including the current GameObject/Object3D)

These methods are also available on the static GameObject type. For example GameObject.getComponent(this.gameObject, Animator) to get the Animator component on a passed in GameObject/Object3D.

To search the whole scene for one or multiple components you can use GameObject.findObjectOfType(Animator) or GameObject.findObjectsOfType(Animator).

Renamed Unity Types

Some Unity-specific types are mapped to different type names in our engine. See the following list:

Type in Unity
Type in Needle Engine

UnityEvent

EventList

A UnityEvent will be exported as a EventList type (use serializable(EventList) to deserialize UnityEvents)

GameObject

Object3D

Transform

Object3D

In three.js and Needle Engine a GameObject and a Transform are the same (there is no Transform component). The only exception to that rule is when referencing a RectTransform which is a component in Needle Engine as well.

Color

RGBAColor

The three.js color type doesnt have a alpha property. Because of that all Color types exported from Unity will be exported as RGBAColor which is a custom Needle Engine type

Transform

Transform data can be accessed on the GameObject / Object3D directly. Unlike to Unity there is no extra transform component that holds this data.

  • this.gameObject.worldPosition is the vector3 position in world space

  • this.gameObject.worldRotation is the euler rotation in euler angles in world space

  • this.gameObject.worldQuaternion is the quaternion rotation in world space

  • this.gameObject.worldScale is the vector3 scale in world space

The major difference here to keep in mind is that position in three.js is by default a localspace position whereas in Unity position would be worldspace. The next section will explain how to get the worldspace position in three.js.

WORLD- Position, Rotation, Scale...

In three.js (and thus also in Needle Engine) the object.position, object.rotation, object.scale are all local space coordinates. This is different to Unity where we are used to position being worldspace and using localPosition to deliberately use the local space position.

If you want to access the world coordinates in Needle Engine we have utility methods that you can use with your objects. Call getWorldPosition(yourObject) to calculate the world position. Similar methods exist for rotation/quaternion and scale. To get access to those methods just import them from Needle Engine like so import { getWorldPosition } from "@needle.tools/engine"

Time

Use this.context.time to get access to time data:

  • this.context.time.time is the time since the application started running

  • this.context.time.deltaTime is the time that has passed since the last frame

  • this.context.time.frameCount is the number of frames that have passed since the application started

  • this.context.time.realtimeSinceStartup is the unscaled time since the application has started running

It is also possible to use this.context.time.timeScale to deliberately slow down time for e.g. slow motion effects.

Raycasting

Use this.context.physics.raycast() to perform a raycast and get a list of intersections. If you dont pass in any options the raycast is performed from the mouse position (or first touch position) in screenspace using the currently active mainCamera. You can also pass in a RaycastOptions object that has various settings like maxDistance, the camera to be used or the layers to be tested against.

Note that the calls above are by default raycasting against visible scene objects. That is different to Unity where you always need colliders to hit objects. The default three.js solution has both pros and cons where one major con is that it can perform quite slow depending on your scene geometry. It may be especially slow when raycasting against skinned meshes. It is therefor recommended to usually set objects with SkinnedMeshRenderers in Unity to the Ignore Raycast layer which will then be ignored by default by Needle Engine as well.

Another option is to use the physics raycast methods which will only return hits with colliders in the scene.

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

Input

Use this.context.input to poll input state:

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

You can also subscribe to events in the InputEvents enum like so:

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);
    }

    inputPointerDown = (evt: NEPointerEvent) => { console.log(evt); }
}
window.addEventListener("click", () => { console.log("MOUSE CLICK"); });

Note that in this case you have to handle all cases yourself. For example you may need to use different events if your user is visiting your website on desktop vs mobile vs a VR device. These cases are automatically handled by the Needle Engine input events (e.g. PointerDown is raised both for mouse down, touch down and in case of VR on controller button down).

InputSystem Callbacks

To make this work make sure your object has a ObjectRaycaster or GraphicRaycaster component in the parent hierarchy.

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

export class ReceiveClickEvent extends Behaviour implements IPointerEventHandler {
    onPointerClick(args: PointerEventData) {
        console.log("Click", args);
    }
}

Note: IPointerEventHandler subscribes the object to all possible pointer events. The handlers for them are:

  • onPointerDown

  • onPointerUp

  • onPointerEnter

  • onPointerMove

  • onPointerExit

  • onPointerClick

All have a PointerEventData argument describing the event.

Debug.Log

The Debug.Log() equivalent in javascript is console.log(). You can also use console.warn() or console.error().

import { GameObject, Renderer } from "@needle-tools/engine";
const someVariable = 42;
// ---cut-before---

console.log("Hello web");
// You can pass in as many arguments as you want like so:
console.log("Hello", someVariable, GameObject.findObjectOfType(Renderer), this.context);

Gizmos

In Unity you normally have to use special methods to draw Gizmos like OnDrawGizmos or OnDrawGizmosSelected. In Needle Engine on the other hand such methods dont exist and you are free to draw gizmos from anywhere in your script. Note that it is also your responsibility then to not draw them in e.g. your deployed web application (you can just filter them by if(isDevEnvironment))).

Here is an example to draw a red wire sphere for one second for e.g. visualizing a point in worldspace

import { Vector3 } from "three";
const hit = { point: new Vector3(0, 0, 0) };
// ---cut-before---
import { Gizmos } from "@needle-tools/engine";
Gizmos.DrawWireSphere(hit.point, 0.05, 0xff0000, 1);

Here are some of the available gizmo methods:

Method name

Gizmos.DrawArrow

Gizmos.DrawBox

Gizmos.DrawBox3

Gizmos.DrawDirection

Gizmos.DrawLine

Gizmos.DrawRay

Gizmos.DrawRay

Gizmos.DrawSphere

Gizmos.DrawWireSphere

Useful Utility Methods

Import from @needle-tools/engine e.g. import { getParam } from "@needle-tools/engine"

Method name
Description

getParam()

Checks if a url parameter exists. Returns true if it exists but has no value (e.g. ?help), false if it is not found in the url or is set to 0 (e.g. ?help=0), otherwise it returns the value (e.g. ?message=test)

isMobileDevice()

Returns true if the app is accessed from a mobile device

isDevEnvironment()

Returns true if the current app is running on a local server

isMozillaXR()

isiOS

isSafari

import { isMobileDevice } from "@needle-tools/engine"
if( isMobileDevice() )
import { getParam } from "@needle-tools/engine"
// returns true 
const myFlag = getParam("some_flag")
console.log(myFlag)

The Web project

In C# you usually work with a solution containing one or many projects. In Unity this solution is managed by Unity for you and when you open a C# script it opens the project and shows you the file. You usually install Packages using Unity's built-in package manager to add features provided by either Unity or other developers (either on your team or e.g. via Unity's AssetStore). Unity does a great job of making adding and managing packages easy with their PackageManager and you might never have had to manually edit a file like the manifest.json (this is what Unity uses to track which packages are installed) or run a command from the command line to install a package.

In a web environment you use npm - the Node Package Manager - to manage dependencies / packages for you. It does basically the same to what Unity's PackageManager does - it installs (downloads) packages from some server (you hear it usually called a registry in that context) and puts them inside a folder named node_modules.

Here is an example of how a package.json might look like:

{
  "name": "@optional_org/package_name",
  "version": "1.0.0",
  "scripts": {
    "start": "vite --host"
  },
  "dependencies": {
	  "@needle-tools/engine": "^3.5.9-beta",
	  "three": "npm:@needle-tools/three@0.146.8"
	},
  "devDependencies": {
	  "@types/three": "0.146.0",
	  "@vitejs/plugin-basic-ssl": "^1.0.1",
	  "typescript": "^5.0.4",
	  "vite": "^4.3.4",
	  "vite-plugin-compression": "^0.5.1"
	}
}

Our default template uses Vite as its bundler and has no frontend framework pre-installed. Needle Engine is unoppionated about which framework to use so you are free to work with whatever framework you like. We have samples for popular frameworks like Vue.js, Svelte, Next.js, React or React Three Fiber.

Installing packages & dependencies

What's the difference between 'dependencies' and 'devDependencies'

You may have noticed that there are two entries containing dependency - dependencies and devDependencies.

dependencies are always installed (or bundled) when either your web project is installed or in cases where you develop a library and your package is installed as a dependency of another project.

devDependencies are only installed when developing the project (meaning that when you directly run install in the specific directory) and they are otherwise not included in your project.

How do I install another package or dependency and how to use it?

First run npm install @tweenjs/tween.js in the terminal and wait for the installation to finish. This will add a new entry to our package.json:

"dependencies": {
    "@needle-tools/engine": "^3.5.11-beta",
    "@tweenjs/tween.js": "^20.0.3",
    "three": "npm:@needle-tools/three@0.146.8"
}

Then open one of your script files in which you want to use tweening and import at the top of the file:

import * as TWEEN from '@tweenjs/tween.js';

Note that we do here import all types in the library by writing * as TWEEN. We could also just import specific types like import { Tween } from @tweenjs/tween.js.

To rotate a cube we create a new component type called TweenRotation, we then go ahead and create our tween instance for the object rotation, how often it should repeat, which easing to use, the tween we want to perform and then we start it. We then only have to call update every frame to update the tween animation. The final script looks like this:

import { Behaviour } from "@needle-tools/engine";
import * as TWEEN from '@tweenjs/tween.js';

export class TweenRotation extends Behaviour {

    // save the instance of our tweener
    private _tween?: TWEEN.Tween<any>; 

    start() {
        const rotation = this.gameObject.rotation;
        // create the tween instance
        this._tween = new TWEEN.Tween(rotation);
        // set it to repeat forever
        this._tween.repeat(Infinity);
        // set the easing to use
        this._tween.easing(TWEEN.Easing.Quintic.InOut);
        // set the values to tween
        this._tween.to({ y: Math.PI * 0.5 }, 1000);
        // start it
        this._tween.start();
    }
    
    update() {
        // update the tweening every frame
        // the '?' is a shorthand for checking if _tween has been created
        this._tween?.update();
    }
}

Learning more

Note that in some cases the type can be ommitted. This can be done for all . These are boolean, number, bigint, string, null and undefined.

You can also use three.js specific methods to quickly iterate all objects recursively using the method:

or to just traverse visible objects use instead.

Needle Engine is making heavy use of a Component System that is similar to that of Unity. This means that you can add or remove components to any Object3D / GameObject in the scene. A component will be registered to the engine when using addNewComponent(<Object3D>, <ComponentType>). The event methods that the attached component will then automatically be called by the engine (e.g. update or onBeforeRender). A full list of event methods can be found in the

this.gameObject.position is the vector3 in local space

this.gameObject.rotation is the in local space

this.gameObject.quaternion - is the in local space

this.gameObject.scale - is the vector3 in local space

Note that these utility methods like getWorldPosition, getWorldRotation, getWorldScale internally have a buffer of Vector3 instances and are meant to be used locally only. This means that you should not cache them in your component, otherwise your cached value will eventually be overriden. But it is safe to call getWorldPosition multiple times in your function to make calculations without having to worry to re-use the same instance. If you are not sure what this means you should take a look at the Primitive Types section in the

Use this.context.physics.raycastFromRay(your_ray) to perform a raycast using a

Here is a editable

If you want to handle inputs yourself you can also subscribe to (there are a ton). For example to subscribe to the browsers click event you can write:

Similar to Unity (see ) you can also register to receive input events on the component itself.

When working with a web project most of you dependencies are installed from . It is the most popular package registry out there for web projects.

To install a dependency from npm you can open your web project in a commandline (or terminal) and run npm i <the/package_name> (shorthand for npm install) For example run npm i @needle-tools/engine to install . This will then add the package to your package.json to the dependencies array. To install a package as a devDependency only you can run npm i --save-dev <package_name>. More about the difference between dependencies and devDependencies below.

The section taught us that you can install dependencies by running npm i <package_name> in your project directory where the package_name can be any package that you find on .

Let's assume you want to add a tweening library to your project. We will use for this example. is the final project if you want to jump ahead and just see the result.

Now we can use it in our script. It is always recommended to refer to the documentation of the library that you want to use. In the case of tween.js they provide a that we can follow. Usually the Readme page of the package on npm contains information on how to install and use the package.

Now we only have to add it to any of the objects in our scene to rotate them forever. You can see the final script in action .

Typescript Essentials Guide
open engine.needle.tools/new
three.js
vision
technical overview
primitive types in Javascript
traverse
traverseVisible
position
euler rotation
quaternion rotation
scale
three.js ray
example for physics raycast
all events the browser provides
IPointerClickHandler in Unity
npmjs.com
Needle Engine
@tweenjs/tween.js
Here
user guide
here
Scripting in Needle Engine
Typescript Essentials
Component Reference
npm.js
Installing
Typescript Essentials Guide
scripting documentation