2014年1月30日木曜日

【Unity、C#】スクリプトでTerrainにStaticGoogleMapを貼り付ける

@baiteen

リアルでは出歩かないので、ゲームをリアルに近づけることにした。

ということで
TerrainにGoogleMap貼り付けて人形歩かせよって思った。


やり方

1.テレインを作成
2.下記のコードをスクリプトにコピペ
3.スクリプトを適当なゲームオブジェクトに追加
4.実行

using UnityEngine;
using System.Collections;
using System;

public class TerrainScript : MonoBehaviour {
    string Url = @"http://maps.googleapis.com/maps/api/staticmap?size=512x512&maptype=satellite&visible=41.832423,140.823471|41.828586,140.821347&sensor=false";
    
    // Use this for initialization
    void Start () {
        StartCoroutine(Download(this.Url, tex => addSplatPrototype(tex)));
    }
 
    // Update is called once per frame
    void Update () {
    }

    /// 
    /// GoogleMapsAPIから地図画像をダウンロードする
    /// 
    /// ダウンロード元
    /// ダウンロード後に実行されるコールバック関数
    IEnumerator Download(string url, Action callback)
    {
        var www = new WWW(url);
        yield return www; // Wait for download to complete
        
        callback(www.texture);
    }

    /// 
    /// テレインにテクスチャを貼り付ける
    /// 
    /// 
    public void addSplatPrototype(Texture2D tex)
    {
        var splatPrototypes = Terrain.activeTerrain.terrainData.splatPrototypes;
        int index = 0;

        SplatPrototype[] newSplatPrototypes = new SplatPrototype[index + 1];
        for (int i = 0; i <= index; i++)
        {
            newSplatPrototypes[i] = new SplatPrototype();
            if (i == index)
            {
                newSplatPrototypes[i].texture = tex;
                newSplatPrototypes[i].tileSize = new Vector2(512, 512);
            }
            else
            {
                newSplatPrototypes[i].texture = splatPrototypes[i].texture;
                newSplatPrototypes[i].tileSize = splatPrototypes[i].tileSize;
            }
        }
        splatPrototypes = newSplatPrototypes;
        Terrain.activeTerrain.terrainData.splatPrototypes = splatPrototypes;
    }
}
GoogleMapからダウンロードする画像サイズとテレインのタイルサイズを合わせないと画像がきれいにでなかったような。
あとテレイン自体のサイズも合わせた方がいんだけど、スクリプトからの指定方法がわかんなかったからやってない。

書いてみたら割と簡単だったけど、テレインをスクリプトから弄るサンプルがあんまりなくて大変だったな。外人さんは多言語対応しようと思わないのかな。

ところでTerrainの読み方ってテレインであってるのかな?

2014年1月26日日曜日

【Unity、C#】オブジェクト間のやりとりにC#のイベント機能って使っていいのかな?

気になった

下記つぶやきが興味深くて考えてみた。
上記ブログではデリゲートを使ってインスタンス生成側からOnMouseDownイベントを拾ってます。
(DelegateFuncって最初から定義されてるのかな…?)

十分実用的なんですが
これをC#イベントで書いたらどうなのかなーって思った。

Unity系のブログとかみててもC#のイベント機能使ってるところが全然ないんですよね。
非推奨とかあるのかな?

MonoBehaviourの流儀がいまだによくわからん。

書いてみた

上記 @narudesign さんのやってる内容をC#イベントで置き換えてみた。
(実行環境がなくて試してないので動くか分かりませんけど。)

Cube.cs
using System;
using UnityEngine;

class Cube : MonoBehaviour
{

    /// <summary>
    /// クリックイベント
    /// </summary>
    public event EventHandler Click;

    /// <summary>
    /// クリックイベントを発生させます。
    /// </summary>
    private void OnClick()
    {
        if (this.Click != null)
        {
            this.Click(this, EventArgs.Empty);
        }
    }

    /// <summary>
    /// 名前
    /// </summary>
    public string Name { get; set; }


    /// <summary>
    /// クリックされた
    /// </summary>
    void OnMouseDown()
    {
        print("Cube - OnMouseDown() : " + this.Name);
        //イベントをRaise
        this.OnClick();
    }
}

