初学者のためのC#

C#とは

 C#はC++からJavaになる際に追加されたガーベージコレクション(GC)や中間言語を介して共通の実行環境で実行することなどを参考にMicrosoftが開発した言語です。C#はIL(中間言語)にコンパイル後.Net Framework上で実行されます。この.Net Framewokというのは標準でWindowsにインストールされており、そのためC#とその統合開発環境のVisual Studioを使うことで簡単にWindowsアプリケーションが開発・公開ができます。また、OUCCで主に使用しているUnityというゲーム作成に使われるフレームワークで使用する言語にも採用されています。

基本的な書き方

using System; // ファイル内でほかの名前空間のものを完全修飾型名を使わずに使用できるようにする

namespace Hoge // 名前空間はこうやって宣言する。
{
    public class Program // 処理は必ずクラスの中に関数を置いて書く
    { // 波カッコで範囲を示す

        public int HogeHoge { get { return _hogeHoge; } set { _hogeHoge = value; } } // プロパティの宣言方法
        private int _hogeHoge; // フィールドの宣言方法

        public static void Main()
        {
            Console.WriteLine("Hello World"); // 1文の最後は ; (セミコロン)で終わる
            var odds = Enumerable.Range(0, 100)
                .Where(i => i % 3 == 0)
                .ToArray(); // こんな感じで複数行にわたって書くことも可能。
            /*
            複数行コメントはこうやる
            */
        }
    }
}

StructとClass

 大きく分けてStructとClassの2種類があり、したのようにいろいろ違いはあります。StructはClassよりも動作が早いのですが参照型でないためにおこる様々な問題があるためオブジェクトを自分で定義する際は何か重要な問題がない限りClassで作ることをお勧めします。

structとclassの違い

struct class
オブジェクトの型 値型 参照型
データが保存されるメモリ スタック ヒープ
継承 interfaceの実装のみ class,interfaceともに可能
コンストラクタの定義 引数ありのものだけ可能 なんでも可能
nullableか nullを入れられない nullを入れられる

structの問題点

  • スタックに保存されるのでメモリを多く占有する大きなオブジェクトを入れると逆に遅くなる。
  • 参照型でないので関数やプロパティでとってきたものを変更してももとのオブジェクトを変更できない。(classでは可能)
  • 継承ができない
  • 引数なしのコンストラクタを作れない
  • nullを入れられない

他の問題を見たい方はC#に潜むstructの罠などを参考にしてみてください。

よく使う型

この中ではstringのみがclassでそのほかはstructです。

エイリアス 実装 リテラル 説明
byte System.Byte 0(収まる範囲内のみ) 符号なし整数(8bit) 主にバイナリデータのために使われます
short System.Int16 0(収まる範囲内のみ) 整数(16bit)
int System.Int32 0(収まる範囲内のみ) 整数(32bit)
long System.Int64 0(収まる範囲内のみ) 整数(64bit)
float System.Single 0f 小数型(32bit)
double System.Double 0.0又は0d 小数型(64bit)
decimal System.Decimal 0m 小数型(128bit)
bool System.Boolean true, false 真偽値(2bit)
char System.Char 'j' (シングルクォーテーションで囲む) UTF-16の文字(16bit)
string System.String "java" (ダブルクォーテーションで囲む) UTF-16の可変長文字列

使用例

int x = 1;
var x = 1; // varキーワードを使えば自動的に型を推測してくれる
System.Int32 x = 1; // こう書くこともできるが普通はしない

詳細(Microsoft公式ページ)

配列

C#で配列はclassであり、大きさは定義時に決定されます。書き方は以下の通りです。

int[] arr = new int[5]; //大きさ5の配列
string[] arr = new string[] { "a", "b", "c", "d", "e" }; //このように書いて初期化することも可能です。

var temp = arr[0]; //このように書くことで配列の要素にアクセスできます。

多次元配列

int[,] int[,,]のように書くことで多次元配列を作れます。たとえばint[3,4]とすると3×4多次元配列になります。

ジャグ配列

int[][]のように書くことでジャグ配列(ギザギザ配列)を作れます。これは配列の配列となっているので内側の配列の要素の数はそれぞれ違っても構いません。

演算子

定番の+ - * / %(余り)はありますが、pythonにはある累乗の**はありません。また、静的型付け言語なので以下のような整数同士の割り算は小数点以下が切り捨てられます。どちらかをdoubleにキャストしましょう。

int a = 10;
int b = 3;
int result = a / b; // 3
double result = (double) a / b // 3.333...

また、自分自身に+ - * / %を行う+= -= *= /= %=や、自分自身に1だけ足したりひいたりする++ -- などもあります。

int i = 0;
i += 1;    //これは
i = i + 1; //これと同等

i++;       //これは
i = i + 1; //これと同等

比較演算子として< <= > >= == !=があります。これらは前後のオブジェクトを比較して真偽値(bool)を返します。<= >=は数学における≦ ≧に相当し、== !=は数学における= ≠に相当します。また、&& ||はそれぞれ真偽値における論理積・論理和をあらわし、!は真偽値の直前につけることで真偽値を反転させることができます。

※論理積 二つともがtrueのときtrueを返す
※論理和 二つのうち一方がtrueのときtrueを返す。

ifとかforとか

条件分岐

C言語と違い条件式に指定できるのは真偽値だけです。ifステートメントとswitchステートメントが実装されており、詳しくはMicrosoft公式に書いてあります。

int x = 10;
if(x < 0)
{
  //ここに処理を書く
}
else if (x < 10) { /* else ifを使うことでいくつものパターンに対応できる */ }
else
  return 0; // 終わるときはelseで終わる。1文で終わるなら 波カッコ{} は不要

switch(x) //たくさんの条件で分岐したいときに使う
{
    case 10: // xが10の時の処理
        break;
    case 20: // xが20の時の処理
        break;
    default: // xが上のすべてと異なったときの処理
        break;
}

繰り返し

C#には繰り返しの処理としてforステートメント, foreachステートメント, whileステートメント, do-whileステートメントが実装されています。Microsoft公式を見るとここより詳しい情報を得られます。

for(var i = 0; i < 100; i++) // (初期化処理 ; 終了条件 ; ループが終わるごとに実行される)
{
    // 処理を書く
}

