tag:blogger.com,1999:blog-23508825783360273942024-03-05T20:33:50.457+09:00ジークス・ラボジークス・ラボは、株式会社ジークスのエンジニアやクリエイターが日々の業務の中での<br>
“ひらめき“と”創造”のタネを公開する場です。ジークス・ラボhttp://www.blogger.com/profile/15344977941527318661noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-2350882578336027394.post-47906466451079376702014-02-19T11:43:00.000+09:002014-02-24T11:03:14.172+09:00[Unity][C#][ラムダ式]他オブジェクトに依存する処理のレシピこんにちは。開発の松本です。<br />
しばらくObjective-Cをやっていましたが、久しぶりにUnityでゲーム開発をしています。<br />
コンポーネント指向のUnityではMVCやオブジェクト指向がはまらず、勘を取り戻すのにやや苦労しました。<br />
<br />
さて...<br />
ゲームに限らず、他オブジェクトに依存する処理は、よくあると思います。<br />
MVCだと「コントローラが、モデルなど他オブジェクトの状態を見て制御」ですが、Unityではしっくりこない気がします。(自分だけ?)<br />
そこで今回、私が実装したレシピをご紹介します。(C#。見やすくするためnullチェックは省略)<br />
<br />
<h3>
例)魔法「イレカワール」</h3>
<h4>
仕様</h4>
<div>
<ul>
<li>自キャラと、仲間ターゲットキャラの位置が入れ替わる</li>
<li>仲間ターゲットキャラが、攻撃中、魔法詠唱中、被ダメージ中、スタン中は、入れ替われない</li>
<li>敵キャラとは入れ替われない</li>
</ul>
<h4>
実装</h4>
<div>
<pre class="brush: c#" name="code1">using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using MagicParams = System.Collections.Generic.Dictionary<string, object>;
public delegate void MagicCallback (GameObject sender, MagicParams userParams);
public class Magic : MonoBehaviour {
/** 入れ替わり */
void Replace (GameObject him) {
// コールバック
MagicCallback replaceRes = (sender, resParams) => {
// 返答OKの場合
if ((bool)resParams ["result"]) {
// 移動
transform.position = (Vector3)resParams ["position"];
}
// 返答NG
else {
// 失敗メッセージ出力などを実装
}
};
// 要求パラメータ
MagicParams reqParams = new MagicParams () {
{"sender", gameObject},
{"position", transform.position},
{"callback", replaceRes},
};
// 入れ替わり要求
him.SendMessage ("ReplaceReq", reqParams);
}
/** 入れ替わり要求 */
void ReplaceReq (MagicParams reqParams) {
// 要求パラメータ
GameObject sender = (GameObject)reqParams ["sender"];
MagicCallback cb = (MagicCallback)reqParams ["callback"];
// 返答パラメータ
MagicParams resParams = new MagicParams () {
{"sender", gameObject},
{"position", transform.position},
};
// 入れ替わり可能かチェック
if (!IsReplacable(sender)) {
resParams ["result"] = false;
if (null != cb) cb (gameObject, resParams);
return;
}
// 移動
transform.position = (Vector3)reqParams ["position"];
resParams ["result"] = true;
if (null != cb) cb (gameObject, resParams);
}
/** 入れ替わり可能か */
bool IsReplacable (GameObject him) {
// himが敵ならreturn false;
// 自分が攻撃中、魔法詠唱中、被ダメージ中、スタン中ならreturn false;
return true;
}
}
</pre>
</div>
</div>
<br />
以上のように、当事者同士でチェックし合って制御しています。ポイントは↓<br />
<ul>
<li>コールバック処理をラムダ式で実装</li>
<li>パラメータはとりあえずDictionaryにぶち込んで渡す</li>
</ul>
<br />
Magic.csを、魔法を使う/受けるGameObjectに付けて使用します。<br />
イレカワール詠唱時に、Replace(ターゲットGameObject)で呼べば、入れ替わります。<br />
<br />
以上、他オブジェクトの状態などに依存する処理のレシピでした。
他にも色々方法はあると思います。ご指摘などあれば、コメントいただけると幸いですm(_ _)m
Anonymoushttp://www.blogger.com/profile/02447764952187584518noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-51441589899641134032013-10-08T11:13:00.000+09:002013-10-08T11:46:39.792+09:00【Unity】NGUI3.0を使ってスクロールビューを作ってみようこんにちは、開発の半沢 匠です。<br />
<br />
今回はUnityでUIを作るとしたら今や欠かせないアセットNGUIについてお話させていただきます。<br />
つい先日NGUIが3.0にメジャーバージョンアップしました。作者さんいつもありがとうございますmm<br />
<br />
そこで今回はこちらを用いてスクロールビューの作成方法を図入りで説明します。<br />
っとは言うものの実は作者さんが既にわかりやすい動画をYoutubeにアップしてらっしゃるので<br />
詳細はそちらを見ていただくのが良いかと思います。<br />
<br />
動画はこちら <a href="https://www.youtube.com/watch?feature=player_embedded&v=OiA4o8KqBFI">https://www.youtube.com/watch?feature=player_embedded&v=OiA4o8KqBFI</a><br />
<br />
こちらは簡単に日本語でまとめたメモとしてご活用いただければと思います。<br />
<br />
======<br />
<br />
<span style="font-size: x-large;">①ベース作成</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtIHf627W47NbKFLSJovTzkeoa-Olgb4qPhu13y1Tte1Z39vVb97BwFn2oTcB5QC-lVsFGCpDC2n-ySYOno6V1y38F1xDfuoqt3StxgOeb0wBpN1DjWYdsZF6CKAtc5q3gYXkJLb0x1t0/s1600/scroll1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtIHf627W47NbKFLSJovTzkeoa-Olgb4qPhu13y1Tte1Z39vVb97BwFn2oTcB5QC-lVsFGCpDC2n-ySYOno6V1y38F1xDfuoqt3StxgOeb0wBpN1DjWYdsZF6CKAtc5q3gYXkJLb0x1t0/s1600/scroll1.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
・メニュのNGUI→Open→UI Wizardを選択<br />
・CameraがSimple 2Dになっていることを確認しCreate Your UI ボタンを押下<br />
<br />
<br />
<span style="font-size: x-large;">②ScrollView作成</span><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi0gSLgTCvmHqyCtuM1lLqpow52pyE32acwG_8IwrCgZtQ7sHqa2jlY4hoXQxc4KVLTy42y2rXARly1zoQTlm3TWZRSDQzcoTFG3jKysOXDxU2TtMn_wijdlfmS2UdGCFDL-_DdzkPIQ8/s1600/scroll2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi0gSLgTCvmHqyCtuM1lLqpow52pyE32acwG_8IwrCgZtQ7sHqa2jlY4hoXQxc4KVLTy42y2rXARly1zoQTlm3TWZRSDQzcoTFG3jKysOXDxU2TtMn_wijdlfmS2UdGCFDL-_DdzkPIQ8/s1600/scroll2.png" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
・Anchorの子オブジェクトとして空のオブジェクトScrollViewを作成<br />
・Add Componentボタンを押下しPanelを選択しUIPanelスクリプトをアタッチする<br />
・UIPanelのClippingをAlphaClipにする<br />
※もしくはSoftClip。こちらの場合は両端のぼやける範囲をSoftnessの値で指定可能<br />
・表示したい場所/領域にCenter/Sizeの値を変更(Scene内の色枠を参考に)<br />
・Add Componentボタンを押下しDraggable Panelを選択しUIDraggable Panelスクリプトをアタッチする<br />
・Scaleの値を移動させたい方向のみに1を入力<br />
※縦スクロール:X0、Y1、Z0<br />
横スクロール:X1、Y0、Z0<br />
<br />
<br />
<span style="font-size: x-large;">③Grid作成</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh23qp1usM2XcMxg07ZjAiEObaFoSfxI0SZ4V9xCCMsO9nYQTWfDVeqIC7gJfA7WE6yBHUBvFEePVeXLms-Bjf0kogVsYLwPy7SkGFLKfl4T15fpr0TwDBHCHG0tFO3gLdLIMnfOd2YadA/s1600/scroll3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh23qp1usM2XcMxg07ZjAiEObaFoSfxI0SZ4V9xCCMsO9nYQTWfDVeqIC7gJfA7WE6yBHUBvFEePVeXLms-Bjf0kogVsYLwPy7SkGFLKfl4T15fpr0TwDBHCHG0tFO3gLdLIMnfOd2YadA/s1600/scroll3.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
・ScrollViewの子オブジェクトとして空のオブジェクトGridを作成<br />
・Add Componentボタンを押下しGridを選択しUIGridスクリプトをアタッチする<br />
・UIGridのArrangementを移動させたい方向に選択<br />
※縦スクロール:Vertical<br />
横スクロール:Horizontal<br />
・アイテム(④で作成するオブジェクト)の1つの大きさをCellWidthとCellHeightで指定<br />
・Gridを移動し②で作成したPanel内の表示させたい場所に移動させる<br />
<br />
<br />
<span style="font-size: x-large;">④アイテム作成</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv90iwM7E3esfFu8kHugVnZOJrWs7qD0fHFp9hkjxp-wIHaq3xLY7H3q9tuGitK_4VVVq5nAzSUBF0H7lLfXgnH1OeDD5G6ldHSXB86wgQwZrOlHJLOiZEfnyneZqG-rTtrF77i_uR27c/s1600/scroll4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv90iwM7E3esfFu8kHugVnZOJrWs7qD0fHFp9hkjxp-wIHaq3xLY7H3q9tuGitK_4VVVq5nAzSUBF0H7lLfXgnH1OeDD5G6ldHSXB86wgQwZrOlHJLOiZEfnyneZqG-rTtrF77i_uR27c/s1600/scroll4.png" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
・ScrollViewの子オブジェクトとして空のオブジェクトItemを作成<br />
・こちらのオブジェクトがスクロールさせるアイテム(画像等)になります<br />
・表示させたいものを子オブジェクトとして追加する(複数可。画像やラベル等)<br />
・Add Componentボタンを押下しDrag Panel Contentsを選択しUIDrag Panel Contentsスクリプトをアタッチする<br />
・メニューのNGUI→Attach→ColliderでBox Colliderをアタッチする<br />
・必要に応じてItemオブジェクトを複数作成する<br />
<br />
<br />
<span style="font-size: x-large;">⑤Outline作成</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZHk30dhvzusFtKf_bFDNnocUrq9jU0f4NHBVjm9U1MC9AaeODM1fhVMP-WonOVolP6lu0vxa3_oqxDav1E8nSwurV5g8dMsLzTCKuiqhTkp5lYpHtoCDpDo-ooYhC_kYudr-CGzIS_Mc/s1600/scroll5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZHk30dhvzusFtKf_bFDNnocUrq9jU0f4NHBVjm9U1MC9AaeODM1fhVMP-WonOVolP6lu0vxa3_oqxDav1E8nSwurV5g8dMsLzTCKuiqhTkp5lYpHtoCDpDo-ooYhC_kYudr-CGzIS_Mc/s1600/scroll5.png" /></a></div>
<span style="font-size: x-large;"><br /></span>
・Anchorの子オブジェクトとして空のオブジェクトOutlineを作成<br />
・メニューのNGUI→Attach→ColliderでBox Colliderをアタッチする<br />
・CenterとSizeを②で作成したScrollViewのUIPanelのCenter/Sizeの値にする<br />
・Add Componentボタンを押下しDrag Panel Contentsを選択しUIDrag Panel Contentsスクリプトをアタッチする<br />
・Draggable PanelにScrollViewをドラッグ&ドロップする<br />
======<br />
<br />
以上でスクロールビューの完成です!<br />
説明すると少し長く思えますが、実際に作ると直ぐにできますので、<br />
是非作ってみてください。半沢 匠http://www.blogger.com/profile/11176898250767151982noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-11556683276615481292013-05-20T11:48:00.004+09:002013-05-20T12:19:11.526+09:00山と開発 ~Mountain climbing and Development~こんにちは、開発の松本英高です。<br />
仕事ではゲームやスマホアプリ開発をしています。<br />
<br />
ずいぶん昔にチーム内勉強会で発表した資料を整理しました。<br />
登山とソフトウェア開発の意外(?)な類似点を、話してみたいと思います。<br />
<br />
実装者の方から、マネージャークラスの方まで、幅広くご参考になれば幸いです。<br />
10数枚の気楽なスライドです、コーヒーでも飲みながら見てください。<br />
<iframe frameborder="0" height="400" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/21479162" width="476"></iframe><br />
<br />
<b>おまけ</b><br />
どうでもいいのですが、登山用語を、ソフトウェア開発用語化してみました。<br />
<ul>
<li>道迷い</li>
<ul>
<li>何の処理を書いてるのだかわからなくなること。</li>
<li>そのまま進むと、スパゲティコードが出来上がる。</li>
</ul>
<li>8合目</li>
<ul>
<li>頂上まであと少しの状態。</li>
<li>PGが「8合目ですね」と言っても、実際まだ5合目にも達していないことも多々ある。</li>
</ul>
<li>プログラマーズ・ハイ</li>
<ul>
<li>プログラミング中、気持ち良くなってくること。</li>
<li>出来上がったコードは、大概微妙。</li>
</ul>
<li>ビバーク(緊急野営)</li>
<ul>
<li>トラブル発生で会社に泊まること。</li>
</ul>
</ul>
Anonymoushttp://www.blogger.com/profile/02447764952187584518noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-76100207047244880352013-03-11T12:00:00.000+09:002013-10-04T15:41:03.362+09:00Unityでの音(サウンド)管理(SoundManager Ver.β)<div class="tr_bq">
こんにちは、開発の半沢 匠です。<br />
今回もUnity(<a href="http://unity3d.com/" target="_blank">http://unity3d.com/</a>)に関しての記事を書きたいと思います。</div>
<br />
<br />
<b>■音管理</b><br />
<br />
ゲーム開発及び、アプリ開発において<br />
音再生は欠かせないもの。<br />
<br />
BGMやSEを導入するだけで、ぐっと雰囲気が出てきます。<br />
今回はこれをなるべく簡単に管理できるような仕組みを紹介したいと思います。<br />
<br />
<br />
<b>■スクリプト</b><br />
SoundManager.csという下記のスクリプト作成いたしましたので、<br />
こちらを紹介させていただきます。<br />
<br />
<pre class="brush: c#" name="code1">using UnityEngine;
using System;
using System.Collections;
// 音管理クラス
public class SoundManager : MonoBehaviour {
protected static SoundManager instance;
public static SoundManager Instance
{
get
{
if(instance == null)
{
instance = (SoundManager) FindObjectOfType(typeof(SoundManager));
if (instance == null)
{
Debug.LogError("SoundManager Instance Error");
}
}
return instance;
}
}
// 音量
public SoundVolume volume = new SoundVolume();
// === AudioSource ===
// BGM
private AudioSource BGMsource;
// SE
private AudioSource[] SEsources = new AudioSource[16];
// 音声
private AudioSource[] VoiceSources = new AudioSource[16];
// === AudioClip ===
// BGM
public AudioClip[] BGM;
// SE
public AudioClip[] SE;
// 音声
public AudioClip[] Voice;
void Awake (){
GameObject[] obj = GameObject.FindGameObjectsWithTag("SoundManager");
if( obj.Length > 1 ){
// 既に存在しているなら削除
Destroy(gameObject);
}else{
// 音管理はシーン遷移では破棄させない
DontDestroyOnLoad(gameObject);
}
// 全てのAudioSourceコンポーネントを追加する
// BGM AudioSource
BGMsource = gameObject.AddComponent<AudioSource>();
// BGMはループを有効にする
BGMsource.loop = true;
// SE AudioSource
for(int i = 0 ; i < SEsources.Length ; i++ ){
SEsources[i] = gameObject.AddComponent<AudioSource>();
}
// 音声 AudioSource
for(int i = 0 ; i < VoiceSources.Length ; i++ ){
VoiceSources[i] = gameObject.AddComponent<AudioSource>();
}
}
void Update () {
// ミュート設定
BGMsource.mute = volume.Mute;
foreach(AudioSource source in SEsources ){
source.mute = volume.Mute;
}
foreach(AudioSource source in VoiceSources ){
source.mute = volume.Mute;
}
// ボリューム設定
BGMsource.volume = volume.BGM;
foreach(AudioSource source in SEsources ){
source.volume = volume.SE;
}
foreach(AudioSource source in VoiceSources ){
source.volume = volume.Voice;
}
}
// ***** BGM再生 *****
// BGM再生
public void PlayBGM(int index){
if( 0 > index || BGM.Length <= index ){
return;
}
// 同じBGMの場合は何もしない
if( BGMsource.clip == BGM[index] ){
return;
}
BGMsource.Stop();
BGMsource.clip = BGM[index];
BGMsource.Play();
}
// BGM停止
public void StopBGM(){
BGMsource.Stop();
BGMsource.clip = null;
}
// ***** SE再生 *****
// SE再生
public void PlaySE(int index){
if( 0 > index || SE.Length <= index ){
return;
}
// 再生中で無いAudioSouceで鳴らす
foreach(AudioSource source in SEsources){
if( false == source.isPlaying ){
source.clip = SE[index];
source.Play();
return;
}
}
}
// SE停止
public void StopSE(){
// 全てのSE用のAudioSouceを停止する
foreach(AudioSource source in SEsources){
source.Stop();
source.clip = null;
}
}
// ***** 音声再生 *****
// 音声再生
public void PlayVoice(int index){
if( 0 > index || Voice.Length <= index ){
return;
}
// 再生中で無いAudioSouceで鳴らす
foreach(AudioSource source in VoiceSources){
if( false == source.isPlaying ){
source.clip = Voice[index];
source.Play();
return;
}
}
}
// 音声停止
public void StopVoice(){
// 全ての音声用のAudioSouceを停止する
foreach(AudioSource source in VoiceSources){
source.Stop();
source.clip = null;
}
}
}
</pre>
<br />
更に音量クラスも作成する。<br />
<br />
<pre class="brush: c#" name="code2">// 音量クラス
[Serializable]
public class SoundVolume{
public float BGM = 1.0f;
public float Voice = 1.0f;
public float SE = 1.0f;
public bool Mute = false;
public void Init(){
BGM = 1.0f;
Voice = 1.0f;
SE = 1.0f;
Mute = false;
}
}
</pre>
<br />
<br />
<b>■使用手順</b><br />
1.上記のSoundManager.csを空のオブジェクトに張り付ける。<br />
2.オブジェクトのタグ名を”SoundManager”とする。<br />
3.追加したい音ファイルをGUI操作で追加する(下図参照)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB9IhygyPkWL8zOtc7bagbsEMUTPRatoo4qca7kWCHpDet4Ao9TzUarhydqpNOtva2Qh7Vhjl0Ac70lJxtaOGqjgWXmAAamCVcRWBdEBCAzklF70nwY-mA8E0hxCaTHuBO4iGpAnKNWTE/s1600/soundmanger.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB9IhygyPkWL8zOtc7bagbsEMUTPRatoo4qca7kWCHpDet4Ao9TzUarhydqpNOtva2Qh7Vhjl0Ac70lJxtaOGqjgWXmAAamCVcRWBdEBCAzklF70nwY-mA8E0hxCaTHuBO4iGpAnKNWTE/s320/soundmanger.jpg" width="320" /></a></div>
4.音を再生したい箇所に下記ソースを、それぞれ追加する。<br />
<pre class="brush: c#" name="code1">SoundManager.Instance.PlayBGM(0);
SoundManager.Instance.PlaySE(2);
SoundManager.Instance.PlayVoice(3);</pre>
<br />
以上で音を再生できるようになったかと思います。
<br />
<br />
<br />
<br />
<b>■解説</b><br />
・SoundManagerは、1シーンに1つのみ生成されるようになっており、<br />
シーン遷移時でも破棄されないように設定されており、<br />
シングルトン化してある為、どのソースからもアクセス可能になっております。<br />
・エディタ上でドラッグ&ドロップだけで音ファイルを簡単に追加/削除できるため、<br />
プログラマー以外の人でも簡単に使えるように想定(別途エクセル等でインデックス管理はした方が良い)<br />
また、鳴らす際も1行のソースを追加するだけの簡単仕様にしました。<br />
・new AudioSource[16];は16個まで同時再生可能という設定になっております。<br />
こちらは状況に応じて色々と変更されると良いかもしれません。<br />
・SoundVolumeに[Serializable]を追加することで、エディタ上に音量やミュート状態を表示するようにし、デバッグ時に使用できるように致しました。<br />
<br />
<br />
<b>■最後に</b><br />
よくある手法ではございますが、こんな感じに私は使用しておりますという事でご紹介させていただきました。<br />
結構便利な機能だと思いますので、是非ご活用頂ければと思います。<br />
Ver.βということで今後も随時使いやすい形に改良していきたいと思います。<br />
<br />半沢 匠http://www.blogger.com/profile/11176898250767151982noreply@blogger.com6tag:blogger.com,1999:blog-2350882578336027394.post-6492877393972263332012-06-01T15:03:00.000+09:002013-10-04T15:41:18.709+09:00Jenkinsを使ってUnity開発をもっと楽にしよう<br />
こんにちは、開発の半沢 匠です。<br />
今回は、CI(継続的インテグレーション)ツール「Jenkins」を使ってUnity開発をもっと楽にしよう!(WebPlayer版 導入編)になります。※<span style="font-family: sans-serif; line-height: 13px;">Macへの導入方法を解説いたします。</span><br />
<span style="font-family: sans-serif;"><span style="line-height: 13px;"></span></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigzY-fTqJX2q5bod23L1NH21Es9etllzcH6RIJuuZ3pPKVawhg2s3T-hDL5Iwvpfv3Jun5VShD-JWbWOuB6pR6baJLlckTIMP68CqiPbFMXeFdsP2i2emiq3TrLvM2vSOjd_O6jrcCFiY/s1600/jenkins.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigzY-fTqJX2q5bod23L1NH21Es9etllzcH6RIJuuZ3pPKVawhg2s3T-hDL5Iwvpfv3Jun5VShD-JWbWOuB6pR6baJLlckTIMP68CqiPbFMXeFdsP2i2emiq3TrLvM2vSOjd_O6jrcCFiY/s320/jenkins.png" width="320" /></a></div>
<span style="font-family: sans-serif;">■Jenkins導入のメリット</span><br />
<span style="font-family: sans-serif;">・いつでも実行可能な最新版のモジュールが、定期的に自動で作成される</span><br />
<span style="font-family: sans-serif;">・ボタンをポチっと押すだけで、いつでも実行可能な最新版のモジュールが作成できる</span><br />
<span style="font-family: sans-serif;">・モジュール履歴を残せる→バグ早期発見に繋がる(どのバージョンでバグが出たのか確認できる)</span>
<span style="font-family: sans-serif;"><br /></span><br />
<span style="font-family: sans-serif;">■今回行うこと</span><br />
<span style="font-family: sans-serif;">1.SVNからの最新版取得</span><br />
<span style="font-family: sans-serif;">2.UnityでのビルドでWebPlayer作成</span><br />
<span style="font-family: sans-serif;">3.Webへのアップロード</span><br />
<span style="font-family: sans-serif;">4.1~3を15分毎に自動で行う</span><br />
<br />
<span style="font-family: sans-serif;"><span style="line-height: 13px;">■準備</span></span><br />
<ul>
<li><span style="font-family: sans-serif;"><span style="line-height: 13px;">以下を用意・構築しておく</span></span></li>
<ul>
<li><span style="font-family: sans-serif;"><span style="line-height: 13px;">Mac</span></span></li>
<li><span style="font-family: sans-serif; line-height: 13px;">SVN環境</span></li>
<li><span style="font-family: sans-serif; line-height: 13px;">Unity</span></li>
</ul>
</ul>
<br />
<span style="font-family: sans-serif;"><span style="line-height: 13px;">■導入</span></span><br />
▼Unity側の準備<br />
<ul>
<li>UnityプロジェクトをSVNにコミット</li>
<li>そのプロジェクト内にビルドスクリプトを作成し、Editorフォルダ内に配置する</li>
</ul>
<pre class="brush: c#" name="code1">using UnityEngine;
using UnityEditor;
using System.Collections;
public class MyBuilder {
[UnityEditor.MenuItem("Tools/Build Project AllScene")]
public static void BuildProjectAllScene() {
EditorUserBuildSettings.SwitchActiveBuildTarget( BuildTarget.WebPlayer );
string[] allScene = new string[EditorBuildSettings.scenes.Length];
int i = 0;
foreach( EditorBuildSettingsScene scene in EditorBuildSettings.scenes ){
allScene[i] = scene.path;
i++;
}
BuildPipeline.BuildPlayer( allScene,
"WebPlayer",
BuildTarget.WebPlayer,
BuildOptions.None
);
}
}</pre>
<br />
<span style="font-family: sans-serif;"><span style="line-height: 13px;"> ▼Jenkinsインストール</span></span><br />
<ul>
<li>Javaのランタイムをインストール(Lionのみ必要になります)</li>
<li><a href="http://jenkins-ci.org/">http://jenkins-ci.org/</a> から MaC OS X パッケージをDL&展開</li>
<li>/Library/LaunchDeamons/org.jenkins-ci.plistの下記箇所を編集</li>
<ul>
<li>JENKINS_HOME を任意のパスに変更(Jenkinsのワークスペースになります)省略可</li>
<li>GroupName をdeamonからログインアカウントの所属グループに変更</li>
<li>UserName をdeamonからログインアカウントの名前に変更</li>
<ul>
</ul>
</ul>
<li>ワークスペースの権限を自分の所属グループ&自分のアカウントに変更</li>
<ul>
<li>初期値のワークスペースの場合は下記の通り</li>
<ul>
<li>sudo chown -R ユーザー名 /Users/Shared/Jenkins/Home</li>
<li>sudo chgrp -R グループ名 /Users/Shared/Jenkins/Home</li>
</ul>
</ul>
<li>システム環境設定を起動し、共有→Web共有をオンに設定します</li>
<li>ブラウザで http://[PCのIPアドレス]:8080/ にアクセスでJenkinsが表示される</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRGsOhKmdgLAMSXLYc-M4y_6wmX1KRkDVNjFYoMQGtlHPbpoFOU9ZgTrZjdha_KIqj7N9BLz4cl8kqUj9mOfSlsTaHSvwxBw7P5lMfFtAda2yDa0nlU_c7sXBD377_Xdkv3Rs1MhavTkk/s1600/jenkins-top.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRGsOhKmdgLAMSXLYc-M4y_6wmX1KRkDVNjFYoMQGtlHPbpoFOU9ZgTrZjdha_KIqj7N9BLz4cl8kqUj9mOfSlsTaHSvwxBw7P5lMfFtAda2yDa0nlU_c7sXBD377_Xdkv3Rs1MhavTkk/s320/jenkins-top.png" width="320" /></a></div>
<br />
--- ここからは、Jenkins(ブラウザ)上での作業になります。 ---<br />
<ul>
</ul>
<div>
<br />
▼プラグインの追加・設定</div>
<div>
<ul>
<li>プラグインの追加</li>
<ul>
<li>ホーム→Jenkinsの管理(左メニューリンク)→プラグインの管理(コンテンツリンク)→利用可能(タブ) を選択</li>
<ul>
<li>Jenkins Unity3d plugin にチェック</li>
<li>SCP Plugin にチェック</li>
<li>下の「ダウンロードして再起動後にインストール」ボタンを押下</li>
<li>再起動されるまで待つ</li>
</ul>
</ul>
<li>プラグインの設定</li>
<ul>
<li>ホーム→Jenkinsの管理
(左メニューリンク) →システムの設定
(コンテンツリンク) を選択</li>
<ul>
<li>Unity 3d </li>
<ul>
<li>名前:適当(例:Unity3.5.1f2)</li>
<li>インストールディレクトリ:/Applications/Unity/Unity.app/</li>
</ul>
<li>SCPリポジトリホスト で設定</li>
<ul>
<li>出来上がったモジュールの公開先をこちらのプラグインで設定します</li>
<li>ホスト名、ポート、ルートリポジトリパス、ユーザー名、パスワード/パスフレーズ、秘密鍵を設定</li>
</ul>
</ul>
<li>左下の「保存」ボタンを押す</li>
</ul>
</ul>
</div>
<br />
▼ジョブ作成<br />
<ul>
<li>新規ジョブ作成 を選択</li>
<ul>
<li>ジョブ名:適当(例:Unity-TestProject)</li>
<li>フリースタイル・プロジェクトビルド を選択</li>
<li>「OK」ボタンを押す</li>
</ul>
</ul>
<br />
▼ジョブ設定<br />
<ul>
<li>ソースコード管理システム</li>
<ul>
<li>Subversion を選択</li>
<li>リポジトリURL:プロジェクトのSVNパス</li>
<ul>
<li>例)svn://localhost/Unity/TestProject</li>
</ul>
<li>ローカルモジュールディレクトリ:ローカルのプロジェクトのパス(※パスはワーキングスペースからなので注意)</li>
<ul>
<li>例)./Unity/TestProject</li>
</ul>
<li>チェックアウト方式:svn revert'してから'svn update'を実行 を選択(任意のものでOK)</li>
</ul>
<li>ビルド・トリガ</li>
<ul>
<li>こちらで定期を指定する。今回は15分に1回リポジトリをチェックし、更新があれば実行するように設定</li>
<ul>
<li>SCMポーリング を選択</li>
<li>スケジュール:下記を記述</li>
<ul>
<li>*/15 * * * *</li>
</ul>
</ul>
</ul>
<li>ビルド</li>
<ul>
<li>ビルド手順の追加:Invoke Unity3d Editor を選択</li>
<ul>
<li>Unity 3d installation name:プラグインの設定で指定した名前を選択</li>
<li>Editor command line arguments:下記を入力</li>
<ul>
<li>-quit -batchmode -executeMethod MyBuilder.BuildProjectAllScene</li>
</ul>
</ul>
</ul>
<li>ビルド後の処理</li>
<ul>
<li>成果物をSCPリポジトリに公開 を選択</li>
<ul>
<li>SCPサイト:プラグインの設定で指定したホスト名を選択</li>
<li>アップロードファイル:追加ボタンを押す</li>
<ul>
<li>ソース:ローカルのアップロードファイル(出来上がったモジュールフォルダ)を選択</li>
<ul>
<li>例)Unity/TestProject/WebPlayer</li>
</ul>
<li>送信先:アップロード先を選択(フォルダ名にビルド番号・リビジョンなどを追記するとよい)</li>
<ul>
<li>例)No${BUILD_NUMBER}_Rev${SVN_REVISION}</li>
</ul>
</ul>
</ul>
</ul>
</ul>
<br />
■動作確認<br />
<div>
<ul>
<li>先ほど作成したジョブを選択し、左メニューから「ビルド実行」をクリック</li>
<li>Unityビルドが実行され、モジュールがローカル上に作られた後、Webにアップロードされる</li>
</ul>
<div>
<br /></div>
<div>
これで、15分に1回は最新版のモジュールが自動で作成され自動でWeb公開されるようになりました!</div>
<div>
また、■動作確認で行った「ビルド実行」をポチッとするだけで、</div>
<div>
いつでも最新版のモジュール作成&公開が行われるようになりました!<br />
<br />
<br />
◎導入してみて<br />
<ul>
<li>「ビルド実行」をポチッと押すだけなのが本当に楽!</li>
<ul>
<li>UnityのUI上でビルドを実行し、ビルドが完了するまで待った後に、出来上がったファイルを、SCPツールでWeb上にアップっといった作業が一切必要無くなった。</li>
</ul>
<li>ビルド&公開作業が自動化された為、その間の時間を丸々他作業に当てれるようになった!</li>
</ul>
<span style="color: red;">→手間と時間の大幅削減に成功!</span></div>
<div>
<br /></div>
<br />
<div>
Jenkinsは、他にも便利な機能がたくさんあり大変便利なツールなので是非導入してみてください。</div>
<div>
<br /></div>
<div>
<br />
<br />
<br /></div>
</div>
半沢 匠http://www.blogger.com/profile/11176898250767151982noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-25112609711573904352012-01-17T17:38:00.002+09:002013-10-04T15:41:51.558+09:00Unityを用いたゲーム開発(タワーディフェンス編)Part.1<div class="tr_bq">
はじめまして、開発の半沢 匠です。<br />
<br />
今話題のゲームエンジンUnity(<a href="http://unity3d.com/" target="_blank">http://unity3d.com/</a>)を使ってゲーム開発をしてみよう!</div>
という事で、まずは「タワーディフェンス」を作ってみました!<br />
<br />
ここでは、作業報告も兼ねて作業経過や開発時に役に立った事等を連載していきたいと思います。<br />
<br />
<br />
<b>はじめに</b><br />
<br />
Unityとは、簡単に表すと<br />
「Windows及びMacで動作可能な3Dゲーム開発ツール」です。<br />
<br />
簡単なGUI操作でコンテンツを構築し、<br />
構築したコンテンツに対してプログラミング言語(JavaScript、C#)を使って動きを作成することができます。<br />
プログラマでない方でも直感的に操作できるインターフェイスになっております。<br />
<br />
さらに、Unityはマルチプラットフォームに対応しており、<br />
下記の実行形式に書き出す事が出来ます。<br />
<br />
・Windows、MacOSXのOS<br />
・WEBブラウザ<br />
・iPhone、Android<br />
・PS3、Xbox、Wii<br />
<br />
Proライセンスは有料ですが、無料版も用意されており、<br />
無料版でも十分な機能が備わっています。<br />
<br />
---------------<br />
<br />
■<b>プレイアブルデモ Part.1</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://db.tt/TSJoJeqS" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfFFC1uXEayzacqEaRWyOEBf28bpvKksJ2DOOAc2yTZEjgtwO7PbKDQ59t5TiLmOQFbk5EeIZxa6Kzhazx3MP_S8A9SFHAbPORA68HBDcYqw9lTZdexDFhJ1quVKDwdsQzxQ01GFko0Jwj/s320/TowerDefensePart1.PNG" width="320" /><br />
TowerDefence.Part.1</a></div>
※プレイするにはUnityのwebプレイヤーが必要になります<br />
<br />
それなりに動いてはいますが、<br />
ゲームとしてはまだまだまだですね。<br />
ここからゲームらしくなるように調整していきたいと思います。<br />
<br />
<br />
<b>■スクリプト</b><br />
Unityはスクリプト言語を使って"ゲームらしさ"を作成することができます。<br />
ここでは、今回開発した際に役に立った事を紹介したいと思います。<br />
今回は C# で開発しております。<br />
こちらでは、ある程度Unityの知識を持った人向けの解説になっております。<br />
<b><br /></b>
<span style="background-color: white; color: blue;">・クリックした位置に銃をポップ</span><br />
画面上でマウス左クリックを押下箇所に銃(GameObject)を生成させます。<br />
- GunPopスクリプトを適当なGameObjectに指定する<br />
<br />
<br />
<pre class="brush: c#" name="code1">public class GunPop: MonoBehaviour {
public GameObject selectGun // 生成する銃を指定
void Update (){
// マウス左クリック押下したか判定
if( Input.GetMouseButtonUp(0) ){
// マウス座標を取得
Vector3 screenPoint = Input.mousePosition;
// マウス座標はXYの2次元なのでZ座標にはカメラのZ座標を指定
screenPoint.z = 17.0f;
// カメラ座標からワールド座標に変換
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(screenPoint);
// 変換されたワールド座標にselectGun(銃のGameObject)のインスタンスを生成
Instantiate(selectGun, worldPoint, selectGun.transform.rotation);
}
}
}
</pre>
<br />
<span style="color: blue;">・弾が敵に当たった場合、当たった敵のHPを減らす</span><br />
- 弾のGameObjectにBulletスクリプトを指定する<br />
- 敵のGameObjectにEnemyStatusスクリプトを指定する<br />
- 弾・敵のGmaeObjectにColliderを設定し、「Is Trigger」にチェックを入れる<br />
<br />
<pre class="brush: c#" name="code2">public class Bullet : MonoBehaviour {
public float hitDamage = 1.0f; // 与えるダメージを指定
void OnTriggerEnter(Collider collisionInfo){
// 当たったGameObjectのタグが"Enemy"か判定
if(collisionInfo.gameObject.tag == "Enemy"){
// 当たったGameObjectに指定されているスクリプトの"ApplyDamege"関数を呼び出し
// 引数、hitdamage を渡す
collisionInfo.gameObject.SendMessage("ApplyDamage",hitDamage);
// 自分自身を消滅させる
Destroy(gameObject);
}
}
}
public class EnemyStatus : MonoBehaviour {
public float hitPoint = 1.0f; // 自分自身のHPを指定
void ApplyDamage(float damage){
// 受けたダメージを自身のHPから減算
hitPoint-=damage;
// HPが0以下になったか
if( hitPoint <= 0.0f ){
// 自分自身を消滅させる
Destroy(gameObject);
}
}
}
</pre>
<br />
<br />
<b>■次回予定</b><br />
・もう少し銃の配置される場所を明示的にし、敵に弾を当てやすいようにする仕組みを導入<br />
・スコア機能を実装半沢 匠http://www.blogger.com/profile/11176898250767151982noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-64094312771790972272011-12-13T19:20:00.001+09:002012-01-20T18:20:04.113+09:00amazonEC2(RHEL-6.1)上でDRBD8.3.12によるミラーリングDRBDによるファイルシステムのミラーリングをamazonEC2上のRHEL6.1上で試してみました。<br />
デバイスレベルでパーティションごとミラーするDRBDのパフォーマンスが気になる所ですが、<br />
2台のネットワーク的な距離によってパフォーマンスは変わるかどうかを調べてみます。
<br />
<br />
環境は下記の通りです。<br />
※チェックポイントとしてAWS Management Consoleで使用するポートがSecurityGroupsで空けられているかどうか+ec2インスタンス内でiptablesで許可されているかどうかを確認してください。いつもはまります^^;<br />
<br />
<b>■同リージョン、同ゾーンでのミラーリング
</b><br />
<table border="1" cellpadding="2" cellspacing="2">
<tbody>
<tr><th><br /></th><th>環境1</th><th>環境2</th></tr>
<tr><td>・ゾーン</td><td>ap-northeast-1a</td><td>ap-northeast-1a</td></tr>
<tr><td>・host名(外部)</td><td>ec2-175-41-235-179.ap-northeast-1.compute.amazonaws.com</td><td>ec2-175-41-198-87.ap-northeast-1.compute.amazonaws.com</td></tr>
<tr><td>・host名(内部)</td><td>drbd-1a</td><td>drbd-1b</td></tr>
<tr><td>・localIP</td><td>10.146.69.136</td><td>10.146.97.107</td></tr>
<tr><td>・globalIP</td><td>175.41.235.179</td><td>175.41.198.87</td></tr>
<tr><td>・EBSデバイス</td><td>/dev/xvdj1</td><td>/dev/xvdj1</td></tr>
</tbody></table>
<b>
<br />
<b>■同リージョン、別ゾーンでのミラーリング
</b></b><br />
<table border="1" cellpadding="2" cellspacing="2">
<tbody>
<tr><th><br /></th><th>環境1</th><th>環境2</th></tr>
<tr><td>・ゾーン</td><td>ap-northeast-1a</td><td>ap-northeast-1b</td></tr>
<tr><td>・host名(外部)</td><td>ec2-175-41-211-88.ap-northeast-1.compute.amazonaws.com</td><td>ec2-175-41-208-108.ap-northeast-1.compute.amazonaws.com</td></tr>
<tr><td>・host名(内部)</td><td>drbd-out-1a</td><td>drbd-out-1b</td></tr>
<tr><td>・localIP</td><td>10.146.23.47</td><td>10.150.187.32</td></tr>
<tr><td>・globalIP</td><td>175.41.211.88</td><td>175.41.208.108</td></tr>
<tr><td>・EBSデバイス</td><td>/dev/xvdj1</td><td>/dev/xvdj1</td></tr>
</tbody></table>
<b><b>
<br />
<b>■/usr/src以降でコンパイルし、インストール(共通)</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>hostname <span style="color: red;">drbd-1a <- ホスト名</span></b></b><br />
<b><b>yum -y install rpm-build flex</b></b><br />
<b><b>cd /usr/src</b></b><br />
<b><b>wget http://oss.linbit.com/drbd/8.3/drbd-8.3.12.tar.gz</b></b><br />
<b><b>tar xzvf drbd-8.3.12.tar.gz</b></b><br />
<b><b>cd drbd-8.3.12/</b></b><br />
<b><b>./configure --with-km</b></b><br />
<b><b>make</b></b><br />
<b><b>make install</b></b><br />
<b><b>ln -s /usr/local/etc/rc.d/init.d/drbd /etc/init.d/</b></b></div>
<b><b>
<br />
<b>■/usr/local/etc/drbd.d/zyyx.resを以下の内容で作成</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>resource zyyx {</b></b><br />
<b><b>meta-disk internal;</b></b><br />
<b><b>device /dev/drbd0;</b></b><br />
<b><b>disk /dev/xvdj1;</b></b><br />
<b><b>on <span style="color: red;">drbd-1a { <- ホスト名 </span></b></b><br />
<b><b>address <span style="color: red;">10.146.69.136:7789; <- IPアドレス</span></b></b><br />
<b><b>}</b></b><br />
<b><b>on <span style="color: red;">drbd-1b { { <- ホスト名 </span></b></b><br />
<b><b>address <span style="color: red;">10.146.97.107:7789; <- IPアドレス</span></b></b><br />
<b><b>}</b></b><br />
<b><b>}</b></b></div>
<b><b>
<br />
<b>/etc/hostsに以下の内容を追記</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b><span style="color: red;">10.146.69.136 drbd-1a <- IPアドレス ホスト名</span></b></b><br />
<b><b><span style="color: red;">10.146.97.107 drbd-1b <- IPアドレス ホスト名</span></b></b></div>
<b><b>
<br />
<b>■drbdの構築(共通)</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>drbdadm create-md zyyx</b></b></div>
<b><b>
<br />
<b>■drbdの起動(共通)</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>/etc/init.d/drbd start</b></b></div>
<b><b>
<br />
<b>■ファイルシステムの作成(drbd-1aのみ)</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>drbdsetup /dev/drbd0 primary -o</b></b><br />
<b><b>mkfs.ext4 /dev/drbd0</b></b></div>
<b><b>
<br />
<b>■ファイルシステムのマウント(drbd-1aのみ)</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>mkdir -p /mnt/drbd/zyyx</b></b><br />
<b><b>mount /dev/drbd0 /mnt/drbd/zyyx</b></b></div>
<b><b>
<br />
<b>/mnt/drbd/zyyx/test.txtに以下の内容を記入</b><br />
</b></b><br />
<div style="background-color: black; color: lime;">
<b><b>this file is in drbd file system</b></b></div>
<b><b>
<br />
<b>■ファイルシステムの解除(drbd-1aのみ)</b><br />
<div style="background-color: black; color: lime;">
umount /mnt/drbd/zyyx</div>
<br />
<b>■スレーブへ降格(drbd-1aのみ)</b><br />
<div style="background-color: black; color: lime;">
drbdadm secondary all</div>
<br />
<b>■プライマリへ昇格(drbd-1bのみ)</b><br />
<div style="background-color: black; color: lime;">
drbdadm primary all</div>
<br />
<b>■ファイルシステムのマウント(drbd-1bのみ)</b><br />
<div style="background-color: black; color: lime;">
mkdir -p /mnt/drbd/zyyx
mount /dev/drbd0 /mnt/drbd/zyyx
</div>
<br />
<b>■ちゃんと同期されているか確認(drbd-1bのみ)</b><br />
<div style="background-color: black; color: lime;">
# cat /mnt/drbd/zyyx/test.txt
this file is in drbd file system
</div>
<br />
<b>■ベンチマークソフトの導入(共通)</b><br />
<div style="background-color: black; color: lime;">
yum -y install libaio-devel<br />
cd /usr/src<br />
wget http://brick.kernel.dk/snaps/fio-1.58.tar.gz<br />
tar xzvf fio-1.58.tar.gz<br />
cd fio-1.58<br />
make<br />
make install</div>
<br />
<b>■速度の計測</b><br />
<div style="background-color: black; color: lime;">
<span style="color: red;">・ローカル環境</span><br />
# fio -filename=/mnt/local1G -direct=1 -rw=randwrite -bs=1m -size=1G -numjobs=4 -runtime=10 -group_reporting -name=file1<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
...<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
fio 1.58<br />
Starting 4 processes<br />
file1: Laying out IO file(s) (1 file(s) / 1024MB)<br />
Jobs: 4 (f=4): [wwww] [100.0% done] [0K/30408K /s] [0 /29 iops] [eta 00m:00s]<br />
file1: (groupid=0, jobs=4): err= 0: pid=31670<br />
write: io=319488KB, bw=31611KB/s, iops=30 , runt= 10107msec<br />
clat (msec): min=29 , max=552 , avg=35.47, stdev=41.48<br />
lat (msec): min=29 , max=552 , avg=35.47, stdev=41.48<br />
bw (KB/s) : min= 1278, max=17520, per=24.77%, avg=7829.02, stdev=2868.20<br />
cpu : usr=0.00%, sys=0.20%, ctx=714, majf=0, minf=99<br />
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%<br />
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
issued r/w/d: total=0/312/0, short=0/0/0<br />
<br />
lat (msec): 50=98.72%, 250=0.64%, 500=0.32%, 750=0.32%<br />
<br />
Run status group 0 (all jobs):<br />
WRITE: io=319488KB, aggrb=<span style="color: red;">31610KB/s</span>, minb=32369KB/s, maxb=32369KB/s, mint=10107msec, maxt=10107msec<br />
<br />
Disk stats (read/write):<br />
xvde1: ios=0/7425, merge=0/0, ticks=0/133277, in_queue=134281, util=98.70%<br />
<br />
<span style="color: red;">・同ゾーン</span><br />
# fio -filename=/mnt/drbd/zyyx/remote1G -direct=1 -rw=randwrite -bs=1m -size=1G -numjobs=4 -runtime=10 -group_reporting -name=file1<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
...<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
fio 1.58<br />
Starting 4 processes<br />
file1: Laying out IO file(s) (1 file(s) / 1024MB)<br />
Jobs: 4 (f=4): [wwww] [100.0% done] [0K/25140K /s] [0 /23 iops] [eta 00m:00s]<br />
file1: (groupid=0, jobs=4): err= 0: pid=31697<br />
write: io=183296KB, bw=17478KB/s, iops=17 , runt= 10487msec<br />
clat (msec): min=36 , max=292 , avg=58.58, stdev=54.42<br />
lat (msec): min=36 , max=292 , avg=58.58, stdev=54.42<br />
bw (KB/s) : min= 97, max=25069, per=89.51%, avg=15644.40, stdev=8701.23<br />
cpu : usr=0.02%, sys=0.17%, ctx=519, majf=0, minf=99<br />
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%<br />
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
issued r/w/d: total=0/179/0, short=0/0/0<br />
<br />
lat (msec): 50=87.71%, 100=2.79%, 250=7.26%, 500=2.23%<br />
<br />
Run status group 0 (all jobs):<br />
WRITE: io=183296KB, aggrb=<span style="color: red;">17478KB/s</span>, minb=17897KB/s, maxb=17897KB/s, mint=10487msec, maxt=10487msec<br />
<br />
Disk stats (read/write):<br />
drbd0: ios=0/4317, merge=0/0, ticks=0/139396, in_queue=145439, util=100.00%<br />
<br />
<br />
<span style="color: red;">・別ゾーン</span><br />
# fio -filename=/mnt/drbd/zyyx/remote1G -direct=1 -rw=randw<br />
rite -bs=1m -size=1G -numjobs=4 -runtime=10 -group_reporting -name=file1<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
...<br />
file1: (g=0): rw=randwrite, bs=1M-1M/1M-1M, ioengine=sync, iodepth=1<br />
fio 1.58<br />
Starting 4 processes<br />
file1: Laying out IO file(s) (1 file(s) / 1024MB)<br />
Jobs: 4 (f=4): [wwww] [100.0% done] [0K/10485K /s] [0 /10 iops] [eta 00m:00s]<br />
file1: (groupid=0, jobs=4): err= 0: pid=3221<br />
write: io=181248KB, bw=17328KB/s, iops=16 , runt= 10460msec<br />
clat (msec): min=40 , max=335 , avg=59.09, stdev=45.68<br />
lat (msec): min=40 , max=335 , avg=59.09, stdev=45.68<br />
bw (KB/s) : min= 97, max=22528, per=90.21%, avg=15630.00, stdev=8596.54<br />
cpu : usr=0.01%, sys=0.13%, ctx=511, majf=0, minf=99<br />
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%<br />
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%<br />
issued r/w/d: total=0/177/0, short=0/0/0<br />
<br />
lat (msec): 50=73.45%, 100=20.34%, 250=3.39%, 500=2.82%<br />
<br />
Run status group 0 (all jobs):<br />
WRITE: io=181248KB, aggrb=<span style="color: red;">17327KB/s</span>, minb=17743KB/s, maxb=17743KB/s, mint=10460msec, maxt=10460msec<br />
<br />
Disk stats (read/write):<br />
drbd0: ios=0/4268, merge=0/0, ticks=0/155106, in_queue=161816, util=99.83%</div>
<br />
同リージョンならゾーンが異なっても速度が変わらないようです。<br />
ゾーンが違うと違うデータセンターに収容されるはずなので<br />
別ゾーンで組んだ方が災害には強いのかもしれません。
</b></b>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-9125185237415515992011-12-09T13:00:00.000+09:002012-01-20T18:17:15.456+09:00Google Channel API を用いたリアルタイム URL 転送アプリ「LinkSnap」をリリースしました。Google App Engine の API の <a href="http://code.google.com/appengine/docs/python/channel/overview.html">Channel API</a> を使用して、リアルタイムに PC から<br />
モバイルブラウザに URL を転送するアプリ 「LinkSnap」 をリリースしました。<br />
<br />
<br />
<br />
<a href="http://link-snap.appspot.com/" style="background: url(http://link-snap.appspot.com/favicon.ico) 0 3px no-repeat; font-size: large; padding-left: 19px;">LinkSnap</a>
<br />
<br />
<br />
<br />
ソースコードは github.com にて公開しています。
<br />
<a href="https://github.com/hinosawa/link-snap">https://github.com/hinosawa/link-snap</a>hinosawahttp://www.blogger.com/profile/02979515550081109631noreply@blogger.com0tag:blogger.com,1999:blog-2350882578336027394.post-48585847755925372372011-12-05T11:20:00.000+09:002012-02-07T17:19:16.924+09:00ジークス・ラボ開設のお知らせジークス・ラボ始めました。<br />
ここでは 開発中のライブラリやノウハウなどの情報を発信していきます。<br />
<br />
<a class="GMUUXGEDHFB blogg-title" href="http://www.blogger.com/blogger.g?blogID=2350882578336027394#allposts">ジークス・ラボ</a>Unknownnoreply@blogger.com0