読者です 読者をやめる 読者になる 読者になる

AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

プレイヤーの周辺だけ明るくする

Necro Dancer Unity2D

 自動生成したダンジョン内を移動できるようにしましたが、
 次は主人公周辺だけ明るくするやつをやってみました。

f:id:yasu9780:20150622213615j:plain

 これは、いわゆるライトは使ってません。
 SpriteRendererのcolorを距離で調整して実現しています。
 予想以上に良い感じになって驚きました(ゝω・)

 主人公の周辺20マス以内で、距離を求めて、距離に応じて色を暗くして、colorに設定。
 距離0でzeroDivideにならないように分子の母数に1を足してます。
 分子の2を大きくすると遠くまで明るくなります。
 例えば主人公が松明を持っているときは、ここを大きくしてやるといいと思います。
 本家のネクロダンサーでは、遠くでは壁などは見えなくて、敵だけはシルエットだけは見えるようになっています。
 たしかに遠くはすべて暗くするよりはゲーム性が増すかもしれませんね。
 厳密には、LightPowerは距離の二乗の逆数かもしれない。

明るさは距離の2乗に反比例する | イメージングソリューション

public void LightUpdate()
{
	int px=(int)player.transform.position.x;
	int py=(int)player.transform.position.y;

	for(int y=py-20;y<=py+20;y++)
	for(int x=px-20;x<=px+20;x++)
	{
		if(x<0 || y<0 || x>99 || y>99 ) continue;
		float distance = Vector2.Distance( player.transform.position, new Vector2(x,y) );
		float lightPower = 2f/(distance+1f);
		if(map3[x,y]!=null) map3[x,y].GetComponent<SpriteRenderer>().color=new Color(lightPower,lightPower,lightPower);
		if(map2[x,y]!=null) map2[x,y].GetComponent<SpriteRenderer>().color=new Color(lightPower,lightPower,lightPower);
		}
	}
}

map2はUnitsレイヤーのGameObjectが格納
map3
はFloorレイヤーのGameObjectが格納
壁は壊せることが前提なので、すべてのマス目に床があります。


 あと、本来、視界という考え方では、となりの部屋の中は、中に入ってみないと見えないはずなんですよね。
 これはモンスターの生成にからんでいて、普通は部屋に入ったら、部屋内にモンスターが発生するというやり方が普通と思います。
 じゃないいと、全体にモンスターを100匹投入するというのも、GameObjectが増えるので、非効率ですよね。
 プレイヤーと離れていたら動かさないというのなら、それほど負荷はないかもしれませんが。
 このへんのモンスター生成の仕組みや、視界の仕組みも考える必要があります。
 本家は、ドアを開いたら、隣の部屋が表示されるって感じで、きちんと視界が実現されています。
これは近くても、ドアを開く前は、室内は真っ暗という処理がいるわけですが、ダンジョン自動生成時に、部屋の情報をリストにしておけば、このへんは実現できそうです。
 ただ、隠し部屋はドアではなく壁をぶちぬいた時点で見えるようになるので、判定はもうちょっと複雑かもしれません。


 モンスターを動かすかどうかは、プレイヤーとの距離で判定すると、ゲームのプラットフォームによって画面解像度が変わってくるし、色々と困難ですね。
 これは、カメラに写っているかどうかで判定するのが正しそうですね。
 というわけで、以下の記事が参考になります。

【Unity開発8】Main Cameraに映るまで敵キャラを待機させておく【横スクロールユニティちゃん12】 - ひよこのたまご Unity5(C#)の初心者・入門者向けTutorials

http://docs.unity3d.com/jp/current/ScriptReference/Camera.OnWillRenderObject.html

OnWillRenderObject はカメラからオブジェクトが可視状態の場合、各カメラごとに一回呼び出されます。

 

広告を非表示にする