2011年12月26日月曜日

制作物

Unityで制作したものを載せていく記事。
ご意見ご感想あればtwitterの@zi_suまたはコメントでよろしくお願いします


アイマス動画でDiva風音ゲーを試作

http://dl.dropbox.com/u/41223194/Im%40sDiva/WebPlayer.html
遊び方:WASDキーをマーカーが合わさったときに押す。
譜面データ製作:友人の@narumi_akiraさん https://twitter.com/#!/narumi_akira
Unityの基礎操作取得し、試作。2D機能がいまいちなのと譜面データとの分離に苦労
音楽と同期や処理最適化がまだまだなので、処理落ちとか発生します


アクションゲーム試作中

http://dl.dropbox.com/u/41223194/Felghana/WebPlayer.html 
遊び方:カーソルキーorWASDキー移動、左クリックorスペースキーで攻撃

  • 白いカプセルが将来的に敵
  • 木箱などが破壊可能なオブジェ
  • 宝石類が一時パワーアップアイテム。
イースフェルガナの誓いを参考に試作中
ザコ敵を屠りながらパワーアップアイテムをかき集め強化→大ボス撃破の遊びを目指してます

2011年11月7日月曜日

EditorWindowを拡張するには

自前のオブジェクトを作成した後、EditorWindowからGameObject→CreateEmptyみたいに選びたい時
忘れないようメモ

スクリプトを書いてAssetsに入れておけばメニューバーに出る


using UnityEditor;
public class GUIMenu : EditorWindow {
   //このAttribute設定が大事
   [MenuItem("GameObject/GUIMenu/CreateGUIPlain")]
    static void CreateGUIPlain(){
        GameObject obj = new GameObject("GUIPlain");
        obj.AddComponent<MeshFilter>();
        obj.AddComponent<MeshRenderer>();
        obj.AddComponent<GUIPlain>();
        obj.GetComponent<GUIPlain>().CreateMesh();
        obj.layer = LayerMask.NameToLayer("GUI");
    }
}

[MenuItem("")]で指定した場所に項目が追加
new GameObjectとAddComponentでゲームオブジェクトを作成

Unity ScriptReferenceのEditorWindowページ
http://unity3d.com/support/documentation/ScriptReference/EditorWindow.html

2011年10月13日木曜日

AnimationのCrossFadeについてメモ

AssetStoreに無料のアニメーション付きモデルSpartanKingを見つけました
Unity入門を読んでAnimationについて知ったことなので、実際にアニメーション制御スクリプトを書いてみました。

Unity入門読んだ通り、PlayとCrossFadeを試しつつちゃんと再生されてクロスフェードされているのを確認していたところ、問題が起きました。
どうもCrossFadeなのにアニメーションが補間されなくて、飛んでしまいます。
どうやらClampForeverかLoop設定になっていないアニメーションの場合、CrossFadeをしてもアニメーション補間してくれないようです。補間しようにもアニメの再生が終わっていて、CrossFadeを実行しても補間先のアニメはあるけど、補間元のアニメは再生されていないからだと思います。しっかり調べてはいませんが・・・

ということで、CrossFadeしたいアニメの場合はClampForeverかLoop設定にしておくのが無難でしょう。
私は攻撃アニメだからLoop設定しないままスクリプトを書いていて、アレコレ悩みました

Animation.wrapModeについてのReference
http://unity3d.com/support/documentation/ScriptReference/Animation-wrapMode.html

追記(2013/4/24)
ClampForever時にアニメーションが終了フレームかどうかは
if(animation["hoge"].length <= animation["hoge"].time){
  animation.CrossFade("huga");
}
でいいと思います。
lengthがアニメーションの最大長,timeが現在再生アニメの時間なので。
floatなので==よりは<=がいいでしょう。

2011年10月3日月曜日

Editor++の使い方

Unityでプレイボタンを押してゲーム実行中にゲームオブジェクトの値を変更しても
ストップボタンを押したら変更内容は変更前の値に戻ってしまいます

そこで、変更した値を保持するエクステンドのEditor++があります
25$です。1$79円支払いで2000円未満でした