MainClass.cs
using System;
using UnityEngine;

public class MainClass : MonoBehaviour
{
    public GameObject prefab;

    void Start()
    {
        //Create Cube1
        GameObject obj1 = Instantiate(this.prefab, new Vector3(-1, 0, 0), Quaternion.identity) as GameObject;
        Cube cube1 = obj1.GetComponent<Cube>();
        cube1.Name = "1st Cube";
        cube1.Click += cube_Click;

        //Create Cube2
        GameObject obj2 = Instantiate(this.prefab, new Vector3(-1, 0, 0), Quaternion.identity) as GameObject;
        Cube cube2 = obj1.GetComponent<Cube>();
        cube2.Name = "2nd Cube";
        cube2.Click += cube_Click;
    }

    void cube_Click(object sender, EventArgs e)
    {
        Cube cube = sender as Cube;
        print("MainClass - cube_Click() : " + cube.Name);
    }

}

どーなんだろうなぁ。
イベントはデリゲートの使い方の一種だからデリゲート使っていいなら問題ないと思うけど…。
パフォーマンス悪くなったりするのかな。

2014年1月25日土曜日

【うに部屋】UnityWebPlayer向けアプリを公開できるサイトを作りました。

宣伝記事です。

本日下記サイトを公開しました。

【うに部屋】UnityRoom http://unityroom.com/

UnityWebPlayer向けにビルドしたアプリを
簡単にアップロードすることができるサイトです。

とにかく「気軽に」「簡単に」

とにかく「気軽に」「簡単に」
Unityを使ったゲームを一般公開できるようなサイトを目指していきます。

開発者フレンドリーなサイトを目指して

開発者さん目線で欲しい機能などがあれば
積極的に取り入れていきたいと考えています。

開発者さんにいくらかのメリットを感じて頂けるサイトを目指します。

お詫び

作者の知識不足もあり素人感満載です。

これから勉強も兼ねて少しずつ更新していくので
暖かく見守っていただければと思います。

2014年1月22日水曜日

【連載Git入門 第7回】SourceTreeでGitを始めよう!Unityを管理する際の注意事項

初心者の方向けにGitの使い方をまとめています。
連載目次:【連載Git目次】ほんとは簡単?SourceTreeでGitを始めよう!
前回:【連載Git 第6回】UnityのプロジェクトをGitで管理しよう

連載ラストです!
前回まででGitの使い方を解説してきました。
今回は運用する上での注意点なんかを書いてみます。

と言ってもまだほとんど使ってないので
懸念事項一覧みたいな感じですね。
ちゃんと対応できたものから追記していきたいと思います。


UnityプロジェクトをGitで管理する際の注意事項


主にチーム開発時の懸念事項とかです。

バイナリファイルはマージできない

Unityの場合、Sceneファイルなどはバイナリファイルです。
バイナリファイルは競合が起こっても差分を確認したり合わせたりすることができません。
(どちらか一方を選択するだけ)
なのでもし2人同時に同じSceneを変更したりすると、
確実に片方の変更は消えることになります。

→2014/01/23 追記
 コメントいただきました。匿名さんありがとうございます。
 Unity3.5からはSceneをテキストファイルとして扱えるようです!
 http://docs.unity3d.com/Documentation/Manual/TextualSceneFormat.html
 設定方法確認しておきます。

 うーんPro専用かな?
 英語版にはPro専用の表記ないし試してみないと分からないな。
 http://docs-jp.unity3d.com/Documentation/Manual/TextualSceneFormat.html
 →BitBucket見てみたらテキスト形式(YAML)で保存されてた!
   UnityFreeでもEditorSettingでAssetSerializationをForceTextにするだけで使えるっぽいです。

対策

同じシーンを同時に編集しないような運用が必要になりそうです。
・各メンバーごとにテスト用シーンを用意し、デバッグはそこで行う。
・主要なシーンにマージする作業は担当者を固定する。
など。
やったことないので予想です。

チーム開発時のブランチの切り方