var arr = new int[]{ 0, 1, 2, 3, 4 };
foreach(var item in arr) //コレクションのループ
{
    item++;
}
foreach((var item, var i) in arr.Select((num, index) => (num, index))) //インデックス付きのコレクションのループ
{
    item += i;
}

while(true)
{
   // 条件を満たす間繰り返す。
}
do
{
  // 最初の一回実行され後条件を満たす間繰り返す。
}while(true)

デリゲート

C#では関数オブジェクトを格納するものとしてdelegateというもがあり、下のように定義し、使うことが可能です。

public delegate string Hoge(int x);//引数がint型 返り値がstring型の関数型Hoge

public class Program
{
  public static void Main()
  {
    Hoge func = new Hoge(Foo); //クラスをインスタンス化するときみたいにかける。
    Hoge func = Foo; //こうもかける。
  }

  public static string Foo(int x)
  {
    return x.ToString();
  }
}

このように定義できますが、実際はFuncActionを使うことが多いです。この2つはジェネリクスを用いて(厳密には違いますが)下のように定義されており、どんな型でもその場で指定して入れることができるので大変便利です。

public delegate void Action<T1>(T1 arg); //Actionは返り値がvoid
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2); //Funcは返り値がTResult(最後の型)

//使い方
public class Program
{
  public static void Main()
  {
    Func<int,int,int,string> func = Foo; //こんな感じで書けます。
  }

  public static string Foo(int x, int y, int z)
  {
    return x.ToString();
  }
}

コレクション

コレクションはデータをまとめて扱うためのクラスでジェネリクスなしのものはSystem.Collection名前空間に、ジェネリクスありのものはSystem.Collection.Generics名前空間にあります。代表的なコレクションはリストと辞書型があります。

リスト

リストは可変長配列のようなもので、配列とは違い検索メソッドやソートメソッドが実装されてたりします。

var arr = new List<int>();
arr.Add(3); //Addで追加
var temp = arr[0]; //これで中身を見る
arr.Remove(3); //引数と最初に一致したものを削除

詳細はMicrosoft公式で確認してください。

辞書型

辞書型はキーと値をセットで保持することができるコレクションです。

var dic = new Dictionary<string, string>();
dic.Add("key", "value"); //Addで追加
var temp = dic["key"]; //これで取得
dic.Remove("key"); //引数と一致したキーを持つ値を削除

詳細はMicrosoft公式で確認してください。

プロパティ

プロパティはclassやstructのメソッドをあたかもフィールドであるかのように扱う機能です。

public class Hoge
{
    public int Number
    {
        get
        {
            return _number;
        }
        private set // アクセス修飾子を片方だけ変えることが可能
        {
            if(value < 0) // 入ってきた値は valueキーワード に格納されている
                value = 0;
            _number = value;
        }
    }
    private _number;

    public int Id { get; private set; }  // getとsetだけ書いて中身は書かないとコンパイル時に
    public int Id { get{ return _id; } set{ _id = value; } }  // これみたいに展開される
    private int _id;

    public void HogeHoge()
    {
        Number = 10; //setプロパティが呼ばれる
    }
}

フィールドではなくプロパティで実装することのメリットはset時に制約をつけたりget時にnullの場合などで条件分岐したりできることがあります。また、interfaceにはフィールドは定義できないですがプロパティは実際は関数なので定義できます。

名前空間

C#ではコードを名前空間で分割することができす。下のようにクラスやメソッドと同じように宣言することができます。名前空間では同じ名前空間にあるもの、またはusingを使って宣言したものだけが制限なく使えます。別の名前空間のものを使用する際はA.Hogeのように名前空間から指定するかusing A;という文言を書いておく必要があります。

using System;
namespace A
{
   public class Hoge
   { }
}

yield return

yield returnで値を返すことで簡単にIEnumeratorを作ることができます。returnの代わりにyield returnを使うとIEnumeratorが自動的に生成され、foreachステートメントで使用できます。

public static void Main()
{
    foreach(var i in GetEnumerator())
    {
        // 処理
    }
}

private static IEnumerator GetEnumerator()
{
    int i = 0;
    while(true)
    {
        yield return i++;
    }
}

UnityではCoroutineという機能で使わています。

継承

C#はオブジェクト指向の言語なので継承が実装されています。継承とはあるクラスから性質を受け継いだ新しいクラスことで、派生とも呼ばれています。例としては以下のようなものがあります。

class Person
{
  public string name; // 名前
  public int    age;  // 年齢
}

class Student : Person
{
  public int    id;   // 学籍番号
}

継承 - C# によるプログラミング入門 | ++C++; // 未確認飛行 Cより

時間がなかったので継承はあとで書きます。

参考させていただいたサイト

Oracle Cloudにsign up出来なかった話

結論から言うと出来ました。
ブラウザの問題でした。

~あらすじ~

実は既に自宅にNASで若干サーバーっぽい物構築しているのでそれでいいかなと思ってました。
しかし無料の演算能力がある鯖が欲しくなって、自宅のは心許ないので、大企業様のOracle社のCloudを使ってみようと思い立ちました。

~苦戦~

様々なサイトを参考にsign upを試みました。
しかしどうも上手くいきません。
何故か東京とTokyoの二つ選択肢があるけどどちらがいいんだろうとか、英語にした方良いのだろうかと試行していました。
その中で一つ分かったことは、電話番号は最初の0は除いて記述することです。
しかしそれだけでは登録できませんでした。
「アカウントの作成には最大で15分かかります」的な表示が出てきてそれ以上進まない。
メールが来るのかと3日間待っても来ないし、chatがあったので、なけなしの英作文能力で質問したら、今審議中で1日かかるよと言われて、結局一日待っても何も起きない。
(最大で15分と書いてあるのに、1日かかると言われるのはこれ如何に)
※Chatは対応してくれるときとしてくれない時があります。2020年4月の一年間無料の締め切り間近の楽天モバイルよりかははるかに対応してくれる印象。

~解決~

私の使っているブラウザのVivaldiが悪いのでは?と思い、KC3冬のハッカソンでデバッグ用にインストールしたChrome Canaryを使用して登録してみました。
その時に違和感が。
Vivaldiの時はメールアドレスを同じやつ何度入れてもメールアドレス検証でエラーを吐かなかったのに、Chromeでは吐いた。
これはもしや...?と思い登録情報を埋めて登録していく...
メールが到着、そこには「Get Started Now with Oracle Cloud」!
秒で届きました。一体今までの苦労は何だったのか。
しかし、ブラウザ間で動作違うってよくありますよね。
実際ChromeとChrome Canaryですら動作異なりますもんね。
だから私はVivaldi、Chrome、Chrome Canary、Firefox、Edge、IE、OperaとかPCに入れてるんですよね。
その日の怒りのノリで書いたこの記事が参考になれば幸いです。

