mayonage-koboの日記

我ら真夜中ゲーム工房の進捗と、ゲーム開発のメモを残しておくブログ

Grow(仮) リフトを作る

雀荘です。

今回はリフトを作ります。
リフトとは、上下左右に移動する床のことです。

上下扉とかにも使えますし、2Dアクションの一つのお約束ですね。

制作には以下の記事を参考にさせていただきました。



隔つ記 - Unity 動く床

やったことはほとんどこのままで
コードもコピペな内容なのですが……



まず手始めに、colliderを2つ作ります。

f:id:mayonage-kobo:20141206174733p:plain

1つは物体のあたり判定用に。
2つ目(物体の上にうっすらと引いてやつ)は他の物体の接地判定用のやつです。
そして、2つ目のtriggerをtrueにしておきます。

これで準備完了です。

using UnityEngine;
using System.Collections.Generic;

public class Lift : MonoBehaviour 
{

	public Vector3 speed    = Vector3.zero; //1フレームで動く距離(マイナスは逆方向)
	public Vector3 distance = Vector3.zero; //この距離まで動く
	
	//distanceまで動いた後に反対方向へ折り返して動くか?
	//falseだとdistanceまで動いたらそこで止る
	public bool turn = true;
	
	private Vector3 moved = Vector3.zero; //移動した距離を保持
	private List<GameObject> ride = new List<GameObject>(); //床に乗ってるオブジェクト
	
	void Update() 
	{
		//床を動かす
		float x = speed.x;
		float y = speed.y;
		float z = speed.z;
		if (moved.x >= distance.x) x = 0;
		else if (moved.x + speed.x > distance.x) x = distance.x - moved.x;
		if (moved.y >= distance.y) y = 0;
		else if (moved.y + speed.y > distance.y) y = distance.y - moved.y;
		if (moved.z >= distance.z) z = 0;
		else if (moved.z + speed.z > distance.z) z = distance.z - moved.z;
		transform.Translate(x, y, z);
		//動いた距離を保存
		moved.x += Mathf.Abs(speed.x);
		moved.y += Mathf.Abs(speed.y);
		moved.z += Mathf.Abs(speed.z);

		//床の上のオブジェクトを床と連動して動かす
		foreach (GameObject g in ride) 
		{
			Vector2 v = g.transform.position;
			g.transform.position = new Vector3(v.x + x, v.y + y);	//yの移動は不要////////////
		}
		//折り返すか?
		if (moved.x >= distance.x && moved.y >= distance.y && moved.z >= distance.z && turn) {
			speed *= -1; //逆方向へ動かす
			moved = Vector3.zero;
		}
	}
	
	void OnTriggerEnter2D(Collider2D other) {
		//床の上に乗ったオブジェクトを保存
		ride.Add(other.gameObject);
		//Debug.LogError ("ride");
	}
	
	void OnTriggerExit2D(Collider2D other) {
		//床から離れたので削除
		ride.Remove(other.gameObject);
	}
}

使用するにあたって
コメントで"yの移動は不要"と書かれた部分をyの移動も行うようにしました。
また、OnTriggerEnterの部分も2D仕様に変更。
これで2D仕様にひとまずはなりました。

今後はそういった上下移動を含む物体を、
このコードを参考に作らせていただきます。

f:id:mayonage-kobo:20141206180027p:plain

違和感のないリフトがこんなに簡単にできるなんて!
C++で自作してた時はぜんぜんうまくいかず泣く泣く外してました。
Unityすごい

さっそく加圧スイッチを作ってみましたが新しい問題に直面することも……

しかしこのイベント用colliderという考え方はすごいな

Grow 葉っぱを投げる

hisojiです。

引き続きアクションを追加してます。
前回の予告通り葉っぱカッターを作ります。
あとは箱を紐につないで天井からぶら下げたい、ということでhinge jointを使ってみたり。

葉っぱを投げる

