【GameMaker Studio 2】サブスクしたのに反映されない?原因と解決策を解説

導入

GameMaker Studio 2では、WindowsやMas OS、Androidなど外部向けにコンパイルする際、自身のアカウントでサブスクリプションする必要があります。

大抵の場合、サブスクリプションが完了したあと、GameMaker Studioを再度開くと、直ぐに外部向けのコンパイルができるようになります。…しかし、自分の場合、同じ手順を行ってもサブスクが反映されませんでした。

最近(2021/8)になって、GameMaker Studio 2の購入システムが大きく変化したこともあり、昔のエラー情報を頼ることはできませんでした。また、GameMaker Communityに相談しても原因を突き止めることはできませんでした。

解決は困難を極めましたが、カスタマーサポートが遂に原因を突き止めてくれました。

原因を探すのが難しいにも関わらず、原因は多くの人にも当てはまる罠だった(コミュニティフォーラムに同じ問題を抱えていた人がいた)ので、これは絶対に共有すべきだと思い、この記事を書きました。

サブスクが反映されたか確かめる方法

自分が制作したゲームプロジェクトを開き、右上を見ます。「Test | Local | VM | Default | Default」などと書いてあると思いますが、一番左にある「Test」が「どのプラットフォームに向けてコンパイルするか」を表しています。

プラットフォームに「Test」があればサブスクは反映されておらず、逆に「Windows」や「Mac OS」、「Android」などがあればサブスクは反映されています。

解決策①

「File > Log out」を選択してログアウトし、そのあと再びログインする。

GameMakerを開いたままサブスクをした場合、サブスクの更新が行われていない恐れがある為です。

このサイトに同じことが書いてあります。

https://help.yoyogames.com/hc/en-us/articles/115001219911-How-To-Update-Your-License-To-See-Your-New-Purchase

解決策②

YoyoAccountの2段階認証を解除する。

これは私が陥っていた罠です。2段階認証を設定していると、サブスクが反映されなくなります。2段階認証を再設定すると、また使えなくなるので、2段階認証はバグが解消されるまでオフにしていた方がよさそうです。

解決策③

セキュリティがサブスクの更新を阻害している可能性があります。

https://help.yoyogames.com/hc/en-us/articles/360022953052-User-Permissions-and-Internet-Access-Required-by-GMS2

このサイトからいくつか分かりやすい例を挙げると、

  • ファイアーウォールが悪さをしている
  • ポート80と443が開いていない
  • クラウドのファイル同期によってファイルがロックされている
  • インターネットに繋がっていない
  • ファイルウォッチャーの不具合

解決策④

「他人を頼る」。筆者もこれによって解決することができました。

ゲームメーカーコミュニティーフォーラムを利用する。

アカウントを作成し、質問を投稿すると、皆が集まって解決策を提案してくれます。

https://forum.yoyogames.com/index.php

カスタマーサポートを利用する。

YoyoAccountにログインしてから以下のリンクを開いてください。開いたら、問題のカテゴリーを入力し、その問題が「すでに報告された問題」に含まれていないなら、「I STILL NEED TO REPORT A BUG」をクリック。その後、必要事項を記入。すると、アカウントのメールアドレスに「整理券が割り振られたので、問題の内容をメールに書いて送って下さい」という内容のメールが届きます。書いたメールを送ると、数時間後にカスタマーサポートが返信してくれます。私は最大で9時間待たされたので、中々返信が来なくてもめげないようにしましょう。

https://accounts.yoyogames.com/contact-us

【GameMaker Studio 2】直線と最初に衝突する物体を取得する

導入

collision_lineは(x1, y1)と(x2, y2)を結ぶ直線と衝突する物体のIDを返してくれますが、(x1, y1)に最も近い物体のIDを返すわけではありません。

「視点」の概念を導入するとき、(x1, y1)に最も近い物体のIDを返してくれたら便利です。悩んでいる人の為にも、その関数を作ることにしました。

※海外の人が既に同じ関数を作っていましたが、バージョンが異なっているし、コードが長めだったので、新規に作ることにしました。

コード

以下のコードを、「スクリプト」に突っ込んでおけば動きます。

(x1, y1)と(x2, y2)を結ぶ直線上にある全てのobjの内、(x1, y1)に最も近いobjのインスタンスIDを返します。

