Unityで「地面にブロックを設置する基本」を実装していきます。マインクラフト風(サンドボックス)にブロックを地面に設置する基本になります。マウス操作でブロックを移動、マウスクリックでブロックを設置します。
はじめに
Unityのバージョンは6.4で作成しています。
3Dゲームで「ブロックを地面に設置する」を実装していきます。Raycastを利用して地面を判定して設置します。
実装開始
フィールドとブロックの作成
「3DObject」→「Cube」と「Plane」を追加します。

「Cube」の名称を「Piece」に、「Plane」の名称を「Ground」に変更します。

「Piece」をAssetsフォルダに移動してプレハブ化します。

スクリプトの作成
スクリプトを作成、名称を「GameManager」とし中身を下記に変更します。
using UnityEngine;
using UnityEngine.InputSystem;
public class GameManager : MonoBehaviour
{
[SerializeField] private GameObject _piece;
private GameObject obj;
private void Start()
{
obj = Instantiate(_piece);
obj.GetComponent<Collider>().enabled = false;
}
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
obj.transform.position = hit.point;
}
}
Instantiateでブロックを生成し、マウス位置からレイを地面に発射して当たった位置にブロック位置を変更しています。
空オブジェクトを追加して名前を「GameManager」に変更、スクリプトをアタッチしてパラメータにプレハブをセットします。

実行すると下記の様な感じに、マウスの位置にブロックが移動します。

スクリプトを下記に変更します。
using UnityEngine;
using UnityEngine.InputSystem;
public class GameManager : MonoBehaviour
{
[SerializeField] private GameObject _piece;
private GameObject obj;
private void Start()
{
obj = Instantiate(_piece);
obj.GetComponent<Collider>().enabled = false;
}
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
obj.transform.position = new Vector3(hit.point.x, hit.point.y + 0.5f, hit.point.z);
if (Mouse.current.leftButton.wasPressedThisFrame)
Instantiate(_piece, obj.transform.position, Quaternion.identity);
}
}
ブロック位置を地面の上に移動、マウスクリックしたときにブロックを生成するようにしています。(+0.5fはブロックサイズの半分です)

マテリアルの設定
マテリアルを設定して見た目を少し変更してみます。下記の様に二つマテリアルを作成して、一つはアルファ値を変更して半透明にします。

Pieceプレハブのマテリアルを変更します。

スクリプトを下記に変更します。
using UnityEngine;
using UnityEngine.InputSystem;
public class GameManager : MonoBehaviour
{
[SerializeField] private GameObject _piece;
[SerializeField] private Material AlphaMaterial;
private GameObject obj;
private void Start()
{
obj = Instantiate(_piece);
obj.GetComponent<Collider>().enabled = false;
Renderer[] renderers = obj.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
renderer.material = AlphaMaterial;
}
}
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit))
obj.transform.position = new Vector3(hit.point.x, hit.point.y + 0.5f, hit.point.z);
if (Mouse.current.leftButton.wasPressedThisFrame)
Instantiate(_piece, obj.transform.position, Quaternion.identity);
}
}
「GameManager」のパラメータに半透明のマテリアルをセットします。

実行して下記の様になればOKです。

今回は基本的な動作の確認です。実際にはここからマス目を区切り、マス目に合わせるようにブロックを設置するなどの制御をすることで利用法に幅が出ます。