見出し画像

初心者が56時間でブラウザゲームを作ってリリースしてみた


ゲーム作りてえええええええええ!!!!!!!!!!!!!

唐突にそんな思いに駆られ、つい先日、ゲーム作り完全初心者のくせに思い切って「Unity1週間ゲームジャム」に参加してみました。

ちなみに実際に僕が作ったゲームはこちらです。

記憶力と推理力を頼りに 形の見えないパズルを解いていくゲームです。よかったら遊んでみてください。PC推奨ですが、スマホでもできなくはないです。ただしSafari君ではダメです。

かなり面白いです。出来た時に「ハイハイ理解理解!!! 俺って頭いいかも!!」ってなれて、心の底にあるキショい欲求が満たされていく実感が心地よいです。以上、バイアスごり掛かり感想でした。


それじゃ、作り始めますね


12月20日(日) ~0日目(作業時間:6時間)~

まだゲームジャムの存在を知りません。

ですが、唐突に体を駆け巡るゲーム作りたい欲求を止めることはできません。

そんな折、こんなブログを見つけました。

ド初心者向けのゲーム制作の教材みたいな感じです。

そんな難しくなさそうだし、丁寧に書いてるっぽい」と思い、やったれやったれと軽い気持ちで始めてみました(実際、超初心者向けにかなり丁寧に解説されており、めちゃくちゃ分かりやすかったです)。

始める前は「このpublicってどんな機能なんだ? なんであったりなかったりするんだ?」みたいなレベルでしたが、終わるころにはゲームは裏でどういうシステムが動いてて、何にどんな機能があるのかとかがなんとなく分かるようになってきました。

そして、終わった頃に偶然「Unity1週間ゲームジャム」の存在を知り、参加を決意。

就寝。


12月21日(月) ~1日目(作業時間:4時間)~

Unity1週間ゲームジャムの概要ページをなんとなく見ます

どうやら、全員が共通のテーマのもと1週間という短い期間でゲーム作りしようぜって感じの企画らしいですね。

今回のテーマは「あける」。ひらがなで書いてあるあたり、「多義的に解釈してくれよ~」という主催者の意図を感じます。こういうのを見ると、オタクとしては裏の裏をかきたくなってしまいますね。

それを踏まえていくつか制作候補を出しました。

・動物同士の間隔を空けて配置するパズルゲーム
・公園の各遊具に閉じ込められたキリンを脱出させるゲーム
・偏ったシマウマの柄をちゃんと配置するゲーム
・アイスクライマーのけつにルービックキューブを詰めるゲーム
・ライオンのいる部屋から脱出するゲーム
・他にも「あける」というワードから連想させる言葉をいくつか出したり

「あける」を開ける、空ける、明けるとか広げたり、あけるのあいうえお作文を作ってみたり、色々頭蓋をひねりながら20個くらい考えました。

迷いつつも、無難に1個目の「動物同士の間隔を空けて配置するパズルゲーム」に決定しました。

どんなゲームにしようかな~って考えてた内容はこんな感じです。

・数種類の動物たちをマス目に配置していく
・動物自体は1マス分の大きさしかない
・しかし、動物は種類ごとに異なる不可視の当たり判定を持っている
・目に見えないピースを記憶力と推理力を頼りに埋めていくパズルゲーム

うーん、よくわからん。

頭の中に何となくのプレイ画面とかがあるんですが、それを文字として出力できない。言葉っていっぱいあって難しいです。

ちなみにこれに決めた理由は大きく次の4つです。

・他の人も作りそうな、凝りすぎてないものにしたかった
 (→自分のと比較して参考にするため)
・とはいえ評価軸にもある「斬新さ」は多少担保したかった
・パズルゲームの情報はネット上にいっぱいありそう
・どういう仕組みを入れればいいかがイメージしやすかった

パズルって「ドラッグアンドドロップを正しい場所に行う」「正しい場所に配置出来たらクリア」くらいの機能が作れれば問題ないっぽいな~っていうカスの見立てをしてました。後々痛い目を見ます。