こんなのを作りました。
f:id:mayonage-kobo:20141126235336g:plain
なんだこれ。
説明すると、クリック長押しで葉っぱを投げています。ブーメランみたいな軌道で戻ってきます。
何か黒っぽい紐に箱がぶら下がってます。葉っぱが紐に当たると紐が消えて箱が落ちてきます。
葉っぱカッターによって紐が切れる様子を作りたかったんですね。

当たると消える処理みたいなのはおなじみRigidbody2DやTrigger2Dで。
後はぶら下げる処理ですがhinge jointでそれっぽいことが出来るらしいので使います。
付ける事自体は簡単で、天井の壁とHingeJoint2Dコンポーネントを追加し、ConnectedRigidBodyの欄に紐を選択します。後はSceneビューで連結点等を調整すれば完成。紐と箱についても同様に。(Unity4.5.5f1を使用しています)
f:id:mayonage-kobo:20141127000859p:plain
ちなみに調整間違えると挙動がよく分からない事になったりします。

目標点に飛ぶ

キャラを飛ばします。
f:id:mayonage-kobo:20141127001600g:plain
なんだこれ。
まだ作成中なんですがモーションが付いたらもう少し分かりそうですね。
とりあえず丸いオブジェクトをクリックするとその方向に飛ばします。直接veclocityをいじってます。

...あんま新しいことしてないね今回。

その他
  • キャラの状態をStay,Throw...みたいな感じで分けてるのですが、何かアクションが追加されるたびに状態についてのコードを追加してます。そのおかげでキャラクターに関するスクリプトが大分長くなってきたのが気になります。現在で250行くらいあります。え、長くない?機能の実現が最優先みたいな感じでやってるからですが、そろそろ整理してもいいかもしれないですね。出来れば作っていく過程が苦とならないようにしたいものです。
  • 背景として適当に森のフリー素材とか入れてみたら意外とそれっぽくなりました。背景大事ですね。
  • 実機でテストしたら今の所問題なく動いてます。タップ以外の操作も考えてみてもいいかも。

そういえば1つ前の記事にちゃっかり橙色のキャラがいましたね。何に見えるのだろう。
今考えられているのは、2人のキャラクターを交互に操作して先に進んでいくようなアクションにしたいという感じです。彼?の出番は緑の子のアクションが終わってから。

Grow(仮) アニメを管理する

雀荘です。

今回は、これまで作ってきたSpriteStudioのアニメを
プログラムから切り替えていきます。

単純にViewの下にアニメを付けるだけだと、
アニメが同時に描画されてしまいます。

f:id:mayonage-kobo:20141124002101p:plain

なので使うアニメ以外のアクティブを切ります。

そしてスクリプトで状態に必要なアクティブをtrueにしてやります。

string name="";

		if (state == FlowerState.Stay) 
		{
			name = "stay";
		} 
		else if (state == FlowerState.Damaged) 
		{
			name = "damaged";
		}
		else if (state == FlowerState.Throw) 
		{
			name = "stay";
		}

		transform.Find("View/"+name).gameObject.SetActive(flag);

それぞれ自分のViewの下に持っているので、
”View/” が必要。
まだ投げるアニメーションはないのでとりあえずこんな感じで。
かなり強引だけど、とりあえずこれで上手くいってるので、
ま、いいかな。

f:id:mayonage-kobo:20141124003042p:plain

左側にいる木のロボットは味方の予定。
ある程度基本的なギミックができてきたので、
実機での様子の確認も兼ねて、テストプレイステージを作りたい。
アニメ作るのはあとからでも大丈夫でしょうたぶん。

それにしてもやられ顔がかわいくない・・・・・・。
アニメ難しい。

Grow(仮) 物を投げる(2)

hisojiです。

今日はバグ潰しや細かい修正が多めなので特筆すべきものがありません。

やったこと

以前、キャラに四角い物体を拾って投げさせることをしていました。これの修正をします。
大まかな事は以下の記事を。

Grow(仮) 再開 - mayonage-koboの日記

やったことをざっくりと羅列。

物を拾ってる状態でキャラがガクガクするバグを直した。

物体のTriggerをONにして衝突が起きないようにしました。ついでに落ちないように重力を0にします。物を離した際には元に戻すようにします。