複数人でソースを共有する場合、
各自が自由にブランチを切り、自由にプッシュしていくと
良くわからないブランチで溢れてしまいそうです。

対策

ブランチを切るルール、プッシュするルールを決めた方がよさそうですね。
簡単に思いつくのは
・各自の名前をつけたブランチを用意する。
・自分の名前のブランチしかプッシュしない。
・フェッチは全員のブランチを取得
とか?
これも予想。実際にやってみないと分からない。

GitFlowなどを使うのも良さそうです。
いまさら聞けない、成功するブランチモデルとgit-flowの基礎知識

とりかくチーム内で認識を揃えること。

Script名の重複

現在のUnityC#では名前空間(namespace)をサポートしていません。
参照:http://ws.cis.sojo-u.ac.jp/~izumi/Unity_Documentation_jp/Documentation/ScriptReference/index.Writing_Scripts_in_Csharp.html

そのため各々が作ったスクリプトのファイル名がかぶった場合、
配置フォルダが違っていてもビルドエラーとなってしまいます。

対策

namespaceが使えない以上はフォルダ分けしても無意味なので
ファイル名をユニークにする必要がありそうです。
・スクリプト作成者の名前をファイル名の頭に付ける
などで対応しましょう。

文字コード

WindowsとMacでコードを共有する場合、文字コードとか気をつけた方がいいかもです。
今度Gitを使ってWindowsとMacでソース共有を始めるつもりなので
確認とれたらちゃんとまとめます。

とりあえず軽く調べて出てきたリンクを置いておきます。
Unityであった.csファイルの文字コード絡みのエラー : これを読めば思い出す
スクリプトファイルのutf-8変換 : DEBUG.LOG

改行コード

文字コードと同じように改行コードもWindowsとMacで違います。
マージするとき大量の差分が出てしまいそうな気がしないでもないですね。
これもまた調べます。

ライセンス

アセットによってはチームで使うとダメなのもあるのかなーって思ったり。
アセットごとに要確認ですね。

その他

思いつくものを書き連ねましたが
実際に使うとまだまだ出てきそうですね。

気づいたものがあれば都度追記していきます。

あとがき

Gitの基礎から全7回に渡って説明してきましたがいかがでしたでしょうか?
SourceTreeという素晴らしいツールのおかげでgitコマンドを
一つも覚えることなく説明を終えることができました。

今回の連載はなるべく画像つきで
そのまま手を動かせば使えるように意識して書きました。

少しでもGit初心者さんの足がかりになれば幸いです。

ここまで読んでいただきありがとうございました。

2014年1月21日火曜日

【連載Git入門 第6回】SourceTreeでGitを始めよう!UnityのプロジェクトをGitで管理しよう

Git初心者の方を対象とした入門記事を連載しています。
連載目次:【連載Git目次】ほんとは簡単?SourceTreeでGitを始めよう!
前回:【連載Git 第5回】リモートリポジトリを使ってみよう

今回はUnityのプロジェクトをGitで管理する方法について書いていきます。
リモートリポジトリを使えばバックアップとしても使えるのでオススメですよ。

作業環境

  • Unity free 4.3.2f1
  • Mac OS X 10.8.5
  • SourceTree 1.8.0.3
  • BitBucket (不明)

Unityプロジェクト作成からプッシュまで

Unityですでに存在するプロジェクトをリモートリポジトリにプッシュするところまでをやってみましょう。
チームで開発する場合も1人目はこの作業となります。

プロジェクトの用意

今回はサンプル用に新規プロジェクトを作成します。
UnityでNewProjectから作成。
適当にCubeやLightを置いときましょう。
ではこのプロジェクトを使って進めます。

Unityのプロジェクト設定

UnityのプロジェクトをGitで管理するために少々設定が必要です。

メニュー->Edit->Project Settings->Editor

Version ControlのModeをVisible Meta Filesに変更。
Asset SerializationのModeをForce Textに変更。
以上でUnity側の設定は完了です。
Sceneを保存して一旦Unityを終了しておきます。

ローカルリポジトリの作成

SourceTreeを立ち上げ、ローカルリポジトリを作成します。
管理したいUnityのプロジェクトフォルダを指定しましょう。

