今回はUnityで「ベルトコンベアみたいな動く床」の実装メモです。
キー入力で操作するプレイヤーがいて、床に乗るとプレイヤーが勝手に動くみたいな感じです。アクションゲームやシミュレーションゲームとかにあったりする感じのものですね。
実装開始
今回使用するのは「Unity 2020.3.26f1」ヴァージョン。3Dで作成していきます。
まずはPlane(平面)を2つ追加。

一つは全体の地面とするのでスケールを大きく変更。名前をGroundにしておきます。

もう一つを動く床にしていきます。名前をroadにしておきます。

カメラ位置は適当に好きなように変更。

見分けがつきやすいようにマテリアルを適当に設定して、下記のような感じにしておきます。
黒い部分が動く床になる場所です。

プレイヤーの実装
次にプレイヤーを作成していきます。
球体(Sphere)を追加して、ポジションとスケール変更。Cubeでも問題なし。

球体をキー操作できるようにするので「Rigidbody」、「Collider」、「PlayerInput」とスクリプト(PlayerMovement)を追加。

プレイヤーを動かすスクリプトの中身は下記に変更。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float PlayerSpeed;
private Rigidbody _rigidbody;
private Vector3 movement;
void Start()
{
_rigidbody = GetComponent<Rigidbody>();
}
void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movement = new Vector3(movementVector.x, 0.0f, movementVector.y);
}
void Update()
{
_rigidbody.velocity = movement * PlayerSpeed;
}
}
プレイヤーの移動方法については下記で詳しく書いています。
動く床の実装
次に動く床を実装します。
正確には床が動くのではなく、「床の上に乗ったプレイヤーに速度を加える」ことで床が動いている様に感じさせます。
まずは動く床部分にタグをセット。

プレイヤーを動かすスクリプトを下記に変更。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float PlayerSpeed;
[SerializeField] private Vector3 Roadforward;
[SerializeField] private float RoadSpeed;
private Rigidbody _rigidbody;
private Vector3 movement;
private Vector3 roadmove;
void Start()
{
_rigidbody = GetComponent<Rigidbody>();
}
void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movement = new Vector3(movementVector.x, 0.0f, movementVector.y);
}
void Update()
{
_rigidbody.velocity = movement * PlayerSpeed + roadmove;
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("road"))
{
roadmove = Roadforward * RoadSpeed;
}
}
private void OnCollisionExit(Collision collision)
{
if(collision.gameObject.CompareTag("road"))
{
roadmove = Vector3.zero;
}
}
}
床の上に乗った場合のみ、指定した速度を加えるようにしています。
あとはパラメータで「どの方向」に「どれだけの速度」を加えるのかを指定。

例えば、右に動く場合は下記の様な画像を用意して

マテリアルを変更して、スクリプトを追加。

スクリプトの中身を下記に変更。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moveroad : MonoBehaviour
{
float scrollSpeed = -0.5f;
Renderer rend;
void Start()
{
rend = GetComponent<Renderer>();
}
void Update()
{
float offset = Time.time * scrollSpeed;
rend.material.SetTextureOffset("_MainTex", new Vector2(offset, 0));
}
}
下のような感じに、動く方向を可視化出来たり。

スクリプトは下記リファレンスをほぼそのまま利用。