筆者:上月
前回の記事:Live2D触ってみた

fishshellを触ってみた

                              執筆者:NamiFuji

(フリー素材です)

この記事はOUCC Advent Calendar 2021の25日目の記事です。前回は上月さんの「Live2Dを触ってみた」でした。さて本日はクリスマスです。皆さんは本日はどのようにお過ごしの予定でしょうか?私はこの前買ったパズルを完成させる予定です。人によってはクリぼっちで最悪だなんて言っている人がいますが、私の考えではクリスマスにひとりで過ごすということは全く恥じることではないと思います。なぜかというとクリスマスというのは本来イエス=キリストの誕生を祝うことが目的であるので、そもそもクリスマスに大勢で集まらなければならないと考えること自体が本来の目的とずれているからです。なので一人であるということ自体に対してなんら問題もなく、逆に誰かといなければと考えること自体が周りの考えに振り回されているということになり、それ自体が問題となるからです。

さて、余談は置いておいて、本記事のタイトルにも書いてある通りfishshellについて話していこうと思います。本記事は調べたらそのまま出てくるような内容をまとめたような形になってしまうかもしれないですが、そのような場合は温かい目で見守ってください。

shell

まず、shellとはざっくりいうと自身がPCに対して行ってもらいたい命令をOS対して出すプログラムのことです。そしてshellにはいくつか種類があり、たとえばbash,tcsh,zshなどがあります。それらには当然のように機能の面において違いがあります。今回話そうとしているfishとはそのようなshellのうちの一つです。

fishのどこがいいのか

さてこれからfishについて話していこうとおもいますが、なぜbashやzshではなくfishなのかと疑問に思う人がいるかもしれません。その理由を端的にいうと、fishは他のshellと比べてとても扱う(カスタマイズをする)のが容易であるからです。

fishのデフォルトの機能としてシンタックスハイライトの機能がついており、それによってコマンドやオプションが間違っているのか一目で確かめることができます。さらにコマンドを入力する際に過去のコマンド履歴からインタラクティブに補完を見ることもできます。

補完機能の例

入力時

間違った入力をした時

fishの簡単なカスタマイズの方法

実行環境:M1mac Monterey

1,iterm2かターミナルでfish_configとコマンドを入力する。

2,ブラウザが開かれるので、そこから設定を行う

以上のような簡単な操作だけでもまぁまぁ見た目を変えることができる。

fishのカスタマイズ方法

さきほどはfishの簡単なカスタマイズ方法を説明しましたが、この方法ではカスタマイズの自由度がとても狭いです。そのためつぎはさらに自由度の高いカスタマイズ方法について話そうと思います。

それは~/.config/fish/config.fishファイルに直接設定を書いていく方法です。

たったこれだけだと、文章として寂しいので私個人が実際にいじった部分をのせようと思います。

現時点の私の設定ファイルは見ての通り、あまり書かれていません。そのためこれからさらに使いやすいように設定ファイルをいじるのが私の目標です。

今までに述べた方法以外にも、プラグインを入れるというカスタマイズ方法もあります。みなさんもこれを機にfishをつかって、みなさんの使いやすいようにカスタマイズしてみてください。

Live2Dを触ってみた

この記事はOUCC Advent Calendar 2021の24日目の記事です。イブですね。イベント開催することで24日の予定を阻むFGOの運営の気持ちがよくわかる日になりました。いかがお過ごしでしょうか?前回は、かき氏の「Reactで時間割アプリを作ってみた」でした。

私が書いた記事は、前回はGANについて、前々回はOpenCVについて、前々々回はUnityについて書くといったように毎回分野を変えて記述しているので、今回はLive2Dについて記述していこうと思います。

~あらすじ~

自分の描いた絵が動くと嬉しいですよね。

というわけで、Live2Dやったことないけどやってみました。

~キャラについて~

今回動かすキャラは、「Angel-Rein」ちゃんです。
春のハッカソンで「嫌われているE-Learningを擬人化して対話することで好きになろう企画」の自然言語で会話する対話Botを作成することになりました。
その時に、新しいキャラを制作することが好きな私がデザインしたのがReinちゃんです。
マフラー付けて冬っぽい服装ですが、考案したのは春で、描いたのは夏ごろです。

名前の由来は、E-Learningのアナグラム

デザインやキャラの詳細については、ここを参照してください。(別ページへ飛びます。)

~出来たもの~

※読み込みに時間がかかるかも。お許しを

ここに画像が表示されるはず
ランダムAというデフォルトで用意されているアニメーションを再生したもの

▼表示されない方はこちらから(高画質版)

又はようつべリンクから

~感想~

むずい! 正直Blenderの方が簡単とさえ思えました。というか実際Blenderの方が簡単だと思います。
3Dを絵を変形させて表現するというのが難しい。
ここがこう回転すればこうなるといったようなことを頭の中で考えながら作成しなければならず、立体図形把握能力が求められる作業だと感じました。

見てください、この点の数!たった腕を動かすだけでこれだけのキーを打ち込まなければなりませんでした。(もっと賢い方法はあるのかもしれませんが)
袖が動いて前と後ろが切り替わる所とか、それによって袖がどう動くかとか、腕がより俯瞰した位置ならどう見えるかなどなど考えて動かすとこうなりました。
Blenderなら立体図形を作成してしまえば、動き方に応じて図形を編集する必要は無いですが、live2dは立体図形は手元にないけど図形を動かすとこう見えるだろうという予測を立てなければならないです。
もっとも可動範囲を狭くする、例えば腕の振れ幅を10度だけにする、顔もほんのちょっとしか動かないとかいったことをすれば簡単になると思いますが、回転や拡大縮小以外の複雑に変形しながら動く場合には、それだけで数時間飛ぶ作業量を要求されたりします。
あと、原画はキャラ設定画像としてなるべく正面で描いた絵なのですが、少し見栄えよく見せようと顔が傾いていたりします。これのせいで、対称編集が出来ないといった書く段階で知りたかった事柄も相まって難易度を底上げしてしまったようです。
物理演算を入れる作業については、あまり細かいところを気にしなかった(気にしている余裕がなかった)からか、結構楽々に設定することができました。