holdObject.collider2D.isTrigger=true;
holdObject.rigidbody2D.gravityScale=0;
何故か投げた物が壁を貫通するバグを直した

投げる際に物のTriggerと重力を直さないとこうなります。

敵に衝突した時に物が拾えなくなるバグを直した

敵に衝突した際も上記の動作をすればいい。

物を拾った後に、敵に当たって物を離すと何故か床を貫通するバグを直した

Collision2Dで物は拾っているのに、キャラクターの状態としてはダメージを受けていて拾えない状態だったようです。

投げる方向を少し改善した

マウス位置への起点をキャラの中心じゃなくて拾った物体の中心を取る。

敵に物が当たったらダメージを受けるようにした

Collision2Dでhpとか赤くする処理つけたり。

アクション系だとバグが発生しやすい気がしますね。
OnCollision2D、OnTrigger2D、Rigidbody2D等に上手く適応すればいいんですがどうも慣れません。

せっかくなんでgifにしました。動いてるはず。
LICEcapというフリーソフトが簡単に画面上のキャプチャ動画をgif形式で作成できるので便利です。
f:id:mayonage-kobo:20141120221816g:plain

・今見て思ったのが

  • 物を拾ってるかどうかよく分からない
  • 移動と投げる際の操作方法が分かりづらい

とかがあります。それらはおいおい直していく予定です。多分。
アニメーションも作ってくれてるので見映えも良くなるはず。

今後の予定

「拾って投げる」という動作が一通り出来たので、次は別のアクションを作ってみることになってます。
植物特有のアクションとか欲しいね、ということで次回は「はっぱカッター」を作る事にします。
急所にあたりやすいとかじゃなくて、葉っぱのブーメランを投げるみたいなものです。これで紐を切って何やかんやするとかが出来そうですね。
ゲームのコンセプトも少し変わりそうだけど出来る事を考えつつ定めていきたいですね。

Grow(仮) 引き続きアニメーション

またSpriteStudio関係の話


以前書いた記事

Grow(仮) 再開 - mayonage-koboの日記

で行っていたAssetStoreからダウンロードしてSprite Studio for Unityを使うのだと、
いまいち使いづらかったので他のを調べた結果SS5Player for Unityを
使った方がよさそうだということになりました。


Home · SpriteStudio/SS5PlayerForUnity Wiki · GitHub

これ。

こっちが現在メインで開発されているらしいので、こっちを使おうと思います。
プロジェクトから直接アニメprefabを作れたりと便利そうですし。

f:id:mayonage-kobo:20141115184714p:plain

gitで公開されているSS5Player for Unityをダウンロードして、
zipを解凍してpurojectに放り込んで、
その後はgitのチュートリアルに従えば大丈夫です。

手間取ったのがアニメの再生。
AssetStoreのSprite Studio for Unityと違って、
手順を踏まなくてはならない。

f:id:mayonage-kobo:20141115185121p:plain
この様にViewというprefabの下に付けないと、
生成されたアニメーションprefabを見ることができない。

このViewというのはダウンロードしたファイルの中にある(はず)なので、
忘れずにつけよう。

f:id:mayonage-kobo:20141115185640p:plain

まだまだ不具合もあるけど頑張ろう

Grow 会話ウィンドウを作る(2014/11/12)

hisojiです。サークルに真夜中という文字が入るくらいなんで、良い子は寝てる真夜中に更新しようと思います。ごめんなさい遅れただけです。

いつも通りにGrowを制作していきます。
今日はアクション部分の制作と会話部分の制作で分業しました。他方では岩をぶん投げたりして楽しそうですが、今回は自分がやった会話の方を。以前の記事で作ったやつに色々足します。

やった事

テキストファイルのロード

テキストファイル毎にロードして表示する機能を付けました。といっても、Resource.LoadでTextAssetとして再代入するだけです。
テキストファイルは今の所Assets/Resources/Text内に全て置いてあります。