リポジトリを開くとこんな感じ。
すでに大量のファイルが保留状態になっていますね。
この中には管理不要なファイルが多く含まれているのでコミットはまだ待ってください。

除外リスト(gitignore)の設定

前述した不要なファイルをGitで管理しないよう設定します。

SourceTreeのリポジトリを開いた画面から
設定->高度な設定->リポジトリ限定無視リストの編集
すると何かしらのテキストエディタが立ち上がると思います。
下記内容をまるっとコピペして保存しましょう。
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/

# Autogenerated VS/MD solution and project files
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj

# Unity3D generated meta files
*.pidb.meta

# Unity3D Generated File On Crash Reports
sysinfo.txt
参照:github/gitignore/Unity.gitignore
保存して閉じましょう。

SourceTreeに戻ると、保留状態のファイルが激減しているはずです。
先ほどのProjectの場合は3つだけになりました。

このように「.gitignore」というファイルを作成することで
Gitで管理したくないファイルを除外することができます。
今回除外したのはUnityやMonoの管理ファイルなどです。
これらはチーム開発時などに邪魔になるため除外してしまいます。

では一度コミットしておきましょう。

リモートリポジトリの作成

前回の記事同様に、リモートリポジトリを作成&選択します。
作成時は誤って「公開する」を選択しないよう気をつけてください。

プッシュ

ではプッシュしてみましょう。
これでプロジェクトをリモートリポジトリへプッシュ完了です。


Unityプロジェクトをクローンして開くまで

今度は逆にリモートリポジトリからデータを取得してUnityで開くまでをやってみます。
他人の作成したプロジェクトにチームとして加わるときや、
MacでプッシュしたプロジェクトをWindowsで開く場合などに行います。

リモートリポジトリからクローン

先ほど作成したリモートリポジトリからクローンします。
自動的にmasterブランチがチェックアウトされます。
中身を見てみるとこんな感じ。
最初に作成したSceneだけが入っていますね。

Unityで開く

Unityを起動し、
File->OpenProject->Open Other->クローンしたフォルダを指定
これだけで問題なく開けてしまいます。

この時点でUnityがいくつかのフォルダを自動生成します。
※全てgitignoreで除外されているのでSourceTreeには表示されません。

Unityのプロジェクト設定

クローンから開いた場合も、Unityのプロジェクト設定は必要です。
プッシュしたときと同じように設定しておきましょう。

メニュー->Edit->Project Settings->Editor
Version ControlのModeをVisible Meta Filesに変更。
Asset SerializationのModeをForce Textに変更。

以上です。あっという間ですね。

まとめ

これでUnityのソースファイルもGitで管理できるようになりました。
リモートリポジトリにも入るのでバックアップとしても活用できますね。

gitignoreはネットで見つけたものをベースに数カ所修正しました。
今のところ問題なく使えてますが、
扱うファイルによっては不備があるかもしれませんので
その場合は各自修正してご利用ください。

これでバージョン管理も万全です。安心して開発できますね。


次回でラスト!
次はチーム開発時の注意点などを書いてみたいと思います。
経験ないので調べながらですがw


2014年1月20日月曜日

【連載Git入門 第5回】SourceTreeでGitを始めよう!リモートリポジトリを使ってみよう

Git初心者の方を対象とした入門記事を連載しています。
連載目次:【連載Git目次】ほんとは簡単?SourceTreeでGitを始めよう!
前回:【連載Git 第4回】マージの競合

前回までの内容は各自のPCの中で完結していました。
今回はインターネット上にリポジトリを作成し、利用する方法を説明します。

※先に断っておきますがこの記事長いです…やりながらだと1時間かかるかも?

リモートリポジトリを使ってみよう

リモートリポジトリとは?

リモートリポジトリの説明に入る前に、ローカルリポジトリをおさらいしましょう。
第2回の記事で作成したリポジトリはローカルリポジトリと呼ばれます。
図にするとこんなイメージですね。
このように自分のPC内にあるリポジトリのことを「ローカル」リポジトリと呼びます。