しかし、この図形を想像しなければいけない部分とかどうにかならないのでしょうか。真に絵を描ける人はこの辺の能力が高いのかもしれませんね。
昔Live2D Euclidとかあって、自分の絵を3D化できるという話を聞いて心躍ったのですが、あれはどうやら既に公開停止になっているようです。何が原因で頓挫したのかは分からないですが、上手くいけばメタバース時代の覇権を握れたかもしれないと思えるだけに残念です。
それにしても、世の中のVtuberはLive2dであそこまで動かせてすごいんだなぁ~って今回作成してみて感じました。

~総括~

Blenderではなく、Live2Dを使用する場面というのは恐らく以下の場面でしょう。

  1. あまり動かさない、又は動く部位が回転や拡大縮小といった単純な変形で構成されることが多い場合

  2. 絵を動かしたい、又は3Dの見た目は好きじゃない、3Dでは表現できないデザインを動かしたい場合

少しでもご参考になれば幸いです。

筆者:上月さん

OUCC Advent Calendar DAY21 Unityでゲーム作るRTA+おまけの謎解き

執筆者:Pres.U(近々ハンドルネーム変更予定)
この記事はOUCC Advent Calendar 2021の21日目の記事です(実質9日目)。前回(12/21)はtakuemonさんのMixamoのススメです。

今回はUnityで2Dゲームをゼロから作りかつ記事を書くという無謀なRTAを行います。多分これが一番早いとは思いません

目次(と思しき何か)

  1. 初めに
  2. 作るゲーム
  3. 今回のRTAのレギュレーション
  4. 準備
  5. ゲームの方針
  6. 実装方法
  7. できた
  8. 完走した感想(俄並感)
  9. 謎解き

初めに

ほかの皆さんの記事は実用性があり内容も素晴らしいのですが、わたくしの書く記事は実用性も糞もなく、TDNただの読んでくださる人および執筆者の時間潰しにすぎません。それでも楽しんで頂けると幸いです。

おせちだよ~
図1:上はほかの皆様の記事、下は僕の記事

作るゲーム

今回は、脱出ゲームを作ってみようと思います。

図2:ゲーム画面の予定

今回のRTAのレギュレーション

  • Any%RTA、すなわち出来の良さを考慮しない
  • 計測開始はブログの執筆を開始した午後4時とす
  • 計測開始時点でのUnityプロジェクトは初期状態とする
  • 計測終了はブログを投稿した時間

準備

まずはプロジェクトを作りましょう。Unity Hubから新規作成→2D→任意で名前変更→作成で作れます。
次に、画像を自作します。ペイントがおすすめです。

ゲームの方針

軽い謎を解いて鍵をゲットし部屋から脱出する感じです。

実装方法


タイトル・本編・クリア画面の3つのシーンをSceneManagerを使って遷移させてやる感じです。また、アイテムの表示・非表示はオブジェクトの座標を画面外に移すことで疑似的に実行しています。

できた

後でドライブにzipファイルを置いておきます。

図3:ゲーム画面

完走した感想(俄並感)

じつは実装しているうちに、GameObjectを非表示にするとアタッチしているスクリプトが無効になるといった仕様に悩まされ方針を変更せざるを得なくなりました。
また、最近Unityに触れる機会がなかったので、いい練習の機会になったと思いました。
最後に、ゲーム作るのは大変でした。

謎解き

本編です。

1213①②16③④
④⑤⑥22⑦②⑧

⑥④⑦⑤er④→?

ヒント1:僕は22です(年齢じゃないよ)

ヒント2:①~⑧に入るのは数字ではなくアルファベット

ヒント3:このイベントはずばり…?

答え:mystery

Mixamoのススメ

執筆者:takuemon

 これはOUCC Advent Calendar 2021の20日の記事です。(なぜ記事を21日に記事が投稿されているんだ…おかしいぞ?…)前日(一昨日)の記事はyuyuさんの政府統計e-Statで学期末レポートを粉砕する 、明日(今日)の記事はMrMocchyさんのローポリのすゝめです。

今回は、Unityでゲーム制作しているときに個人的にお世話になったサイトを紹介させていただきたいと思います。

URL:https://www.mixamo.com/#/

Mixamoはどんなサイトかといいますと、大量のキャラクターとモーションが無料で使い放題という慈善事業みたいなことしてるサイトです。ここではキャラクターをアップロードして、専用のモーションをダウンロードするまでを解説していきます。

1.アカウントを作る

青色のボタンをクリックしてアカウントをつくります。

右上のCharacterのタブをクリックすると大量のキャラクターをダウンロードできますが、今回は自分でキャラクターをアップロードします、UPLOAD CHARACTERをクリックしましょう。

するとこのウィンドウが表示されます。私はユニティちゃんのfbxファイルをアップロードしました。

テクスチャが貼られたモデルをアップロードしたい場合は、テクスチャとモデルを圧縮したzipファイルをアップロードしてください。

左下の頭蓋骨をおすと、ボーンが表示されます。NEXTをクリックします。

すると、こんな感じに警告文が表示されます(初見でちょっとビビった)が、全く問題ないので無視してNEXTをクリックしましょう。

これでユニティちゃんがアップロードされました! 左側のモーションをクリックすることで、ユニティちゃんにモーションを反映させることができます。例えば、

それではこれらのモーションをダウンロードしてみましょう。DOWNLOADをクリックします。

するとこのようなウィンドウが表示されますがそのままでDOWNLOADをクリックしてください。これでユニティちゃんのモーションがダウンロードされました。

いかがだったでしょうか? Unityで3Dゲームを作る時、キャラクターのモーションに悩まされることは多いと思います。そんなとき、Mixamoに頼ってみると、あなたの求めるキャラクターやモーションが手に入るかもしれません。気になった人は是非!

ローポリのすゝめ

執筆者:MrMocchy

はじめに

この文章はOUCCアドベントカレンダー2021の12/21のものです。
前回はtakuemonさんのMixamoのススメです。

これが自分のはじめてのブログ記事になります。
調べものの際によく出てくるブログをまねる感じで書くつもりです。
暖かい目でご覧ください。

ローポリ

自分はノートパソコンしか持っていないのですが、3Dゲームは重いのばっかりで興味をもったやつの多くは必要スペックを満たせずに断念していたりします。
しかし、ある程度のグラフィックでも快適に遊べるものもあります。まあゲーム性自体がシンプルだってのもありますが、その多くは(たぶん)ローポリです。