function collision_line_first(x1, y1, x2, y2, obj)
{
	var list_ = ds_list_create();
	
	collision_line_list(x1, y1, x2, y2, obj, false, true, list_, true);
	if (ds_list_size(list_) >= 1)
	{
		list_0 = list_[| 0];
		ds_list_destroy(list_)
		return list_0;
		
	}
	ds_list_destroy(list_);
	return noone;
}

※データリストがインスタンスであることに注意

使わなくなったds_listは自動的に捨てられるわけではないので、ds_list_createをしたあと、ds_list_destroyで必ずインスタンスを捨てる必要があります。

自分はその失敗をしてメモリを一瞬で喰われました…。

【GameMaker Studio 2】親オブジェクトの変数や関数を子オブジェクトで継承する方法

導入

オブジェクトの親オブジェクトを設定したとき、子オブジェクトの「Create」や「Step」は親オブジェクトと同じものに設定されます。

子オブジェクトの「Create」や「Step」を新たに作成すると、親オブジェクトの「Create」や「Step」は消えてしまい、変数や関数を継承できません。

じゃあどうすれば良いか?…その答えが見つかったので、それを共有したいと思います。

前提として

オブジェクトの「Parent」という欄でオブジェクトの親オブジェクトを設定することができます。

方法①(関数と変数を継承)

例えば「Create」に書かれている関数を継承したい場合、子オブジェクトに新しく「Create」を作り、その一行目に以下のコードを挿入する。

// 子オブジェクトの「Create」
event_perform_object(object_get_parent(object_index), ev_create, 0);

このコードは、親オブジェクトの「Create」を呼ぶコードです。このコードの下に処理を書いていけば、任意の変数や関数を変更することができます。

また、親オブジェクトの「Step」を呼びたいときは、ev_createをev_stepに変更すると良いです。

方法②(変数のみを継承)

親オブジェクトを開き、「VariableDefinition」を開きます。そして、「Name」 に変数の名前、「Type」に変数の型、「Default」に初期値を入れます。

次に、子オブジェクトの「VariableDefinition」を開き、変数の右にある「鉛筆マーク」をクリックすると、変数はオーバーライドされます。このとき、変数を初期値を独自に変更できるようになります。

また、オーバーライドを解除したいときは同じ場所を再度クリックすると良いです。

【Quaver】初心者の為の基本操作まとめ

導入

Quaverという音ゲーの基本操作を解説します。

目次

曲のダウンロード

一番左上にあるメニューの「MAPS」というところをクリックすると、公開されている曲の一覧を見ることができます。

引きたい曲を2回クリックすると、曲のダウンロードが始まります。その後、「HOME」→「SINGLE PLAYER」を選択するとその曲を弾くことができます。

演奏設定

画面下のメニューにある「MODIFIERS」をクリックすると、曲の演奏設定を開くことができます。

SPEEDは0.05倍刻みに0.5倍から2倍まで曲の速度を変更することができます。(太鼓の達人などの倍速と違い、譜面の速度だけでなく、曲の速度も変更されます)

JUDGEMENT WINDOWSノーツの判定の範囲を変更できます。(ただし、判定を「Standard」以外にすると、ランクスコアの提出ができなくなります)

AUTO PLAYをONにすると、自動演奏してくれます。

NO FAILをONにすると、曲の途中でHealthが0になっても、曲が中断されなくなります。(Quaverではノーツを叩き損ねるとHealthが減少し、0になると曲が中断されるというシステムになっています)

INVERSEは空白をノーツにして、ノーツを空白にします。

RANDAMIZEはノーツの位置がランダムで横に移動します。

曲のオフセット調整

曲を演奏し終えたあと、左下のメニューのFIX OFFSETをクリックして曲のオフセットを調節することができます。直前に自分がプレイした演奏に基づいて、オフセットを自動で調節してくれます。

「+5ms」は「ノーツの流れてくるタイミングを5ミリ秒遅らす」、「-5ms」は「ノーツの流れてくるタイミング5ミリ秒早める」という意味です。

キー設定

OPTIONS」→「INPUT」からどのキーでノーツを叩くかを設定することができます。

【Unity】Cinemachineのカメラの向きをスクリプトで取得する方法

導入

CinemachineVirtualCameraの垂直方向の向き(VericalAxis.Value)を

this.gameObject.GetComponent<CinemachineVirtualCamera>().Aim.VerticalAxis.Value

で取得しようとしたところ、「CinemachineVirtualCameraにはAimという名前のプロパティはありません」というエラーが発生。

