初めて質問させて頂きます。TomoeEbihara と申します。ゲーム作りに興味を持ちまして、Unity の勉強を始めました。Unity のバージョンは「2017.3.0f3」です。練習のつもりで、2D の『倉庫番』を作ってみようと思いたち、色々な教材を参考にしながら、ようやくゲームパッドの左スティックで主人公を上下左右に動かすところまで作りました。以下のスクリプトを、主人公「Player」にセットしています。ゲームパッドで「target」を動かし、主人公は常にそこに向かって歩き続けているという仕組みです。
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Player : MonoBehaviour 6{ 7 float x_axis; 8 float y_axis; 9 10 Vector3 target = new Vector3(0, 0, 0); 11 int grid = 1; 12 float speed = 3f; 13 14 // Use this for initialization 15 void Start(){} 16 17 // Update is called once per frame 18 void Update() 19 { 20 PlayerControll(); 21 Walk(); 22 } 23 24 void PlayerControll() 25 { 26 x_axis = Input.GetAxisRaw("Horizontal"); 27 y_axis = Input.GetAxisRaw("Vertical"); 28 29 //「Raycast」という機能を使って、主人公の周囲に線を引く 30 RaycastHit2D HitTop, HitRight, HitBottom, HitLeft; 31 HitTop = Physics2D.Raycast(transform.position + new Vector3(-0.4f, 0.5f), Vector2.right, 0.8f); 32 HitRight = Physics2D.Raycast(transform.position + new Vector3(0.5f, 0.4f), Vector2.down, 0.8f); 33 HitBottom = Physics2D.Raycast(transform.position + new Vector3(-0.4f, -0.5f), Vector2.right, 0.8f); 34 HitLeft = Physics2D.Raycast(transform.position + new Vector3(-0.5f, 0.4f), Vector2.down, 0.8f); 35 36 //主人公が「target」と同じ位置にいて、進行方向に障害物が無い場合、ゲームパッドで「target」の座標を変更する 37 if (target == transform.position) 38 { 39 if (HitTop.transform == null) {if (y_axis > 0) { target += new Vector3(0, grid, 0); x_axis = 0;}} 40 if (HitRight.transform == null) {if (x_axis > 0) { target += new Vector3(grid, 0, 0); y_axis = 0;}} 41 if (HitBottom.transform == null) {if (y_axis < 0) { target -= new Vector3(0, grid, 0); x_axis = 0;}} 42 if (HitLeft.transform == null) {if (x_axis < 0) { target -= new Vector3(grid, 0, 0); y_axis = 0;}} 43 } 44 45 } 46 47 //主人公を「target」に向かって歩かせる 48 void Walk() {transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);} 49}
ブロックの壁「Wall」がある場合は、それより先には進めない様にしたいと思っています。そこで、今は「Raycast」機能で、進行方向にブロックの壁があるかどうかを判定し、無い場合にのみ、進める様にしています。その為に、ブロックの壁には「Box Collider 2D」をセットしています。
ただ『倉庫番』は倉庫の中に散らばった荷物を所定の位置まで運ぶという内容のゲームですので、主人公が荷物に接触している事を判定させる為には、壁だけでなく、荷物の方にも「Box Collider 2D」をセットしなければならないのかな、と考えています。
しかし、どうやら今のスクリプトだと「Wall」だけでなく「Box Collider 2D」をセットした荷物の方まで障害物となってしまう様なのです。しかし「Box Collider 2D」を外してしまうと、主人公と荷物が接触しているかどうかを判定できない気がしています。なので、ブロックの壁には「Wall」荷物の方には「Baggage」というタグまたはレイヤーを設定して、下記の様に、主人公が接触した場合の処理を書き込む事ができれば便利だなと思っています。
現状
C#
1if (HitTop.transform == null) 2if (HitRight.transform == null) 3if (HitBottom.transform == null) 4if (HitLeft.transform == null)
書き換え案(タグ)
C#
1//壁と接触 2if (HitTop が「Wall」というタグが設定された物と接触) {上に進めない} 3if (HitRight が「Wall」というタグが設定された物と接触) {右に進めない} 4if (HitBottom が「Wall」というタグが設定された物と接触) {下に進めない} 5if (HitLeft が「Wall」というタグが設定された物と接触) {左に進めない} 6 7//荷物と接触 8if (HitTop が「Baggage」というタグが設定された物と接触) {上に荷物を押せる} 9if (HitRight が「Baggage」というタグが設定された物と接触) {右に荷物を押せる} 10if (HitBottom が「Baggage」というタグが設定された物と接触) {下に荷物を押せる} 11if (HitLeft が「Baggage」というタグが設定された物と接触) {左に荷物を押せる}
書き換え案(レイヤー)
C#
1//壁と接触 2if (HitTop がレイヤー「Wall」に設置された物と接触) {上に進めない} 3if (HitRight がレイヤー「Wall」に設置された物と接触) {右に進めない} 4if (HitBottom がレイヤー「Wall」に設置された物と接触) {下に進めない} 5if (HitLeft がレイヤー「Wall」に設置された物と接触) {左に進めない} 6 7//荷物と接触 8if (HitTop がレイヤー「Baggage」に設置された物と接触) {上に荷物を押せる} 9if (HitRight がレイヤー「Baggage」に設置された物と接触) {右に荷物を押せる} 10if (HitBottom がレイヤー「Baggage」に設置された物と接触) {下に荷物を押せる} 11if (HitLeft がレイヤー「Baggage」に設置された物と接触) {左に荷物を押せる}
参考にしていただけるかどうか分かりませんが、以下に Unity の画像を貼り付けておきます。
Player
Wall
ゲーム画面
参考リンク
倉庫番 - Wikipedia
倉庫番(ゲームボーイ版の動画)
まだまだ、Unity やプログラミングの知識が全然足りなくて、試行錯誤しながら学習を進めているところです。こういう場合にはタグを使うのが良いのか、それともレイヤーを使う方が良いのか、もしくは他にもっと良い方法があるのかなど、是非ご教示いただきたいです。質問した部分以外にも、もし何か気づいた事があればアドバイスを頂きたいです。よろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/04 08:09 編集