その後は構想を詰めて、ラフを描いて、どんなオブジェクトが必要かを列挙して、AssetStore(背景とかゲームシステムとかがいっぱいあるショップ的な)から使えそうなやつを探してきて、簡単にUnity上に配置してみました。

画像2

動物オブジェクトの絵を先に描いても仕方ないのでとりあえず手持ちのやつを適当に。赤丸のとこに動物(パズルのピース)を置いておいて、マス目に配置していく感じを想定してます。黄色で塗ってるとこは赤いオブジェクトの当たり判定で、ここに触れるとダメ、みたいな。動物を上位レイヤーに表示できず、パズル待機場所の下に配置されちゃうのなんでだろう。

現状、スクリプトは1文字も書いてません。なーんにも分からないので。

あと、かなり似た境遇の先行者がいたので1週間の流れの参考にしました。こういう知見がネット上に溜まっていくの、ありがてぇ。


12月22日(火) ~2日目(作業時間:4時間)~

自分の中で「最低実装すべき内容」「できれば実装したい内容」「理想の実装内容」をざっくり分類しました。期日までに提出することが大事なので、変なところでこだわって時間を取らないようにするためです。

それで「最低限実装すべき内容」の中で特に重要だと思っていた処理が2つあります。「パズルのドラッグアンドドロップ」「パズルの形状の作成(見えない当たり判定をつける)」です。まず前者から取り掛かりました。

【ドラッグアンドドロップ関係の処理でやりたいなと思ってこと】

・動物(パズルのピース)をドラッグできる
・配置場所(ステージのマス目)真ん中にドロップされる
・待機場所か配置場所以外に置いたら元の場所に戻る
・(できれば)複製したオブジェクトを配置したい
・ちまちま戻すのは手間なので、リセットボタン付けたい

結果、全然うまく実装できませんでした。
自分がやりたい処理が書いてる記事を見つけても、言外に端折られてる超常識的部分とかが自分には分からない、ということが往々にしてありました。

上記2つの記事は、まさに自分の実現したい処理でしたが、初心者の自分にとってはエラーが起きる理由も、どう解決していいかも分からず断念。ちなみに今見たら結構理解できたので、この2つはやはり分かりやすくて良質な記事でした。

そもそも僕の想定するパズルゲームの知見が思った以上にない、もしくは専門的過ぎて理解するのに時間がかかるものでした。

パズルはパズルでも、マッチ3パズル(例:パズドラ)、落ち物(例:ツムツム)、クリックするとタイルがひっくり返って模様そろえるやつとかはいっぱいありました。

とはいえ、「パズル(オブジェクト)のドラッグアンドドロップ」「パズル(オブジェクト)に見えない当たり判定をつける」さえ実装できれば良いので、根気よく調べたりコードを書き替えたりしてみます。

画像1

ドラッグアンドドロップを制御するためのコードがいっぱいある……。

就寝。


12月23日(水) ~3日目(作業時間:3時間半)~

ドラッグアンドドロップ、完成。

この方の動画がめちゃくちゃ分かりやすかったです。この人がいなければ詰んでました。ありがとう、スタジオしまづさん。

とはいえ、まだ1ステージも作れてないどころか、当たり判定すらつけられてないです。

しかも、この時点でいったんプロジェクトを作り直しました。元々画像はGameObject→Spriteでシーンに置いてたんですが、UIにしてたほうが操作しやすいなって気が付いたので。(それが正しいかどうかは分かりません)

やばいやばいと焦りながら、ぐっすりと就寝。


12月24日(木) ~4日目(作業時間:7時間半)~

【この日実装したもの】

・各パズルの当たり判定
・パズル待機場所にパズルをきれいに配置する機能(Grid Layout Group)
・リセット機能

パズルの当たり判定、めちゃくちゃ時間掛かりました。変遷はこんな感じ。

そもそもどうやってやるのかを調べ、どうやらColliderだけでなくRigidBodyも必要だと知るが、何か上手くいかない。