じゃあどうすれば取得できるのか、Unity公式リファレンスを当たったところ、なんとか正答に到達。その正答にたどり着く作業は意外と大変だったので、ここで共有しておこうと思います。

コード

これがCinemchineVirtualCameraの垂直方向の角度の値を取得するのに必要なコードです。

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

public class LESSON : MonoBehaviour
{
    CinemachineVirtualCamera camera;

    // Start is called before the first frame update
    void Start()
    {
        camera = this.gameObject.GetComponent<CinemachineVirtualCamera>();
        
    }

    public float GetVerticalAngle()
    {
        return camera.GetCinemachineComponent(CinemachineCore.Stage.Aim).GetComponent<CinemachinePOV>().m_VerticalAxis.Value;
    }
 
}

補足

GetCinemachineComponent とは

定義は

public CinemachineComponentBase GetCinemachineComponent(CinemachineCore.Stage stage)

「CinemachineCore.Stage」に応じた「CinemachineComponentBase」を返します。

CinemachineCore.Stage とは

CinemachineVirtualCameraコンポーネントにある、「Aim」「Body」「Noise」などを含む列挙型メンバーです。

CinemachinePOV とは

CinemachineComponentBaseの継承クラスの一つ。Aimの項目を「POV」に設定したときに継承されます。

水平方向の場合

m_VerticalAxisのところをm_HorizontalAxisに変えればOKです。

参考文献

Unity公式ドキュメント – ChinemachineCore.Stage

Unity公式ドキュメント – CinemachinePOV

Unity公式ドキュメント – CinemachineVirtualCamera

Unity公式ドキュメント – CinemachineComponentBase

【思考力を鍛える論理講座】第一回「隠れた論理」

本講義の目的

本講義の目的は、一般社会の議論で扱われる論理の質を高めることです。一般社会に少しでもより洗練された論理が広まってほしいという想いからも来ています。

「隠れた論理」とは

AC間に因果関係はなく、AB間、BC間に因果関係があるとする。このとき、「AならばC」という事実に対するAB間やBC間の因果関係を「隠れた論理」と呼ぶ。

これだけでは分かりにくいので、例を用いて説明します。以下の例では、「隠れた論理が存在するなら」という前提の下、考え得る隠れた論理の内の一つを紹介しています。

「早起きな人の6割は、健康である」

これは、「早起き」自体が直接「健康」を導くのではない。隠れた論理が存在するなら、「早起きな人は、生活習慣が良い場合が多く」、「生活習慣が良いから、健康である」。「早起き」自体に健康作用がある訳ではなく、「早起き」によって、「早寝」が促進され、「生活習慣」が改善されるというような場合になる確率が高いから、この事実が成立している。

「なぜナビ大学に入った人の8割は、染色体がXXである」

これは非常に分かりやすい例である。「なぜナビ大学に入ることで、高い確率で染色体がXXになる」わけではない。そりゃ当たり前である。なぜナビ大学は入学するだけで性転換させられる大学ではない。隠れた論理を補うと、「なぜナビ大学に入学した人の8割は女性であり」、「女性は染色体がXXである」となるので、この事実が成立する。

「このサプリを飲んだ人は、平均して、平均寿命よりも5歳寿命が長い」

これは怪しい広告文言でも使われそうな巧妙な文である。隠れた論理が存在するなら、「このサプリを飲んだ人は、健康志向の人が多い為、生活習慣が平均よりも良い傾向にあり」、「生活習慣が平均よりも良い人は、平均寿命よりも寿命が長い可能性が高い」から、この事実が成立している。

「なぜナビ湾周辺の土地の購入者の多くは、2年以内に収入が1000万円増えている」

これも少し怪しげな匂いのする文である。隠れた論理が存在するなら、「この土地は高額で、この土地を買う余裕があるのは大富豪の中の上位層のみであり」、「この高額な土地を買えるだけの金銭を有する富豪は、相当なやり手で、平均して毎年800万の収入が増え続けている」ので、この事実が成立するのである。その為、「高確率で2年以内に収入を1000万円増やす」為の投資として、貧乏人がお金をかき集めてその土地を購入したとしても、収入には何の変化もない。

注意

先の例で、「隠れた論理が存在するなら」とわざわざ書いているのは、隠れた論理が存在しない場合もあるから。

例えば、サプリに本当に寿命を伸ばす成分が入っているとしたら、「サプリを飲むこと」と「平均寿命よりも寿命が長いこと」に因果関係が存在するので、「このサプリを飲んだ人は、平均して、平均寿命よりも5歳寿命が長い」には隠れた論理は存在しない。