使い方としては、ゲーム実行中に値を変更したオブジェクトを選択した状態で
メニューバーのWindow→Remember,Clipboard,Bactherを開いて

  • Rememberの場合
    • Rememberウィンドウのrememberボタンを押す
    • 値が記録されるので、ゲーム実行を停止
    • Applyボタンを押して記録した変更をオブジェクトに適用

  • Clipboardの場合
    • 選択したオブジェクトのインスペクター上でコンポーネントの名前を右クリック→コピー
    • コピーしたいオブジェクトのコンポーネントに右クリック→ペースト



Batcherはまだ使っていないので、またいずれ

書籍Unity入門を読みました

10/1に発売されたUnity入門 高機能ゲームエンジンによるマルチプラットフォーム開発(著 高橋啓治郎)
を読み終えました

サポートページ http://unity-yb.github.com/

Unityの説明から始まって、段階的に実製作を通して色々な機能の説明がされています。
制作したものをモバイル用に移植する時の説明が特徴だと思います。

私は一人でネット検索しながら色々試作していましたが、知らなかったことが多くて非常に勉強になります。
CGやモデリングのUnity上のワークフローよりかは、Unityエディタとスクリプトの説明が主でした。
今まで制作経験のない人も、ネット検索と英語チュートリアルしてきた人も、読んでみると再発見がありそうです。

2011年9月29日木曜日

セーブデータの作り方

Unityでプレイヤーの状態とか、どこにいるとか、いわゆるセーブデータを作る必要があるなぁと思って、どうしたらいいかなぁと考えてました

困ったときのUnity Answersにスレッドがありました
http://answers.unity3d.com/questions/8480/how-to-scrip-a-saveload-game-option.html#

何も考えずちょっと下にあるコードをコピペして、何とかなります
バイナリデータにシリアライズして、読み込み時にデシリアライズしているんでしょうか
詳しい挙動は把握していませんが、ちゃんと変数の状態が保存されていました

別のセーブデータ作成方法

PlayerPrefsってクラスがUnity側で用意されていて
これがセーブデータを作成してくれるようです
http://unity3d.com/support/documentation/ScriptReference/PlayerPrefs.html
WebPlayerだと1MBまでのファイルサイズ制限があるみたい?
これを利用する方が楽だと思います。

2011年9月23日金曜日

ヒエラルキーペインの整理方法

オブジェクトをどんどん作ってヒエラルキーペインに追加していくことになるのですが
同じカテゴリのオブジェクトがどんどん溜まっていくと、ヒエラルキーペインがいっぱいいっぱいで見づらくなってきました。

フォルダー的な役割できないかなーと思っていて、考えつきました

1.空のGameObject作る
2.Folder_***な適当な名前にする
3.そのGameObjectに実際のGameObjectを入れる

これで整理できて見やすくなりますね。

2011年9月21日水曜日

rigidbody.AddForceで動かしたい

rigidbody.AddForceで瞬間的に力入れて動かしたいと思って、あるメソッドから
GameObject obj = (GameObject)Instantiate(gems[type], pos + dir, gameObject.transform.rotation);
obj.rigidbody.AddForce(Vector3.one * 10.0f);

とかで呼んでいたのですが、どうにも動いてるように見えない。
第二引数にForceModeがあるんですね。これがForceMode.Forceになっているようです

ググッて参考にしたところ
http://code.google.com/p/vga-unity/wiki/GP10UnityCourse04

で、ForeceMode.Impulseを指定して呼び出してやると、動くようになりました

2011年9月14日水曜日

Destroyの問題

ゲーム中で何かアイテムを使用するメソッドがあります。
アイテムの効果を実行します。
効果音を再生するようGetComponent<Audiosource>().Play()を行います。
使ったので、そのままDestroy(gameObject)します。

効果音再生がされずにDestroyされました。


GameObjectがDestroyされると効果音再生が終了されるようです。
コンポーネントが消えるからでしょうか。

とりあえず自分で困ったとこを対処したのは
renderer.enabledとcollider.enabledをfalseにする。
Destroyフラグを立てる。

フラグと効果音の再生終了を見て、Destroyを実行する。
描画とコリジョンが無効になるので、これで自分としては困らないかなー

追記
AudioSource.PlayClipAtPoint(AudioClip, Vector3)を使用すれば
効果音再生終了と同時にDestroyしてくれるGameObjectが生成されました。
上記のまどろっこしいことしなくても、このメソッドで一発解決です

