【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「アミノ酸スコア」

【Unity】プレイヤーが壁に引っかかる理由とその対処法

導入

プレイヤーを動かす設定はできたが、今度はプレイヤーが壁にくっつくようになってしまった。…そんな人の為に、解決策とその現象が発生する原因を解説します。

以下に紹介するのは2Dでの対処方法ですが、3Dでも応用できるように原因を解説しているので、3Dで困っている方は「原因の解説」を読むことをお勧めします。

▼問題の現場はこんな感じ

解決策

①引っかかりを直したいゲームオブジェクトにRigidBody2DもしくはBoxCollider2Dをアタッチする。

②Project > Asset を開き、左上の「+」を押して「PhysicMaterial2D」を選択する。もしくは、右クリックして、「Create > PhysicMaterial2D」を選択する。今作成したファイルを開き、Frinction、Bouncinessを共に0にする。

③RigidBodyもしくはBoxColliderのMaterialという項目に、「Friction(摩擦)、Bounciness(反発)を両方0にしたもの」をドラッグ&ドロップで設定する。

結果

普通の横スクロールアクションのように、壁に引っかからずにプレイヤーを操作することができています。

原因の解説

原因は、「摩擦(Friction)」です。ある物体が平面に接しているとき、ある物体をその平面上で動かそうとする向きと逆向きに、その物体に対して摩擦力が働きます。そのとき働く力の大きさは、「平面が物体から垂直方向に受ける力の大きさ」×「物体と平面間の摩擦係数」で表されます。

つまり、原因は摩擦力となるわけですが、…Unityでは摩擦力の計算が少し違うことに注意して下さい。Unityでは、2Dならば、「摩擦力の大きさ=PhysicMaterialFrinctionの大きさ」です。より正確にいえば、「Frinctionが0なら摩擦力は0、Frictionが1なら力を加えない限りオブジェクトは動かないような摩擦力がはたらく(中間値はその間)」という感じに定義されています。

そして、デフォルトの設定(None)では、「Friction=0.4、Bounciness=0」である為に、今回の現象が起きるのです。

補足

Unityの摩擦力は、先ほども述べた通り、「摩擦力の大きさ=PhysicMaterialのFrinctionの大きさ」なので、「平面が物体から垂直方向に受ける力の大きさ」には比例しません。従って、物体が重力の向きに垂直に広がる平面上を滑っていたとしても、質量(Mass)に関係なく、Frinctionの値が同じである限り、同じ摩擦力がはたらきます。

2Dでは動摩擦力(Dynamic Friction;物体が動いているときにかかる摩擦力)と静止摩擦力(Static Friction;物体が静止しているときにかかる摩擦力)は同じFrictionで定義されますが、3Dでは個別に設定することができます。

【論理クイズ】真実の記事は何割?

導入

今回は皆さんに論理クイズを出題しようと思います。テーマは「何割が真実の記事か」です。問題は全部で三問あります。よく考えて解いてみてください!

問題①(難易度:簡単)

  • ある人のブログには、100本の記事がある。その中の一本に次のような文章を含んだ記事がある。
  • 「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である。」
  • このとき、この人のブログの記事の内、何%が真実の記事といえるか。
  • ※ただし、全ての記事は、「真実の記事」または「嘘の記事」のいずれか一方であり、「真実の記事」に含まれている全ての文章は、命題ならば必ず「真」であり、「嘘の記事」に含まれている全ての文章は、命題ならば必ず「偽」である

答え

スクロールして答えを見る

スクロールして答えを見る

正解は「0%~99%のいずれか」

これは朝飯前でしょう。

理由を説明すると、「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である」という文章を含んだ記事が真実の記事であるとすると、文字通り、記事全体の内99%が真実の記事ということになります。一方、この文章をふくんだ記事が嘘の記事であるとすると、「ちょうど99%が本当の記事」が嘘にならないといけないので、この場合、99%と100%になることはあり得ません。よって、答えは、「0~99%のいずれか」になります。