また、隠れた論理は複数存在する場合もある。例において「隠れた論理が存在するなら~」のあとに示した「隠れた論理」以外にも考えられる論理はいくつもある。

日常への応用

普段の生活では、主に「Pは大抵Qになる」という表現に注意すれば良い。「Pは大抵Qになる」という表現から、「Qにならない為にPをしない」「Qになる為にPをする」というように派生するのは、必ずしも正しいとはいえないこと」に注意すれば良い。

【Unity】Unityで作ったゲームをandroid端末で実行する手順を紹介

導入

Unityで作ったゲームをandroid端末向けにビルドしようとしたとき、「CommandInvokationFailure: Gradle build failed.」や「UnityEditor.BuildPlayerWindow+BuildMethodException」などのエラーが発生し、ビルドが途中で中断してしまった。その原因を調べては試し、また調べては.試したが、正解は中々見つからなかった。そんなとき、「unityでエクスポートして、それをandroid studioでビルドすれば出来ました。」という文章を発見。自分もその方法を試したところ、見事に成功。

…というわけで、今回は、私もお世話になった、Unityで作ったゲームをandroid端末向けにビルドする方法を紹介します。

目次

今回使うもの

  • android studio
  • android 端末

流れ

①JDK、SDK、NDKをインストール → ②プロジェクトのエクスポート → ③Android studioで開く → ④android端末にビルド

①JDK、SDK、NDKをインストール

Unity2019以降のversionを使う場合

Unity Hub」(Unityのプロジェクト起動時に使うやつ)を開き、「インストール」タブを選択します。すると、Unityのマークと共に今までインストールしたUnityのversionが表示されます(2019.4.19f1 など)。

自分が使いたいUnityのversionを選び、「・・・」が縦に並んでいるボタンを押し、「モジュールを加える」を選択します。すると、モジュールがずらーっと出てくるので、「Android Build Support」と、その下の階層にある「Android SDK & NDK Tools」と「OpenJDK」にチェックを入れ、「次へ」を選択します。

そして、ライセンスの同意にチェックを入れ、「実行」します。すると、ダウンロードが始まるので、終了するまで待てばOKです。

Unity2018以前のversionを使う場合

JDK、SDK、NDKをそれぞれ特定の場所でインストールする必要があります。

>> JDK、SDK、NDKのインストール方法(公式ドキュメント)

②プロジェクトのエクスポート

UnityのProjectを開き、「File」→「Build Settings」を選択し、Build Settingsを開きます。Platformが「Android」になっていなければ、「Android」を選択した後、左下の「Switch Platform」を押します。すると、少し長いロードの後、PlatformがAndroidに切り替わります。

このとき、Platformの右に、「TextureCompression」や「ETC2fallback」など、沢山の項目が出てこない場合は、Unityを一回閉じて、開き直して下さい(①でインストールしたやつが反映されていないので)。

①が反映されていれば、「ExportProject」という項目にチェックを入れ、左下の「Export」を押して下さい。すると、エクスポート先のファイルを選択する画面が出てくるので、パスに日本語が使われていない階層のファイル内にエクスポートして下さい(もしエクスポート先のファイルパスに日本語が含まれている場合は、③でgradleの同期に失敗します。)。

これで、プロジェクトのエクスポートは完了です。

③Android Studioで開く

Android Studioを開き、「ファイル」→「開く」を選択します。そして、先ほどエクスポートしたプロジェクトの、一番上の階層のフォルダを開きます(このとき、先ほどのプロジェクトのエクスポートに成功していれば、プロジェクトのアイコンが「ドロイド君」の絵になっているので探しやすいです)。

プロジェクトを開いたとき、Android Studioで使用しているSDKとプロジェクトで使用しているSDKのパスが異なる場合、「どちらのSDKを使うか」問われることがありますが、プロジェクトの方を選択して下さい。

④android端末にビルド

USBケーブルでandroid端末とパソコンを繋ぎます。

端末側の準備

端末の開発者モードがONになっていない場合は、「設定」→「システム」→「端末情報」を開き、「ビルド番号」を7回タップして、開発者モードをONにします(端末によっては最初から開発者モードがONになっている場合があります)。開発者モードがONであれば、「設定」→「システム」→「開発者向けオプション」を開き、「USBデバッグ」をONにして下さい