ローポリとは、ロー・ポリゴンの略で、少ないポリゴン(=面)でできた、ざっくり言えば精巧でない3Dモデルを形容する言葉です。
それを綺麗に見せるためにテクスチャやシェーダーに力を入れているようなのですが、本記事のメインはローポリです。

エンティティを大量に配置するゲームを作る際、クオリティより数を必要とする際、その他とにかく軽くしたい際、ローポリは非常に有効です。

カメ

さて、ローポリについて話すとなれば何かの3Dモデルを用意する必要がありますが、なぜでしょうか、カメを作ろうと思いました。甲羅にポリゴン感があるからでしょうか。
「カメ 3Dモデル」などと検索してみてください。精巧なカメの画像がたくさん見つかると思います。手足や頭の曲線、皺、甲羅の凸凹感。重そうですね。

そこで自分が作ったカメがこちらです。

シンプルですね。5分で作れそうです。15分ぐらいで作りました。
しかし、このモノクロでもカメ、それもリクガメでもウミガメでもない、ミドリガメのようなカメだと分かります。

画像の左上にあるのがこれの三角面数などの情報です。比較対象は後に出しますが、基本的にこれが少ない=データ量が小さい=描画が軽いということになります。

ちなみに、もっとローポリにすることも可能です。それがこちら。

もはやカメだとも言われなければ分からなさそう...ですかね?よく見ればカメだとは思いますが。
ですがテクスチャを設定するだけで、随分と分かりやすくなるものです。現に、2色のべた塗りでも、

ほら、カメです(断言)。

先ほども述べましたが、モデルの精巧さだけでなく、このテクスチャにこだわることでもより正確なカメを表現することができます。
ただ、自分個人の意見としては、このような極端なローポリのモデルは、同じく極端に単純なモデル、パステルカラーなイメージの少ない色数といった感じのデザインで統一し、かわいい方向にした方が好きですね。

ウサギ

カメときたらウサギです。

誰が見てもウサギ、かは分かりませんが、多くの人はウサギだと言ってくれるでしょう。

これもさらにローポリにしようとしたのですが、なかなかうまいこと行きませんでした。

とりあえず鼻先を小さくするとして、やはり胴体がネックですね()。これが限界な気がします。

なので、逆に精巧に作ってみることにしました。

なにかがおかしい。犬でもない。なにかこう、いそうでいないようなクリーチャーができました。

できました。口の周りを膨らませたらウサギっぽくなりました。あとは草を咥えさせたら完全にウサギです。
色と背景を付けるとこうなります。

完成。

ここで見てもらいたいのが、2つ上の画像の左上の数字。...潰れてますね。こちらです。

そして先ほどのカメの数字をご覧ください。

ローポリの偉大さが分かっていただけたのではないでしょうか。

おわりに

まとめ:ローポリは軽い。作るのは非常に楽。かわいい。

ご覧いただきありがとうございました。

次回のOUCCアドベントカレンダー2021は、Pres.UさんのOUCC Advent Calendar DAY21 Unityでゲーム作るRTA+おまけの謎解きです。

ちなみに

上の3DモデルはBlenderというフリーソフトで作りました。完全フリーです。どこかの機能を使おうとしたら有料アップグレードを要求されることなんてありません。広告もありません。開発側はどうやって稼いでいるのでしょうか。

ローポリモデル欲しい、けどモデリングしたくない人は
「○○ 3Dモデル フリー」とかで検索、ダウンロード⇒Blenderにインポート⇒モディファイアーを追加>デシメート⇒比率を調整
で簡単にポリゴンの削減ができるはずです。あまり削減しすぎると崩れてきますが。

そしてウサギの背景をもらってきたのはPoly Havenというサイトからです。そこのHDRIs(=360°画像)で入手することができます。このサイトではテクスチャや3Dモデルも無料で利用できます。IT業界の発展のための無償公開だそうです。非常にありがたいです。

Blender:https://www.blender.org/
Poly Haven:https://polyhaven.com

政府統計e-Statで学期末レポートを粉砕する

執筆者:yuyu

この記事はOUCC Advent Calendar 2021の19日目の記事です。前回はyuさんの「パワポを動画にしようとしてみた」でした。

吐く息も白くなってきて、いよいよ令和も3年目を終え、はや4年目を迎えることに驚きを隠せておりません。yuyuです。みなさんはいかがお過ごしでしょうか。私は下宿をしている身ですが、部屋に備え付けの暖房の効きが異常に悪く、毎日布団にくるまっているミノムッチ状態です。

さて、今日は「政府統計の総合窓口」e-Statについて解説したいと思います。e-Statとは例えば「人口・世帯」、「労働・賃金」といった17の分野の政府による統計結果が集まったサイトです。具体的には国勢調査の結果や賃金構造基本統計調査(様々な業種の基本給を調査)の結果などが公表されています。URLはこちら。https://www.e-stat.go.jp/

※この記事は主にデータ分析のために、あるいは基盤教養科目などのレポート課題で自身の主張を裏付けるために公的な統計結果が欲しい方向けです。例えば、法学部に所属している私なら、特に政治学の分野において適切な政策を考案するために日本の現状を知る手段の一つとしてe-Statを利用しています。

目次

  1. はじめに
  2. この記事で伝えたいこと
  3. 解決したい問題
  4. じゃあ、どうする?
  5. e-Statの良いところ・悪いところ
  6. e-Statの使い方
  7. 補足
  8. おわりに
  9. リンク

1. はじめに

あなたはこれまでの人生で公的な統計結果が欲しいと感じたことがありませんでしたか?高校で調べ学習を課されたり、大学の基盤教養科目でレポート課題を課されたり。往々にして「引用するデータは信頼のおける発信者のものにしなさい」と注文が来ます。信頼のおける発信者とは公的機関、特に政府機関です。とはいえピンポイントで見つけるのは難しいです。たいていの場合は省庁が出している報告書に引っ掛かる程度。

そこで登場するのが我らがe-Statであり、これはありとあらゆる公的な統計調査結果を集約したサイトで、そこからさまざまな調査結果を調べ、データのダウンロード、ブラウザ上で表作成、グラフ作成が可能です。

こんな便利なサイトがあるのに使いこなさないのはもったいない!!!ということで、今日は[冬季集中講義]e-Stat基礎論を開講します。安心してください、楽単ですよ。