2011年9月11日日曜日

Dropboxのhtmlへ直リン

Dropboxを利用してみました。2GBまで無料で使えるオンラインストレージです。
ファイルへの直リンが可能ということで、WebPlayerビルドしたUnityゲームを公開する手段に使えるかなーと。
 下記ファイルでテスト

公開終了

うまくいきましたー

2011年9月2日金曜日

UnityC# + LINQ

C#3.0の機能LINQが使えました。
LINQはデータベース言語のようですね
詳しくはこの辺
http://ufcpp.net/study/csharp/sp3_linq.html

uinsg System.Linq;
でクエリ文が使えるようになって、あれこれデータ作り。

試作データはこんな感じに
{攻撃名, 攻撃データ}
攻撃名でアクセスしてデータを引っ張ってくる。
LINQ使う必要がないけど、使いたかった。

試作クラスは以下の通り。
public class PlayerAttackData : MonoBehaviour {
   
    enum AttackCode{ONE, TWO, THREE};
    class AttackData{
        public int Power{
            get;
            set;
        }
        public int Frame{
            get;
            set;
        }
       
        public AttackData(int power, int frame){
            Power = power;
            Frame = frame;
        }
    }
   
    class AttackInfo{
        public AttackCode Code{
            get;
            set;
        }
       
        public AttackData Data{
            get;
            set;
        }

        public AttackInfo(AttackCode code, AttackData data){
            Code = code;
            Data = data;
        }
    }
    AttackInfo[] attack_infos = new AttackInfo[2];

    // Use this for initialization
    void Start () {
        //Define Data
        attack_infos[0] = new AttackInfo(AttackCode.ONE, new AttackData(15, 10));
        attack_infos[1] = new AttackInfo(AttackCode.TWO, new AttackData(10, 5));
       
        AttackCode now_attack_code = PlayerAttackData.AttackCode.ONE;
        var attack_info =
            from p in attack_infos
                where p.Code == now_attack_code
                select p.Data;
        AttackData data = (AttackData)attack_info;
        Debug.Log(data.Frame);
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}

2011年7月31日日曜日

厳密なタイミング管理

音ゲーなどで、フレームやミリ秒できっちり譜面の出現を管理したいとき
Time.frameCountを使っていたら、微妙にずれてくることがありました。

取った解決策
System.Environment.TickCountをStart()で開始時間保持します
Update()でTickCount - start_tickCountで経過時間を計算。フレームに変更

譜面のタイミングと動画がマッチしたっぽい。

2011年6月5日日曜日

テキストファイル

TextAssetを使用する
スクリプト
public TextAsset text_file;
生の.txtデータをプロジェクトペインからドラッグアンドドロップ
text_file.textが全文字列になってる

.csvは読み込めないっぽい。自分で正規表現書いて対応する
string[] str = Regex.Split(text, ",|\r\n")

2011年5月16日月曜日

GUITexture 回転問題

GameObject(Components)のGUITextureは回転に対応していない
ゲーム中に敵アイコンの向きなど、回転させたい時どうしよう?

Scriptを書く

Texture2DとGUI.DrawTextureを利用。
OnGUI()内でGUI.DrawTextureを呼び出す。
第一引数で描画範囲をRect指定。第二引数にTexture2Dを渡す
描画成功!

このままだとGUITextureと同じ。
回転させるには