ここで、端末とパソコンをUSBケーブルで繋ぎます。

ケーブルで繋ぐとすぐに、端末側に反応が現れます。パソコンからのアクセスを許可していない場合には、端末の方で「許可しますか」と問われることがあるので、許可して下さい。接続の用途を問われた場合は、「充電のみ」ではなく「ファイルを転送」を選択して下さい。

パソコン側の準備

Android Studioの上のツールバーにある「実行」(緑色の三角)を押すと、プロジェクトのビルドが始まります。ビルドが完了したら、端末側でプロジェクトのアプリケーションが作成されます。

これで、目的達成です!おめでとう!

【Unity】スクリプトだけでドット絵を作る方法

導入

ドットゲームの中には、装備によってキャラクターの見た目が変わるものがあります。そのシステムを実装する際、全てのキャラクターの見た目を作っていたらキリがありません。

…もしスクリプトでドット絵を作ることができたら、その膨大とも思える作業量やメモリをコンパクトにできるでしょう。というわけで今回は、スクリプトのみでドット絵を表示させる方法を解説します。

こんな感じで、コードからドットの画像を作ることができます。(完全ランダムにも関わらず、既視感のある画像が何度も生成されているのは、Unityの疑似乱数の性質によるものです)

コード

以下のコードは、動画で使われているコードの内、無駄な部分を全て省いたバージョンです。なので、RawImageをアタッチして、変数riに「RawImageがアタッチされたゲームオブジェクト自身」をアタッチすれば、そのまま使えます。

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

public class BrogIntroduce : MonoBehaviour
{
    public RawImage ri;

    void Start()
    {
        ri = GetComponent<RawImage>();

        SetMarioTexture();
        
    }

    void Update()
    {
        
        
    }

    // ーーーーーーーーーーーーーーーーーーーー
    //    関数一覧
    // ーーーーーーーーーーーーーーーーーーーー

    public string[,] CreateMarioPicture()
    {
        string BBB_ = "#000f";
        string rrr_ = "#f00f";
        string _e_e = "#ff0f";
        string x___ = "#0000";

        string[,] picture_str = new string[,]
        {
            {x___,x___,x___,rrr_,rrr_,rrr_,rrr_,rrr_,x___,x___,x___,x___},
            {x___,x___,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,x___},
            {x___,x___,BBB_,BBB_,BBB_,_e_e,_e_e,BBB_,_e_e,x___,x___,x___},
            {x___,BBB_,_e_e,BBB_,_e_e,_e_e,_e_e,BBB_,_e_e,_e_e,_e_e,x___},
            {x___,BBB_,_e_e,BBB_,BBB_,_e_e,_e_e,_e_e,BBB_,_e_e,_e_e,_e_e},
            {x___,BBB_,BBB_,_e_e,_e_e,_e_e,_e_e,BBB_,BBB_,BBB_,BBB_,x___},
            {x___,x___,x___,_e_e,_e_e,_e_e,_e_e,_e_e,_e_e,_e_e,x___,x___},
            {x___,x___,BBB_,BBB_,rrr_,BBB_,BBB_,BBB_,x___,x___,x___,x___},
            {x___,BBB_,BBB_,BBB_,rrr_,BBB_,BBB_,rrr_,BBB_,BBB_,BBB_,x___},
            {BBB_,BBB_,BBB_,BBB_,rrr_,rrr_,rrr_,rrr_,BBB_,BBB_,BBB_,BBB_},
            {_e_e,_e_e,BBB_,rrr_,_e_e,rrr_,rrr_,_e_e,rrr_,BBB_,_e_e,_e_e},
            {_e_e,_e_e,_e_e,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,_e_e,_e_e,_e_e},
            {_e_e,_e_e,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,rrr_,_e_e,_e_e},
            {x___,x___,rrr_,rrr_,rrr_,x___,x___,rrr_,rrr_,rrr_,_e_e,x___},
            {x___,BBB_,BBB_,BBB_,x___,x___,x___,x___,BBB_,BBB_,BBB_,x___},
            {BBB_,BBB_,BBB_,BBB_,x___,x___,x___,x___,BBB_,BBB_,BBB_,BBB_},
        };
        return picture_str;
    }

