にほたもるのブログ

にほたもるがゲームなどについて気ままに書くブログです。

【Blender 2.8】陰面処理のショートカット

どうも。お久しぶりです。
前回の記事が1年以上前^^; サボってすみません。はい。

さて、今回は、モデリングについてのお話です。
私はBlenderを使っています。このBlenderで、オブジェクトの編集をしていると、オブジェクトに隠れている裏面を編集したくなります。このオブジェクトに隠れている面の処理のことを陰面処理と言ったり言わなかったりするらしいです。

f:id:nihotamor:20190829182941p:plain
さて、この陰面処理、画面上のアイコンからクリックでオンオフを切り替えることができます。これを切り替えて裏面を選択するわけですね。ですがこれ、いちいちアイコンをクリックしていたらマウスを動かしまくってもう大変!ということで、ショートカットキーに設定する方法があります。

Blender 2.7時代で参考にしていたサイトは、こちらです。
blogs.yahoo.co.jp

簡単にまとめると、
設定を開き、「入力」→「3Dビュー」→「メッシュ」を順に開く。
f:id:nihotamor:20190829183413p:plain
一番下の「Add New」をクリックし、noenと書かれているところに「wm.context_toggle」と入力する。
f:id:nihotamor:20190829183616p:plain
右側のキー設定で、登録したいキーを入力する。アトリビュートの欄に、「space_data.use_occlude_geometry」と入力する。
f:id:nihotamor:20190829184654p:plain

これで、登録したキーを押すと陰面処理のオンオフをワンタッチで切り替えるようになるわけです。
f:id:nihotamor:20190829185118g:plain

さて、2.8でも登録しよ~っと。

あれ?登録できんぞ!メッシュの下の方に行ってもAdd Newボタンがないじゃないか!!
f:id:nihotamor:20190829185310p:plain
心配ご無用。Mesh(Global)を開けば下の方に登録ボタンがあります。
f:id:nihotamor:20190829185441p:plain
f:id:nihotamor:20190829185455p:plain

なんだ、そんなことか。全くBlenderちゃん、変わったなら言ってくれればいいのに~。
さて、登録も終わったし早速使ってみよう。

f:id:nihotamor:20190829185626p:plain
は?

何事?!機能が使えないだけではなく、よくわからんエラーログが出たんだけど!!
これは罪じゃ!許されんぞBlender

…というわけにもいかないので、原因究明を。陰面処理用のボタンにマウスオーバーしてみます。
f:id:nihotamor:20190829185832p:plain
f:id:nihotamor:20190829190004p:plain
あれ?よく見てみたら、2.7には

Python: SpaceView3D.use_occlude_geometry
bpy.data.screens["Default"] . . . use_occlude_geometry

2.8には

Python: View3DShading.show_xray
bpy.data.screens["Layout"].shading.show_xray

と書かれている…これはもしや?

アトリビュートの欄に、「space_data.shading.show_xray」と書き込んだら…
いけた!
f:id:nihotamor:20190829190615g:plain

なるほど、バージョンが上がってキーが変わっていたのね。

ちなみに、2.8ではこの機能のことを透過表示というらしいですね。

ともあれ、これで安心してBlender2.8に移行できる。
この一件がわからないばっかりに、半年以上Blenderのアップデートができずに悩んでいたのよね。日本語はおろか、英語でも記事が少なくてどれを参考にすればいいかわからなかったけど、ログを詳しく見たら案外すんなり行けて満足です。これからは2.8で新機能も取り入れながらモデリングができるね。

近況報告&プログラミング日記

お久しぶりです。

最後の投稿(2018/03/20)からはや四か月。いや~時が流れるのは早いですね(棒)

 

さてさて皆様いかがお過ごしでしょうか。私は元気です。たぶん。

実は最近、Unityを触り始めました。というのも、今まで使っていたDXライブラリというゲーム制作特化型のライブラリが、うまく動いてくれなかったのが原因です。まあ3Dゲームを作ろうとした自分が悪いんですがね…

 

話は変わりますが、ホームページの更新を久々に行いました。内容は、タイトルにもあるようにプログラミング日記。DXライブラリを使って、音楽を再生できるアプリケーションを作ろうと思い立って作ったものです。もちろんまだ完成してません。なので途中で打ち切りになる可能性ありです。いや大です。

 