問題②(難易度:普通)

  • ある人のブログには、100本の記事がある。その中の99%は次のような文章を含んでいる記事である。
  • 「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である。」
  • また、残りの1%の記事は、次のような文章を含んでいる。
  • 「私のブログの記事100本の内、ちょうど1%が嘘の記事である。」
  • このとき、この人のブログの記事の内、何%が真実の記事といえるか。
  • ※ただし、全ての記事は、「真実の記事」または「嘘の記事」のいずれか一方であり、「本当の記事」に含まれている全ての文章は、命題ならば必ず「真」であり、「嘘の記事」に含まれている全ての文章は、命題ならば必ず「偽」である。

答え

スクロールして答えを見る

スクロールして答えを見る

正解は「0%

理由を説明すると、「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である」という文章を含んだ記事99本全てが真実の記事であると仮定すると、残りの1本の記事が嘘の記事であるということになります。しかし、残りの一本の記事には「私のブログの記事100本の内、ちょうど1%が嘘の記事である。」という文章が含まれているので、この記事だけが嘘の記事になってしまうと、「私のブログの記事100本の内、ちょうど1%が嘘の記事である。」という命題が真になってしまい、この記事が真実の記事であるということになり、矛盾を起こしてしまいます。なので、最初の過程が間違いであるということができます。すると、「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である」という文章を含んだ記事の内、少なくとも1本は嘘の記事であるといえることになります。その99本の内、一つが嘘の記事であると仮定すると、「私のブログの記事100本の内、ちょうど99%が真実(嘘ではない)の記事である」を含んだ全て記事が嘘の記事ということになります。なので、必然的に「私のブログの記事100本の内、ちょうど1%が嘘の記事である。」という文章を含んだ記事も嘘の記事になり、全ての記事が嘘の記事である、という結論が導かれます。

問題③(難易度:普通)

  • ある人のブログには、100本の記事がある。全体の90%は次のような文章を含んでいる記事である。
  • 「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」
  • また、全体の5%は次のような文章を含んでいる記事である。
  • 「全体の記事の中に、嘘の記事がある。」
  • このとき、この人のブログの記事の内、何%が真実の記事といえるか。
  • ※その2つの文章のどちらも含んでいる記事があるかもしれないことに注意せよ。
  • ※ただし、全ての記事は、「真実の記事」または「嘘の記事」のいずれか一方であり、「本当の記事」に含まれている全ての文章は、命題ならば必ず「真」であり、「嘘の記事」に含まれている全ての文章は、命題ならば必ず「偽」である。

答え

スクロールして答えを見る

スクロールして答えを見る

正解は「90%もしくは5~10%

どうでしたか?答えが微妙に違った人は爪が甘いですよ!

理由を説明すると、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含む記事があるので、全ての記事が真実の記事になることはありません。よって、「全体の記事の中に、嘘の記事がある。」という命題は必ず真になり、この文章を含む記事は必ず真実の記事になります。「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含む記事に「全体の記事の中に、嘘の記事がある。」という文章が含まれていたとき、この記事は真実の記事になり、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含まない記事は嘘の記事になります。なので記事全体の90%が本当の記事になります。また、このとき、「全体の記事の中に、嘘の記事がある。」という文章を含む記事は5本とも、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含みます。なぜなら、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含まない記事の中に、「全体の記事の中に、嘘の記事がある。」という文章を含む記事があると、真実の記事の数が90を超えてしまい、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という命題が偽になってしまうからです。逆に、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という命題が偽になる場合、「全体の記事の中に、嘘の記事がある。」という文章を含む記事は5本とも、「私のブログの記事100本の内、ちょうど90%が真実(嘘ではない)の記事である。」という文章を含みません。なので、このとき、全体の90%は嘘の記事であることが確定し、全体の5%は真実の記事であることが確定します。よって、答えは、「90%もしくは5~10%」になります。

最後に

どうでしたか?三問とも正解できた人は、論理が得意といっても良いかもしれません。

また、「ちょっと簡単過ぎて物足りなかった」という人は、コメントで教えてくれると助かります(次の問題制作に生かします!)。

これからも論理クイズを作っていこうと思っているので、また気が向いたときにちょくちょく遊びにきてくれると嬉しいです。