    public Texture2D ToTexture2D(string[,] picture_str)
    {
        Texture2D picture = new Texture2D(picture_str.GetLength(1),picture_str.GetLength(0));
        
        for (int x = 0; x < picture_str.GetLength(1); x++)
        {
            for (int y = 0; y < picture_str.GetLength(0); y++)
            {
                string colorCode = picture_str[y,x];
                Color color = default(Color);

                if(ColorUtility.TryParseHtmlString(colorCode, out color))
                {
                    picture.SetPixel(x, picture_str.GetLength(0)-1-y, color);
                }                
            }
        }

        return picture;
    }

    public void SetTexture(Texture2D texture) 
    {
        texture.filterMode = FilterMode.Point;
        texture.Apply();
        ri.texture = texture;
    }

    public void SetMarioTexture()
    {
        string[,] picture_str = CreateMarioPicture();
        Texture2D picture = ToTexture2D(picture_str);
        SetTexture(picture);
    }
}

↓ ちなみにコードの結果はこうなります(右はさっき居た奴です)

コードの説明

大筋

①マリオの絵をカラーコードで描く→②UnityEngine.Texture2Dに置き換える→③ゲームオブジェクトのRawImageのテクスチャを置き換える

①マリオの絵をカラーコードで描く

CreateMarioPictureの部分で担当。

BBB_とか_e_eとか変な名前が付いていますが、「遠くから見たらそれっぽく見える」以外に深い理由はありません。

②UnityEngine.Texture2Dに置き換える

ToTexture2Dの部分で担当。

GetLength(int i)は配列のi次元の要素数を取得する関数。

ColorUtility.TryParseHtmlString(string colorCode, Color outcolor)は、「colorCodeがUnityEngineColorに変換できるか」の判定をbool(真偽)を返し、trueの場合、outcolorに変換後の色を代入する関数。

SetPixel(int x, int y, Color color)は、Texture2Dの座標(x, y)のピクセルの色をcolorに変更する関数。Unityの座標はx座標が→方向、y座標が↑方向になっている一方、コード内のpicture_strはx座標が→方向、y座標が↓方向になっているので、y座標をpicture_str.GetLength(0)-1-yで置換しています。

③ゲームオブジェクトのRawImageのテクスチャを置き換える

SetTextureの部分で担当。

filterModeをPointに変更しているのは、ドットがぼやけないようにする為。

Apply()最も重要な関数。この関数は、Texture2Dの変更内容を適用する関数。これが無ければ、変更が適用されないので、灰色の画像が現れます。

補足

Textureの画像はピクセル数が増えても、大きさが変わらないので、大きさを不変にするか、大きさを変えるコードを作っておいた方が良いです。

また、作ったピクセルを動かしたい場合は、UIのRawImageではなく、ゲームオブジェクトにRawImageをアタッチして下さい。

Q&A

Q1. SpriteRendererのSprite.textureを使用せず、RawImage.textureを使用しているのは何故?

A1. SpriteRendererのSprite.textureは読み取り専用だからです。

Q2. ピクセルが表示されない。

A2. テクスチャを表示するにはキャンバスが必要なので、キャンバスの階層の下に移動させて下さい。

【Unity】「ドット絵がぼやける」対処法を紹介

導入

spriteのぼやけを直すときは、素材となる画像の設定をいじれば良かったが、コードで作った(素材となる画像が存在しない)textureのぼやけを直すときは…あれ?どこをいじれば良いんだろう…。

――というわけで「texture ぼやける」と検索。

しかし、解決策が出てこない…。仕方なくUnityの公式ドキュメントで検索したところ、使えそうなコードを発見!

というわけで、使えそうなコードを見つけたので、Unityドット勢には是非知っておいてほしいコードを共有したいと思います。

コード

やっていることは、コードを使ってtextureのfilterModeをPointに変えているだけ。

テクスチャのぼやけを消したい場合

// どのtextureに対して行うか選ぶ
// (例1)
Texture texture = GetComponent<RawImage>().texture;
// (例2)
Texture texture = GetComponent<Renderer>().material.mainTexture;

// 今回紹介するコード(フィルターモードをpointに変更する)
texture.filterMode = FilterMode.Point;

スプライトのぼやけを消したい場合

スプライトのtextureに対して、さっきの処理をするだけです。

// どのspriteに対して行うか選ぶ
// (例1)
Texture texture = GetComponent<Renderer>().sprite.texture;

// さっきと同じ
texture.filterMode = FilterMode.Point;

いつ使うの?

冒頭でも触れましたが、「いつ使うか?」と聞かれたら、コード内で作ったtextureのfilterModeをPointにしたいときです。それか「ゲームの途中でfilterModeを変えるとき」とか(『Evoland』っぽいゲームを作りたいなら使うかも)。