ということで、UnityにDXライブラリに、ゲーム制作(片方は今はゲームではないが)に忙しい日々になりそうです。今年の夏はとても暑いので、皆さんも私も熱中症にならないように気をつけて過ごしましょう。

コマンドでTNT Run作ってみた

どうも、にほたもるです。今回は、コマンドでTNT Runを作ってみたので紹介します。

 

そもそもTNT Runとは何かというと、TNTの上に砂が乗った足場が何層かあるフィールドで、歩くと消える足場を乗り継いで落ちないように耐久するゲーム。PVPサーバーのhypixel等にあるゲームです。

 

このゲームを再現するには、接地しているプレイヤーの真下が砂である(二つ下のブロックがTNTである)ことを検知して、その足場を消すことが必要です。

 

それではまず接地判定から考えていきましょう。

接地しているかどうかは、YesNoの2択なので、スコアボードタグを使うとよさそうです。

/scoreboard players tag @a[tag=!onGround] add onGround {OnGround:1b}

/scoreboard players tag @a[tag=onGround] remove onGround {OnGround:0b}

スコアボードコマンドでは、NBTタグを用いて検知できるので、上のようなコマンドにしてみました。タグを持っているプレイヤーにタグをつけてもしょうがないので、タグを持っていないプレイヤーにのみタグをつけるようにしました。逆も同様です。

 

次にブロックを消す下準備です。

足場が砂だったら消せばいいのですが、それだけだと走る早さよりも早くブロックが消えてしまい、ゲームになりません。なので足場を踏んでから消えるまで若干のラグが必要です。そのラグは、エンティティの落下時間を利用します。

/execute @a[tag=onGround] ~ ~ ~ detect ~ ~-1 ~ sand 0 summon armor_stand ~ ~3 ~ {Invisible:1b,Tags:["tnt"]}

足場が砂だったら、3マス上空に透明なアーマースタンドを召喚します。

このままだとブロックの上に滞在している間ずっと召喚され続けて負荷になるので、足場のブロックを別のブロックに置き換えます。

/execute @a[tag=onGround] ~ ~ ~ detect ~ ~-1 ~ sand 0 setblock ~ ~-1 ~ sand 1 replace

このブロックは何でもいいですが、TNTを着火しないブロックにしてください。大変なことになります。

 

最後に、実際に足場を消す処理です。

まず、アーマースタンドが落下して来たら処理をするためのタグを新たにつけます。

/execute @e[tag=tnt] ~ ~ ~ detect ~ ~-1 ~ sand -1 scoreboard players tag @s add tntkill

次に、そのタグのエンティティから足場を消去します。

/execute @e[tag=tntkill] ~ ~ ~ fill ~ ~-1 ~ ~ ~-1 ~ air 0 replace sand 1
/execute @e[tag=tntkill] ~ ~ ~ fill ~ ~-2 ~ ~ ~-2 ~ air 0 replace tnt -1

これで足場が消去できました。このままだとアーマースタンドが残り続けるうえ、下の層があったらさらに落下して下の層まで足場を消してしまうので、不要になったアーマースタンドをキルします。

/kill @e[tag=tntkill]

 

これらの8つのコマンドを常時実行することで、TNT Runを再現することができます。ただし、このコマンド群はあくまで簡易版であり、問題点が多々あるのでご注意ください。これ以上は若干難しい内容ですので、余裕があれば解説したいと思います。

Minecraft 1.12.2 MOD制作日記

 どうも。にほです。

最近記事を書くことが無さ過ぎてまったく更新していなかったのですが、せっかくなので日記形式で現在作っているマイクラのMODの制作過程を書いていけたらなぁと思った次第です。

 

