使用 React

React 是一個流行的庫,可讓您創建易於重用的 UI 組件。Hology Engine 提供了一個專門的庫,用於幫助將 React 組件與遊戲狀態和角色整合。

使用 Hology Scene Scene component組件

要在 React 應用程序中運行 Hology Engine,您可以簡單地使用 HologyScene 組件。

<HologyScene gameClass={Game} sceneName='demo' dataDir='data' shaders={shaders} actors={actors}>  
</HologyScene>

這將使用給定的場景啟動 Hology Engine 運行時。您還需要為 Hology Engine 傳入一些參數,因為這些參數可能會根據您的項目設置而有所不同。如果您在創建新的 Hology 項目時使用默認的 React 項目模板,那麼上面代碼中顯示的值應該可以正常工作。

  • sceneName - 您想要加載的場景名稱

  • dataDir - 所有 Hology 遊戲數據所在文件夾的路徑

  • shaders - 包含著色器類的對象

  • actors - 包含角色類的對象

添加 UI 組件

HologyScene 組件內部,您可以放置應該顯示在渲染遊戲之上的組件。

function App() {
    return (
      <HologyScene gameClass={Game} sceneName='demo' dataDir='data' shaders={shaders} actors={actors}>
        <p>This will be displayed over the game</p>     
      </HologyScene>
    )
}

必需的 CSS

為了在使用 HologyScene 組件時正確處理指針事件,需要在您的項目中添加以下 CSS。這將確保可以在畫布上捕獲指針事件(由指針事件服務使用),同時也可以捕獲添加為組件子元素的 HTML 元素上的事件。

.hology-overlay {
  pointer-events: none
}
.hology-overlay * {
  pointer-events: auto; 
}

Hology React hooks

在 HologyScene 組件內使用的組件可以使用像 useService 這樣的hooks來訪問遊戲實例中的任何遊戲服務。


function PlayerHealthDisplay() {
  const playerState = useService(PlayerState)
  return <h1>{playerState.health.value}</h1>
}

function App() {
    return (
      <HologyScene gameClass={Game} sceneName='demo' dataDir='data' shaders={shaders} actors={actors}>
        <PlayerHealthDisplay></PlayerHealthDisplay>   
      </HologyScene>
    )
}
  • useService - 獲取遊戲代碼中任何服務的實例。這對於持有一些全局遊戲狀態的服務很有用,您可能想要顯示這些狀態。

  • useActorQuery - 查詢當前添加到遊戲世界的角色。每當匹配查詢的角色被添加到世界或從世界中移除時,組件將重新渲染。

  • useRenderUpdate - 在每一frame之前執行給定的函數。

  • useRenderLaterUpdate - 在每一幀之前但在其他更新函數之後執行給定的函數。

當狀態改變時更新 UI

React 旨在僅在某些內容發生變化時才重新渲染,這對於高性能的用戶界面來說很好,但它需要知道什麼時候發生了變化。如果您想在用戶界面中顯示遊戲代碼中的某個值,您可以通過訪問服務或角色來讀取該值,但您需要讓 React 知道該值已經改變。

管理這種情況的一種方法是使用信號。信號是一個在 Web 前端開發中越來越流行的概念,它允許您以一種方式表示狀態,使得該狀態的消費者可以知道信號的值何時發生變化。當您創建一個新的 Hology Engine 項目並選擇 React 作為 UI 框架時,它會自動安裝一個名為 @preact/signals-react 的庫。

假設您的遊戲代碼中有一個如下所示的服務。我們在定義屬性時使用 signal 函數。

import { Service } from '@hology/core/gameplay'
import { signal } from "@preact/signals-react"

@Service()
class PlayerState {
  health = signal(100)
}

export default PlayerState

現在我們可以在 React 組件中訪問這個健康信號,如下所示。首先,我們使用 useService hook來訪問 PlayerState 類的實例。可以使用 .value 屬性訪問健康信號的值。

function PlayerHealthDisplay() {
  const playerState = useService(PlayerState)
  return <h1>{playerState.health.value}</h1>
}

我們可以稍後通過為 value 屬性分配新值來更新信號的值。在下面的例子中,我們定義了一個方法,根據給定的傷害量更新健康信號。

import { Service } from '@hology/core/gameplay'
import { signal } from "@preact/signals-react"

@Service()
class PlayerState {
  health = signal(100)
  
  takeDamage(damage: number) {
    this.health.value = Math.max(0, this.health.value - damage)
  }
}

export default PlayerState

每當信號更新時,React 組件將自動重新渲染。

最后更新于