altebute.hatenablog.com

犬も歩けば規格にあたる

Git 環境構築メモ on Windows

CUIGUIは分けて考える. 導入するツールは以下の通り.

ライセンスに気をつける. 特にGUIアプリケーション. GUIアプリケーションは好きなもの1つでよいだろう.


各アプリケーションの更新はRSSを購読して確認する.

GUIアプリケーションは更新通知機能がついてたり, ついていなかったりするかも知れない. 最近Sourcetreeが不自然な挙動見せるけど実利用で問題ないので見て見ぬふりをする.


基本的に公式に書いてある手順に従って導入する.

GitのインストーラはオプションでGit LFSも同時にインストールする事が出来るが, 必ずしも最新版とは限らないため使わない方が良い. git-lfs/README.mdに従ってインストールしよう.

git-flowはWindowsだとちょっと難しい感じがしないでもない.


シェルはGit Bashが基本だが, 余力があればfish shell等を導入しても良いかも知れない. ここらへんUnix, Linux環境向けの話ばかりで初心者はトラブルが起きた時自分で対応出来ない気がする.

シェルを思い通りにしようと思うと, コマンドプロンプト, Windows PowerShell, Git Bash, Cygwin, MSYS2等の各のシェルについてどのようにパスを通し, どのように環境変数が参照されるのかを把握する必要があるため, 学習コストが高い.

基本的に長いものにはまかれろの精神で, メジャーでカスタマイズする項目が少なくて済むツールを導入する. 多くの人が使用している環境の方が情報も豊富.


まずgit init --bare --sharedでベアリポジトリを作成. ディレクトリを作成する訳ではなく, カレントリディレクトリ自身をリポジトリに作成するので注意. ベアリポジトリの名前はxxx.gitとするのが通例.

次にgit clone <repository> [<directory>]でベアリポジトリをクローン, ノンベアリポジトリを作成する. クローン先のディレクトリが空でなかった場合, クローンに失敗する. 指定しなかった場合, リポジトリ名と同じ名前のディレクトリを作成し, そこにクローンする. 作成しようとしたディレクトリ名のディレクトリが既に存在した場合, クローンに失敗する.

Git LFSの設定はワークツリー内で行う. 例えばgit lfs track "*.png"等とすればpngファイルのコミット時にGit LFSが使用される. 設定は.gitattributesファイルに保存される. 恐らく, Gitの操作をする際にこのファイルを読み, それに従ってコミットを行う, という仕組みなのだろう. 当然Git LFSの設定は共有すべきなので.gitattributesファイルはコミットしておく.

最後にgit-flowの初期化処理を行う. git flow initで初期化したらそれで終わりである. 対話形式で初期設定を行うが, 基本的にデフォルトの設定で構わない. 尚, この行程はGUIアプリケーションでもたぶん問題ない.


その他, SSHの設定等が必要かもしれないが, サーバーをきちんと用意したりしないのであればたぶんデフォルトで問題ない.

尚, Git LFSは自身が管理するファイルについて, 複数のユーザによる同時アップロードが発生した際の競合を防ぐためのファイルロックの仕組みを備えるが, 殆どサーバは実装していないため, 以下のような警告が発生するかも知れない. その場合警告に従ってこの設定を無効化する必要があるかも知れない. 詳細はこちら

Remote "origin" does not support the LFS locking API. Consider disabling it with
:
  $ git config lfs.C:/Users/agate_pris/test.git/info/lfs.locksverify false

以上.

Unity プロジェクト作成

手順

  1. Dropbox 上にディレクトproject-name を作成.
  2. そのディレクトリに移動.
  3. 以下のコマンドを実行.
    git init --bare --shared=true project-name.git
  4. 同期の完了を待つ.
  5. 作業用ディレクトリにプル. ディレクトリ名は project-name/dev.git にした.
  6. dev.git に移動 Unity のプロジェクト project-name.unity を作成.
  7. Assets/ProjectName/Games/Game.cs を作成, Visual Studio で開ける事を確認, シーン Game に空のオブジェクト Game を作成し, コンポーネント Game を追加. 実行確認.
  8. .gitignore を作成. 内容は後述.
  9. コミット, プッシュ.