とはいっても、既にMODの基礎は出来上がっている状態なので、日記というよりこれまでにやってきたことを振り返るような感じになってしまいます。加えて大して技術的なことはしておりませんし、MOD制作のチュートリアル的なものでもありません。ですので、期待はしないでください(^^; MOD制作のチュートリアルは、近いうちにブログではなく自分のサイトで紹介しようかなぁと思っております。

 

さて、これだけで終わるのも何なので、メインクラスくらいまでは書いてしまおうかなと。といっても、通常のプログラムのようにmain関数から始まって…というわけではないので、メインクラスというのも若干語弊がありますが。

 

まずは、src/main/javaの直下に適当なパッケージを作ります。そこに新しいクラスMain.javaを作っていきます。このMain.javaには、様々なMOD情報を記述していくことになります。このプログラムがMODであることを示すための情報ですね。その中の情報に、MODIDというMODを表す一意の文字列を記述しなければなりません。このMODIDは、Main.javaの中に直接書いてしまってもいいのですが、様々なところから参照するので、他のクラスを作ってそこから参照させるようにします。

 

何故参照するためのクラスを作るかというと、仮に後でMOD内のいろんなところで参照したい値ができてきたときにも同様にして値を宣言・定義するのですが、参照したい値がいろんなクラスに点在しているととても分かりにくいです。MODIDがMain.javaにあって、MOD名がName.javaにあって、MODバージョンがVersion.javaにあって…となると、ソースコードを書くのも大変です。なので、システムで利用する値は全部同じファイルに纏めてしまいます。

 

とりあえず新しいクラスを作りましょう。一般的にはReference.javaとするようですが(Referenceは参照の意味)、私はこのサイトでゲームプログラミングを勉強したので、Define.javaという風に名前を付けました。変数は、MODのIDとMOD名、MODバージョンを用意すればいいでしょう。変数名は適当でいいので、わかりやすい名前をつけましょう。

 

package doph.niho.melonpan.system;


public class Define {

    public static final String MODID = "melonpan";

    public static final String MOD_NAME = "Melonpan Mod";

    public static final String MOD_VERSION = "0.00";

}

 

 これで、Defineクラスを通じてMODのデータを参照できるようになりました。

 

それではメインクラスです。

 

package doph.niho.melonpan.system;

 

import net.minecraftforge.fml.common.Mod;

 

@Mod(modid = Define.MODID, name = Define.MOD_NAME, version = Define.MOD_VERSION)

public class Main {

    

 

これでメインクラスの雛型が出来上がりました。ここに、初期化処理や登録処理等を書いていくことになります。

 

さて、今回はこの辺で。次回はアイテムの追加について書いていきたいと思います。それではまた。

arrayの参照渡し

どうも。にほです。

今日は、ゲームプログラミングの中で出てきた疑問点を解消したので、そのことに関して備忘録を残そうと思います。

※この記事は自分で調査した内容を記していますが、間違いがある可能性があることをご了承ください※

 

まず、arrayについてです。arrayとは、c++における標準のライブラリで、配列のような挙動を可能にしてくれるものです。また、配列とは違って、サイズを取得するなど、便利な機能がそろっています。なので、c++でプログラミングをしているなら、よほどの理由がない限り配列よりarrayを使った方がいいのかな?

 

ところで、配列では、関数に値を渡すとき、先頭のアドレスを渡しますよね。そこで以下のコードを見てみましょう。

#include <iostream>

using namespace std;

 

int rewrite(int arr[5])

{

    arr[0] = 10;

    arr[1] = 1652;

    arr[2] = 2768;

    arr[3] = -126;

    arr[4] = 0;

}

 

int main()

{

    int arr[5];

    for(int i = 0; i < 5; i++)

    {

        cout << arr[i] << endl;

    }

    for(int i = 0; i < 5; i++)

    {

        arr[i] = i * 3;

        cout << arr[i] << endl;

    }

   rewrite(arr);

   for(int i = 0; i < 5; i++)

   {

        cout << arr[i] << endl;

    }

}

f:id:nihotamor:20180209004023p:plain

このように、配列をそのまま関数で受け取っても値を自由に書き換えられてしまいます。これを防ぐには受け取り側でconstな変数を受け取るなどの手法があります。

では、このコードをarrayを使って書き換えてみましょう。

#include <array>

#include <iostream>
using namespace std;


void rewrite(array<int, 5> arr)

{

    arr[0] = 10;

    arr[1] = 1652;

    arr[2] = 2768;

    arr[3] = -126;

    arr[4] = 0;

}


int main()

{

    array<int, 5> arr;
    for (int i = 0; i < 5; i++)

    {

        cout << arr[i] << endl;

    }
    for (int i = 0; i < 5; i++)

    {

        arr[i] = i * 3;

        cout << arr[i] << endl;

    }

    rewrite(arr);
    for (int i = 0; i < 5; i++)

    {

        cout << arr[i] << endl;

    }
    return 0;

}

 それでは実行結果を見てみましょう。

f:id:nihotamor:20180209004946p:plain

このように、値は変わっていません。これは、arrayが値渡しされていて、要はarrayのコピーが関数に渡されているわけです。これを渡して関数の送り先で値を変更するにはどうしたらいいでしょうか。答えは参照渡しです。c++では、参照渡しをすることで、関数を渡した時に元の変数と同じアドレスの同じ値を扱うことになります。

#include <array>

#include <iostream>
using namespace std;


void rewrite(array<int, 5>& arr)

{

    arr[0] = 10;

    arr[1] = 1652;

    arr[2] = 2768;

    arr[3] = -126;

    arr[4] = 0;

}


int main()

{

    array<int, 5> arr;
    for (int i = 0; i < 5; i++)

    {

        cout << arr[i] << endl;

    }
    for (int i = 0; i < 5; i++)

    {

        arr[i] = i * 3;

        cout << arr[i] << endl;

    }

    rewrite(arr);
    for (int i = 0; i < 5; i++)

    {

        cout << arr[i] << endl;

    }
    return 0;

}

f:id:nihotamor:20180209005906p:plain

同じ値を扱っているので、この方法では書き換えることができました。このように、参照渡しを使うことで呼び出し元の変数を直接呼出し先で変更することができます。どこでも変数をいじれるのは危険なことではありますが、覚えておいて損はないでしょう。

2018年、あけましておめでとうございます

 皆様、お久しぶりです。

 最近ブログというものの存在を完全に頭の片隅からも抹消してしまっていたらしく、ここ2カ月間近く更新しておりませんでした。。。

 

 それはさておき、今日から年が変わって2018年ですね。皆様、2017年はいかがだったでしょうか。私は、C++を勉強し始め、Javaのデザインがだんだんと分かってき、このブログも開設し、仲のいい友達もたくさんできまして、とても充実した1年でした。昨年はいろいろなことがありましたが、今年もそれ以上に充実した生活を送ることができるよう、頑張っていきたいと思います。

 

 さて、これで終わりというのもあれなので、ここに今年の目標というか抱負を記しておこうかなーと思ったり思わなかったり。

 

 まずプログラミング関連ですね。これに関しては、ゲームを完成させる! これに尽きますかね。小規模なツールなどはすでにいくつか作ったことはあるのですが、大規模なコードが必要なゲームはまだ完成したことがありません。現在マイクラ用に作っているプラグインも一応未完成なので、そちらも完成させたいですね。

 

 次に動画制作について。今年は実況動画を投稿し始めて2年目を迎える年でもありますので、もっといろいろなことに挑戦して(例えばホラーとかホラーとか)、もっとチャンネルを盛り上げていこうかと思います。あと個人的にやってみたいのは、解説動画系ですね。自分の得意な分野について、他人に教えられるようになりたい、というのが今の自分の目標としているところですかね。

 

 最後に、日常生活のこと。これに関しては、だらけない。これしかありません() とりあえず、何に関しても怠惰にならずに、進んで辛いこともできるようになれるといいなぁと思っております。特に自分は物事の習慣化がとても苦手なので、それに関しても人並みには慣れるように努力していきます。

 

 さて、こんな感じで今年の抱負をまとめておきます。兎にも角にも、2018年は今までより充実した1年にする!そして、人間としても一つ成長して、また来年のこの時期に胸を張って(?)記事を書けるようにしたいと思います。

 ということで、どうぞ今年もよろしくお願いいたします。

こんなメールが届いた。

こんなメールが届きました。

 

にほたもるのブログ を更新されてから約1ヶ月が経過しました。そろそろ次の記事を投稿してみませんか?

はてなブログは、あなたが日々の生活から感じたこと、考えたことを書き残すことができる場所です。記事を書き続けることで、あなたの感性や関心が読者にも伝わり、同じ興味を持つ人とのつながりが生まれるかもしれません。

ぜひ、はてなブログで、あなたの思いや考えを言葉にしてみませんか?

 

 ブログ更新するの忘れてた(^q^)

 

この記事を読んでくださっている方の中に私の記事を待ってくださっている方がどれほどいるのか分かりませんが、これから頑張って記事を書いていくのでどうかお許しください(((;´д`)

 

で、これだけで今日のブログ終わり!というわけにはいかないので、近況報告の方をさせていただきます。

実は私、先日11月3日、念願のNintendo Switchを購入いたしました!イェ~イ

 

で、肝心のソフトなんですがこれがまだ買えていません()

スイッチがあと3000円程安かったら買えたんだけどなぁ…←

 

ということで、そういう報告でした。よーし、これから遊ぶぞ~