これに対して「リモート」リポジトリは、インターネット上に作成するリポジトリのことです。
ローカルリポジトリの内容をリモートリポジトリに保存したり、
逆にリモートからローカルに取り込んだりすることができます。

では、実際にやってみましょう。

BitBucketのアカウント登録

リモートリポジトリを作れるサービスはいくつかあります。
自分が知ってるのはGitHubやBitBucket、CodeBreakなど。
たぶん他にもあります。

その中でも今回は、SourceTreeと同じ会社が運用している
BitBucketというサービスを使ってみます。
(もちろん無料です。チーム6名以上は有料ですが)
以前登録方法をまとめたことがあったのでこちらの記事もどうぞ。
Bitbucketのアカウントを作成する。

リモートリポジトリの作成

※Macならリモートリポジトリの作成は全てSourceTreeから行えます。
※Windowsの場合は一部BitBucketでの操作が必要です。(2014/01/20時点)

すでにローカルリポジトリがある前提で説明します。
前回の記事のリポジトリ(testRepository)が残っている場合はそれを開いておきましょう。

前回まで使っていたtestRepositoryを開きます。
設定->リモート->追加
地球マークをクリック
(Windowsにはこのボタン無いです。後ほど説明する方法を使ってください。)

※初回のみ BitBucketアカウント追加を行います。
追加ボタンからBitBucketアカウント情報を登録

ここで入力するユーザー名はBitBucketのWebサイトから確認できます。
正しくBitBucketアカウントが表示されればOKです。

新規リポジトリの作成からリポジトリ情報を入力します。

このとき”公開する”のチェックを必ず外してください。
※外さないとインターネット上の誰でもソースが見れる状態になります。
この画面の作成ボタンを押した時点で、BitBucket上にリモートリポジトリが作成されています。(BitBucketのWebから確認できます。)

作成されたリポジトリを選択
SourceTree上で表示する名前を入力してOK
リモートリポジトリ情報が追加されているのを確認してOK

これでSourceTree上にリモートリポジトリが表示されました。

Windowsの場合

WindowsはSourceTreeから直接BitBucket上のリモートリポジトリを作成できません。
BitBucketのWebサイトでリポジトリを作成してから、
地球マークのボタンを押すステップでURLを入力します。

BitBucketでリポジトリ詳細画面に入り、ブラウザのURLに".git"をつけるだけでいける…はず?(ちょっと未確認です)
上記の場合「https://bitbucket.org/naichilab/testrepository.git」ですね。

プッシュしてみよう

ローカルリポジトリのコミット内容をリモートリポジトリに書き込むことを
「プッシュ」と言います。

やってみましょう。

プッシュ->書き込むブランチを指定->OK

グレーの矢印()を持ったタグが追加されました。
この矢印()はリモートリポジトリ上のブランチの最新版を表します。
今はプッシュした直後なので、全てのブランチの最新版がローカルとリモートで一致しています。

では試しにmasterブランチをチェックアウトし、何か変更を加えてコミットしてみましょう。
ローカルmasterとリモートmasterがズレましたね。
さらに「1 ahead」と表示されています。
これはプッシュできるコミットが1つあるよ。って意味です。
この進んだ分はまだリモートリポジトリに書き込まれていません。
バックアップとしてリモートリポジトリを使うのであれば、
こまめにプッシュするようにしましょう。

では再度プッシュしてから次へ進みます。

クローンしてみよう

リモートリポジトリからからデータを引き取り、そのままローカルリポジトリを作成する
ことを「クローン」といいます。
さきほどプッシュしたデータを取り込みながら新しいローカルリポジトリを作ってみましょう。

リポジトリ一覧から
リポジトリ追加->クローン->地球マークからリモートリポジトリを選択->保存先を指定->クローン

追加されたリポジトリを開くとこんな感じになってるでしょうか?
・ローカルブランチはmasterのみ、リモートブランチはmaster,sub,HEADの3種であることに注意してください。
・リモートHEADブランチはクローン時に勝手にできるので無視していいです。
・HEADを除くリモートブランチがさきほどプッシュしたものと一致していることを確認しましょう。