あと、なぜコード内でtextureを作っているかといえば、「2DObjectの4方向から見たimageを作る手間を省くため」です。

↓ 実際に使う場面はこのような場面です。

https://nazenavi.com/2021/02/24/%e3%80%90unity%e3%80%91%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0%e3%81%ae%e3%81%bf%e3%81%a7%e3%83%89%e3%83%83%e3%83%88%e7%b5%b5%e3%82%92%e8%a1%a8%e7%a4%ba%e3%81%95%e3%81%9b%e3%82%8b%e6%96%b9/

参考文献

今回の参考文献は冒頭でも触れた通り、「Unityの公式ドキュメント(2021.1)」>「Filter Mode」

Unity公式ドキュメント – Filter Mode

【ヴィーガン必見】動物性食品を食べないとどうなるか?を解説

目次

導入

誰しもヴィーガンという単語を一度でも目にしたことがあるのではないでしょうか。そして大抵の場合、そこには白熱した議論が付属します。「動物が可哀そう」と主張する人もいれば、「生きる為には欠かせない」と主張する人もいて、…「ヴィーガンの食事は普通の食事よりも健康的だ」と主張する人もいれば、「必要な栄養素が足りなくなる」と指摘する人もいます。

では、実際のところヴィーガンの食事は健康面で問題はあるのでしょうか。科学的な視点で考えていこうと思います。

ヴィーガンとは?よくある誤解

まず、ヴィーガンについての語が曖昧なので、この記事で誤解を与えないように、一応、ヴィーガンについての定義をおさらいしようと思います。

veganとは、『研究社 医学英和辞典第2版』によると、「完全菜食主義者、超純粋派ベジタリアン」のことであり、『栄養・生化学辞典 普及版』によると、「卵と魚さえも摂取しない完全菜食主義者」のことを指しています。※1

しかし、一部の地域では「クラゲ」と「卵」を食べても良いという「ゆるいヴィーガン」が存在していたり、週一で活動する「ゆるいヴィーガン」も存在しています。

つまり、同一の「ヴィーガン」であっても、「完全菜食主義者」と「菜食主義者の一種」の両方の意味が混在していることに気をつけなければなりません。更にいえば、「食事」だけ制限する「ヴィーガン」(訳:完全菜食主義者)と、「食事」以外も制限する「ヴィーガン」(訳:脱搾取主義者)が混在していることにも注意しなければなりません。

そもそも「ヴィーガン」は「ヴィーガニズム」から来た言葉でありそうですが、英国ビーガン協会によれば、「Veganisimとは、可能な限り食べ物・衣服・その他の目的のために、あらゆる形態の動物への残虐行為、動物の搾取を取り入れないようにする生き方」と定義されている為、今日の文脈では、「ヴィーガン=ヴィーガニズムを実践する人」が誤りになるケースが多いことにも、注意せねばなりません。

今回の私の記事は、正確にいえば、「ヴィーガン」(訳:完全菜食主義)の方向けの記事になっていますので、よろしくお願いします。

注意① 必須アミノ酸の不足(注意度:中)

必須アミノ酸は、肉などの動物性食品を食べればすぐに補えますが、野菜ではそうはいかないのでしょうか。それについて実際の数値を用いて考えたいと思います。

アミノ酸がどのように含まれているか、を調べる指標として「アミノ酸スコア」があげられます。「アミノ酸スコア」は、「必須アミノ酸のバランス」を表しており、一つでも欠けたら意味が失われてしまう必須タンパク質の性質に沿った指標になっています(詳しくは補足を参照)。肉も大豆も同様にアミノ酸スコアは100なのでともに良質なタンパクですが、実際の含有量が分からなければ、必要なタンパク質が摂取できているとはいえないので、いくつかの食材のタンパク質の含有量を載せておきます。

100gあたりのタンパク質含有量(植物性)※2

  • 若鳥、もも、皮つき、焼き・・・25g
  • 牛肉、サーロイン、脂身付き・・・17g
  • 豚肉、ばら、脂身付き・・・14g