→→Physics2D.OverlapCircleでやってみると、いけなくはなさそうだけど理想の挙動にならない(相手のCircleに触れるとリセットされるが自分のに触れられてもリセットされない)

→→もう一回Collider&RigidBodyで試してみるといけた。多分スクリプト内に{}が余ってたっぽくて、それで作動しなかったかもしれない。見直し大事。

実際に書いたスクリプトはこんな感じです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class Movement : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
   public Transform defaultParent; //canvasTran って他の教材とかだと書かれがち
   public Transform oya; //パズル配置場所を定義

   private void Awake()
   {
       
   }

   public void OnBeginDrag(PointerEventData eventData)
   {
       defaultParent = transform.parent;
       transform.SetParent(defaultParent.parent); //Canbas=親(defaultparent)の親 が親になった
       GetComponent<CanvasGroup>().blocksRaycasts = false;

       //動物の複製をする場合はAwakeにdefaultParent = transform.parent を宣言して
       //ここでCreateDragObjent関数(自分で作れ)を発動させる
   }

   public void OnDrag(PointerEventData eventData)
   {
       transform.position = eventData.position;
   }

   public void OnEndDrag(PointerEventData eventData)
   {
       transform.SetParent(defaultParent);
       GetComponent<CanvasGroup>().blocksRaycasts = true;
         
   }

   void OnTriggerStay2D(Collider2D collision)
   {
      
       //後者の条件だけでいい気がする。後で確認→ダメだわ
       if ((collision.transform.parent.tag == "DroppableField") && (transform.parent.tag == "DroppableField"))
       {
           Debug.Log("aaaaaa");
           PositionReset();
       }
   }


   public void PositionReset()
   {
       GameObject[] animals = GameObject.FindGameObjectsWithTag("Animals");
       foreach (GameObject animal in animals)
       {
          animal.transform.parent = oya;           
       }
   }

}

うん、比較的まとまってる気がする。Awake関数はオブジェクト複製の際に使おうと思い、置くだけおいてます。PositionReset関数はリセットボタンにも割り当てました。

animal.transform.parent = oya;

最後の↑は、動くけど「SetParentを使ってくれ」とコンソールに警告出てたので本番環境では書き換えてます。noteの最後に完成版載せてます。


次はクリア判定の実装。

このパズルは置く場所ではなく、動物同士の位置関係が大事なので、ポジションではなくタグを上手く使ってクリア判定を使用と試みました。

が、かなり難しかった。以下変遷。

動物のタグ→Animals、 パズル設置場所のタグ→DroppbleField と定義

「全ての動物の設置が終わった時に全てのAnimalsタグの親のタグがDroppbleFieldならクリア」→上手くいかない

→→「パズル待機場所に何もない、かつ、DroppbleFieldの子タグがAnimalsならクリア」→上手くいかない

→→配列を使ったり、孫タグを使ったり、数を数えたり色々した→上手くいかない。

→→「クリアボタン(新しく作る)を押したときに、パズル待機場所に子オブジェクトがなかったらクリア」→上手くいった!!!!!

というわけで、最低限パズルゲームとして成立させるべき機能は完成しました。次の問題は、僕は画面遷移ステージ変更等をどうやってやればいいかを調べること。

今まで考えてこなかったレベルデザインをちょっとずつ考えながら、就寝。


12月25日(金) ~5日目(作業時間:12時間)~

色々やったので分けて書きます。今日で「あとはいっぱいステージを作るだけだー」まで持っていけると思ったけど、そうでもなかったです。

◆SEとかBGMつける。かなりめんどくさかった◆

AudioSourseでBGMは鳴らせたんですが、SEが上手くいかなかったです。原因が分からず面倒だったので、楽にできそうな下記のアセットを使用しました。丁寧に書いていただけて分かりやすかったです。

(本来の機能的にはできるが)僕には個別でSEの音量調整が出来なかったので、全体でSEの音量を0.5まで下げました。

SEはフリー素材を、BGMは過去に作ったオリジナル曲を使いました。時間があったら音色変えたりループ対応できるよう再調整したい。


