Unity C# 変数と型の使い方 宣言や代入・型変換について | Unity入門の森 ゲームの作り方

Unity C# 変数と型の使い方 宣言や代入・型変換について

変数には型と名前が必要になるの画像 Unity C#入門講座
変数を使う時には一緒に型と名前をつける必要がある。


Unity入門の森オリジナル本格ゲーム制作講座はこちら
11種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

前回はコンパイルエラーとその対処法について解説しました。

前回の記事:

Unity C#のコンパイルエラーの種類と対処法について
前回ははじめてのUnity C#プログラミングに挑戦しましたね。 前回の記事↓ プログラミングではコンパイルエラーが付き物です。 コンパイルエラーはスクリプトの書き方が間違っていることを私たちに教えてくれる機能となります。コンパイルエラーが...

今回の記事ではC#の文法についてみていきましょう!

プログラミングにおいて最重要な変数と型についてしっかり解説しています。

型については、初心者さんはいきなり全部を理解しようと思うと挫折すると思います。

型の解説からはある程度Unity C#に慣れながら理解していけばOKです。


【Line登録者限定のプレゼントもあるよ!】

変数とは

変数とはアプリケーション上のデータ、値を表すものになります。

変数の宣言と変数の初期化

変数には型と名前が必要になるの画像

変数を使う時には一緒に型と名前をつける必要がある。

それでは変数の使い方について解説していきたいと思います。

変数を使用する際には必ず、変数の宣言、もしくは初期化を行う必要があります。

変数の宣言の書き方は二つに分かれます(コードではなく日本語で書くと以下の形)。

  • 変数の宣言の場合:<型名> <変数名>; 
  • 変数の宣言+初期化の場合:<型名> <変数名> = <初期値>;

前者では、 型が<型名>で名前が<変数名>という変数があることを宣言しています。

後者では、/型が<型名>で名前が<変数名>という変数があることを宣言して、<初期値>を値として設定しています。

最後の;(セミコロン)忘れないようにして下さい。忘れますとコンパイルエラーが発生します。

変数の使い方の例

それでは実際にスクリプト上で変数がどのように使われているのか見ていきましょう。

ソースコード上の至る所にvarから始まる行が見受けられると思いますが、その部分が変数を宣言または初期化している部分になります。

varは上で説明した型名の部分に当てはまります

  • 変数の宣言:<型名> <変数名>;
  • 変数の初期化:<型名> <変数名> = <初期値>;

varの後にa_1b2などが続いていますが、その部分が変数名となります。つまり、上のサンプルコードではa」と「_1」、「b2」といった3つの変数が存在しています。

変数名について

変数名に使える文字の画像

変数名には頭文字にa-z,A-Z,_から始め、その後にはa-z,A-Z,0-9,_を続けることができる

変数名は頭文字がアルファベットまたは_で始まり、その後にアルファベットまたは数字、_が続く文字列(ワード、テキスト)にする必要があります。