TextAsset tasset;
...
public void loadText(string path){
...
tasset = (TextAsset)Resources.Load(path);
if(tasset == null){
	Debug.LogError("cannot load text!");
}
...
}
改行の追加

文章内で改行を入れるための機能を付けます。
改行なんでテキストファイルに'\n'を入れてみたのですが、これだとそのまま表示されてしまうみたいです。
なので、プログラム内で、テキストファイル内のある文字列を'\n'へと置き換える事にします。
テキストファイルをこのようにします。

こうやって<br>改行すれば<br>便利な時がある。

というわけで、"<br>"を"\n"へと置き換えるようにします。
幸い、C#のstring.Replaceという文字列を置き換える関数がそのまま使えます。

string s = texts[textOffset].Replace("<br>","\n");

こうすることで、改行されて表示されるようになりました。
f:id:mayonage-kobo:20141113005405p:plain
たぶん。

改行じゃなくて他の機能を入れる際も使えそうですね。

イベントフラグ追加

キャラが特定のオブジェクトに近づいたら会話ウィンドウが出るようにします。
いつもながらのCollider2D、Trigger2Dを使います。オブジェクトのタグがMessageFlagであれば、ゲームオブジェクトの名前のテキストをロードします。

void OnTriggerEnter2D(Collider2D other){
	if(other.tag == "MessageFlag"){
		...
		talk.loadText("Text/" + other.name);
	}
}

Rigidbody2Dコンポーネントを入れないとCollider2Dの判定をしてくれません。ちゃんと入れましょうね。こんな事に30分もかけないようにね。自分とかね。
f:id:mayonage-kobo:20141113003116p:plain
とりあえず葉っぱを置いてテストしました。
まあまあそれっぽい?

次回やる事

会話ウィンドウということで文章を表示させるだけを行ったけど、これをイベント等にも応用させたい所です。
あるイベントが発生したら、あるキャラが喋って、右に動いて、カメラが動いて、もう1つのキャラが喋る...みたいな。
文章だけじゃなくて、ちょっとした言語を作んないといけないですね。
例えばこんな感じ?

talk,ここは危ない所だよ。
moveCamera,20,80
talk,そう?

カンマで区切ってるだけならなんかSplitすればそれっぽく出来そう。
作ってる途中なのでまた今度に。

Grow(仮) 再開

雀荘です。

朝が冷える季節になってきました。
さて、遊んでくれた方の意見を基に行っていたNightBatの修正も終わり、
時期的にも一区切りがついたのでgrow(仮)を再開します。

  • 今日の進捗

こんな感じ

f:id:mayonage-kobo:20141105192620p:plain

何が起きてるかというと、
キャラクターがブロックを投げているんです。


まず、プレイヤーのグラフィックについては以前の記事でお話した通り、
SpriteStudioで作ったファイルを使っています。

ちなみにUnityでSpriteStudioで作ったアニメファイルを使うには
「spritestudio player for unity」というAssetをImportする必要があります。
詳しい内容は以下のページにおそらく公式の記事が掲載されていますので、
これを追っていくだけでできます。

http://www.webtech.co.jp/spritestudio/unity3d.html

「追記」2014年11月15日現在、ページがなくなってしまいました

次にブロックを持って投げる部分ですが、

………………………………
tapX = GameObject.Find(player).transform.position.x;	
tapY = GameObject.Find (player).transform.position.y;
………………………………

Vector2 tapPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
			tapX = tapPoint.x;
			tapY = tapPoint.y;

			if(flower.IsHoldingObject())
			{
				flower.ThrowObject(new Vector2(tapX,tapY) * 250.0f);
			}

………………………………
………………………………
public void ThrowObject(Vector2 vec2)
{
	Debug.Log ("throw:" + vec2);
	holdObject.rigidbody2D.AddForce (vec2);

	holdObject = null;
}

っていう感じにholdObjectに対してAddForceでマウス距離に応じて力を加え、
持っているブロックを投げる処理を作りました。

結構AddForceの処理は癖がありそうで要調整ですが、
まあまずはプロトタイプを作っていってから考えていきたいですね。