 GUIUtility.RotateAroundPivot

をGUI.DrawTextureの前に呼び出す
第一引数に回転角度、第二引数にRectでピボット(回転の中心位置)を指定

これでGUIで回転するテクスチャのできあがり

2011年4月13日水曜日

Transformの親子関係

スクリプトから、Transformコンポーネントの親子付をする際の注意

毎フレーム、transform.parent = null とか transform.parent = hoge;
とかすると、コントローラの入力受け付けて移動してくれなくなった。
nullの時、nullじゃないときみたいにif文かませて親子付すると、親の移動しつつ
コントローラの入力で移動してくれるようになった。

2011年4月5日火曜日

ビューポートの変更

CameraオブジェクトのNormalizedViewportRectangle設定を変えると
そのカメラから見た画面の描画位置をずらすことができる。
セカンドカメラを作成してX:0.7 Y:0.05 W:0.2 H:0.2などに設定(0.0~1.0)するだけで
完成。
http://unity3d.com/support/documentation/Components/class-Camera.html



2011年4月4日月曜日

UnityExtension Detonator

Detonator:爆発を簡易に作成できる拡張機能
UnityExtensionの一つ。メニューバーWindow->AssetStore->Extensionからダウンロード&インポート

コンポーネントからDetonatorを追加して
Detonator dc = GetComponent("Detonator") as Detonator;
dc.Explode();
でぶつかったときに爆発するようにできた。

2011年3月26日土曜日

シーン遷移

スクリプト中でシーンを変えたいところにApplication.LoadLevel("シーン名");
ってするだけ。
メニューバーのFile->Build Settings (ctrl+shift+B)を開いて
Scenes in list にシーン追加しておかないと、エラーでます。
プロジェクトからシーンをドラッグアンドドロップすればいい。

2011年3月24日木曜日

動画再生(UnityProのみ)

動画ファイルインポートして、ゲームオブジェクト(Planeとか)に追加する。

スクリプトで
MovieTexture mov = (MovieTexture)renderer.materials.mainTexture;
mov.Play();
のように一度テクスチャをキャストしてあげれば無事再生できる。
オーディオクリップが別になってるので、プロジェクトペインから忘れず追加する。

2011年3月23日水曜日

3Dサウンド<->2Dサウンド

プロジェクトペインの対象ファイルを選択して、3DSoundのチェックを外してApply押すだけ
AudioListenerが無いと音が聞こえない。

右ジョイスティック設定

360の右ジョイスティックの値は、ProjectSettings->Inputインスペクタの
Axes->Sizeを増やして、適当な名前(Horizontal2とかVertical2)つけてあげる。
階層の他の項目はHorizontalを参考にする
Horizontal2->Axisの値を4th axis とVertical2->Axis 5th axisに設定すると
スクリプトからInput.GetAxis("Horizontal2")で値が取得できる。

2011年3月22日火曜日

コライダに関するメモ2

ChaacterControllerとColliderの衝突判定だと

CharacterController付きゲームオブジェクトのOnControllerColliderHit側だけしか判定できない?
CharacterController付きゲームオブジェクトAとBoxCollider付きゲームオブジェクトBで
BにOnCollisionEnterを書いても反応せず。

リファレンスを読んでみると、CharacterControllerについては記述見当たらない。
http://unity3d.com/support/documentation/ScriptReference/Collider.OnCollisionEnter.html?from=Collision

OnControllerColliderHit(ControllerColliderHit hit)内で
Aと衝突するオブジェクトBをタグ付けて、分岐させたのち
hit.collider.gameObject.GetComponent<T>().Hoge();
でBの衝突メソッドを呼び出して解決してみた。

コリジョンの状態

CharacterController.Moveの返り値CollisionFlagsで
CollidedAbove
CollidedSides
CollidedBelow
CollidedNone

if(collisionFlags & CollisionFlags.CollidedAbove)
if(collisionFlags == CollisionFlags.CollidedAbove)
で上、下、横のどこで衝突しているか判定できる

2011年3月21日月曜日

インスペクタにメンバのクラスを表示する方法

クラスの属性に
[System.Serializable]
public class XXX{
}
とつけるとインスペクタにクラス内クラスのメンバが表示された。

引用元
http://d.hatena.ne.jp/nyakagawan/20100523/1274626612

スクリプトリファレンス

本家スクリプトリファレンス英語
http://unity3d.com/support/documentation/ScriptReference/index.html

崇城大学の和訳。途中まで
http://www.cis.sojo-u.ac.jp/~izumi/Unity_Documentation_jp/Documentation/ScriptReference/index.html

C#の例が見たい場合は本家を見る。
和訳はjsだけっぽい。

ボタンの押下状態

Input.GetButton系の状態メモ
GetButtonDownが一回押した
GetButtonUpが離した
GetButton が押しっぱなし

っぽい

コライダに関するメモ1

コライダ-衝突判定をやってもらうには、ゲームオブジェクトに
動くオブジェクトAにリジッドボディorキャラクターコントローラとコライダを追加
動かないオブジェクトBにコライダを追加
する。OnCollisionEnter、Stay,Exitのイベントが呼び出される。

挙動はPhysXで動いてくれる。
このガジェットでエラーが発生しました