◆タイトルシーン、ステージ選択シーンの作成と遷移スクリプトできた◆

タイトルにはこのアセットを使いました。絶対自分で作るよりも早いと思ったので。

だいぶシンプルですが、パズルゲームを作るにはこれくらいで大丈夫ですね。Quitを消して、チュートリアルが表示されるようにだけ変えました。(チュートリアルは完成後の画像ですが、フォント以外は制作中のと同じです)

画像3

画像5

ほんとは1~3ステージあたりをプレイしながらゲームシステムが理解できるチュートリアルみたいにしたかったんですが、多分そんな余力はないのでこの形に落ち着きました。ここでこだわりすぎないで良かったです。

ステージ選択シーンについては、何ステージ作るか決めてないのでざっくり作りました。シーン移動のスクリプトは分かったし、実際に挙動も確認したので、あとは増やしていくだけです。

画像4


◆動物全体のPrefabを消して各動物をそれぞれPrefab化した◆

元々「Animal」というPrefabを作り、そこに個別で動物達の画像や当たり判定をつけていたのですが、動物個別のPrefabがないとステージ増やすときに面倒だと思い、大元のAnimalを削除→個別動物Prefab化を実行しました。

今にして思えば、別にAnimalを消す必要はなかったのですが、Prefabで作ったものをPrefabにできることを知らなかったのでこんな感じになりました(もちろん失敗したときに備えた安全策は用意してました)。

しかし、この処理をしたことでなぜかリセットボタンが使えなくなり、かつ、リセットされた場合オブジェクトが消える事態が発生しました。PositionReset関数はちゃんと働いてるので、原因が分からず、最悪なくても困らないなと思いリセットボタン自体は消しました。

後で判明したのですが、各動物達をPrefab化したときに彼らに設定してた「待機場所」が外れていたためでした。後ほどリセットボタン復活。

画像13

◆ステージの表現やデザインの調整◆

動物の置けるマス目だけをステージに配置するとこの動物はどこに何マスの当たり判定を持っているかが直感的に分かりにくいと思い、「動物を置けないマス目」も作成(上のGIFにある赤黒いエリアです)。

UIをきれいにするのは余裕なくてできず。


ここらであとやらないといけないことを改めて整理しました。

必須:

〇各動物の当たり判定を決定する
〇各ステージのレベルデザイン(動物が全8種だし最低8ステージ作る)
〇各シーンのUIや背景等に画像入れたりデザインをきれいにしたりする
・タイトル画面:背景、ロゴ、各ボタン、遊び方説明画面
・ステージ選択画面:背景、各ボタン(最大20程度を配置できるように)
・プレイ画面:各ボタン(Check、Reset、Title、NextStage、BackTitl)

努力:

〇BGMを改めてこのゲーム用のを作りたい
〇SEも自分で作りたい
〇シーン遷移やタイトル画面等の構成をもう少しスマートに
〇20ステージは作りたい


ゲームっぽくなってきた。就寝。


12月26日(土) ~6日目(作業時間:9時間)~


最低限提出しても問題ないくらいまで進みました。

◆動物の追加とステージ作成◆

各動物の当たり判定を決めた際に「もう少し簡単なやつも必要だな」と思い1種類追加しました。ちなみにパンダの当たり判定(=パズルピースの形状)はこんな感じです。

画像6

他のやつはゲームの方で見れるので、興味がある方はぜひ「タイトル→ステージ選択→各動物の感染エリアの答え」を見てみてください。


また10ステージ目まで作りました。

作りながら「これ、めっちゃ難しいうえに、何をすればよいのかわかりにくいのでは?」と思い、途中で1度母にテストプレイをしてもらいました。結果、やはり操作方法やクリア条件がわかりにくく「そもそもどういうゲームか」も理解しにくいことが分かりました。

なので1~3ステージには文字を入れて静的なチュートリアルっぽい感じにしてみました。それでも分かりにくいですが、多少マシになりました。

画像8