そのため、サンプルコードの中にあるNGケースとして、11*{といった変数名はつけることができません。11は頭文字が数値から始まっており*{は使用できる文字以外のものが使われているので、このような変数名がある時はC#コンパイラーはコンパイルエラーとして扱います。

また、C#が使用しているキーワード(usingvarなどの単語)はそのまま変数名には使用できません(※)。

※一応回避策がC#では用意されていて、変数名にキーワードを使用したいときは、@を先頭につけることで使用できます。が、特に理由がない限り使用しないようにしましょう。

var @using = 10;

var @var = 12;

varキーワードについて(型推論)

varを使うと型名を省略することができるの画像

varを使うと型名を省略することができる。その時には必ず初期値も必要になる。

少し手順が前後するのですが、変数の型について説明する前に先にvarキーワードについて解説します。

varキーワードは変数の初期化の時に使用できるキーワードで、変数の型名を省略することができます。

その際、初期値の内容から変数の型をC#コンパイラーが推測して自動的に設定してくれます。この機能のことをプログラミングの世界では型推論と呼ばれています。

そのため変数の初期化の時にだけしか使うことができません。また、まだ解説しておりませんがメンバ変数の宣言にも使用できません。

変数の型とまだ解説していないものがでてきて困惑されると思いますが、変数の型はプログラミングの世界において重要な意味合いを持つものになりますので、しっかり理解していただきたい要素になります。

この後すぐに追加の説明をしていきますが、今は変数には型というものが必要で、型名を省略したい時はvarが使える場合があると覚えてください。

変数の型とは (やや高度な内容も含むので焦らずに)

型は重要の画像

型をつけることで分類分けのようなもので、変数がどのようなものなのかがわかるようになる。

変数の型とは「変数がどのようなものか」を説明するためのものです。

C#では変数を使用する時はどこかでその変数の型を指定する必要があります。このことを専門用語で静的型付け言語と言います。(プログラミング言語の中には型を書く必要がないものがありますが、それはC#でいうところのvarを毎回使用していることと同じ意味になります。)

そのため変数を使用する際にはC#にはどのような型があるのかを必ず知っている必要がありますので、それについて説明していきます。

変数の型には次の種類があります。

  • C#が提供している基本型
  • 基本型を組み合わせてできたclass型やstruct型

C#で使用できる変数の型について

C#の型は大きく分けて基本型(Build-in Type、組み込み型)とユーザー定義型の二つの種類に分類されます。

基本型はC#が提供している型の最小構成単位になります。基本型はそれ以上分割できません。

その反対にユーザー定義型は基本型を組み合わせた型になります。

また、型は値型参照型にも大きく分類されます。

値型と参照型の違いにつきましては参照型のところで説明していますのでそちらを参照して下さい。

C#の値型に分類される基本型には主に次のものがあります。

  • int: 整数型
  • float: 浮動小数点型(実数)
  • char: 文字型
  • bool: 論理型
  • uint: 符号なし整数型(正の数のみ)
  • byte: 符号なし整数型(正の数のみ)
  • double: 浮動小数点型(実数)
  • decimal: 浮動小数点型(実数) 
  • enum型:System.Enumクラスを継承した型。値型として扱われる。
  • struct型:classとして扱える値型

C#の参照型に分類される基本型には主に次のものがあります。また、クラスとして定義されたユーザー定義型はすべて参照型として扱われます。

  • string:文字列型
  • object:オブジェクト型
  • dynamic:実行時型チェック型(Unityでは使用できません。)
  • ポインタ型:メモリへのアドレスを表す型。複数ある。
  • delegate・event型:メソッドをデータとして扱える型

整数型

整数型は整数を表す基本型で次のものがC#では定義されています。byte、sbyte型のサイズである8ビットを最小サイズとして、その倍数のビット数を持ちます。

【符号つき整数型(正と負の数を表現できる整数型)】

  • sbyte: 8ビット数の整数型。-2の7乗から2の7乗-1までの範囲を取る。
  • short:16ビット数の整数型。-2の15乗から2の15乗-1までの範囲を取る。
  • int:32ビット数の整数型。-2の31乗から2の31乗-1までの範囲を取る。
  • long:64ビット数の整数型。-2の63乗から2の63乗-1までの範囲を取る。

【符号なし整数型(正の数のみ表現できる整数型)】

  • byte: 8ビット数の整数型。0から2の8乗-1までの範囲を取る。
  • ushort:16ビット数の整数型。0から2の16乗-1までの範囲を取る。
  • uint:32ビット数の整数型。0から2の32乗-1までの範囲を取る。
  • ulong:64ビット数の整数型。0から2の64乗-1までの範囲を取る。

なお、プログラミングの世界では値が取れる範囲に制限があり、これはコンピュータのハードウェア側の都合によるものです。また、値の範囲の限界は基本的に2の乗数をとりますが、こちらもハードウェアによるものになります。

また、符号ありなしといった負の数を取るか取らないかでも型分けされています。

プログラミングでは整数を表す時にはint型がよく利用されていますので、基本的にはint型で大丈夫でしょう。

また、longを超えるようなとてつもなく大きい数値を扱いたいときはUnityでは BigInteger型が用意されています(実際にBigIntegerを使ってゲームを作っている記事はこちら)。

ビット数(bit)とバイト(byte)について

整数型の説明でビット数という単語が出てきました。ビット数(bit)はコンピュータのメモリ上のサイズを表す単位になります。

また、8ビットで1バイト(byte)になります。バイトのサイズは2の乗数単位に区切られています。

現在のコンピュータでは8ビットを最小データサイズとして扱われることが多いです。

ビット数はアセンブリ(機械語)などのコンピュータそのものを扱う時に重要になるものになります。

現在ではあまりビット数を意識する必要はないのですが、C#が参考にしたC言語というプログラミング言語はアセンブリ寄りのコンピュータに寄り添った言語として昔から広く使われています。

コンピュータが生まれて間もない時にはアセンブリやC言語しかありませんでした。

アセンブリやC言語を用いたアプリケーション開発はコンピュータの仕組みや都合に合わせて実装する必要があったため、難解な技術が要求され、バグが生まれやすいものでした。

それらの反省を踏まえて、C#やJava、Ruby、Python、Golang、Swiftなど近年製作されたプログラミング言語の大半は人が使いやすくアプリケーションを簡単に製作できるように設計されています。

2進数、16進数表記について

2進数、16進数は数値を2進数では0か1、16進数では0-9、A-F(a-f)で表す数の書き方になります。16進数のアルファベットは大文字、小文字のどちらでも問題はありません。

これらの書き方はコンピュータ上のデータを直接表現するものになります。

また、ビット演算を行う時際には2進数、16進数の方が見やすいためよく使われています。詳しくはビット演算の解説と合わせて行いたいと思います。

浮動小数点型

浮動小数点型は実数(小数点を含む数)を表す基本型で、次のものがC#では定義されています。

【浮動小数点型】

  • float: 32ビット数の整数型。C#上では末尾にfをつけるとfloat型として扱われます。
  • double:64ビット数の整数型。C#上では通常の実数がdouble型として扱われます。
  • decimal:128ビット数の整数型。C#上では末尾にmをつけるとdecimal型として扱われます。

浮動小数点型にも整数型と同じく値が取れる範囲に制限があり、またビット数が小さいものになる程計算精度の問題が大きくなります。(こちらもコンピュータ側の都合によるものです。)

また、浮動小数点型は実数をコンピュータ上で表現するための一つの方法になり、割り当てられたビット数を次の要素に分割しています。

  • 正負を表す符号部
  • 指数の値を表す指数部
  • 値を表す値部

基本的にビット数が大きいほど、指数部と値部が大きく割り当てられており計算精度の問題が小さくなります。

プログラミングの世界における実数の計算には計算誤差の問題がまとわりつくものですが、日常生活範囲の用途での計算ではfloat型を使用することで十分信頼できる計算結果が得られます。基本的にはfloat型を使いましょう。

文字型、文字列型

文字型、文字列型はその名の通り、文字や文章、テキストを表す基本型になります。

  • char型:文字型。一文字を表す。characterという英単語を省略したものになります。
  • string型:文字列型。文章やテキストを表す。複数のchar型の変数の並びになります。

これらの型もコンピュータから見ると数値として扱われています。

数値のままだとどの文字を表しているのかわからないため、コンピュータの世界では文字コードという数値と文字の対応表を使って文字、文章を表現しています。

C#での標準文字コードはUnicodeの一種であるUTF-16になります。

プログラミング言語によって標準の文字コードが異なっていますが、近年ではUTF-8が広く利用されています。(UTF-8もUnicodeの一種であります。)

余談ですが、今後文字コード間の変換が必要になる時が出てくるかもしれませんが、その時C#の標準ライブラリを利用しましょう。

文字の書き方

文字の書き方およびchar型の設定方法は下の通りです。

  • 文字の書き方:'<一文字>'
  • char型の書き方:char <変数名> = '<一文字>';

'はクォーテーションと呼び、文字型を表すときは'で1文字を括って下さい。(初めてこの文字を見た方には入力の仕方がわからないと思いますが、一般的なキーボードには対応するキーが存在していますので探してみて下さい。筆者のキーボードではShiftを押しながら7キーを押すと入力できます。)

基本的に文字はキーボードなどから入力したものをそのまま使用できますが、改行やタブなど一部の文字にはそもそも文字が割り当てられていません。そのような特殊な文字に対応するためプログラミング言語および文字コードにはエスケープシーケンスと呼ばれる書き方が存在しています。

エスケープシーケンスの書き方は先頭に\を付けた後に対応する文字を続けます。具体的には下の通りです。

\<文字>

これだけではイメージし辛いので次にエスケープシーケンスの一部をリストアップします。

  • \n:改行文字
  • \r:行頭に戻る
  • \t:水平タブ
  • \v:垂直タブ
  • \b:ブザー
  • \u:Unicode文字の文字コード。Unicode文字を表す文字コードを16進数の4文字を続ける。
  • \x:UTF-16の文字コード。Unicode文字を表す文字コードを16進数の4文字を続ける。
文字列の書き方

文字列の書き方およびstring型の設定方法は下の通りです。

  • 文字列の書き方:”<文字>..."
  • char型の書き方:string <変数名> = "<文字>...";

"はダブルクォーテーションと呼び、文字型を表すときは"で1文字を括って下さい。(筆者のキーボードではShiftを押しながら2キーを押すと入力できます。)

文字列の中には複数の文字を入力することができます。文字として扱えるものは文字列の中でも使用することが可能となっています。

また、文字列には下の特殊な書き方が存在しています。

  • @”<文字>…” : 入力した文字列そのまま使用したい時に使用する。
  • $”<文字>…” : 書式(Format)付き文字列。変数を文字列の中で使用したい時に使用する。
@”<文字>…”

@"<文字>..."を使用することで<文字>...の中に入力したものをそのまま文字列として表現できます。

通常の文字列の中にエスケープシーケンスの文字(例えば\n)をそのまま書きたい時は\\n\をエスケープする必要がありますが、@"<文字>..."の中だと\nと入力するだけでよくなります。

ファイルパスを直接書きたい時などに使用すると便利な書き方になります。

$”<文字>…”

$"<文字>..."を使用することで<文字>...の中に変数を埋め込むことができます。

変数の埋め込み方は{変数名}{}で変数名を括ります。

また{変数名:<書式>}と書くことで、変数の値を文字列に変換する方法を指定することができるようになります。このような機能を書式(Format、フォーマット)と呼ばれています。

書式の書き方は変数の型によって異なりますので、随時調べてみて下さい。

こちらも手軽に変数を文字列に変換することができるので、C#のとても便利な機能になっています。

論理型

論理型は1か0またはtrue(真)かfalse(偽)を表す型になります。

論理型はアプリの状態を表すフラグとして使用されたり、条件式などアプリの処理を分岐させる部分で使用されています。

参照型

参照型はデータそのものを表すのではなく、使用しているデータの位置を表す型になります。

そのため参照型の変数自体にはデータの実体はなくC#が裏で自動的に参照型が指し示すデータを確保しています。

そのため参照型のサイズは見かけ上全て同じになりますが、それは使用しているデータの場所を表しているためで、実際のデータのサイズは型の定義内容によって異なります。

これはC言語のポインタという機能に近いものですが、C#では一般的にポインタを意識することはありません。ポインタの利用は危険性があり、バグの原因になりやすいものです。

そのためC#ではポインタを直接使用するより安全に参照を活用できるように改良が加えられています。

C#を使用する上で参照型を意識することはあまりないですが、この参照型の性質について理解をしていないと不可解な動作にしか見えない部分がC#には存在していますので、こういうものがC#の裏側にはあることは覚えておくといいでしょう。(特にメソッド周りを理解する時に助かります。)

参照型として扱われる型は次のものがあります。

  • 全てのclass型
  • object型
  • dynamic型(※Unityでは使うことができません。)
  • string型
  • delegate型
  • event型

また、これまで紹介してきたstring型以外の基本型は全て値型としてC#では定義されています。値型の変数は直接データを表しています。

この参照型と値型の違いを理解していると、今後説明するメソッドの引数の受け渡し周りの理解を捗らせることでしょう。

下のサンプルコードは参照型の一例になります。中で型変換というC#の機能を使用しています。

型変換については後ほどこの記事で説明していきます。

ポインタ型

参照型に似たものなのでポインタ型についてもここで触れておきます。

C#にもC言語でいうポインタ型が存在しますが、通常積極的には使用しません。

C#にはunsafeなコードというものがあり、その中ではC言語のようにプログラミングを行えるようになっています。ポインタはその中で利用できます。

また、DLL(動的リンクライブラリ)を利用する時にも使用されます。こちらはunsafeではなくても利用できます。

以上から、直接アセンブリやメモリ操作を行いたいときやアプリ外の機能を利用したい時に使用されるものとなります。

struct型

struct型はclass型のように使用できますが、値型として扱われます。

構造体とも呼ばれます。

使い方としてはこの両者に一見違いはないですが、class型にはできるのにstruct型にはできないことがいくつか存在します。

また、値型と参照型の違いを利用したアプリ実装も存在しています。

一般的なアプリ開発ではclass型の方を使用するだけで十分となります。

enum型

enum型は列挙型ともいい、アプリ上で固定値フラグとして使用したいものを複数まとめて定義したい時に利用されます。

enum型は値型として扱われます。

enum型として定義されたものにはC#側で自動的に値が割り当てられ、int型に型変換することができます。また、こちらから自由な値を指定することも可能です。

別の記事で説明するswitch文などを用いた条件分岐に利用されることが多いです。

直接数字を扱わないことでコードの可読性を高めています(急に出てくるよくわからない数値はマジックナンバーと呼ばれ、プログラムの理解を妨げます)。

delegate型・event型

delegate型およびevent型はメソッドを値・データとして扱うために使用される型になります。

メソッドを値として扱えて何かメリットがあるのかと思われますが、GUIアプリケーションや皆さんが現在見ているブラウザにもたくさん使われている重要なプログラミングの機能になっています。

delegate型とevent型についてはまた別の記事にて解説しますが、以下に簡単な使用例を挙げておきます。

今はdelegate型・event型があることだけ覚えておけば十分です。

型変換(キャスト、Cast)について

型は変換できるの画像

変数の型は変換することができる。変換する時、変換元の変数は何も変わらず、C#によって新しい変数が自動的に生成される。

型変換(キャスト、Cast)とは型を変換することになります。プログラミング中に使用している型を他の型に変換したい場合に使用します。

書き方は次のようになります。変換したい値・変数の前に、括弧で括った変換先の型の名前を書くだけです。

(<型名>)<値または変数>

型変換の原則として、変換元の型と関連がある型にしか変換できません。

基本的に数値型同士の変換継承関係のあるclass型やstruct型なら型変換が可能になります(継承に関しては今はわからなくてOKです)

C#では静的型付け言語なので型変換ができないものを変換したときはコンパイルエラーになります。

ですが、object型やdynamic型などを使用した時はコンパイラーによるエラー検査が行うことができず、アプリを実行するまでエラーが発生しません。

そのようなコードを含んでいる場合、その箇所を実行した時は型の互換性のないものへ無理やり変換したとみなされアプリの実行時エラーとして例外が発生します。

一応、コードを注意深く読むことで発見することはできるのですが、コードを深く読む熟練の技術が必要になるので、基本的にobject型やdynamic型を使うことは避けましょう

文字列型と他の型の相互変換について

型変換に因んで、全ての型はToString()メソッドを使用することで文字列型(string)に変換することができます。

先に$"..."で変数を文字列に変換することができると説明しましたが、その裏側でこのToString()が使用されています。

ToString()では数値などの値型はその値が直接文字列に変換されます。

class型などの場合はその型名が文字列に変換されますが、それはclass型などはその内容が型によって異なるためコンパイラーが自動的に決定することが難しいためです。

型名以外の文字列に変換したいことはよくあるので、C#ではToString()メソッドをオーバーライド(※)するとこちらで決めた文字列に変換することができます。

またもちろん、ToString()でも書式(フォーマット、Format)を指定することができます。

※メソッドのオーバーライドはクラスの継承と関係があるC#の機能になります。

その反対の文字列から他の型に変換する際は、自作するかC#の標準ライブラリを使用する必要がありますが、それらには値型など簡単な型への変換処理しか用意されていません

より高機能で簡単に文字列と型の相互変換を行いたい時は次に説明するシリアライズ機能を利用して下さい。

余談:シリアライズ(Serialze)について

文字列への変換にはToString()以外にシリアライズ(Serialize)と呼ばれるデータを文字列に変換する処理も存在します。

サーバー間通信などアプリの間でデータの受け渡しを行う際にはシリアライズを利用するととても便利なため、C#やUnityではあらかじめ標準ライブラリとして提供されています。

シリアライズの際にはどのように型の内容を文字列として表現するか決める必要があるのですが、それについては既に色々な形式が考案されています。代表的なものとしてはXMLJSON形式などがあります。UnityではJSON形式やYAML形式などが使われています。

ちなみにシリアライズしたものをもとのデータに変換することをデシリアライズ(Deserialize)と呼ばれています。

実際に変数をUnityで使ってみよう

以前と同じだが、スクリプトの構造はより理解できるようになったの動画

実行しても以前と同じだが、スクリプトの内容はより理解できるようになった。

変数の型について長く説明してきました。まだまだ型についての注意点、性質などがあるほどプログラミングの世界で「型」は重要です。

が、ここでは一旦この程度で解説を区切り、実際にUnity上で変数を使っていきます。

以前の記事で既に変数は使用していますが、変数について何も知らなかった時と、変数について知った後で、ソースコードの見え方が変わったかと思います。

スクリプトの作り方がまだわからない方は以前の記事を参照してください。

また、GameObjectにアタッチする時はファイル名と中のクラス名を一致させないといけないので注意して下さい。

以下のサンプルコードをそのまま使用する時はclass Sample : MonoBehaviourと書かれた行のclass名がSampleになっているので、ファイル名をSample.csとしてください。

変数の型について長々と説明しましたが、サンプルコードにはまだ解説していないC#の構文があります。

と言っても算数の足し算的なものなので気にせず書いてみましょう。

まとめ

かなり解説が長くなってしまいましたが、この記事をまとめると次のようになります。

  • C#には変数というものがある
  • 変数を使う前には変数の宣言または変数の初期化を行う必要がある
  • 変数の宣言と初期化には、変数の型と名前が最低限必要になってくる
  • varキーワードを使うと変数の型を省略することができるが、変数の初期化の時だけ使える。
  • 型には基本型(Build-in Type)とユーザー定義型がある。
  • 基本型はC#が提供している型で全て数値を表す。
  • class型とstruct型は基本型を組み合わせてできた型。
  • 型には値型と参照型の2種類ある。
  • 値型は変数自体に値が格納される型。
  • 基本として、整数を使いたい場合はint, 実数を使いたい場合はfloat, 文字列を使いたい場合はstring
  • 参照型はデータの場所についての情報が変数に格納され、実際のデータはC#側で管理される。
  • 「型」はプログラミングの世界ではとても重要なものでかつ奥が深いもの。

それでは、次の記事に行ってみましょう。

次の記事:

Unity C#の演算子の使い方をマスターしよう
今回の記事では演算子について解説していきます。 演算子は簡単に言うと、足し算、掛け算、引き算、割り算などを意味する記号ですね。 プログラミングする上ではこうした四則演算以外でも演算子を利用することがあります。 以前の記事の中でも既にいくつか...

初心者向けUnityC#入門講座に戻る>>



Unity入門の森オリジナル本格ゲーム制作講座はこちら
11種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

コメント

タイトルとURLをコピーしました