.gitignore

/project-name.unity/[Aa]ssets/AssetStoreTools*
/project-name.unity/[Bb]uild/
/project-name.unity/[Bb]uilds/
/project-name.unity/[Ll]ibrary/
/project-name.unity/[Oo]bj/
/project-name.unity/[Tt]emp/

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

# Unity3D generated meta files
*.pidb.meta

# Unity3D Generated File On Crash Reports
sysinfo.txt

# Builds
*.apk
*.unitypackage

ディレクトリ構成

リモート

  • project-name
    • project-name.git

ローカル

  • project-name
    • dev.git
      • .gitignore
      • project-name.unity

dev.git については, ブランチを切る時はまた別のディレクトリを作成してそこで作業をする.

参考文献

Unityを三日坊主して分かった事

最初から目標を大きくするな

それ一番言われてるから.

使用する機能を最初から隅から隅まで理解しようとするな

機能が必要になったら調べればいい. そもそも全体を把握しないと何のためにあるのか分からない事もある.

郷に入らば郷に従え

エンジンの設計に逆らうのはエンジンをある程度理解してからでも遅くない.

案ずるより生むが易し

簡単な小さい目標を立てて, 何でもいいからまず動かす.

とりあえず

週末なんかしたいな.

Unity 5 日記 6 ショットを発射

もう適当にさっさと書かないと飽きるので雑に書いていく. さっさとショット発射してみたい. 敵にあたるとかそんなんどうでもいい.

Unity 5 日記 2 スクリプトの作成Unity 5 日記 3 deltaTime の適用 で作成したオブジェクトにショットの発射機能を持たせる.

作成してあった移動処理をメソッド Move に分離し, メソッド Update を以下のように書き換える.

private void Update()
{
    Move();
}

変数 float shootFreezeSystem.Collections.Generic.List<GameObject> shots を追加する.

private QuantizedTime shootFreeze;
private System.Collections.Generic.List<GameObject> shots;

ついでにメソッド Start に各々の初期化処理を追加しておく.

void Start()
{
    ...
    shootFreeze = 0;
    shots = new System.Collections.Generic.List<GameObject>();
}

はっきり言ってこの書き方は良くない. クソコードである. 関心の分離もへったくれもない. 本当なら別途ショットを管理するためのクラスを用意すべきだが, ここではとりあえず後回しにする.

Unity 5 日記 5 Prefab で書いたような感じで Prefab を作成し, Resouces フォルダに Shot という名前で適当にいれる.

そしてショットにスクリプトを追加する.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShotBehaviorScript : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        var x = transform.position.x;
        var y = transform.position.y;
        var z = transform.position.z;
        z += Time.deltaTime * 100;
        transform.position = new Vector3(x, y, z);
    }

    public bool IsOut()
    {
        return 32 < transform.position.z;
    }
}

メソッド Update で移動を行う. IsOut は消去判定を行うためのメソッドだ. Unity では画面外に出たことを判定するための関数があるが, ショットは画面外に出た時に消えてしまうのは困るので自分で色々判定する. ここでは本当に適当な値の比較にした.

そして自機側のスクリプトにメソッド Shoot を追加する. この名前もかなり悪い.

private void Shoot()
{
    if (0 < shootFreeze.Value)
    {
        var deltaTime = Time.deltaTime;
        shootFreeze -= deltaTime.Value;
        return;
    }

    var fire = UnityEngine.Input.GetButton("Fire1");
    if (fire)
    {
        GameObject shotPrefab = (GameObject)Resources.Load("Shot");
        var shot = Instantiate(shotPrefab, new Vector3(0,(float)_position.Y, (float)_position.X), Quaternion.identity);
        shots.Add(shot);
        shootFreeze.Value = 128;
    }
}

