Grow 木の仕掛けを作る(2015/02/04)
雀荘です。
木の仕掛けを作ります
概要はこんな感じです。
いろいろあって、
リリーちゃんはやっぱりモノを持てない方が
いいんじゃないかということになったので、
具体的に敵を倒す仕掛けになっています。
hisojiさんが背景のプログラム作ってくれたので、
背景描いて木を生やして敵を作ってボスを作るだけで
ステージ完成ですね!!(白目)
しばらく間が空いてしまったので、
またぼちぼちと頑張りたいです。
Grow 背景の物体をそれっぽく動かす(2015/01/17)
hisojiです。
今回は背景を一枚絵じゃなくて複数画像でそれっぽく見せるようなことをします。(Unity 4.5.5f1)
今までは背景を素材からお借りしつつ自然を感じながら作っていたんですが、そろそろ背景を作らないといけなくなりました。
で、一緒に作ってる雀荘さんが「背景を分けましょう」みたいなことを言い出したんですね。
最近のゲームでは使われているらしいです。へー。
それでこんなものを作りました。gifで。
奥行きが出ていたりするんじゃあないでしょうかたぶん。
奥の柱みたいな画像と花の画像をそれっぽく動かしてます。
どうやってしてるかというと、キャラのx軸の進み具合によって位置を変えているんですね。
ただ奥側のオブジェクトほど位置の変化を小さくしています。
理論とか分からないけど現実でも奥側の風景ほど視点の変化が小さいからじゃないんですかね、空とか。
現時点のありのままのコード。
... public GameObject back; public GameObject lotus; public GameObject lotus2; public GameObject chara; void Update (){ float x = chara.transform.position.x; setBack (back.transform,0.1f,x); setBack (lotus.transform,0.2f,x); setBack (lotus2.transform,0.2f,x,50); } void setBack(Transform t,float z,float x,float offset = 1){ t.position = new Vector3(x - (x-offset)*z,t.position.y,t.position.z); }
setBackという何とも言えない名前の関数でフレーム毎に新しいVector3を代入してしまいます。zが奥行きを表す係数みたいなもので、xが基準値みたいなもので、キャラのx位置。offsetがオブジェクトの実際の位置みたいな。みたいな感じです。
ただこれたくさんオブジェクト作った時どうすればいいか考えてないんですよね。どのくらい置くのかも不明ですが。
あとは実際の位置が判断しづらいです。offset*z計算すればいいけどもう少し上手い具合に書いた方がいい気がします。
そういえば背景こんな感じにグリグリ動かしてるflashがあったんですよ。もう忘れたんですが。
奥行きの層を大量につくって動かしたらそれだけでも面白そうですね。
Grow 処理落ちを減らしたい
明けましておめでとうございます。hisojiです。
今年もサークル共々、ゲーム制作を続けていけるよう頑張ります。
今回は高速化について調べました。ゲームのジャンル的にはアクションですからそれなりに処理はかかるんじゃないかと思うので、この際にまとめてみようと思います。
処理速度の問題については前作の「NightBat」でも起こっていました。思えばCollider付きのオブジェクトが大量発生してた気がします。
そもそもこのゲームにおいて高速化する必要があるかが未検証なのですがまあ使うかもしれないですよ多分。
日本語のサイトを色々調べていたのですが、以下の記事で様々な手法が挙げられています。
Yaminabe:うにばな 講座みたいなもの番外編(高速化について) - livedoor Blog(ブログ)
O-Planning 書籍サポートページ 「Unityではじめる2Dゲーム作り徹底ガイド」
シェーダ等3D機能については把握しきれなかったのですが、「Unityはじめるぞー」みたいな初めての方も参考に出来る手法も色々あったので羅列していきたいと思います。
あとはUnity公式サイトを見るのがいいと思うけどえいごよめない。
DrawCallを減らす
多くの記事で取り上げられていたのが、DrawCallの数を減らすことでした。
DrawCallの数は、GameタブからStatsをクリックすると見る事が出来ます。
この画面の状態だと26回呼ばれているようですね。
この数はどうなんでしょう。...どうなんでしょう?諸説あるようでよく分からないのですが、この状態で実機テストしたところ処理落ちせず動いています。とにかくDrawCallは少なくした方がいいようです。
ではどうするかというと、これについて後者の記事(pdf)ではスプライト関連の最適化が紹介されていました。スプライト画像を1つの画像にまとめる(アトラス化?)、拡大、回転、アルファ値など工夫出来る事はあるようです。
ちなみに左2人のキャラクターがDrawCallsの大半を占めていました。現在のゲームはキャラクターがアニメーションしてるのですが、それぞれのパーツが別々の画像ファイルになっているからかもしれないです。なので高速化の余地は一応あるのですが、実際に出来るかどうかは検討しないといけません。
そういえばキャラがカメラの画面外に出たらDrawCall数減るんですね。
さらに言えば画面外に出た時の処理とかも書けるんですね。OnBecameVisible()等があるようです。
さらに言えばオブジェクトがアクティブになった瞬間に呼ばれる関数もあるんですね。OnEnable()のような。
もしかして周知の事実...?
無駄な処理を減らす
当たり前なんですが、余計なコンポーネントが付いていたら削除します。
で、調べたら壁全体にrigidbody2D付いてたんですね。消しても特に問題ありませんでした。知らずに壁大量に配置させたらやばかったね。
updateに関する小技もありましたね。ある条件(画面外、離れている等)ではさっさとreturnしてしまうとか。
同じくsetActiveを駆使する方法もありました。ただ非アクティブ化したものを上手くアクティブ化するのが難しい。
GameObject.Find~系の関数は避けた方がいいという案もありました。便利なんだけどねー。なるべくStart時にまとめて格納するのがいいようです。
遅くなったらとりあえず上記の事でも気にしてみようと思います。
隣では背景を描いていました。早く緑に包まれて遊びたい。
Growというゲームの概要(2014/12/27)
雀荘です。
年越し準備でいろいろとあわただしくなってきました。
年賀状もまだ書いてないです。
春には体験版を出したいということで、
作った操作の部分に細かい調整を加えています。
なので今回はそもそもこのゲームがどういう操作を
するのかという部分をお話ししていきます。
このゲームってどういうゲームなの?
まず「Grow」というゲームはスマートデバイスで遊ぶことを前提としています。
特性の異なる2体のキャラクターを動かす、
いわゆるアクションパズルゲームといった感じになります。
そして「Grow(成長)」という名前の通り、
キャラクターのできることも物語が進むにつれて
できることも増える、といいなって感じです。
全体的に植物を使った小学校の理科の知識で解けそうな
謎解きを用意したい感じです。
操作キャラクター:リリィ
葉っぱと花の妖精リリィ。
葉っぱカッターを使った糸の切断や、
つたを使った「引き寄せ」や「フックショットじみた動き」を行います。
材質的に体重が軽いことが謎解きに使われるかは微妙。
笹船したい。
操作キャラクター:バウム
木と枝の妖精バウム。
リリィと違って腕や足があるので、
「ジャンプ」や「パンチ」、手を使ったギミックの操作ができる。
材質的に力持ちな点が差別化に使われるかは微妙。
いつか火だるまになると噂されている。
操作:協力アクション
このゲームのウリにしたい部分の一つ。
協力アクション。
二人で足りない部分を補い合い、
一人じゃできないことを実現するのだ!
片方が植木鉢を持つのか、
合体して一つになるのかはまだ決まっていない。
あまり実装が進んでいないので強く言えない。
最後に
2月3月くらいには体験版をリリースするようにしたいです。(願望)
そのために足りない部分の実装を済ませて、
ステージを完成させたい。
ゲーム自体もアクションの難しさではなく、
謎解きのギミックを推していきたいので、
そのネタを考えるのが大変そう。
でも楽しそう。
最後に、来年もマヨナゲをよろしくお願いします。
タップ操作を作りたい(2014/12/20)
hisojiです。
様々な諸事情により進捗が少なめになってしまいました。年末のせいにします。
なので今日はざっくりとタップ入力について調べました。
MouseとTouch
タップを扱う手段として2つ考えてます。Input.GetMouseButton系の関数と、Input.GetTouch系の関数です。
(他にもNGUI、Asset storeなど手段はあるようなのですが省きます。)
以前、タップでオブジェクトを検出する際にInput.GetMouseButtonDown(0)を使いました。
名前から分かる通り、もともとはマウスの入力を取得する関数です。ただandroidのタッチに対しても同じように反応するので、「押された瞬間」「押している状態」などが分かります。
一方で、unityにはタッチ用の機能も存在します。Input.GetTouchなどです。こちらだと現在タップしている指の状態(触り始めたか、動いているか)をTouchPhase列挙子で受け取ることができます。また、タップしている指の数を調べたりできます。以前制作された「NightBat」ではスマートフォン用の入力にこちらを使ってました。
ここで「1本指ならどっちでもいいんじゃね。てかどっち使おう」という考えが浮かびました。
とりあえず機能的には同じなのか?という疑問に関しては以下のサイトで回答されています。
Input.mousePosition equivalent to first finger touch? - Unity Answers
えいごわかんない人なんですが、多分「最初の指に対してはどちらも同じように動きますよ」的な事が書かれています。
制作中のGrowは今の所1本指でのタップとスワイプしか使わないので、とりあえずInput.GetMouseButton系の関数を使う事にします。これだとマウスの処理と区別する必要が無いので実装が若干楽になります。後に2本指とか使う場合は場合分けしないといけないので、操作方法については検討する必要がありそうです。
スワイプ
タップするだけなら上記のを使えばいいので、スワイプについて考えます。とりあえずInput.GetMouseButtonだけを使ってみます。
押された瞬間にその位置を記録して、今押している位置との差異をなんやかんやすればスワイプ方向を検出出来そうです。以下、未検証なコード。
public class TapCursor : MonoBehaviour { ... public enum Direction{ None, Left, Right, Up, }; Vector2 from; Vector2 to; void Update () { Vector2 input = Input.mousePosition; Vector2 v = new Vector2(input.x,Screen.height-input.y); if(Input.GetMouseButtonDown(0)){ from =v; to = v; } if(Input.GetMouseButton(0)){ to = v; } if(Input.GetMouseButtonUp(0)){ from = v; to = v; } } public bool isDirection(Direction d){ Vector2 v = to - from; switch(d){ case Direction.Left: return v.x < -10.0f; case Direction.Right: return v.x > 10.0f; case Direction.Up: return v.y < -10.0f; default: return false; } return false; } }
isDirection関数によって、方向が右である時と上である時の条件などが同時に行えます。
updateのmousePositionをいじってるのはy軸方向が違うらしいからです。
もしかしてInput.Touchの方が楽とか...?後で調べておきたいです。
そしてタップ操作が追加されるという事はそろそろ実機でテストプレイが出来るとか出来ないとか...?
Grow(仮) ステージを作る(2014/12/13)
雀荘です。
今回はステージ作りのお話。
しかしどうも記事を書くのが下手で申し訳ない。
それと日付を書かないと正確な活動日が
わからなくなりそうなので復活させました。
動作チェック兼チュートリアルステージ
マップオブジェクトがすごい数になる。
必要アクション的にはちょうど真ん中ぐらいかな?
ゲーム的に基本となる操作で構成されたステージです。
ステージ的に使えるギミックは
フックジャンプ(マーカーに向かって飛ぶやつ)と、
加圧スイッチ、ひも、などです。
入り口付近にいるサメっぽい敵はスイッチを踏むように置くことで、
加圧スイッチの役割を伝えるようにしようとか
ふわふわ考えながら作っています。
合わせてhisojiさんに必要なものを作ってもらったり、
正月ぐらいには体験版が遊べるといいですね。
しかし、ペースなどを考慮して作り変えるとなったら結構大変だなあ
一応ボスも考えてあるんだけど実装できるかな……?
unity2dでレイヤーを使ってキャラ同士をすり抜けさせたり上をすり抜ける床を作る(2014/12/10)
hisojiです。タイトルながい。
今日は衝突判定方面を色々やりました。簡単に言うとレイヤーを弄りました。
すりぬけ床についてはこの記事の後半に書いてあります。
実は今までunityのレイヤーとかいう機能を知らなかったので必死に「unity collider すり抜け」とか「unity 床 すり抜け」で検索してました。「なぜか床をすり抜ける」とかは出るんだけどね。上手く出ませんね。よく見たら「レイヤー」っていう単語自体は検索結果に出てたはずなんだけどね。イラスト方面で聞いてるはずなんだけどね。
キャラ同士をすり抜けさせる
ゲーム内では2人のキャラを交互に使っていきます。その時にキャラ同士がぶつかり合うと色々不便なので、「他の物体と衝突判定をしつつキャラクター同士の衝突は避ける」みたいなことがしたいです。
こんな風にぶつかってないやつ。
方法として、レイヤーを使います。(Unity4.5.5f1)
まずはInspector->Layer->Add layer...で新しいレイヤーを追加します。名前は任意なのでCharacterとかにします。
その後2人のキャラのLayerにCharacterを設定します。
そして、レイヤー毎の衝突判定を設定します。上部メニューよりEdit->Project Settings->Physics 2Dで開き、Layer Collision Matrixの欄を設定します。
で、縦と横がCharacterの欄のチェックを切ります。この行列によって、各レイヤー同士の物体が衝突判定するかどうかを設定することが出来ます。
起動すると、無事キャラ同士が干渉しなくなりました。よかったね。
やり方を知っていれば簡単なんですが、方法を探すまでが難しかったです。←人に聞こう
こちらも参考に
上方向にすり抜ける床
(2014/12/13追記)
後から調べたところ、シンプルな解決策が紹介されていました。とりあえず下記のサイトをご参照ください。
Unity3D - 一方通行なコライダ - Qiita
Eficient one-way collider - Unity Answers
Physics2D.IgnoreCollisionはcollider同士の衝突判定の有効、無効を設定出来ます。床とは別にトリガーのcolliderを用意し、入ったら衝突判定を無効にして、トリガーから出た瞬間に再度有効とすれば上手くすり抜けてくれます。これはすごい。
よって下で行われた試行錯誤は御用となってしまいましたが残しておきます。というかそろそろUnityの関数一覧とか全部見といたほうがいい気がする。
(以下、実装案の1つとして)
何かよくアクションであるような「上からジャンプしたらすり抜けるけど下からは通れない(又は下に入力を入れると通れる)床」的なものを作れればいいなという案がありました。説明しづらい。あと検索しづらい。
Unity関連で探す限り、以下の記事で試みが行われていました。
hide behind blog (仮): 下からすり抜けて上に乗ることができる床の実装例 (Unity C#)
unity2Dのジャンプアクションゲームでブロックから飛び降りれるようにするには: ドット絵とアイデアと
collider2dを無効にしたり、triggerのON/OFFを切り替えることで実装されています。
で、参考にしつつ色々考えた結果、とりあえずこうなりました。
方法としては、スクリプト内でレイヤーを切り替えてみます。飛んでる時はレイヤーを変えて、通常時には元のレイヤーに戻します。
gameObject.layer = LayerMask.NameToLayer("CharacterHook");
現状、CharacterHookというレイヤーは上部の床のレイヤーとは衝突しません。現状だと他にも色々すり抜けてしまうんですが、後々には床以外の物体とは上手く衝突するように設定できそうです。
で、キャラクターはいいんですが、「どうせなら投げる物もすり抜けさせたいね」とか考え始めました。投げる物のレイヤーを増やせばいいかな?とか考えたけどレイヤーの数が凄い事になりそうです。
頭にあるのは、床をすり抜ける物体をまとめて1つのレイヤーで対処できないかなあと。例えばy軸の速度が上方向ならすり抜けるレイヤーに設定しておけばいい...とか?(これだと下にすり抜けられない)
何か「これだ!」みたいな方法があればいいですね。
レイヤーは色々と勉強になりました。unityで普通のアクションゲームを作る時もお世話になりそうですね。
ちなみに作業段階としてはそろそろステージ作成が始まるとか。