コンポーネントでゲームオブジェクトを操る
Unityでは、ゲームオブジェクトが主人公になります。コンポーネントは、そのゲームオブジェクトの「機能」としてゲームオブジェクトにアタッチされています。
コンポーネントの機能を変化させることでプログラミングを進めていきます
基本のサンプル
2つのオブジェクト間アクセスのサンプルで見ていきます
シーンの構成
ゲームオブジェクトを2つ配置します
Cube
Position (-2, 0, 0)
Rigidbody (Use Gravity = false)
UseGravityTestスクリプト
Sphere
Position (2, 0, 0)
Rigidbody (Use Gravity = false)
落下するゲームオブジェクトにスクリプトがアタッチされている場合
サンプルでは、CubeにスクリプトとRigidbodyコンポーネントがアタッチされています。
作業としては、このRigidbodyのUseGravityのプロパティをオンにします
解説用シーン
Cubeにアタッチするスクリプト
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
GetComponent<Rigidbody>().useGravity = true;
}
}
}
スクリプトがアタッチされてない別のゲームオブジェクトを落下させるには
サンプルでは、Cubeにスクリプトがアタッチされていますがこれを落下させるわけではありません
別のゲームオブジェクト(Sphere)にアタッチされているRigidbodyコンポーネントに作用させます
作業としては、このRigidbodyのUseGravityのプロパティをオンにします
解説用シーン
スクリプト
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
GameObject.Find("Sphere").GetComponent<Rigidbody>().useGravity = true;
}
}
}
別の記述1
アクセスする頻度が高い場合、CPUの負荷を下げるために事前に変数にFindメソッドの結果を代入しておきます
このようにできるのは、Findメソッドの結果が変化しないからです
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
GameObject sphere;
void Start()
{
sphere = GameObject.Find("Sphere");
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
sphere.GetComponent<Rigidbody>().useGravity = true;
}
}
}
別の記述2
いっそのこと、コンポーネントレベルでキャッシュ(一旦保存)しておきます
ゲームオブジェクトの時(別の記述1)と同じく、メソッドの結果が変化しないことを利用しています
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
Rigidbody sphereRigidbody;
void Start()
{
sphereRigidbody = GameObject.Find("Sphere").GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
sphereRigidbody.useGravity = true;
}
}
}
別の記述3
さらに、メソッドで取得するのではなく、インスペクター上で得たいオブジェクトまたはコンポーネントをドラッグ&ドロップする方法があります。これも、変化することがないことが条件になります
2つのパターンをみていきましょう。ゲームオブジェクトを取得する方法とコンポーネントを取得する方法です
ゲームオブジェクトをインスペクターから取得する
取得したいゲームオブジェクトにアタッチされているコンポーネントにアクセスするのですが、さらにこのオブジェクトの他のコンポーネントにもアクセスしたい場合はこの方がいいです
ゲームオブジェクトをアウトレット接続(ドラッグ&ドロップ)することで、sphereフィールド変数にゲームオブジェクトが代入されます
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
public GameObject sphere;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
sphere.GetComponent<Rigidbody>().useGravity = true;
}
}
}
Rigidbodyをインスペクターから取得する
取得したいゲームオブジェクトの特定のコンポーネントにしかアクセスしない場合は、このように特定してもいいでしょう
ゲームオブジェクトをアウトレット接続(ドラッグ&ドロップ)することで、sphereRigidbodyフィールド変数にRigidbodyコンポーネントが代入されます
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
public Rigidbody sphereRigidbody;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
sphereRigidbody.useGravity = true;
}
}
}
おまけ
CubeをクリックするとSphereが落下する
Cubeをクリックして、Sphereゲームオブジェクトを落下させるコードになります
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
public Rigidbody sphereRigidbody;
void OnMouseDown()
{
sphereRigidbody.useGravity = true;
}
}
Cubeのドラッグ中(クリックしている間)、Cubeの位置を連続して取得
Input.MousePositionでは、マウスポインター(マウスの矢印の先)のスクリーン座標が取得できます。(カメラから見た2次元の座標で、左上が(0,0)になります。縦横はディスプレイのピクセル値になります。いわゆる画面をスクリーンとして見立てた場合の座標)
この座標をもとに、CubeにRay(光線の喩え)を照射して、コライダーの衝突場所を取得するようなことをやっています
using UnityEngine;
public class UseGravityTest : MonoBehaviour
{
public Rigidbody sphereRigidbody;
void OnMouseDrag()
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit))
{
Debug.Log(hit.point);
}
}
}
ディスカッション
コメント一覧
まだ、コメントがありません