10ステージ目までで4種類しか動物を使ってないけど、いきなり難しくは出来ないので、順当だと信じたいです。逆に、各ステージの難易度差を考えると、できればあと10~15ステージはないとダメだ。しんど。

画像7


◆一回ビルドしてみる◆

ステージをいっぱい作った後に「実はそもそも失敗してました」とかなると最悪だと思い、試しに一回ビルドしてみました。

結果、画面が普通にズレてました。気が付けてよかった!!

画像9

調べた結果、Canvas Scalerを設定すればいいっぽいと分かり Scale with Screen Sizeに設定してみますが、それでもズレる。アンカーポイントが原因かと思いましたが、あんまり変わらず。

結果、普通に出力の画面サイズを変えて解決しました。WebGLは960×600pxがデフォルトらしいのですが、僕は1024×768pxで作ってたのでコレが一番の原因ですね。

今思えば、出力サイズ変えただけなのはただの対処療法でしかないので、今後は画面サイズ調整とかも色々勉強したいです。

あと、初期設定のArialフォントだと日本語が出力されないことを知ったので、日本語に対応できるフォントを追加しました。ついでに幾つか使えそうなのもUnity内に持ってきました。元々フォントをいっぱい持っていたので、時間はあまりかけずに対応完了。


◆その他◆

・タイトル画面に背景や動物を入れた
・SEやBGMの音量調整した(BGM聞きすぎて嫌いになってきたので変えたい)


いよいよ終わりが見えてきました。〆切の27日20時まで時間もないので、明日やることを再度まとめました。

必須:

〇ステージ20まで作成する
〇18時までに完成させてビルドする

努力:

〇UIをもっときれいに
〇BGMの音色を作り直す、もしくは新しく作る
〇チュートリアルをアニメーションありで作りたい
〇タイトルロゴとかにアニメーション加えたい

12月27日が僕の誕生日だったのですが、Twitterでいっぱいお祝いメッセージ来てて嬉しいーって思いながら就寝


12月27日(日) ~最終日(作業時間:11時間)~

27日20時が〆切。クオリティを上げていきたい自分からしたら結構ギリギリなスケジュールですが、うまく折り合いつけていきたいですね。

◆ステージ追加を決定◆

20ステージまでの予定を「24ステージ」に変更。理由は「動物の数に対して、ステージが足りなかったから」。どの動物がどんな当たり判定を持っているかを探らせるために丁寧に作りすぎた気もするが、こういうのは作り手の想定する難易度と実際の難易度が乖離する気がするので丁寧に越したことはないと自分を納得させました。

16時の時点であと5ステージ作れば完成で、かつ3つは構想も出来てたので「よゆーだな」って調子づいてました。後々死にます。


微調整◆

クリア画面でBGMを消したかったのですが、上手くできませんでした。AudioSourse周りは初心者にとってはかなり鬼門でした。音なんてゲームでもよく使う機能なのに全然使いこなせてないのやばいなぁ……。

あとはタイトルにアニメーションつけました。いい感じですね~。

画像10

アニメーションには上記ブログで紹介されていた「TypefaceAnimator」を使用しました。すごい簡単で助かりました。


現時点で17時くらいです。ここから怒涛のスパートを迎えます。

・いくつかのステージでリセットがうまく機能しないバグ発見。直す。
・動物の当たり判定の答えが必要だと思い、急遽シーン追加。
・最終ステージ終了後の画面を追加

この辺は思考時間がもったいないと思い、ごり押しみたいなスクリプトを書いたし、レイアウトも適当です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class AnswerCOntroller : MonoBehaviour
{
   public GameObject pandaPanel;
   public GameObject momongaPanel;
   public GameObject eaglePanel;
   public GameObject kangarooPanel;
   public GameObject lionPanel;
   public GameObject pegasusPanel;
   public GameObject chickenPanel;
   public GameObject elephantPanel;
   public GameObject giraffePanel;


   public void ClosePandaPanel()
   {
       pandaPanel.SetActive(false);
   }

   public void OpenPandaPanel()
   {
       pandaPanel.SetActive(true);
   }

   public void CloseMomongaPanel()
   {
       momongaPanel.SetActive(false);
   }

   public void OpenMomngaPanel()
   {
       momongaPanel.SetActive(true);
   }

~~~~~~中略~~~~~~~~

​    public void OpenGiraffePanel()
   {
       giraffePanel.SetActive(true);
   }

   public void BackTitleMove2()
   {
       SceneManager.LoadScene("Title Scene");
   }

}