デフォルトでmasterブランチがローカル側にも存在し、リモートの最新と一致しています。masterブランチを使って作業を進める場合はこのまま続けましょう。
ですがもしsubブランチで作業を継続したい場合はどうでしょうか?
ローカルsubブランチが存在しないですよね。
これを作成する必要があります。

作ってみます。

リモートsubブランチをダブルクリック
自動的にブランチを切る画面になるのでブランチ名を決めてOKを押す
これだけでローカルブランチができました。あとは今まで通り作業できます。


※ここから先(プルとフェッチまで)の内容は下記に該当する場合に使う機能です。
 ・チームで開発したい
 ・個人だが2台以上のPCで作業する
 該当しない方は無理に覚える必要ありませんので飛ばしてください。

次の項目に移る前に、下記手順に従ってクローンしたリポジトリからプッシュしてください。

手順は
・testRepository2(クローンした新しいリポジトリ)で
・作業フォルダのファイルを変更(チェックアウトブランチは何でもいいです)
・ローカルリポジトリに追加&コミット
・リモートリポジトリに全てのブランチをプッシュ

subブランチでコミット&プッシュしたところこんな感じになりました。

では次の項目に移ります。

プルとフェッチ

リモートからローカルへデータを取ってくる方法はクローンだけではありません。
クローンの他にプルとフェッチという方法があるのですが…

はい、今すぐプルは忘れましょう
同じことはフェッチ&マージでできるのでフェッチだけ説明します。

先ほど下記手順を踏みました。
  1. testRepositoryからプッシュ
  2. クローンしてtestRepository2を作成
  3. testRepository2からプッシュ
図にするとこんな感じ。
testRepositoryが知っているのは①時点のリモートリポジトリ(のコピー)です。
でも本物のリモートリポジトリはすでに③になっていますね。
最新のリモートリポジトリを取得し、コピーを差し替えるのがフェッチです。
フェッチで変更されるのはあくまでも”リモートリポジトリのコピー”のみです。
ローカルリポジトリやローカルブランチには影響しないので安心してください。

ではやってみましょう。

testRepositoryを開いてください。

※もしポップアップが出て「プルできます。」と言われ
 下記アイコンが表示されても絶対に押さないでくださいね。
フェッチとマージで解決できますから。

フェッチ->OK
これだけでリモートリポジトリのコピーが更新され、③と同期されました。
今度はローカルsubとリモートsubがズレましたね。
ローカルsubの横に「1 behind」と表示されています。
これはリモートブランチに比べてローカルブランチの方が1つ遅れてるよ。
ということです。
他人(他リポジトリ)が更新したデータをフェッチしたよってことですね。

解決するには
・ローカルブランチをチェックアウト
・リモートブランチをマージ
これだけです。

マージ後はこんな感じ。
ローカルsubとリモートsubが一致しましたね。
他人がプッシュした内容をローカルリポジトリに取り込めたということです。

もしここでマージの競合が起きちゃったら…
面倒ですがプッシュした人と話し合いましょう!

まとめ

今回はリモートリポジトリを使ってみました。

リモートリポジトリを使う目的ごとに
最低限覚えなきゃいけない機能を整理しましょう

個人でバックアップ用途で使う場合

  • コミット
  • チェックアウト
  • (ブランチ、マージ)使えると便利
  • プッシュ
  • クローン

複数PC、もしくはチームで使う場合

  • コミット
  • チェックアウト
  • ブランチ
  • マージ
  • プッシュ
  • クローン
  • フェッチ

こんな感じですかね。
チームの場合は競合が起きないような運用も必要です。


さて、ここまで5回に渡ってGitの機能を説明してきました。
これで大体の機能は説明できたかなと思います。

ここまで理解されればもうほとんど不自由なく使っていただけるかと思います。
是非紹介した BitBucket + SourceTree で快適なGit生活を送ってください。

次回以降は運用編です。
UnityプロジェクトをGitで管理する方法や、
チームで利用する際の注意点なんかを考えてみます。

ここまで読んでいただきありがとうございました。

Related Posts Plugin for WordPress, Blogger...