2. この記事で伝えたいこと

  • e-Statは政府統計調査のポータルサイトとしての役割をもつ
  • データのダウンロードが可能、簡単に利用できる

3. 解決したい問題

公的統計調査結果の効率的な収集です。そもそも、どのような統計調査が行われているのかを具体的に認識していないと単にブラウザで調べるという手法では限界があります。

4. じゃあ、どうする?

ついにこの記事の真打、e-Statの登場です。先述の通り、e-Statとは政府統計調査のポータルサイトです。ここを経由して様々な統計データにアクセスができます。ここでいったんe-Statの長所短所を確認しておきましょう。

5. e-Statの良いところと悪いところ

◇良いところ

  • 政府統計調査ポータルサイトの役割を担い、あらゆる統計調査にアクセスできる
  • csv形式やxlsx形式でデータのダウンロードが可能
  • 全国で平均を取ったデータだけでなく、都道府県別、市区町村別のデータも完備
  • 「詳細」からその統計を管轄する機関のサイトに飛び、細かい情報を得られる

◇悪いところ

  • 若干、作成したグラフが見づらい

こんなところです。べた褒めをしても政府の回し者に思われてしまいそうなので短所を出しておきましたが、個人的には気にならないかなと思っています。それは、デザインの問題であるという性質上、xlsx形式でダウンロードしてExcelを開いて自分で表やグラフを作成すれば済むことだからです。

6. e-Statの使い方

今回は「家計調査」を題材として説明していきたいと思います。

(1)e-Statにアクセスする