画像11


そんなこんなで19時過ぎに完成!!!!!!!


達成感!!!!!!!!!!


あとはビルドして提出するだけ。とはいえ、時間も結構ギリギリなので予断は許さない状況。先んじて提出に必要な文章をビルド中に書いておく。

そして、20時35分提出完了!!! おりゃぁぁぁ!!!

はい、普通に時間オーバーしました。オーバーしてもそんなに問題ないとはいえ、かなり凹みました……。
オーバーした原因はこんな感じです。事前に予期・対応できるものばかりだったので未熟すぎて悔しいです。

〇出力時の圧縮方式を間違えていた
〇(多分アクセス集中で)サイトが落ちたりしてた
〇サムネイル用のGIFを急遽作成(画像でもいいのですが、GIFの方がインプレッション稼げそうだなって思いまして)

提出後に1回プレイしてみましたが、概ね大丈夫そうです。ですが急遽追加した動物の当たり判定一覧日本語フォント入れ忘れてた場所を見つけました。あー、わざわざボタンとか使わないで一覧で表示しちゃってもよかったかも。


とはいえ、1週間かけて作ったゲームがリリースされるのは達成感や解放感もすさまじく、この後食べたご飯は喉をスルスルと通りまくりました。


そしてこの後、誕生日お祝いをくれた人に勝手にイラストを描いて送りまくるというテロリズムをして就寝。


まとめ

こうして初ゲーム作りに没頭した1週間は終わりました。

これまでの時間合計はこんな感じです。

事前学習(0日目)  :6時間
ゲーム制作(1~7日) :50時間

画像12

こんだけ時間があってもやり足りないことばかりでしたが、自分の頭の中で描いていたものを出力するのは過程も結果も楽しかったです!

振り返りとしては下記の感じですかね。

【やっておけばよかったこと】

〇事前にWebGLの出力の基本について調べておく
〇Prefab化についてもっと調べたうえで計画的に
〇一言で簡潔に説明できる仕様にする
〇他の人のゲームをもっとプレイして遷移やUI、説明などを見ておく

【もっとこのゲームシステムをよくするためにやりたいこと】

〇直感的にはわかりにくいゲームシステム
〇リセット機能を「誰かの当たり判定同士が触れたら全動物リセット」ではなく、「当たったやつらだけがリセット」に変更
〇プレイ中に当たり判定が表示できる「ヒントモード」の搭載
〇UIをシンプルかつおしゃれに(色あんまり使わなくていいかも)
〇コンセプトや説明をもっとスマートにできるように
〇動的なチュートリアルを導入したい
〇レベルデザインをもっといい感じにしたい


まだ他の方のゲームはプレイできてないので、これからいっぱい遊びます!!

改めて、僕が今回作ったゲームです。


今回書いたスクリプト


ステージクリア画面の表示

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour
{
   public GameObject storeCount;

   public GameObject clearScreen;

   // Start is called before the first frame update

   public void IsClear()
   {
       int StoreChildCount = storeCount.transform.childCount;
       if (StoreChildCount == 0)
       {
           clearScreen.GetComponent<ClearScreen>().OnEnter();

           //clearScreen.SendMessage("OnEnter");
           //SceneManager.LoadScene("StageSelect");
           print("Clear"); 
           //これだとクリアした瞬間に行ってまう
       }
   }

   // Update is called once per frame
   void Update()
   {
       
   }
}


クリア画面の操作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using KanKikuchi.AudioManager;