100gあたりのタンパク質含有量(動物性)※2

  • 大豆、乾燥・・・34g
  • 大豆、ゆで・・・16g
  • 納豆・・・17g
  • 小豆、ゆで・・・9g
  • えんどう豆、ゆで・・・9.2g
  • そら豆、乾燥・・・26g
  • そら豆、ゆで・・・11g
  • アスパラガス、ゆで・・・2.6g
  • ブロッコリー、ゆで・・・3.5g
  • 枝豆、ゆで・・・12g
  • 芽キャベツ・・・6g
  • とうもろこし、生・・・3.6g(アミノ酸スコア:70)
  • そば、ゆで・・・4.8g(小麦粉の量に依る)(アミノ酸スコア:90)
  • アボカド・・・2.5g(アミノ酸バランス◎)
  • バナナ・・・1.1g(アミノ酸スコア:60)
  • 米・・・6.8g(アミノ酸スコア:60)

タンパク質の一日に必要な摂取量は、成人男性であれば60~65g、成人女性であれば55~60gなので、「ご飯200g、納豆50g」(※米はリジンが不足している為、アミノ酸スコアは高くないが、納豆はリジンが豊富なので組み合わせるとアミノ酸スコアは高くなる)を3食食べるだけで、大体摂取量には届くということになります。つまり、「必須アミノ酸」という観点でいえば、「完全菜食」は問題ないといえるかもしれません。

注意② アラキドン酸の不足(注意度:極めて低)

アラキドン酸は、野菜にはほとんど含まれていません。文部科学省の食品成分データベース※2で調べたところ、野菜では、「にんじん」「ほうれん草」「かいわれ大根」、きのこ類では「しいたけ」、豆類では「豆腐」、穀類では「もろこし」などに最も多く含まれていますが、いずれも100gあたり2mg程度です。一方、一般に食べられる豚肉や鶏肉では、100gあたり100mgを超える部位が数多く存在します(300㎎を超えるものも存在する)。

アラキドン酸は、野菜や豆では殆ど摂取できないことが分かります。

そして、ここで重要なのは、アルツハイマーの患者さんや高齢者には「アラキドン酸」の量が少ない傾向にあり、「アラキドン酸」を摂取することが「認知症予防」につながるともいわれていることです。つまり、「アラキドン酸」を摂取しないことが、これらの症状を招くかもしれないということです。

しかし、そこまで心配しなくても良いかもしれません。

アラキドン酸は野菜に殆ど含まれませんが、「リノール酸→γ-リノレン酸→アラキドン酸」というように体内で合成することができる為、リノール酸やγ-リノレン酸を摂取することで補うことができます。

γ-リノレン酸は野菜には殆ど含まれていませんが、リノール酸は肉だけでなく、大豆、枝豆、アボカド、ぶなしめじ、ニンジンなどの多くの食品に含まれている為、「リノール酸→γ-リノレン酸→アラキドン酸」の合成の速度は定かではありませんが、それが適切な速度ならば、「アラキドン酸」を補うことができるといえます。

結論

「完全菜食」はあまり問題はないといえるかもしれません。しかし、「完全菜食」の場合、必要なタンパク質を摂取する為には、毎日、肉にも劣らない量の大豆を摂ることが求められます。その為、大豆が好きなら問題はありませんが、単に健康の為に「完全菜食」をしているなら、大豆食品を多く摂ることに抵抗があったり、ストレスを感じる場合、逆効果になりかねないことに注意しなくてはなりません。また、肉はかなり上質なタンパク質ですから、例え「一般的な食事」よりも「ヴィーガン食」の方が健康的であったとしても、「ヴィーガン食」よりも「ヴィーガン食」+「動物性食品」の方が、低コストで済む上により栄養価が高くなる場合が多いということにも注意しておかなければなりません。

補足

「完全菜食でも大丈夫」という文脈の中で、「野菜のアミノ酸スコアが高いこと」があげられる場合がありますが、それには注意が必要です。「アミノ酸スコア」は、「タンパク質を構成する窒素1g あたりに占める各必須アミノ酸のmg 数で表され、FAOやWHO等による合同委員会が基準としたアミノ酸評点パターンに対する割合」で算出されます※3。つまり、アミノ酸バランスの良さを表しているだけであって、実際の含有量は考慮されていないということです。例えば、ニンジン、キャベツ、ほうれん草のアミノ酸スコア55、53、50に対して、キュウリのアミノ酸スコアは66になっています。その為、アミノ酸スコアをアミノ酸摂取の文脈で用いるときは、アミノ酸の含有量と併せて用いる必要があることに注意しなければなりません。

引用

※1 Wikipedia「ヴィーガニズム」

※2 食品成分データべース – 文部科学省

※3 Wikipedia「アミノ酸スコア」