任意のWebブラウザで「e-Stat」と検索していただくと”e-Stat政府統計の総合窓口”にアクセスできると思います。(直リンは https://www.e-stat.go.jp/)

トップページはこんな感じ

(2)知りたい情報のキーワードを考える

ここからお目当てのデータにたどり着くには「・統計データを探す」というところから「すべて」、「分野」、「組織」、キーワード検索の4通りの方法があります。基本的には探しやすい「分野」を用いるのが良いと思います。探し出せなければキーワード検索を使いましょう。

今回の例として用いる題材は家計調査でしたね。つまり、キーワードは「家計」、「経済」です。まず分野を確認してみて、なければキーワード検索です。

「分野」をクリック

「企業・家計・経済」という分野の主な調査に掲載されている「家計調査」をクリックしましょう。

「家計調査」をクリック

(3)統計調査の詳細な内容確認

クリックして次のページに進んだら当該統計調査の目的と内容が大まかに書かれているのがわかると思います。統計データを分析するには統計で用いられている用語の定義を確認することが非常に重要です。自分の考えていた意味とは全く異なる場合があります。統計調査名の右にある「詳細」をクリックしてください。

「詳細」をクリック

すると担当機関名や課室名、連絡先などの情報がありますがそれらは無視して「ホームページURL」とあるのをクリックしてください。担当機関の当該統計調査に関するページに飛びます。

URLをクリック

ここには調査の概要や結果が載っています。この統計では総務省統計局のホームページですが、別の統計で担当機関が異なる場合でも同様に調査の概要を説明するページに飛びます。さて、最も重要なのは用語の定義です。調査の結果 > 用語の解説と進みます。

調査の結果 > 用語の解説

可処分所得を例に確認します。

「実収入」から税金,社会保険料などの「非消費支出」を差し引いた額で,いわゆる手取り収入のことである。これにより購買力の強さを測ることができる。

用語の解説

実収入と非消費支出にカギ括弧がついていますが、これらの定義も同じページに説明があるので確認してみてください。

(4)データ取得

用語の定義を確認したらいよいよデータを取得します。(2)が終わった段階までページをさかのぼります。「データベース」と「ファイル」の2つが確認できるかと思います。

このうち、「データベース」を選択した場合はブラウザ上で表の作成、グラフの作成ができます。単に内蔵データを確認したいならこちらを選択してください。一覧が出てくるので家計収支編 > 総世帯 > 年次を選び(図1)、続けて用途分類(総数)の全国の右にあるDBをクリックしてください(図2)。作成された表を閲覧できます(図3)。表をそのままダウンロードも可能です。APIは私自身がよくわからないので使っていません。

図1
図2
図3

一方、「ファイル」を選択した場合は Excelデータのダウンロードができます。

(5)データ分析

データを取得したら分析をして類似する別のデータを調べたりします。その場合は(1)からの手順を繰り返します。データ分析の手法は本題ではないので省略します。

7. 補足

今回取り扱った統計調査は国が行ったものであって、その収集単位も国全体です。しかし都道府県別のデータなど、地方公共団体を単位とする統計調査データが欲しいときもあると思います。そんなときはe-Statのトップページから「・統計データを活用する」にある「地域」を選択してください。

8. おわりに

いかがでしたでしょうか。ここまでお付き合いくださりありがとうございます。次節のリンクに学習用サイトのリンクを貼っておくのでわからない部分があればそちらを参考にしてください。

レポート課題のときだけでなく常日頃からさまざまな統計データに触れておくことで現政府の政策にある意図に気づくことができます。コロナ禍の今は皆さんも政府の動向にとりわけ注意を払っているはず。せっかくの機会ですからいろいろ考察してみると面白いかもしれないですね!

OUCC Advent Calendar 2021 次回はtakuemonさんです!お楽しみに!

9. リンク

パワポを動画にしようとしてみた

はじめに

この記事は、OUCC Advent Calendar 2021の18日目の記事です。前回はAreiさんのハンドヘルドコンピュータの製作と展望でした。 今回はPower Pointのスライドショーを動画に変換しようとしてみました。

やり方

音声付きスライドを考えると動画を作るためには画像と音声が必要です。しかし、pptxファイルやppsxファイルから直接画像や音声を取り出すことのできるライブラリはありませんでした。

まずは音声ファイルの抽出から行うことにしました。pptxを含むoffceファイルは中身はただのzipファイルなのでos.Rename()を使ってファイル形式を変え、zipfileライブラリで開くことで中の情報に直接アクセスできます。音声ファイルがあるのは ppt/media のディレクトリで、どの音声がどのスライドに紐づけられているのかというのは ppt/slides/_rels にあるrelsファイルに書いてあります。relsファイルはxmlファイルなのでこれもos.Rename()でファイル形式を変えて扱います。そこから音声ファイルとスライドの関連情報が得られ、音声ファイルの準備は完了します。

次に画像ファイルの作成ですが、現状pptxから自力で画像を作ること大変難しいのでPower Pointアプリを起動し、画像をエクスポートさせます。これはcomtypesライブラリを用いることで実現しました。

最後にこれらをまとめるのですがこれにはffmpegというコマンドライン上から動画編集ができるソフトをいれ、python上でそのコマンド実行するというゴリ押しの方法で行いました。

作っている途中で気づいたこと

Power Pointのエクスポートに動画に出力する機能があり、自作するより圧倒的に多機能であること

それを知って

デバッグする気力がなくなったため、途中からデバッグしてません。理論は分かったけど、もう動作させる理由がありませんでした。たぶん動かないと思います。

import os
import re
import zipfile
import glob
from comtypes import client
import xml.etree.ElementTree as ET
import subprocess

def getM4aPath(relsPath):
    root = ET.fromstring(relsPath)
    for child in root:
        data = child.attrib["Target"]
        print(data)
        if re.match(".+\.m4a",data):
            return "pptxZipTemp/voice/ppt/" + data.replace("../","")
    return ""

def generateMp4(relsPathList,pptxPath):
    aviPathList = []
    concat = "concat:"
    for index,relsPath in enumerate(relsPathList):
        voicePath = getM4aPath(relsPath)
        pngPath = "pptxZipTemp/images/slide{}.PNG".format(index)
        aviPathList.append("pptxZipTemp/avi/temp{}.avi".format(index))
        subprocess.run("ffmpeg -loop 1 {} -i {} -vodec mpeg4 -acodec pcm_s16le -shortest {}".format(pngPath,voicePath,aviPathList[index]),shell=True)
        concat = concat + aviPathList[index] + "|"
    concat = re.sub(".+\|$","",concat)
    pptxPath = pptxPath.split("/")
    pptxPath = pptxPath[-1].split(".")
    subprocess.run("ffmpeg -f concat -i {} -vcodec libx264 -acodec aac -pix_fmt yuv420p {}".format(concat,pptxPath[0]))

def zip2mp4(zipPath,pptxPath):
    with zipfile.ZipFile(zipPath) as pptxZip:
        inforLi = pptxZip.infolist()
        voicePathList = []
        relsPathList = []
        for info in inforLi:
            fname = info.filename
            if re.match(".+\.m4a",fname):
                voicePathList.append(fname)
            elif re.match("ppt/slides/_rels/.+\.rels",fname):
                relsPathList.append(fname)
            print(fname)
        for voiceIndex, voicePath in enumerate(voicePathList):
            pptxZip.extract(voicePath, "pptxZipTemp/voice")
            voicePathList[voiceIndex] = "pptxZipTemp/voice/" + voicePath
        for relsIndex, relsPath in enumerate(relsPathList):
            renamedRelsPath = relsPath.replace(".rels","")
            pptxZip.extract(relsPath, "pptxZipTemp/rels/")
            os.rename("pptxZipTemp/rels/"+relsPath, "pptxZipTemp/rels/"+renamedRelsPath)
            relsPathList[relsIndex] = "pptxZipTemp/rels/" + renamedRelsPath

        generateMp4(relsPathList,pptxPath)

def export_img(fname, odir):
    application = client.CreateObject("Powerpoint.Application")
    application.Visible = True
    current_folder = os.getcwd()

    presentation = application.Presentations.open(os.path.join(current_folder, fname))

    export_path = os.path.join(current_folder, odir)
    presentation.Export(export_path, FilterName="png")

    presentation.close()
    application.quit()

def rename_img(odir):
    file_list = glob.glob(os.path.join(odir, "*.PNG"))
    for fname in file_list:
        new_fname = fname.replace('スライド', 'slide')
        os.rename(fname, new_fname)

def getLines(path):
    reg = '\.pp[s|t]x'
    renamedPath = re.sub(reg,".zip", path)
    print("match:")
    print(renamedPath)
    print(path)
    if os.path.isfile(path):
        try:
            subprocess.run("mkdir pptxZipTemp",shell=True)
            export_img(path,"pptxZipTemp/images")
            rename_img("pptxZipTemp/images")
            os.rename(path,renamedPath)
            print("This path exists.")
            print(renamedPath)
            zip2mp4(renamedPath,path)
        except OSError as e:
            print("An OSError occured")
            print(e)
        finally:
            os.rename(renamedPath,path)
            print("終了しました")
    else:
        print(path+"は存在しないか、対応していません。")

def main():
    while True:
        print("scan:")
        inputString = input()
        if inputString == "exit":
            break
        else:
            getLines(inputString)

if __name__ == "__main__":
    main()

ゲームや動画等の演出の話 (雑)

OUCC Advent Calender 2021 16日目の記事です。 執筆者: ちょくぽ
前回はShiokaiさんの GrabPassで取得したテクスチャが意外と後まで使える でした。

演出関連の気づきを、自分用にメモするくらいの気持ちで書いていきます。
これは特別演出の勉強などはしていない、一般趣味クリエイターによる記事です。読者としてポートフォリオを作るような方々ではなく、一般人を想定しています。

特殊演出や凝った編集のような話ではありません。普段コンテンツを見る側として気にも留めていなかった、しかし制作側は知っておかないと作れない、そんなことが中心です

色彩

基本的には目立たせたい所にコントラストを使い、色相・明度・彩度に差を出します。これは広く知られていることかと思います。しかし、実際に三要素全てで差を出すと強烈になりすぎます。メイン(キャラや障害物等、ゲームプレイに関係のあるもの)と比較して背景は明度で差を、敵や弾と主人公とは色相で差を出し(例.2Pカラー)、主人公等見て欲しいものにより高い明度・彩度を使う(≒光を当てる)ことで目立たせる等が常套手段。

逆に単一オブジェクトの中では三要素全てをある程度まとめるべきです。特に背景はぼかしてでも1~3色程度にまとめましょう(敵の弱点やギミック等は見て欲しいものなのでこの限りでない)。 単一オブジェクト内では、下画像のように使用色がパレット上で一直線に並ぶようにするとまとまりが良いです。色相を少しだけ変えると汚くなりにくい。アクセントの色はむしろ外れる方がキャッチーかも。

確かに使用色がばらけるほど目立ちますが、ゲームや動画・キャラデザの文脈では目立ちすぎると目が疲れる・悪目立ちといった印象になるので、メイン色範囲(直線)1本、アクセント1,2色程度に留めましょう。

OUCC Advent Calender 2021 day16 pic1

ビジュアルノベルやRPG(アクションでない)等では、逆に雰囲気を重視し環境光などでキャラをなじませることがよくあります。書いてあることと逆じゃないかと思うかもしれませんが、このときは背景美術や音楽などもっと目立たせたいものが他にあることや、キャラの実在感を出すためということもあります。後者の場合、光を当てたり視点誘導などでメインが目立つようにしています。

動画や広告等でも同じことが言えます。字幕を縁取りすることはコントラストを作り目立たせる手法として一般的です。また、赤色の特徴である購入意欲向上や、信頼感の青色、明るい気分の黄色など色の特徴を使うこともあります。

いら〇とやなどを使うときは当然他の素材と競合しないようにするべきです。い〇すとや等イラスト素材は、それ単体でメインになる程度の情報量(≒色の多さ、十分な明るさ、三要素のばらつき具合)を持っています。文章だけの掲示に彩りを与えるには良いですが、他にメインとなる画像素材がある場合、いらす〇やは実は邪魔かもしれないのです。

動き

イージング最高!イージング最高!イェイイェイ!

すべてのUI、ズームイン/アウト、表示などに、親の仇のようにイージングを使いましょう。イージングとは、簡単に言うと加減速のことです。

アイコンやボタンなどの表示はEase-In-Outがいいでしょう。最初に加速、最後に減速です。いきなりアイコンが動くとユーザーが驚くし、急に停止すると不自然な上にフリーズか仕様か分かりません。加速度の絶対値が小さすぎるとのっそりもっそりしてしまうので、すぐに最高速度に達するようにしましょう。

ボタンを押したとき等、ユーザーが能動的に操作するとき、その演出にはEase-Outを使いましょう。最初からトップスピード、最後に減速です。ユーザーが触れた瞬間に動き出すので、クリックにより"弾いた"感があり、操作している感が出ます。

*直線移動、Ease-in-out、Ease-outの例をGIF画像で作ったがこのブログ.gif対応してない*

ぶっちゃけ動きの演出なんて無限通りあります。イージングはいついかなる場所でも大体通用しますが、エフェクトはそう簡単ではありません。

使用するエフェクトは世界観ごとに、前もってある程度まで限定しておきましょう。
サイバーな世界ではグリッチやモザイク、発光などを多用し、ポップな世界ではバウンド、いったん拡大縮小しすぎて戻るやつなどを多用します。アイコンはもちろん、キャラクターの動きや字幕までエフェクトを統一すると、より世界観を演出できます。

ゲームに限った話ではありません。業務用ソフトのUIや動画にも世界観というものはあります。UIに明るい世界観を与えると、ユーザーフレンドリーな感じになります。

一瞬色を反転させる、拡大縮小と共にフェードインさせる、明度が高い所だけを先に描画し印象付ける、など世界観を持たない演出は便利に使えますし、他の演出と組み合わせることもできます。無限です。ここはもう製作者の好みの話です。

配置

余白を上手く使うことができる人は強いです

イラストを描く人なら知っているかもしれませんが、キャラが向いている方向に空間があると、安定して良く見えます。逆にキャラの背後に空間があると不安を煽り、キャラの頭上に空間を大きく取ると開放感を与えます。また、キャラが前を向いていると未来を、振り返っていると過去を、カメラと目が合うと元気さを、カメラと目が合わないと不思議を演出します。

視点誘導の方法も様々です。見て欲しいものをキャラが見ている方向に置いたり、光を当てたりすると目立ちます。窓枠やその他物などで囲いを作り、中に見て欲しいものを置くのもありです。(ただし、四角形の中に物を入れるのは不安感を煽る手法でもあります)

先ほどの四角の他に、画面を傾けたり(Dutch angle)、重要なものの一部をあえて画面外へやることでも不安感を演出できます。未知や不安定は怖いものです。

画面上の適当な三角形の領域に見て欲しいものを収める構図は躍動感を与えます。(丸の場合は安定感を出します) 広く知られていながら、常に強力な構図です。*三角構図*
同様に、画面を3×3分割し、その交点上 or 線上に見て欲しいものを置く(≒ド真ん中を避ける)のも魅力的です。*三分割法*

広告の文脈では、人間は左上→右下で視点を動かす癖があるので、これを意識した配置にするのがおススメです。街中の広告でも、見出しが左上に書いてあることが多いかと思います。(縦書きの場合右上→左下)

当たり前に聞こえるかもしれませんが、大きいものは目立ちます。文字や画像に大小をつけるということは優先順位を定義することであり、ユーザーはどれから見れば良いのかが分かります。逆に大小がないとユーザーにストレスがかかり、読まれません。動画やゲームでもそうです。ボスの登場時はボスにカメラを寄せて強敵感を出しますし、エフェクトが派手で大きいと印象に残ります。

音響

金銭的理由からフリー音源を使いがちな趣味クリエイターには辛いことですが、SEとBGMはそのコンテンツの世界観の半分を決定します。神ゲーと言われるインディーゲームのほとんどはBGMやSEに信じられないほどの情熱を注いでいます。

詳しくは触れませんが、当然ながら、音楽は強烈な世界観を持ちます。調や進行だけでなく、音源やリバーブですら世界観を演出します。SEもまた世界観を持ちます。

音楽と絵の世界観は、不気味さを演出するのでない限りは合わせるべきです。が、これがなかなか難しい。特定の世界観を持たない演出を多用すれば音楽に合いはしますが、個性が潰れます。DTMを嗜む御仁や絵の描ける御仁は、自分の手の届かない、素材を使うしかない領域を先に作り、その世界観に合わせて柔軟に制作をしてみてはいかがでしょう。

しめ

コンテンツ内容とエフェクト、音楽と絵のように、複数の要素間で世界観を共有するのは非常に難しいことです。ディレクターの大事な役割の一つは、世界観を開発メンバーと共有し調節することなのでしょう。ここがアマチュアとプロの境界であり、マルチクリエイターの強みでもあるかと思います。

さいごに、細かい設定を練った末に出てくる些細なこだわりはオタクの心をくすぐる神演出になるものです。裏の設定を練りましょう。舞台裏を、世界を想像しましょう。

OUCC Advent Calender 2021 次回は izumi104 さんです!