手元のスクリプトとブログに書いてあるスクリプトが一致していないので座標周りがおかしかったり変数名があっていなかったりするが心の目で読んで欲しい. Resouces ディレクトリに入れた Prefab は上記のような感じでインスタンス化することが出来る. 生成したショットは shots に追加する.

最後に画面外に出たショットを削除するためのメソッド RemoveShots を追加する.

void RemoveShots()
{
    for (int i = 0; i < shots.Count;)
    {
        var shot = shots[i];
        var script = shot.GetComponent<ShotBehaviorScript>();
        if (script.IsOut())
        {
            Destroy(shot);
            shots.Remove(shot);
            continue;
        }
        ++i;
    }
}

GetComponent でアタッチしたコンポーネントを取得し, メソッド IsOut で判定を行い, Destroy 関数で GameObject を削除する.

ShotBehaviorScript の中で Destroy(this) するとオブジェクト全体ではなくコンポーネント単体を削除してしまうらしい.

なんかもう記事書くのも面倒になってきた. この雑さ極まるコードを GitHub に丸上げして, コミットログにリンク張って日記にする程度でいいんじゃなかろうか.

Unity 5 日記 5 Prefab

Hierarchy 内に生成したオブジェクトを Project にドラッグ & ドロップするとなんか青くなる. 以後は Project 側からドラッグ & ドロップすると簡単にオブジェクトを複製出来る. Inspector からオブジェクトのパラメータを変更すると一括で変更出来る. オブジェクトのどの要素が個別に扱われ, どの要素が一括で変更されるのかはよく分からない. ぐぐって.

参考文献

Unity 5 日記 4 InputManager の調整 キーボードの入力で慣性がつく問題の修正

デフォルトの設定だと UnityEngine.Input.GetAxis("Horizontal")UnityEngine.Input.GetAxis("Vertical") で入力をいい感じに受け取れるが, ジョイパッドで操作する分には問題ないものの, キーボードで操作する場合に妙な慣性がついてしまう. 今回は入力系の設定変更でこのあたりの調整を行う.

Edit->Project Settings->Input から Unity の通常の入力系の設定を行うことが出来る. InspectorHorizontal とかかれた項目が 2 つあると思うので, それを開く. 片方はキーボードの, 片方はジョイパッドの設定だ. Gravity はボタンを離した時の加速度, Sensityvity はボタンを押した時の減速度である.

大体 64 程度にしておけば FPS 60 の環境で 1 フレームで最大値になる. 高フレームレートでも同様になってくれる事を期待するのであれば 255 等にしておけば良いだろう.

欲を言えば 0 にした場合は必ず 1 フレームで最大値になる等の設定が欲しかった所だが残念ながらそういった機能はない. それどころか負数の指定すら出来てしまい, 入力方向に対して明後日の方向に加速していってしまう. それでよかったのか, Unity......

Unity 5 日記 3 deltaTime の適用

なんだか 前回 まで大真面目に記事を書いてたせいで新しく記事を書くのが億劫になってきてしまっていたので, 今回からもっと雑に書いていくことにする.

UnityEngine.MonoBehaviour を継承したクラスのメンバ関数 Update は毎フレーム呼ばれるが, 毎フレーム呼ばれるということはフレームレートの高い環境ではそのままではゲームの動作まで早くなってしまう. そこで, Time.deltaTime を乗算する事でこの問題を解決する.

void Update()
{
    var x_axis = Input.GetAxis("Horizontal");
    var y_axis = Input.GetAxis("Vertical");
    var vx     = x_axis * 60 * Time.deltaTime;
    var vy     = y_axis * 60 * Time.deltaTime;
    var v      = new Vector3(vx, vy, 0);
    this.transform.position += v;
}

Time.deltaTime には前回のフレームから今回のフレームまでに経過した時間が秒単位で保持されている. 型は float である.

FPS が 60 の環境である事を前提にフレームカウンタを回して任意の動作を実行するようなアルゴリズムを実行した場合は, Time.time の差分を取るか, Time.deltaTime を毎フレーム加算して, 大小の比較演算によって実行する必用がああるだろう. 浮動小数点であるから, 同値比較を行うと危険である事に注意.