表示テーマ
GameObjectの操作
Hierarchyで選択するGameObjectは、C#ではNEMEngine.GameObjectとして扱います。 このマニュアルでは、Editorの説明もGameObjectの表記に揃えています。内部のC++/ECSの型名や、既存の公開API識別子を変更するものではありません。
| Editorでの呼び方 | C#で使うもの | 役割 |
|---|---|---|
| GameObject | GameObject | 名前、アクティブ状態、Componentの取得・追加など |
| 自分のGameObject | gameObject | Scriptを所有するGameObject |
| Transform | transform、target.transform | 位置・回転・拡縮、親子関係 |
| Component | GetComponent<T>() | そのGameObjectに付いているComponentやScript |
NativeEntityとManagedWorldHandleはEngineとC#を接続するための情報です。ゲームコードで番号を組み立てたり、保存用のIDとして使ったりしません。
自分と別のGameObjectを取得する
Script内のgameObjectは自分のGameObjectです。別のGameObjectはGameObject型の保存Fieldを用意し、InspectorへHierarchyのGameObjectをドラッグして設定します。
csharp
[SerializeField] private GameObject? target;
void MoveTarget() {
// 参照先が残っている場合だけWorld位置を変更
if (target == null) return;
target.transform.position = new Vector3(0.0f, 1.0f, 0.0f);
}同じ参照先を繰り返し使う場合は、Inspectorから設定するか、検索結果をFieldへ保持します。未設定・参照先の破棄・Sceneの切り替えを考慮して、使用前に確認してください。
名前やタグから取得する場合は、次のAPIを使います。
csharp
// 名前またはタグから操作対象を探す
GameObject? player = GameObject.Find("Player");
if (player != null) Debug.Log(player.name);
GameObject? tagged = GameObject.FindWithTag("Player");
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");検索結果の名前が重複する場合、目的の個体を名前だけで区別できません。検索のたびに対象を探すため、毎frameの検索を前提にせず、参照を保持して使います。タグはプロジェクト設定のタグ・描画レイヤー設定で用意してください。
Componentを取得・追加する
csharp
// 既存の描画Componentを操作
MeshRenderer? renderer = gameObject.GetComponent<MeshRenderer>();
if (renderer != null) renderer.Visible = true;
// 追加したComponentへ後から設定できる参照を受け取る
PointLight light = gameObject.AddComponent<PointLight>();GetComponent<T>()はComponentを追加しません。存在しなければnullです。組込みComponentとMonoBehaviour派生Scriptは、同じ取得方法で扱います。
AddComponent<T>()は追加直後から設定するための参照を返します。構造の変更や他Scriptのコールバックがすべて完了した、とみなす操作ではありません。削除にはNEMEngine.Object.Destroy(component)を使い、GameObject全体の破棄と区別してください。
新しいGameObjectを作る
csharp
// 空のGameObjectを作り、World位置を決める
GameObject marker = new GameObject("Marker");
marker.transform.position = new Vector3(0.0f, 1.0f, 0.0f);これは空のGameObjectです。名前を付けるだけではMeshは表示されません。表示したい場合はRendererなどを追加・設定するか、設定済みのPrefabをNEMEngine.Object.Instantiate(prefab)で生成します。
生成や追加の要求には安全地点で反映される処理があります。同じコールバック内で、ほかのScriptのStartまで実行済みだとは仮定しないでください。Play中に生成したGameObjectは、Stop後の編集Sceneへ自動保存されません。
親子関係と座標
transform.positionはWorld座標、transform.localPositionは親を基準にした座標です。親の設定にはTransform.SetParentを使います。
csharp
// 親から見た位置で子を配置
GameObject child = new GameObject("Child");
child.transform.SetParent(transform, worldPositionStays: false);
child.transform.localPosition = new Vector3(0.0f, 1.0f, 0.0f);第2引数をtrueにすると、親の変更前のWorld位置・姿勢を保つ指定になります。falseは親を基準に配置したい場合に使います。親を外す指定はSetParent(null)です。
子の数はtransform.childCount、指定番号の子はtransform.GetChild(index)で取得します。番号は0始まりで、範囲外は例外になります。異なるSceneへの親子変更ができるとは仮定せず、Scene・Prefab・親子関係の制約を確認してください。
アクティブ状態と破棄
| 操作・状態 | 意味 |
|---|---|
target.SetActive(false) | GameObject自体を非アクティブにする。破棄とは異なる |
target.activeSelf | そのGameObject自身に設定した状態 |
target.activeInHierarchy | 親の状態も含めたアクティブ状態 |
NEMEngine.Object.Destroy(target) | GameObjectの破棄を要求する |
NEMEngine.Object.Destroy(component) | 指定したComponentまたはScriptの破棄を要求する |
破棄は要求後の安全地点で適用されます。呼び出した直後にすべての後処理が終わるとは限りません。適用後は、C#の参照変数が残っていてもtarget == nullが成立します。
生存確認にはtarget == null、target != nullを使います。 ReferenceEquals(target, null)やtarget is nullはC#参照そのものの確認です。?.や??もEngine側の破棄判定を代わりに行うものではありません。破棄済み対象へアクセスするとMissingReferenceExceptionになる場合があります。
Sceneのアンロード後に古い参照を使い続けないでください。Inspectorで指定したGameObject参照と、実行中のハンドルの番号を自作ファイルへ保存する方法は同じではありません。
そのまま使える例
このScriptをGameObjectに追加すると、子GameObjectを作り、親から見て1単位上へ置きます。空のGameObjectなので、確認はPlay中のHierarchyとInspectorで行ってください。
cs
using NEMEngine;
public sealed class GameObjectBasics : MonoBehaviour {
[SerializeField] private Vector3 childOffset = new Vector3(0.0f, 1.0f, 0.0f);
private GameObject? child;
void Start() {
// 自分を親にして子のGameObjectを生成
child = new GameObject("Marker");
child.transform.SetParent(transform, worldPositionStays: false);
child.transform.localPosition = childOffset;
}
void OnDestroy() {
// Scriptだけを外した場合も生成した子を破棄
if (child != null) NEMEngine.Object.Destroy(child);
}
}