public class ClearScreen : MonoBehaviour
{
   public GameObject panel;
   public int index;
   public GameObject audioSourse;

   void Start()
   {
       panel.SetActive(false);
   }

   public void OnEnter()
   {
       panel.SetActive(true);
       SEManager.Instance.Play(SEPath.CLEARSOUND);
       audioSourse.GetComponent<AudipControll>().BgmStop();

   }

   public void NextStageMove()
   {
       int index = SceneManager.GetActiveScene().buildIndex;
       index++;
       SceneManager.LoadScene(index);
   }

   public void BackTitleMove()
   {
       SceneManager.LoadScene("Title Scene");
   }
}


ドロップされる側のオブジェクト(フィールド上のマス目)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class DropPlace : MonoBehaviour, IDropHandler

{
   public void OnDrop(PointerEventData eventData)
   {
       Movement animal = eventData.pointerDrag.GetComponent<Movement>();
       if (animal != null)
       {
           animal.defaultParent = transform;
       }
   }
}


ドラッグする側のオブジェクト(ほとんどこれで制御してます)
(一回↑で載せてますが、それにSE操作を加えたものです)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using KanKikuchi.AudioManager;

public class Movement : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
   public Transform defaultParent; //canvasTran って他の教材とかだと書かれがち
   public Transform oya;

   public void OnBeginDrag(PointerEventData eventData)
   {
       defaultParent = transform.parent;
       transform.SetParent(defaultParent.parent); //Canbas=親(defaultparent)の親 が親になった
       GetComponent<CanvasGroup>().blocksRaycasts = false;

       //動物の複製をする場合はAwakeにdefaultParent = transform.parent を宣言して
       //ここでCreateDragObjent関数(自分で作れ)を発動させる
   }

   public void OnDrag(PointerEventData eventData)
   {
       transform.position = eventData.position;
   }

   public void OnEndDrag(PointerEventData eventData)
   {
       transform.SetParent(defaultParent);
       GetComponent<CanvasGroup>().blocksRaycasts = true;
​       SEManager.Instance.Play(SEPath.MOVESOUND);
   }

   void OnTriggerStay2D(Collider2D collision)
   {
       //後者の条件だけでいい気がする。後で確認→ダメだわ
       if ((collision.transform.parent.tag == "DroppableField") && (transform.parent.tag == "DroppableField"))
       {
           Debug.Log("aaaaaa");
           PositionReset();
       }

   }


   public void PositionReset()
   {
       GameObject[] animals = GameObject.FindGameObjectsWithTag("Animals");
       foreach (GameObject animal in animals)
       {
           animal.transform.SetParent(oya);
       }

       SEManager.Instance.Play(SEPath.SYSTEM20);
   }
}

 


特殊な当たり判定を持つ動物のCollider操作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using KanKikuchi.AudioManager;

public class ResizeBoxCollier2D : MonoBehaviour
{
   private float START_SECOND_First = 3.0f;
   private float START_SECOND_Second =3.2f;
   private float INTERVA_SECONDS = 3.0f;

   void Start()
   {
       InvokeRepeating("ResizeChickenCollider1", START_SECOND_First, INTERVA_SECONDS);
       InvokeRepeating("ResizeChickenCollider2", START_SECOND_Second, INTERVA_SECONDS);
   }

   void ResizeChickenCollider1()
   {
       BoxCollider2D collider = GetComponent<BoxCollider2D>();
       collider.size = new Vector2(480, 480);

       if (transform.parent.tag == "DroppableField")
       {
           SEManager.Instance.Play(SEPath.CHICKENCRY);
       }
       
       //したいこと
       //親がFieldの時、鳴く
       //もしくは、親がFieldの時、Colliderに何か当たったら鳴く
   }

   void ResizeChickenCollider2()
   {
       BoxCollider2D collider = GetComponent<BoxCollider2D>();
       collider.size = new Vector2(100, 100);
   }
}


ありがとうございました~。今後もいっぱいゲーム作っていきたいです!

この記事が気に入ったらサポートをしてみませんか?