Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/calico-games/react-native-godot

Bring Godot to React Native ๐Ÿ”ฎ. Create immersive 3D experiences or interactive games directly within React Native.
https://github.com/calico-games/react-native-godot

3d android gltf godot godot-engine godotengine ios metal opengl react-native react-native-godot rendering vulkan

Last synced: 6 days ago
JSON representation

Bring Godot to React Native ๐Ÿ”ฎ. Create immersive 3D experiences or interactive games directly within React Native.

Awesome Lists containing this project

README

        

react-native-godot


Bring **Godot** to **React Native** ๐Ÿ”ฎ.
Create immersive 3D experiences or interactive games directly within React Native, allowing for high-performance graphics and responsive interactions.

[![npm version](https://img.shields.io/npm/v/react-native-godot.svg?style=flat)](https://www.npmjs.com/package/react-native-godot)
[![godot engine](https://img.shields.io/badge/Godot-4.3-blue)](https://godotengine.org/download)

## Screenshots ๐Ÿ“ธ

[Multiple Cubes demo](screenshots/screenshot1.jpeg)
[Earth demo](screenshots/screenshot2.jpeg)

### Features ๐Ÿš€

* ๐ŸŽ๏ธ Native C++ JSI performance
* ๐Ÿ”ฅ GPU-accelerated by Metal and OpenGL/Vulkan
* โœ… Supports old and new arch
* ๐Ÿ™‚ Supports Godot Variants in React Native
* ๐Ÿงจ Call GDScript methods in React Native
* ๐Ÿ“ฆ Easy import of your Godot projects

## Device Support ๐Ÿ“ฑ

iOS support is implemented, full support for Android is almost ready.
We'll ship that soon ๐Ÿ˜Š

| Platform | Supported |
| ---------------- | --------- |
| iOS Simulator | โœ… |
| iOS Device | โœ… |
| Android Emulator | ๐Ÿšง |
| Android Device | ๐Ÿšง |

## Requirements ๐Ÿฅธ

* Godot 4.3 ([https://godotengine.org/](https://godotengine.org/))

## Installation ๐Ÿš€

```sh
npm install react-native-godot

or

yarn add react-native-godot
```

## Usage ๐Ÿ‘‡

Take a look at the `example` folder for a full implem ๐Ÿ‘€.

### React Native <-> Godot Communication ๐Ÿ“ก

You can send messages from React Native to Godot and receive messages from Godot in React Native.

* **React Native -> Godot**: You can send messages from React Native to Godot using the `emitMessage` method.
* **Godot -> React Native**: You can receive messages from Godot in React Native using the `onMessage` prop.

```tsx
// โš ๏ธ IMPORTANT โš ๏ธ
// GodotProvider is required to initalize Godot properly
// (See in the example folder for more details)
//
//
//
//
//
// It should be at the root of your app.
// The highest level is recommended. e.g. App.tsx

import React, {useRef} from 'react';
import {Godot, GodotView, GodotProvider, useGodot} from 'react-native-godot';

const Example = () => {
const godotRef = useRef(null);
const {Vector3, Vector2} = useGodot();

// Call gdsript method from React Native
useEffect(() => {
if (!godotRef.current || !godotRef.current?.isReady) {
return;
}

// Emit a message to Godot from React Native
godotRef.current?.emitMessage({
message: 'Hello from React Native!',
position: Vector3(1, 2, 3),
});

// Use Godot Vector3 and Vector2 variants
// All methods and properties are available too :)
console.log('Vector3 y:', Vector3(1, 2, 3).y);
console.log('Length', Vector2(3, 1).length());

// Retrieve a node from your scene
const node = godotRef.current?.getRoot()?.getNode('MySuperNode');
if (!node) {
return;
}

// Call method `hello_world` from the gdscript attached to the node in your scene
node.hello_world();

// You can also call your method and return a value with any supported types
const something = node.method_that_returns_something();
console.log('Something:', something);
}, [godotRef.current?.isReady]);

return (
console.log('Godot message:', message)}
/>
);
};
```

### Godot implementation (GDScript) ๐Ÿง™โ€โ™‚๏ธ

```gdscript
# This class is a demonstration of GDScript with React Native.

extends Node

func _ready() -> void:
if Engine.has_singleton("ReactNative"): # Always check if the ReactNative singleton exists
Engine.get_singleton("ReactNative").on_message(_on_message)

func _on_message(message: Dictionary) -> void:
print("React Native message:", message)

func _input(event: InputEvent) -> void:
if "position" not in event:
return

var adjusted_position = adjust_for_window(event.position)

if Engine.has_singleton("ReactNative"):
# Emit a message to React Native
Engine.get_singleton("ReactNative").emit_message({
"message": "Input event position",
"pos": adjusted_position,
})

func hello_world() -> void:
print("Hello World!")

func method_that_returns_something() -> int:
return 42

## This function is used to adjust the screen position for the window.
func adjust_for_window(pos: Vector2) -> Vector2:
var window = get_viewport().get_window()
var window_id = window.get_window_id()

if window_id == DisplayServer.MAIN_WINDOW_ID or window_id == DisplayServer.INVALID_WINDOW_ID:
return pos

var window_position = Vector2()

if Engine.has_singleton("ReactNative"):
window_position = Engine.get_singleton("ReactNative").get_subwindow_position(window_id)

return Vector2(
pos.x + window_position.x,
pos.y + window_position.y
)
```

## Godot Variants ๐Ÿญ

Godot variants are available in React Native, here is the list:
`AABB | Basis | Color | Plane | Projection | Quaternion | Rect2 | Rect2i | Transform2D | Transform3D | Vector2 | Vector2i | Vector3 | Vector3i | Vector4 | Vector4i`.

For primitives like `int`, `float`, `bool`, `dictionary`, `array`, etc, you can use normal JS types and it will be automatically converted to Godot variants and vice versa.

All methods and properties are available too, for instance, you can use `Vector3(1, 2, 3).length()`.
Complete documentation is available at [https://docs.godotengine.org/en/stable/classes/index.html#variant-types](https://docs.godotengine.org/en/stable/classes/index.html#variant-types).

## Access any Godot Nodes from React Native ๐ŸŽฏ

You can retrieve a node from your scene in React Native and call methods on it.

Current supported methods for a Node are:

* getNode(name: string): Node | null
* getParent(): Node | null
* getChildren(): Node[]
* getChildCount(): number

(+ Any method you've defined in your gdscript ๐Ÿ˜Œ)

## Import your Godot Project (How to) ๐Ÿ“ฅ

* To import your **Godot project** into React Native, you need to **generate a pck file** that basically packs up all your game assets, scripts etc.
It's a convenient way to pack your game into a single file.

* First, you need to add a `export_presets.cfg` in the directory of your Godot project.
We provide a working example of this file at the root of this repository.

* After that, you're now able to generate a pck file, just run `./gen-pck PROJECT_FOLDER_PATH`.
Be sure you have `/Applications/Godot.app` set on your machine, if you're using another path or another OS than macOS, just modify this very simple shell at your convenience.

* Then, you just need to move the pck file in your assets folder.

* One last important thing, don't forget to add a `project.godot` in your XCode project, see in the example folder for more details.

## Metro Config ๐Ÿš‡

* You need to add the following to your `metro.config.js` in order to treat `.pck` files as assets and exclude them from being treated as source files.

```js
// Treat `.pck` files as assets
assetExts: [...assetExts, 'pck'],
// Exclude `.pck` from being treated as source files
sourceExts: sourceExts.filter(ext => ext !== 'pck'),
```

And...

```js
server: {
enhanceMiddleware: (middleware) => {
return (req, res, next) => {
if (/\.pck$/.test(req.url)) {
res.setHeader('Content-Type', 'application/octet-stream');
}
return middleware(req, res, next);
};
},
},
```

## Library Size ๐Ÿ“ฆ

Godot takes around 35MB for iOS when embedded into the app binary for production builds (with all features!).

In the future, removing `MoltenVK` for iOS in Godot 4.4, not depending on `godot-cpp`, might help us squeeze size even more.
Also, your pck file must be considered in the size of your app. Which can be quite large too if you have a lot of big assets like 3D models, textures, etc.

For a game that is packed that takes around 50MB in Godot, the final app size will be around 90MB. Not too bad and probably slightly better than Unity ๐Ÿ˜…

## Limitations & Known Issues ๐Ÿšง

* When importing a texture or 3D model, be sure you don't import them as `VRAM Compressed`, for some reason when exporting the pck file, it doesn't import the assets. Might be a mistake from our side.... (TBD) ๐Ÿ˜…

[VRAM Compressed](screenshots/screenshot3.png)

* **PCK Asset Swapping**: For now, you can't swap the pck asset at runtime properly, you need to reopen the app to load a new pck asset. It seems to be a limitation of the Godot engine itself, but we're investigating this as it would be super useful to debug on device in almost real-time.

## TODO ๐Ÿ“

* [x] iOS support
* [ ] Android support
* [x] Improve library size
* [x] Add support for all Godot variants
* [ ] Investigate PCK asset swapping
* [x] Add support for more Godot features

## Contributing ๐Ÿค

We're open to any contributions. Feel free to open an issue if you want to help us improve this library.

All the interesting stuff is located in a private repository so if you want to contribute, just send us an email at `[email protected]`.
You should have previous experiences of building the Godot Engine yourself, C++, and building blazing fast React Native libraries is a plus.
[Bazel](https://github.com/bazelbuild/bazel) is also used internally to build the library fyk.

## Copyright / License ๐Ÿ‘จโ€โš–๏ธ

Copyright **Calico Games** 2024. All rights reserved.

This library is released under a **Custom License** with the following conditions:

* **Free for non-commercial use**: You may freely use this library for personal, educational, or open-source projects.
* **Commercial use by revenue-generating entities**: Any company or individual with an annual revenue exceeding $50,000 must obtain a commercial license to use this library.
* **No Redistribution Allowed**: This library cannot be redistributed, repackaged, or resold.

PS: We are pretty flexible atm and we would like to also support the Godot Foundation by giving them a share of the revenue generated by this library.

For commercial licensing inquiries, please contact us at `[email protected]`.

## Credits ๐Ÿ™

* Special thanks to all the contributors of the [Godot Engine](https://github.com/godotengine/godot).
* A big shoutout to [Migeran](https://github.com/migeran) that helped us a lot to build this library.