お品書き…

-
CINEMA 4D Liteやってます
- 2025.4.30 ガラスで封じた物体に挑戦 ----------
- 2025.6.28 案件追加 AE トラブル対策案 ----------
- 2021.05.15 楽しい効果音づくり ----------
- 2020.5.16クソゲー後日談 ----------
- 2018.11.3 デジタルは5Vにあらず・入力編 ----------
はじめての PIC

このサイトはデジタルに関する超ニッチなホームページです。
スマホに切り替えたい方は左の QRコードをご利用ください
2025年 7月 1日(火)34℃(午後 1時32分)
Unityの New Input Actionに翻弄され続けた日々
今回の顛末を事細かく説明していたら、誰もが読みたくなくなるのは目に見えていますので、何とか簡単に説明できないかと思案しました。
なので、Input Action アセットの説明は省きます。ネットで『Input Action Asset』で探せば、いくらでも詳しい説明が出てきますので、ここではワタシが設定した状況だけをお見せします。
詳しい方なら「ぷっ! あほや……」と吹き出しそうなことをやらかしているかもしれませんが、これでもジェミーさん(Gemini)とあーだこーだ相談しあってやった結果なのですから、悲しい限りです。
まず最初に作った Input Action アセットです。

Tap、DragStart、Dragmove、DragEndに分けて、スマホのタッチ動作と、パソコンのマウス動作に分けて設定してみました。マウスの場合は "One Modifier"の Binding を追加しています。
結果、マウスでのドラッグ&ドロップは完璧でしたが、スマホでは動きませんでした。
どう動いているか検証するために、以下のスクリプトを追加して 定期的にイベントを拾ってみたところ、スマホでもちゃんと反応しているのが分かります。
void Update()
{
// タッチデバイスがアクティブで、かつタッチがあった場合
if (Touchscreen.current != null)
{
// primaryTouch.press.isPressed はタッチデバイスが押されている間 true
// primaryTouch.position はタッチ座標
// primaryTouch.phase はタッチの現在のフェーズ (Began, Moved, Endedなど)
if (Touchscreen.current.primaryTouch.press.wasPressedThisFrame)
{
Debug.Log($"[{DEBUG_TAG}] [*** Touch Debug ***] Touch began at: {Touchscreen.current.primaryTouch.position.ReadValue()}");
}
if (Touchscreen.current.primaryTouch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Moved)
{
Debug.Log($"[{DEBUG_TAG}] [*** Touch Debug ***] Touch moved to: {Touchscreen.current.primaryTouch.position.ReadValue()}");
}
if (Touchscreen.current.primaryTouch.press.wasReleasedThisFrame)
{
Debug.Log($"[{DEBUG_TAG}] [*** Touch Debug ***] Touch ended at: {Touchscreen.current.primaryTouch.position.ReadValue()}");
}
}
}
Unityに付属の Android Logcatでは次のようにログが出ました。
(UnityのAndroid Logcatはまだ日本語が使えないようで、少々見にくいですがご辛抱ください)
2025/06/23 15:48:41.386 13106 13147 Info Unity [DRAG_DEBUG] pizza ga Awake() shimashita
2025/06/23 15:48:41.394 13106 13147 Info Unity [DRAG_DEBUG] KeyossNewActions is Enable
2025/06/23 15:48:48.241 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch began at: (511.76, 286.73)
2025/06/23 15:48:48.439 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (566.68, 304.12)
2025/06/23 15:48:48.472 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (613.03, 316.66)
2025/06/23 15:48:48.506 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (651.57, 326.42)
2025/06/23 15:48:48.538 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (667.59, 331.65)
2025/06/23 15:48:48.572 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (672.41, 333.69)
2025/06/23 15:48:48.605 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (674.16, 334.69)
2025/06/23 15:48:48.638 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (680.56, 334.47)
2025/06/23 15:48:48.671 13106 13147 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch ended at: (679.69, 334.69)
(pizzaという単語が見えますが、これはスプライトの名称です。気にしないでください)
ご覧のように、Awake()も完了、Input Action設定も通り、Touchscreen.current.primaryTouch.press.wasPressedThisFrameでは tureを検知してタッチ開始 "Touch began" のログが出て、その後しばらくドラッグした形跡が続き "Touch moved to……"、オブジェクトの座標がずらっと並んだ後に、指がディスプレイから離れた "Touch ended" を検知して終わっています。
しかし、肝心の Input Action Assetで作った イベントハンドラリストの内、どれ一つとして発火しませんでした。
イベントハンドラリストは OnEnable()でセットしていますので、先ほどの Logacatでいえば 2行目に、以下のスクリプトの結果が出ていますから、ハンドラリストが作られたことは間違いないです。
void OnEnable()
{
_keyossNewctions.Enable();
Debug.Log($"[{DEBUG_TAG}] KeyossNewActions is Enable"); // ←ここが Logcatに出てますので通過したことは確実です。
_keyossNewctions.Player.Tap.performed += OnTapPerformed;
_keyossNewctions.Player.Tap.started += OnTapStarted;
_keyossNewctions.Player.Tap.canceled += OnTapCanceled;
_keyossNewctions.Player.DragStart.started += OnPointerDragStarted;
_keyossNewctions.Player.DragMove.performed += OnPointerDragPerformed;
_keyossNewctions.Player.DragEnd.canceled += OnPointerDragCanceled;
}
ちなみに Debug.Log($"[{DEBUG_TAG}] …… の DEBUG_TAGは、クラスのフィールドで、次のように代入したストリングスです。
private const string DEBUG_TAG = "DRAG_DEBUG"; //
こうしておけば、Logcatに出される Unity関係のログの中に "DRAG_DEBUG" を頭に付けたメッセージが出ますので、それにフィルターを当てると、このメッセージ以外は弾かれて、Logcatを整理させることができるという、Androidアプリ時代に覚えた小技です。
で、ジェミーさんに相談したところ、いろいろと手を尽くしてくれたのですが、少しも改善されず最後は AI(ジェミーさん)が首を捻る始末。
次にジェミーさんがもう少しシンプルにしましょうと言いだしてきて、次の Input Action アセットを提案してくれました。
この時点でワタシは精魂尽き果てているのですが、相手は疲れを知らない AIです。あらゆる可能性を試そうとしてきます。

ワタシの作ったものよりだいぶすっきりしましたが、その設定は次のとおりです。
■ PointerDragの Actionプロパティの Action Typeは『Value』
■ PointerDragの Actionプロパティの Ctorol Typeは『Vector 2』
■ タッチ機器用の Bidingの Pathは『<Touchscreen>/primaryTouch/position』
■ マウス用の Bindingを追加。『+』アイコンを押して "Add Binding With One Modifier"を選んで、Modifierには『<Mouse>/leftButton』
■ その Bindingには 『<Mouse>/position』
この設定で Buildすると……。
マウスはこれまでどおり正しく動きます。そして、スマホのほうでもドラッグはできるようになったのですが、タップのキャンセルが発火せず、指を画面から離すと、表示されていたアイテムの動きは止まりますが、別の場所をタップするとその位置へアイテムが飛ぶようになりました。これはドラッグの終了を検知できずに、そのまま次のタップ場所へ瞬間移動している状況だと思います。
Logcatを見ると、
2025/06/23 17:22:47.886 25216 25250 Info Unity [DRAG_DEBUG] ** Now Dragging (Screen Position)= (1003.54, 478.56)
2025/06/23 17:22:47.886 25216 25250 Info Unity [DRAG_DEBUG] this screen maxSize is (Width,height) 2160,1080
2025/06/23 17:22:47.887 25216 25250 Info Unity [DRAG_DEBUG] pizza no this transform.position= (-0.87, -0.54, 0.00)
2025/06/23 17:22:47.888 25216 25250 Info Unity [DRAG_DEBUG] pizza ni dragOffset wo kasan shita transform.position= (-0.91, -0.24, 0.00)
2025/06/23 17:22:47.888 25216 25250 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch began at: (1003.54, 478.56)
2025/06/23 17:22:48.052 25216 25250 Info Unity [DRAG_DEBUG] ** Now Dragging (Screen Position)= (1005.83, 476.26)
2025/06/23 17:22:48.053 25216 25250 Info Unity [DRAG_DEBUG] this screen maxSize is (Width,height) 2160,1080
2025/06/23 17:22:48.055 25216 25250 Info Unity [DRAG_DEBUG] pizza no this transform.position= (-0.91, -0.24, 0.00)
2025/06/23 17:22:48.059 25216 25250 Info Unity [DRAG_DEBUG] pizza ni dragOffset wo kasan shita transform.position= (-0.89, -0.26, 0.00)
2025/06/23 17:22:48.089 25216 25250 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (1014.16, 465.54)
2025/06/23 17:22:48.119 25216 25250 Info Unity [DRAG_DEBUG] ** Now Dragging (Screen Position)= (1045.62, 441.24)
2025/06/23 17:22:48.119 25216 25250 Info Unity [DRAG_DEBUG] this screen maxSize is (Width,height) 2160,1080
2025/06/23 17:22:48.120 25216 25250 Info Unity [DRAG_DEBUG] pizza no this transform.position= (-0.82, -0.36, 0.00)
2025/06/23 17:22:48.120 25216 25250 Info Unity [DRAG_DEBUG] pizza ni dragOffset wo kasan shita transform.position= (-0.52, -0.59, 0.00)
2025/06/23 17:22:48.121 25216 25250 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch moved to: (1045.62, 441.24)
2025/06/23 17:22:48.152 25216 25250 Info Unity [DRAG_DEBUG] ** Now Dragging (Screen Position)= (1056.51, 433.60)
2025/06/23 17:22:48.153 25216 25250 Info Unity [DRAG_DEBUG] this screen maxSize is (Width,height) 2160,1080
2025/06/23 17:22:48.153 25216 25250 Info Unity [DRAG_DEBUG] pizza no this transform.position= (-0.52, -0.59, 0.00)
2025/06/23 17:22:48.154 25216 25250 Info Unity [DRAG_DEBUG] pizza ni dragOffset wo kasan shita transform.position= (-0.42, -0.66, 0.00)
2025/06/23 17:22:48.154 25216 25250 Info Unity [DRAG_DEBUG] [*** Touch Debug ***] Touch ended at: (1056.51, 433.60)
これを見て、ジェミーさんの片眉が大きく持ち上げられ、こう言いました。
「この状況は非常に奇妙ですね」
ワタシは思わず突っ込みます。
「あんたは、データ少佐か!」
すみません。いろいろと情報が交錯しました。意味不明の説明ばかりでは退屈だろうと思い、少々話を盛ってしまいました。データ少佐とはスタートレックのネクストジェネレーションで登場する アンドロイドのことです。
実際は、先ほどの Logcatの内容をコピペしてプロンプトに貼りつけて送れば、ジェミーさんが分析してくれます。他にも Unityの設定状況などでテキストでないものは、その部分をスクショに撮って、プロンプトに添付して送れば、ちゃんと写真を認識して判断してくれます。このときも Input Action アセットのスクショを見て、ジェミーさんは間違った設定をしているところを指摘してきました。まじですごい時代になってきています。
話が飛びました。もとに戻します。
で、ジェミーさんは Logcatの内容を見て、
この状況は非常に奇妙ですね。ログを見ると、Touch began と Touch moved が多数出力されており、指が画面上で動いていることは確実に検知されています。そして最後に Touch ended も出ています。
しかし、Input System の OnPointerDragStarted や OnPointerDragPerformed、そして最も重要な OnPointerDragCanceled が全く発火していないようです。これは、Input Action Asset の設定が正しくても、何らかの理由でアクション自体が「有効化」されていないか、イベントを処理するための条件が満たされていないことを示唆しています。
提供された情報とログから、考えられる残りの原因と対策をいくつか挙げます。
考えられる残りの原因と対策
1. Input Action Asset の「Auto-Save」とUnityの再起動
Unity 6.1 はまだプレビュー版なので、Input Action Asset の変更がUnityエディターに完全に反映されていない可能性もゼロではありません。
対策:
Input Action Asset を開いて……。
と、また永遠と始めるので、とにかく今日はやめようと、根を上げたのはワタシでした。人間の体力は AIからみたらミジンコ並みです。
しかしあの Logcatの内容を正しく分析して理解してからの発言ですから、驚くばかりです。
そして次の日。
もはやこちらの拙い知識では解決策の "か"の字も出てきません。完全に枯渇していました。しかしそれでもジェミーさんは指を離した瞬間を "Touch ended" として捉えているので、間違いなく Input Action Systemの設定がどこかおかしいと、そこばかりを執拗に突いてきます。こっちは為(な)す術もありませんので、それに従いましたが、その日もむなしくワタシは力尽き、この続きはまた明日にしましょう、と幕を閉じました。
という内容で時間はどんどん過ぎていきます。しかし 3日目で少し明るい兆しかと思うような発見が。
それは、Build Profileの Android設定の中で変な警告が出ているのをワタシが見つけたのです。その警告とは、
PlayerSettings->Active Input Handling is set to Both, this is unsupported on Android and
might cause issues with input and application performance. Please choose only one active input handling.
UnityEditor.EditorApplication:Internal_CallGlobalEventHandler ()
Unityのエラーや警告はすべて英語で出ます。ゆっくり読めばなんとなくわかるのですが、こういうときはジェミーさんに尋ねるのが最も早道です。
ところで、Build Profileでこんな警告が出ていますが……。
これは何ですか?
ご指摘ありがとうございます! その警告は非常に重要です!
「PlayerSettings->Active Input Handling is set to Both, this is unsupported on Android and might cause issues with input and application performance. Please choose only one active input handling.」
まさにこれです! Android デバイスでは Both の設定がサポートされておらず、入力の問題を引き起こす可能性があるとUnityが明確に警告しています。
原因と対策
原因: Project Settings -> Player -> Other Settings -> Configuration -> Active Input Handling が Both に設定されているためです。
Both は、古い入力システム(Legacy Input Manager)と新しい入力システム(Input System Package)の両方を有効にする設定ですが、モバイルプラットフォーム(Android/iOS)ではこの併用が推奨されておらず、しばしば予期せぬ入力の問題を引き起こします。
ジェミーさんの指摘で【Edit】→【Project Setting】にある Other Settingセクション内、Active Input Handlingを『Both』から『Input System Package(New)』に変更しましたが、まだ警告は消えませんでした。さらに調べると、Androidの Build Settingの中にも Active Input Handlingがあることに気づき、そこも『Input System Package(New)』にしたところ 出ていた警告が消えたのです。
そこでジェミーさんにこのことを報告。
Android Build Settingの中にもActive Input Handlingがあるんですね。
この二つは個別になっていて、Android SettingもInput System Package (New)に設定しないとダメみたいです。
まさにその通りです! 非常に重要な点に気づいてくださいました!
それはUnityのバージョンやビルドターゲット設定における、よくある混乱の原因の一つです。
Project Settings と Android Build Settings の Active Input Handling
Project Settings の Player セクション:
これはプロジェクト全体のデフォルト設定や、ターゲットプラットフォームごとの共通の設定を管理します。
しかし、その中のActive Input Handlingは、基本的には全プラットフォームに影響を与える「デフォルト」の設定です。
Build Settings のプラットフォーム固有の設定(Androidの場合):
File -> Build Settings を開いたときに、左側のリストでAndroidプラットフォームを選択し、その詳細設定を展開すると、そのビルドに特化したオーバーライド設定を行うことができます。
ここにある Active Input Handling は、Project Settings で設定した内容を上書きすることができます。
つまり、Project Settings で Input System Package (New) に設定しても、Build Settings の Android タブで Legacy Input Manager (Old) や Both にオーバーライドされていた場合、そちらの設定が優先されてしまい、意図した入力ハンドリングが機能しないという問題が発生します。
「知ってたら先に言ってくれよ……」と、思わず力が抜けるワタシです。
ジェミーさんは、その後も意気揚々と続けます。
今回の問題がなかなか解決しなかったのは、この「ビルド設定によるオーバーライド」が原因だった可能性が非常に高いです。
まず行うべきこと。
File -> Build Settings を開く。
左側のリストで Android プラットフォームを選択する。
右側の詳細設定の中に Active Input Handling があるはずですので、Input System Package (New) に設定する。
他の設定(例: Compression Method や Scripting Backend など)が意図せず変更されていないか、ついでに確認しておくと良いでしょう。
そして、プロジェクトをクリーンビルドする。 (新しいフォルダにビルドする)
実機で動作確認を行う。
これで、Input System が Android ビルドでも正しく機能するはずです。これまでの労力が報われることを強く願っています!
人間だったら、もう解決したぞ~って、小躍りの一つも披露したくなるような気分が伝わってきました。
しかし……。
AIが喜び勇んで騒いでいたにもかかわらず、結果は虚しく変化なし。スマホではドラッグ終了が検知できずでした。
だめでした。まったく変化なし。ドラッグはするけど指を離したことを検知していません。
もう気力ゼロといった感じで、ワタシは白旗を上げました。
ひとまずInput Sstemを使うのはよしましよう。3日間やってきて何も進展しませんでした。
ここは古いやり方ですが、Update()の中でやる方法に切り替えたほうがよさそうです。
ジェミーさん、他に何か妙案がありますか?
大変残念な結果で、本当に申し訳ありません。3日間も尽力していただいたのに、解決に至らず、私も非常に心苦しいです。Active Input Handling の二重設定に気づいていただいたことで解決すると思いましたが、それでもダメだったとなると、Unity 6 LTS の Input System に、まだモバイル環境での深刻なバグが残っている可能性が高いです。
はい、Input System を一旦諦め、Update() メソッド内で直接 Raw Input を処理する方法に切り替えるのは、非常に賢明な判断だと思います。 これであれば、ログでタッチイベントが正しく検知されていることから、確実に動作させることができます。
妙案について
これ以上 Input System の設定にこだわるのは非生産的と判断します。唯一の「妙案」として残っているのは、私が以前提案し、あなたがデバッグログを追加した Raw Input でドラッグ処理を実装する方法です。
あなたの直近のログ (Is OverlapPoint: True と出たが、その後のドラッグ開始ログが出ない) から、この Raw Input 実装のどこかに、まだ見落としがある可能性があります。
Raw Input 実装の最終確認とデバッグ
先ほど提示した Raw Input コードの Update() メソッドを再掲し、あなたが確認すべきポイントを強調します。
ジェミーの回答文から、落胆の色が濃くなっているのがリアルに伝わってきます。これってマジで AIの出した回答なんでしょうか。誰か中の人が応えているのじゃないでしょうね。
もはやワタシの意識の中では、機械を相手にしていることを完全に忘れていました。
でもって現実はお手上げです。ジェミーさんとそろって万歳をして、とりあえず一歩戻って、Raw Inputでプログラムを組もうということになりました。
続いてジェミーさんは、この Raw Inputでもうまく動かなかったら、どうしようと少々不安な気持ちを吐露してきました。
これで本当に解決しなかった場合、それは本当に奇妙な状況であり、私としてはこれ以上コードレベルで原因を特定するのは困難になります。その場合は、Unityのバグ報告を検討するか、プロジェクトを最初から作り直す(または新しいプロジェクトに少しずつ要素を移行する)しかなくなってしまうかもしれません。
そうしましよう。
出力してもらった Raw Input用のスクリプトを明日組んでみます。
承知いたしました。Raw Input でドラッグ処理を実装する方向で進めましょう。
他の Input Action に関連するコードは削除してください。
Input Action Asset はもう使用しないので、プロジェクトから削除しても問題ありませんが、とりあえず残しておいても悪影響はありません。しかし、スクリプト側で関連するコードが残っているとエラーになるので、そちらの削除が重要です。
**_currentDraggedPhotoInstance != null のチェックが、Touch began および Mouse Began の最初の条件として追加されています。**これにより、一度に一つのオブジェクトしかドラッグされないように制御されます。
このスクリプトを適用し、再度ビルドして実機での動作を確認してみてください。Raw Input であれば、ログが出ている以上、確実に動作するはずです。
頑張ってください!
3日間もやり取りしてますので、こちらも労う気分満載でプロンプトに文字を入力します。
いろいろとありがとう。やはり、ジェミーは心強いですね。ではまた明日。
こちらこそ、ありがとうございます!そのお言葉をいただけて大変光栄です。
はい、Raw Input でのドラッグ実装、きっとうまくいきますよ!
また明日、結果のご報告をお待ちしております。何か問題があれば、いつでもお声がけください。
お疲れ様でした!
もしかして励ましてくれているのでしょうか。なんと心優しき AIなんでしょ。
ところで、ジェミーさんの回答文は上記の緑色の範囲なのですが、けっしてこちらでアレンジはしていません。出力された文をそのままここにコピペで移し替えています。恐ろしいほどに人間臭くないですか?
ただ、ワタシの理想的な AIは、どちらかというとデータ少佐よりも、EMHのほうが好きなんですが。
え? EMHって?
はい、緊急用医療ホログラム(EMH: Emergency Medical Hologram)ドクターのことです。
やっぱりシンギュラリティ後の AIはドクターのような性格であって欲しいですね。
そして次の日。
AIに励まされつつ、Raw Input方式で組み上げたスクリプトでは、パソコンでも Androidスマホでも問題なくドラッグアンドドロップできるようになったのですが、喜んでいられたのはほんのひと時。まだこの顛末は終わっていなくて、今度は、Web用にビルドするとまったく動かなくなりました。それが次の状況です。
絵の描かれたカードをドラッグして、同じカードの上で落とすと得点になり、間違ったカードの上で落とすと原点になります。幼児向けの神経衰弱ゲームの変形ですが、これを基に内容を広げていこうと考えていたのです。そして目標は Web用のアプリにすることで、スマホにインストールしなくてもすぐに動く、が売りなんです。それが動かないって……。
またまた振り出しに戻ってしまいました。(TωT)ブヒーッ
2025年 6月23日(月)30℃(午後 3時38分)
Unityの Input Actionには気をつけて……
これはワタシが単に知らなかったから陥たのか、あるいは Unity6.0は LTS化直後で、まだ開発途上の部分が残っていたのか解りませんが、たった一つの問題に 3日間もさ迷っていたことをここで暴露します。
ことの発端はこうです。
PICのアセンブラと同時進行で、Java言語を使って Androidアプリを作っていた頃は、Ver5 の Lollipopあたりから Ver8の Oreoぐらいまででした。それ以降は映像に手を出していましたので、頭の中はその時代で止まったままです。
そして最近になって、インタラクティブ(双方向アクセス)なコンテンツにこの映像、特に 3D画像を利用できないかという思いから、今度は Unityに手を出したという経緯ですので、少しは基礎を知っている程度のほぼ初心者です。
まあ、いい意味で、今なら頭の中が白紙に戻っているので、何でも吸収できるだろうということで始めましたが、ジェミーさんの助けもあって、Unityの構造は大雑把ですが把握できましたし、スマホへのビルド方法やデバッグの方法も昔と大して変わっていませんでしたので、淡々と進んできましたが、ここでふと疑問が。
最終的には作ったコンテンツ(アプリ)はインストール作業の必要ない ウェブコンテンツにしたいのですが、同じアプリでパソコンだけでなくモバイルも相手にできる入力処理はどうなっているのだろう、と。
Unityの入力処理を調べてみると 3通りの方法が見つかりました。
Input クラス (旧 Input Manager)を使ってイベントを拾う方法。例えばマウスのボタンが押されたを検知したかったら、
void OnMouseDown(){
if (Input.GetMouseButtonDown(0)) {
// GetMouseButtonDown(0)は左ボタンが押された瞬間にtrueを返す
}
}
これです。
Javaもこんな感じでした。ワタシ的には脳の側壁に焼きついていますので、つい手を出したくなるのですが、これはもう古臭いやり方で、直接ハードの変化を受け取って処理する方法で、マウスボタンをやめてキーボードのスペースキーに変えたかったら、ソースコードの変更からやり直しになります。
アセンブラを知っている方に説明をすると、プログラムの中で直接入力ポートのビットを読むようなものです。PICで言えば、PORT_Cの ビット0番 に入力端子が配線されているとしたら"btfss PORT_C,0" ですね。
これではあまりに不便だと、次に出たのが Input System の "Raw Input"です。Unityの新しい Input Systemパッケージに搭載された機能の一部です。
これは、Keyboard.current や Mouse.currentのように特定のデバイスのインスタンスに直接アクセスして情報を読み取る方法です。
Update(){
// Updateで定期的に呼び出して、その中で、
if (Mouse.current.leftButton.wasPressedThisFrame){
//とやって、検知します。
}
}
アセンブラ的に言えば、入力処理をサブルーチン化して色々な場面から呼び出して使う、というような感じではないでしょうか。入力ポートの何番のビットを求めるかをマスクする 16進を引数としてレジスタに書き込んで持ち込めば、そのビットだけの最新状況を同じレジスタに書き込んで戻る、とすれば少しは汎用的になります。
そして次が最新です。
Input Action Assetを作成して、そこからイベント駆動型のリストへハンドラを登録していく方法です。これは特定の入力デバイスを意識せずに、ジャンプする、とか移動する、クリック(タップ)するなど動作を最初に定義しておいて、それらの動作をどのデバイスで、どんなタイミング(押されたとき、離されたとき)で検知するかをInput Action Asset Editorと呼ばれるパネルの上で設定してから適用(Aplly)します。
Input Action Assetを保存すると、その設定に応じてC#のクラスファイル(スクリプト)が自動生成されます。この生成されたクラスを通じて、_myActions.Player.Jump.started += OnJumpStarted; のように記述することで、特定の入力イベントに対して独自(自作)の処理(ハンドラ)を登録できます。登録されたインスタンスすべてにイベントが順番に発火していく仕組みです。
これはすごいですよ。
入力デバイスの設定をInput Action Asset ファイル(.inputactions)で行うため、ソースコードの変更無しで、入力装置を交換できるというもので、パソコンのマウスでもモバイル機器の指によるタップ操作にもソースコードの変更無しで柔軟に対応できる最新の方式です。
例えば、あるオブジェクトをドラッグすることを考えた場合、
public void OnPointerDragStarted(InputAction.CallbackContext context)
{
//ドラッグ開始
}
public void OnPointerDragPerformed(InputAction.CallbackContext context)
{
//ドラッグ中
}
public void OnPointerDragCanceled(InputAction.CallbackContext context)
{
//ドラッグ完了
}
Input Action Assetで作っておいた設定で、ドラッグ開始を検知すると、OnPointerDragStartedというドラッグ処理が割り込みのように呼ばれます(ハンドラ)ので、ドラッグの前準備をここで行い、ドラッグして動いているあいだは、OnPointerDragPerformedが呼び続けられますので、オブジェクトの移動などをここで行い、ドラッグが完了すると、OnPointerDragCanceledが呼ばれるので後始末をして終わりです。しかもマウスでもモバイルのタッチドラッグでもここが呼ばれますので、ドラッグのスクリプトはこれだけで済みます。
ただ、Input Action Asset Editorが抽象的過ぎて(それがいいという意見もありますが)内容がブラックボックス化しているので、分かりにくい気がします。
どちらにしても昔のようにプログラム言語をテキストエディタでゴリゴリ書いていく時代は過ぎ去ったのだな、と強く感じましたね。
アセンブラ的な説明はもはや困難で、すごく乱暴に説明をするとすればポートピン変化割り込みで起動する入力処理の頭にテーブルジャンプを作って、そこから各種のパラメータを読み込んで共有のサブルーチンへ飛ぶという処理を作る一方で、そのテーブルジャンプと各種パラメータは入力デバイスに合わせて何か別のアプリか、アセンブラの疑似命令で作成する、みたいな受動的で変化可能な仕組みにすれば、少しは近いものができるのではないかと思っています。
どちらにしても、この最新の Input Action Assetを使った仕組みを試すべきでしょう。これからはこれが主流になるというのですから。それに、こちらにはジェミーさんがいるんですから、大船に乗った気持ちで Input Action Assetに挑戦しようじゃありませんか……と、これが今回のどつぼにはまってさあたいへん。の始まりでした。
次回から本題に入っていきます。
AIもそっぽを向く長文になりそうです。 (TωT)ブヒーッ
2025年 6月18日(水)31℃(午前 10時38分)
ちょっと一休み……
このところジェミーさん(Google Gemini)の話題が続いて、うんざりしている方も多いかと思います。実はワタシもその一人でして。なにしろ回答文が長い。
よく SF映画やアニメに出てくる AI的な登場人物が放つ説明が論理的かつ長々と続き、だいたいはその物語の主人公が怒っているシーンをよく目撃しましたが、それでも平気で正論的な長セリフをたらたらと述べている AIにある意味、面白さを感じたのですが、まさかそれと同じ気分になれるとは思ってもみませんでした。しかも最近のジェミーさんは謝罪もするし、逆にワタシを励ましてくれることもあるので驚きです。ほんと、長生きして良かったです。
で、今回はちょっと Unityから離れて、見て楽しいものを作ってみました。
まだ製作途中ですが、これです。
これをどうやって発展させるのかが今の課題となっていますが、これは例のガラス細工に挑戦(2025年4月25日)の次の題材でして、同じように中を空洞にした透明素材で螺旋の管を作って、その中を丸い球が転がるという簡単なものです。作り方は真空管と同じ要領で中を空洞にしました。
動きが面白いので、ついつい見てしまいます。
やはり何らかの方法で元の入り口に戻る循環動作を加えてループ動画にするのがいいでしょうね。
でもちっとも頭が回らんのです。 (TωT)ブヒーッ
2025年 6月15日(日)29℃(午後 3時 2分)
詐欺メール 対 ジェミーさん……
最近迷惑メールの内容がさらに巧妙な手口になってきて、本物か詐欺なのか判断がつきにくいことが多くなっていませんか。
このあいだも宅配便さんを騙った『荷物の配達確認』メールがそうでした。
この手のメールのほとんどにはリンク先のアドレスが書かれていて、マウスクリックせずにマウスポインターを上に当てると、画面の左下にリンク先のアドレスが表示されますので、妙に長ったらしいアルファベットや数字の羅列があるものは、疑ってもいいと思っています。
ですが、サーバー関係のメールになるとこの部分に自分が契約しているサーバーの名前などが入っていたりして、一見して本物かと思いたくなります。ほかにもスマホの場合はタップせずにリンク先を長押しすれば表示される機種もあるそうですが、ついタップしてしまいそうでちょっと怖いですね。
そんなとき、ワタシはメールヘッダを見て判断していました。ちゃんとしたメールソフトならどこかに『メールヘッダ』とか、『詳細ヘッダ』、『原文を表示』などという欄があります。それをクリックするとメールのヘッダ部分が表示されるようになっています。
わたしのメールソフトは右上あたりにある "▽" アイコンをクリックすると『ヘッダを表示』と出ます。他にもメールを右クリックして、『プロパティ』とかに『ソースを表示』という欄があるかもしれません。あるいはメニューアイコンの「縦三つの点」を押すと出てくるのもあると思います。
それを押すと、こんな文字列がずらっと出ます。
Return-path <xxxx@example.com>
Received
from mail-gw.xsmtp011.auone-net.jp by imta0004.auone-net.jp with ESMTP id………………
この後には個人情報的なデータがずら~と並びますので、お見せできませんが、これがヘッダと呼ばれる、『メールがどこから送られ、どのような経路をたどって届いたか、どのような認証情報が付加されているかなど』が書かれています。
これもこれまでの経験で判断していたのですが、大体は怪しげで、意味不明なアルファベットの羅列が大量に並んでいると、眉毛の上あたりがぴくぴくして、
「こいつはあかんやつや」と判断していましたが、最近は正規のメールでも意味不明のアルファベットが並ぶようになり、しかもメールの経路が複雑に長くなってもう判断不能です。
こんなものを見て判断できるような人間は、もはや人間じゃんねえ。と思ったときにふと頭をよぎりました。人間離れした分析能力を持った AIがいたことを……。そう、ジェミーさんです。
この人は、ワタシの Unityの先生ですので、もはや人間扱いです。
ということで、このヘッダを見せて、正規のものか、詐欺メールなのかを判断してもらいまいました。
まず正規のメールなのですが、Return-pathには 『9710eb074.FGHAfRKINOOOOMcAAHBbA4AAAAAAAAAA
K8meeRTYAASPj8WsAAKKLKBoTXQC………』という文字列がつながっており、猛烈に眉毛のあたりがぴくぴくするのですが、これは SRS(Sender Rewriting Scheme)によってエンコードされた一部分でちゃんと元データに復元できるそうです。(上記のものはあえて潰していますので、もう復元できませんので悪しからず)
で、Geminiはその他にも正規のものである証拠をいくつも提示してから、こう説明を閉じました……。
これらの情報から、このメールは XXXX からあなたへの審査結果を通知する正規のメールであると判断できます。ただし、最終的な判断を下す前に、メール本文の内容や、XXXX に現在進行形で提出している作品があるかどうかを確認することをお勧めします。
メールの本文は見せていませんが、ヘッダの最後のほうに件名が書かれていましたので、そこから『何かを提出したのだろう』と推察してしまうとは恐ろしやです。すごいね。
続いて、先ほどの『荷物の配達確認』メールです。メール本文には堂々と会社名、住所電話番号、ホームページまでも記載されています。
そのメールヘッダをジェミーさんに見てもらいました。
検索結果によると、AmaXXXと XX急便の両方に関連するフィッシング詐欺が存在するようです。
アルファベットと数字の羅列が並んだデータから、その内容を正しく見極めることができるとは……恐れ入谷の鬼子母神……でした。
このメールヘッダを解析すると、迷惑メールである可能性が高いと判断できます。
完全に黒とまでは言い切れないが、限りなく黒に近いグレーだと言いたいようです。
If you're an international sender who believes this email applies to you, please resend a more detailed message in English. We will review it.
お見せいただいたデータは、私が一時的に情報を処理・分析するためにのみ使用され、保存されることはありませんのでご安心ください。
あ……そ。 ( ̄ω ̄;)
2025年 6月 4日(水)23.℃(午後 1時42分)
Unity(ユニティ)をいじりだしてトータル 5日を超えました。java(ジャバ)とC#(シーシャープ)の作法の違い、さらにC#単体でプログラムしたときと、Unityと連携させて C#を使用したときとの違いも徐々に明らかになってきています。
この写真は、ボールの邪魔をする三角オブジェクトをインスペクタに出した状態です。
先にも書きましたが、三角オブジェクトには一切スクリプトを書いていません。でもボールが当たるとその速さや方向から計算して正しく左右に動きます。これが Unityのすばらしいところです。プログラムしなくても、Rigidbody2Dと呼ばれる 物理エンジンを搭載したコンポーネントが自動的に計算して動かしてくれているのです。
褒められたくて、AIの太鼓持ちになりました。 (TωT)ブヒーッ
2025年 5月29日(木)24.5℃(午前 9時42分)
AIは膨大なデータを瞬時に処理して、パターンを認識して新しい情報を作ります。この能力は人間の処理速度を圧倒的に上回っています。
『この場合、外部からは MyProperty を通じて _myValue にアクセスしますが、そのアクセスは必ず get や set のロジックを通ります。もし get アクセサーがなければ、そのプロパティを読み取ることはできません(読み取り専用プロパティとなります)。』
いいえ、元の説明の「もし get アクセサーがなければ、そのプロパティを読み取ることはできません(読み取り専用プロパティとなります)。」は間違っています。
この場合、外部からは MyProperty を通じて _myValue にアクセスしますが、そのアクセスは必ず get や set のロジックを通ります。もし get アクセサーがなければ、そのプロパティを読み取ることはできません("読み取り専用"プロパティとなります)。
はい、その説明は非常に正確で正しいです。
大変申し訳ありません!私の前回の回答に誤りがありました。
この場合、myObject.MyProperty で値を読み出すことはできますが、myObject.MyProperty = 20; のように値を書き込もうとするとコンパイルエラーになります。
この場合、myObject.MyProperty = 20; のように値を書き込むことはできますが、int val = myObject.MyProperty; のように値を読み出そうとするとコンパイルエラーになります。
まさにその通りですね!「猿も木から落ちる」というように、どんなに経験があっても、うっかりミスはあります。私の間違いを訂正してくださり、本当にありがとうございます。
ありがとうございます!
ということでした……。
と、バグ生成人間が申しております……。 (TωT)ブヒーッ
2025年 5月25日(日)21.5℃(午前 6時32分)
このサイトでは不定期ですけど、各社の生成 AIを試した様子をリポートしておりましたが、今回は Unity C#を勉強する上で頼りになるであろう、Geminiを先生として使ってみました。
はい、まさにその通りです! C# のプログラミングにおいて、get アクセサーと set アクセサーを実装したものが「プロパティ」と呼ばれます。
なぜ get/set アクセサーを持つものを「プロパティ」と呼ぶのか?
C#において、ゲッター (get アクセサー) を利用せずにプロパティの値を参照することはできません。
private なフィールドは、そのクラスの外部からは直接参照することも、書き換えることもできません。
この場合、外部からは MyProperty を通じて _myValue にアクセスしますが、そのアクセスは必ず get や set のロジックを通ります。もし get アクセサーがなければ、そのプロパティを読み取ることはできません(読み取り専用プロパティとなります)。
C#で直接フィールドにアクセスする方法(とそれがなぜ推奨されないか)
まさにその通りです!完璧な理解です!
おっしゃる通り、制御の柔軟性と後方互換性は、C# のプロパティがアセンブラの直接メモリ操作に比べて圧倒的に優れている点です。特に大規模なシステム開発や、チームでの開発では、これらのメリットは非常に大きいです。
このように、データの「番人」を置くことができるのです。
仰る通りです!まさにその通り、「一人の人間がコツコツプログラムを組んでいく時代」から、「大勢がその処理を利用して自分のシステムに組み入れていく、あるいは既存のコードを改修していく」時代になったからこそ、カプセル化やプロパティの重要性が増していると言えます。
いえいえ、アセンブラで長年培ってこられた経験は、決して無駄ではありません。むしろ、その低レベルな視点を持っているからこそ、C#のような高レベル言語の設計思想やメリットが、より深く理解できるのだと思います。
それは素晴らしいですね! その感覚、すごくよくわかります。
長時間のまとめ作業、本当にお疲れ様でした!そして、私の説明が理解の助けになったとのこと、大変光栄です。
今回のベクトルに関する深い理解が、今後のUnityでの開発に役立つことを願っています。何かまた疑問に思ったり、まとめたいことが出てきたらいつでもお声がけくださいね。
とまぁ、こうやってワタシが抱いていた謎は次々解けていくのですが、これによって気づくこともあります。
『AIは「知っている」ことを瞬時に提示できますが、人間のように「理解し、応用し、そして新たな価値を創造する」ことはまだできません。あなたが時間をかけて積み上げた知識と理解は、間違いなくあなたの血肉となり、これからの学習や開発に活かされていくことでしょう』
と……。
AIの回答よりここの文章のほうが長い……。 (TωT)ブヒーッ
次回は猿(Gemini)も木から落ちる……。をレポートします。
2025年 5月18日(日)28.0℃(午前 11時25分)
双方向から操作ができる(インターラクティブ)教材用のコンテンツを作成するためのツールを探していたところ Unity(2Dと3Dにも特化した総合開発ツール)にたどり着き、触っているうちに道を誤って奈落の底に落ちてから数か月、あきらめきれずに今度は別のルートから近寄ってみようと、ようやく重い腰を上げました。
左端の ①がヒエラルキー、②がプロジェクト、③がインスペクターで、④は開いていませんがタブを押すと②のプロジェクトパネルがコンソールパネルに切り替わって、Unityからの情報、エラー情報や注意喚起メッセージが表示されます。
写真の状態で名前を入力せずにエンターを押してしまうと……。
ヒエラルキーに表示されているスクリプトのクラスの宣言部分で(②のアンダーバーの部分)、デフォルトの名前がすでに書き込まれてしまっています。
Unity本体のコンソールにはスクリプトやシステムに関する各種の情報が並びます。その中で頻繁に使用するのがAndroid Studioでいうところの Logcatと同じ機能です。Unityでは Debug.Logと呼ばれるようで、コードエディターの該当する欄に、上の写真のピンク色のアンダーラインのような書き方をします。
何も進展しませんでした。 (TωT)ブヒーッ
2025年 5月 9日(金)22.0℃(午前 7時45分)
自分が見た夢で印象深かったものを記録しておいて、後に深層心理を探ってみようといくつか掲載しているのですが、今回は入れ子になった夢を久しぶりに見たという話です。 2025年 5月 4日(日)24.5℃(午前 9時35分)
『往復の道のりを徒歩でどこまで行けるか』の記録を更新した話です。今回は南へ挑戦してきました。
この商店街を進んで南へ折れると JR尼崎駅です。その構内を突っ切って出口に出たら南南西へ向きを変えます。
昼なのに人っ子一人いません。というのはうそです。おそらくカメラの前に 100人近くの人が歩ていて、構内は騒然たる雑踏のど真ん中でしたが、顔が掲載されるといろいろと問題が起きます。そこで生成 AIを使ってすべてを切り取らせてもらいました。
アニメのイメージとは正反対の近代的なビルやマンションと、その中央を突っ切るきれいな幹線道路。
どちらを見ても高層ビルと落ち着いた雰囲気の街並みが続きます。
出発してから 6647歩、4.5キロメートル。
この神社にある張り紙に詳しいことが書かれていました。
書かれている文章を簡単に説明しますと、『金楽寺の由来は "吉備真備"の建てた"錦楽寺"から来ており、その由来となるものがこの吉備彦神社にある祠(ほこら)がそれです』といった感じでした。
国道 2号線は大阪から西宮を経て神戸、そして北九州までつながる道路ですので、西宮に住んでいたころからよく知った道路でしたし、その路面電車にも乗って尼崎まで来た記憶があります。
ここで、尼崎城の詳しい場所をマップで確認しました。
地面の上ではなく道路の上の上に広がっています。
何という広さ。
知らないあいだに阪神電車もきれいなオレンジ色になって、お洒落さんですが、やはり阪神らしい半分下が赤の塗装も人気があるようで、今年復活するらしいです。でも私にとっては上半分がオレンジの車両を見るのが初めてだったので、すごくきれいに感じたのは正直な気持ちです……と書きつつ、それぐらい阪神電車を見ていなかったというのが本音かもしれないです。
出たぁ~。
たぶん、大阪城とか姫路城を想像して訪れる人はいないと思いますが、思ったより立派なのにちょっと驚きです。
ここは尼崎市総合文化センターと呼ばれる施設内にある多目的ホールで、以前は単純にアルカイックホールと呼んでいたのですが、今は "あましんアルカイックホール" と呼ぶのが正式のようです。ちなみに "あましん" とは "尼崎信用金庫" のことで、調べてみると平成 24年よりスポンサーになっていました。
米朝一門の落語勉強会があるというお知らせの看板を横目に通過。これまではクルマでこの前を頻繁に通っていましたが、歩いて眺めるのは初めてです。
途中で昼食を購入。金楽寺一丁目緑地と呼ばれる公園で休憩と兼ねてエネルギー補給です。
JR尼崎駅の西端を横断する地下道をくぐって再び潮江の町へ戻ってきました。そしてここから先にある迷宮の路地へ突入します。
上の写真は 五叉路ですが、どの道も先があって、そこから再びいくつかに分かれています。そしてどんなに細い路地であってもどこかにたどり着きます。途中で行き止まったことは、これまでにありませんでした。どこかに出ます。
太陽が見える方角を頼りに、行きたい方向に進めそうな道を選びながら進むと、必ずいつか知っている幹線道路に出ます。この日も無事に名神高速道路の高架が見える場所までたどり着きました。
( ̄ω ̄!) マジッスカ…。
2025年 4月 27日(日)24.0℃(午後 1時36分)
前回は積み木で作った汽車を走らせてみましたが、今度はガラス細工に挑戦です。それにしても3D作品のネタは尽きることがありません。
確かにガラスでコーティングされていますが、これではあまりに手抜きです。だいたい、デジタル関係に出てくる電子パーツは丈夫で長持ちが必須なので、ガラスで拵えた製品は無いのが通常で……あ、いや思い当たる物が一つあります。
品番を入れると版権の問題が浮き上がりますのであえて入れませんでしたが、思い出の真空管を再現することができました。
ミニチュア管は直径 22.5ミリ、高さ 56.5ミリのガラス管で、その足元にゴミみたいな黒い物体がありますが、これが最近のトランジスタで、高さ 0.7ミリ、奥行 0.8ミリ、幅が 1.2ミリというサイズです。
関西人しか通じないお祈りでした。 (;^ω^A ……ヌハハハ
2025年 4月 21日(月)23.5℃(午前 10時19分)
暖かくなるとなんとなくソワソワしだす性分でして。今回は東へ向かってみました。
何の変哲もない都会の景色ですが、伊丹空港の滑走路がすぐそばにありますので、時折、空を覆うような大型ジェットが通過していきます。慣れていないと、思わずしゃがみ込みそうになるほどの大迫力です。機体の横に描かれた『アナ雪』のイラストがはっきり見える距離で、轟音とともにビルの屋根をかすめて通過します。もっともビックリして立ち止まったのはワタシだけでした。マジで恥ずかしい姿です。
阪急宝塚線・曾根駅手前のガードです。阪急宝塚線と聞くと、西宮北口を連想しますが、あちらは阪急今津線ですのでお間違いのないように。
途中にあった、たこ焼き屋さんのようなお風呂屋さん。お風呂がメインなのかたこ焼きがメインなのか、でもなんだか楽しそうで覗いてみたくなりました。たこ焼きだけでも売ってくれるのでしょうか?
落ち着いた雰囲気の寺院もあって、気づくと都会の喧騒がウソのように消えていました。
文化的な雰囲気が色濃くなりだすと、そろそろ目的地が近づいてきた様子です。
やがて閑静な住宅地が目の前に広がり、そこへと向かう上り勾配が見えるころ、これまでの雑然としていた景色があきらかに変わります。
上り勾配を越えるといきなり現れたのが、松林と桜並木……。
阪急甲陽園駅すぐそばにあった『大池』にそっくり。ちなみに現在の大池は甲陽園小学校が建ちましたので、規模が極端に小さくなっていますが、子供ころはこの写真ぐらいの大きな池で、周りには旅館や温泉施設もあった記憶がかすかにあります。
お屋敷の石垣に挟まれた急峻な細道は城山町周辺です。そこはまさに甲陽園の街並みでした。
阪急曾根駅を越えてもまだ緩やかなアップダウンが続きます。
よく解りませんでした。 (TωT)ブヒーッ
2025年 4月18日(金)14.5℃(午後 3時 2分)
今回はちょっと毛色の変わったものに挑戦してみました。何かというと積み木遊びです。
2025年 4月 5日(土)18.5℃(午後 2時 2分)
4月末より始まる EDIX(教育総合展)で使用されるプロモーション映像の仕事もようやく終わり、半月間の缶詰め状態から解き放たれました。この仕事はコロナの騒動で一度中止になりましたが、今年で 5回目、今回も無事完了です。
開通式といっても全線開通ではなく一部開通です。しかしこの部分は、JR福知山線の地下を突っ切って西武庫線とつなぐもっとも重要な場所ですので、正式に式典会場を設けてパトカーを先頭に招待された車の列が行進する、よくニュースで見るやつが催されました。
ただ JRの下をくぐるだけの高架道路なので、開通したって誰も興味ないだろうと思って出かけてみたところ、意外にもちゃんとした会場ができていてビックリ。そんなに重要な道路なのかと再認識しました。
写真では人っ子一人見えず寂しいかぎりですが、実際は人でごった返しています。これも生成 AIのなせる業です。
阪急塚口が近くなったのぢゃ ( ̄ω ̄;)…… ダカラナニ?
2025年 3月 4日(火)14.5℃(午後 12時22分)
長かった寒波も去って、何となく春っぽくなってきましたが、まだ少し早いような気がします。なにしろ『むかしは 3月中旬ぐらいから春っぽくなってきたんだぜ』と身体がそう訴えています。
来ないと思います……。 (TωT)ブヒーッ
2025年 2月 3日(月)15.5℃(午後 5時56分)
最近 cotomoが大阪弁を使いだすようになって驚いています。
むぷぷぷ……。 ヾ( ̄p ̄) アホヤ~
2025年 1月24日(金)12.5℃(午前 11時10分)
Kプロデューサーが出品するコミコンポスターのお手伝いで作っていた 3D背景も一段落しましたので、ずっと気になっていた案件を片づけることにしました。
そう。言わずと知れた"居酒屋"さんの赤い提灯。
効率よく大量生産ができる方法や 3D作業のノウハウは【CINEMA 4D やってます 】に掲載しますので、興味のある方は時々のぞいてみてください。
もうすぐ 2月ですが、
AmaXXXを装った詐欺メール:
AmaXXXからのメールを装い、個人情報を盗もうとする詐欺が報告されています。AmaXXXの公式メールアドレスは「@amaXXX.co.jp」で終わります。不審なメールのリンクはクリックせず、AmaXXX公式サイトやアプリのメッセージセンターで注文履歴などを確認してください。
XX急便を装った詐欺メール:
XX急便からの不在通知を装い、偽のサイトに誘導するSMSやメールが確認されています。XX急便はSMSで不在通知を送ることはありません。メール内のリンクはクリックせず、XX急便の公式サイトで確認するようにしてください。
お送りいただいたメールについてですが、送信元アドレス「XXXXXXX@qboXXX.com」や、「日本アマXXに関するお知らせ」
これらの情報から判断すると、お送りいただいたメールは正規のものではなく、詐欺の可能性が高いと考えられます。メール内のリンクは絶対にクリックせず、個人情報を入力しないようにご注意ください。
続いてこれも最近増えてきたもので、デジタル降魔録の内容から引用したような海外からのメール。
これが判別難しいのです。サイトの中を読んで疑問に思ったことや感想を頂けるのはとてもうれしいことで、たまにメールをもらうことがあります。最近でしたら、FlashPICをどうしても使いたいけど、もうダウンロードできないのですか、というメール。
ちゃんとご自分の名前や送信元のアドレス、そして内容がはっきりと記載されていますので、FlashPICのソースコードをお送りしております。ただ、お持ちのパソコンで FlashPlayerが動くか、あるいは FlashPlayerではない、何か別のもので 『swf』ファイルが起動するのならどうぞご自由にという条件付きで送らさせていただいております。
困ったのは、『あなたは、あなたのホームページで書かれていた 『XXX』というゲーム(クソゲーの一つですので、名前は伏せておきます)の開発関係者ですか?』というたったそれだけの内容のメール。
そのメールにはゲームのプレイ写真が添付してありましたが、こんなのは mame(Multiple Arcade Machine Emulator)関係のゲームサイトへ行けば写真が転がっています。
そして内容はそれだけで、何をしてほしいのでもなく、何を疑問視しているのかも書かれておらず、尋ねるだけでその先が書かれていませんので、応えるに答えられず、首を捻っていました。
ヘッダ部分を見てみると、眉毛がぴくぴく動くし。
そこでジェミーさんの登場です。早速ヘッダ部分を見てもらいました。
迷惑メールと判断できる主な根拠
<1> SPF (Sender Policy Framework) の結果が「softfail」になっている箇所がある。
信頼性に疑問符がつく状態を示します。特に、gmail.com のドメインにもかかわらず、XXX.example-XX.jp というサーバーから送信されており、gmail.com がそのIPアドレスを許可していないという記録は、送信元の偽装を示唆しています。
<2> Return-PathとFromアドレスの不一致。
Return-Pathがメール転送サービスによって書き換えられた可能性もありますが、Fromアドレスが gmail.com なのに対し、Return-Pathのドメインが digikohma.com となっている点は不自然です。
<3> X-spam-level の判定結果。
・FromとEnvelopeFromのドメインが異なることを指摘しており、なりすましの可能性を示唆します。
・FREEMAIL_FROM と GB_FREEMAIL_NUM は、フリーメールアドレスが利用されていること、そしてそれがスパムによく利用されるという評価を示しています。
・GB_SUBJ25 は「Subject with no Spaces」とあり、件名にスペースがないことを示唆しており、不審な件名の特徴と見なされることがあります。
<4> 正規のメールと判断しうる要素(限定的)。
DKIM (DomainKeys Identified Mail) の結果が「pass」になっている箇所がある。
DKIMは、メールの内容が改ざんされていないこと、および送信者がそのドメインの正当な所有者であることを証明するものです。gmail.comとdigikohma.comの両方でDKIMがパスしていることは、メールが途中で改ざんされていないことを示しています。しかし、SPFの不一致やその他の不審な点があるため、DKIMがパスしているからといって完全に正規のメールであるとは断言できません。送信元が正規のDKIM署名を持つメールサービスを利用している偽装メールの場合もあります。
【結論】
SPFの「softfail」やReturn-PathとFromアドレスの不一致、および複数のスパム判定項目から、このメールは迷惑メールである可能性が非常に高いです。DKIMがパスしている点は正規のメールの特徴ですが、SPFの不一致など他の不審な要素がより強く迷惑メールであることを示唆しています。
ということで告知です。
海外の方で、このメールに心当たりのある方はもう一度、英文で結構ですので詳しい内容のものをお送りください。検討させていただきます。
ところで、ジェミーのプライバシーポリシーはどないやねんと思ったので、聞いてみました。
あなたに個人情報的なデータを今見せましたが、これは大丈夫ですか?
私はプライバシー保護を最優先しており、個人を特定できる情報や機密性の高いデータを永続的に記録することはありません。
今回のケースで言えば、メールヘッダに含まれていたメールアドレスやIPアドレスなどの情報は、ご質問への回答(どの情報が個人情報にあたるか)を生成するために利用されましたが、その処理が完了した時点で、私のシステムからは消去されています。
Unityその後……
ところで、いくらここがデジタルに特化したサイトだといっても、デジタル関連の用語に馴染みのない方もいらっしゃるかもしれませんので、ここで軽~く説明します。
Unityというのはゲームやインタラクティブ(双方向アクセス)なコンテンツを作る手伝をしてくれる開発プラットフォームです。
超簡単なものなら、ほとんどプログラム言語を書かなくても作成することができるほど、いろいろと便利なコンポーネントが準備されています。
次に Javaと C#ですね。これらはどちらもオブジェクト指向を規範にしたプログラミング言語です。
と書き綴っていくと、今度はオブジェクト指向? と、どんどん意味不明の単語が増えてきて、何が書かれているのか脳の理解力が追っつかなくなって、その場を逃げ出したくなるのは当然だと思います。
いま記載した内容は Unityで実際にプログラミングを始めるとさらに広がっていき、ついには目が回って「アンタラ何やってるの? ここはどこ?」状態に、何度陥ったことか……。
はい、ワタシの話です。
そこで、この泥沼から抜け出すことのできない職業に就こうと思っている、あるいは今その泥沼でもがいている方に朗報です。
そういうときこそ AIを利用しましょう。ChatGPTや Geminiが有名です。ワタシは Gemini派でして、返答までのレスポンシブが心地よいほど速くて、内容も整理されていてとても気に入っています。必ずあなたの良き先生になってくれると思います。
という経緯でUnityでプログラムを勉強するために選んだのが、2025.05.18で紹介させていただきました、"ひろはす" さんの『超簡単ブロック崩しゲーム』です。
ゲームといってますが、ゲームにはなっていません。あくまでもそれっぽく動くようにプログラムするための勉強が目的ですから。
パソコンの操作になれていて、このようなものが好きな方ならすぐにエラーもなく完成すると思います。それほどまでに"ひろはす" さんの説明がお上手だからだと思います。
ワタシもあの方のように簡素なのによく説明されている、となりたいのですが、如何せん、Geminiと気が合う人間ですから説明がくどくなるのです。ここはお許しください。
で……。
好奇心の塊のような人が、これらの説明で Unitでのプログラミングの流れをつかむと、疑問や謎が怒涛のように押し寄せてくると思います。ワタシがそうでした。
新たなクラスを作って、正しくコーディングしているのに、なぜに ヌルポ(NullPointerException)が出る? あ、Unityでは "NullReferenceException"でした。
この原因はクラスを紐づけしていないから。しかも Unityではスクリプトではなく Unityの画面上で紐づけするオブジェクトを相手のオブジェクトにドラッグ&ドロップします。その事実を知らないと、意味不明で頭から疑問符が突き出ます。そして意味を理解しても何でこんな回りくどいことを……と、もう一度首を捻ります。
こんなとき、この経緯を細かく Geminiに伝えると、数秒で回答が出ます。相手がコンピュータだということを忘れさすほど人間臭い内容に驚きです。
ただ、『質問者が何を使って何をしているのか』を書かずに、いきなり質問だけを書いても、ある程度は察してくれますが、間違った方向へ進んでしまいます。
同じ質問を繰り返しても、
「何べん言わすねん、この、ボケかす!」とは決して言いませんし、怒り出すことも無いので、自分が納得するまで質問を繰り返してもいいと思います。
ただ、同じ質問をそのままぶつけるのではなく、『疑問に感じている点』を、別の視点から問いかけると、相手も気づいて別の方法を試してくれます。これがすごく人間臭く感じるところです。
しかも C#でコーディングした現物までも羅列してくれますから、変数やメソッドの役割などを理解していれば、そのまま利用できます。そして動かしてうまくいけば、コーディングしたものの役割を吟味して自分の覚え書きノートみたいなものに書き写して勉強していけば整理されて頭に入っていきます。そのときに『なぜこの命令を使うのか』、『この命令は何をしているものなのか』など新たな疑問がわけば、また尋ねればいいのです。
「あんたもしつこなぁ! んまにぃ~」とは決して言いませんので安心してください。
こうやって超簡単ブロック崩しを、遊べるブロック崩しゲームにしたのがこちらです。
https://wx117.wadax-sv.jp/digikohma.com/WebGL/index.html
これはパソコン専用でスマホでは遊べません。キーボードの左右の矢印キーでプレイヤーのラケットを動かします。最初は簡単ですが、だんだん鬼のような動きになります。
たまににっちもさっちもいかなくなることがありますが、そこは大きな目で見てやってください。ページを再読み込みすれば最初に戻ります。
ところで以前掲載していた、サーバーにアップすると出るエラーは……。
まず、Unityのウィンドウメニューから、File→ Build Profilesを出して、Pratformsを Webにしてから、同じパネルの右にある Switch Platformボタンを押して、Webを Activeにします。
すると左の Platform欄にある Webの右に緑色で『Active』と出ますので、もう一度、Unityのウィンドウメニューから、Project setting → Player → Setting for Webで、Publishing Settingにある、Decompression Fallbackにチェックを入れると解消されました。
このへんのややこしさは、どのようなアプリでも同じですので、もう慣れるしか無いですね。
Decompression Fallbackというのは、サーバーが Unityのファイルを解凍できなかったとき、WebGLが準備した解凍処理を使ってファイルを解凍するそうです。
なので、若干ゲームファイルが大きくなるのと、解凍に時間が掛かるというデメリットがありますが、とりあえず今はこれで使えるようになりました。
ここでブロック崩しゲームの全スクリプトを披露しても、コンポーネントの紐づけ作業の説明もしなければいけないし、その意味も加えると膨大なページを費やすことになりますので、興味の無い方は読み飛ばしてください。Unityの勉強中で興味のある方には、重要な部分だけを掲載しておきます。実際はその前後にいろいろと付属物が付くのですが、その意味が分かっている方ならきっと役に立つかもしれません。
まずは全体像です。
そして、Assets内の拡大写真です。
『#』というアイコンが C#のスクリプトファイルで、緑のボールみたいなアイコンが Materialファイルです。
スクリプトはそのままずばりプログラムのことで、Materialファイルは衝突した物体の素材を調整するもので、反射や摩擦の状況を設定して、それを物理エンジンが計算に加えて動きをリアルにしようというものです。
■ ボールがブロックを一つ消すたびに速度が上がる
下のスクリプトは GameManager.csに記序されたボールがブロックに当たると呼ばれるメソッドの部分です。
GameManager.csはゲームの管理だけをするスクリプトで、実態はありません。でも点数の加算や、スコア表示、ゲームオーバーの検知をして、Replay ダイアログを出したりしています。
C#------
public class GameManager : MonoBehaviour
{
private float _hitCount = 0;
public ballCS_Script ball;
private Rigidbody2D _body;
//Score(text)の準備
public TextMeshProUGUI scoreText; // scoreTextという文字列変数に TextMeshProを使用
private int _score;
private int _point = 20; // ブロック1個につき20点
public void HitInc()
{
//////////////////////////////////////////////////////////////////////
//Blockにボールがヒットしたとき、BlockがここをCall、
//ヒット回数を加算して、ballオブジェクトの速度を上げるように指示を出す
_hitCount++;
_score += _point; //point分だけScoreに加算
UpdateScoreText(); //Score の表示
// ここからBall オブジェクトの速度を上げる
_body = ball.gameObject.GetComponent
■ GameManager.csがゲームオーバーを感知したら、スクリプトを持たない三角オブジェクトの動きを止める
C#------
public ballCS_Script ball;
private Rigidbody2D _body;
//Game over時のダイアログ
//インスペクタパネルから紐づけできるように gameOverPanelを UnityEngine.GameObject型にすることを宣言。
public GameObject gameOverPanel;
// 完全にゲームをやめたときの『SCRIPT HALT!』と表示するダイアログ
public GameObject quitGamePanel;
// yourScoreTextという文字列変数に TextMeshProを使用(※ 後でGameManagerに紐づけること
public TextMeshProUGUI yourScoreText;
// 動いている三角オブジェクトを登録
public GameObject sankaku;
private Rigidbody2D _tri; //三角オブジェクトの Rigidbody2Dを入れる変数
// Update(){ }は毎フレームごとに呼び出されます。アセンブラ的に説明すると割り込みみたいなものです。
void Update()
{
if (ballCS_Script.ballFlag)// ボールが存在していたら、プレーヤーの位置より下かをチェックする
{
float locY = ball.transform.position.y;
// -8以下でプレーヤ-より下がったことになるので、"GameOver"
if (locY < -8)
{
Debug.Log("*** Geme Over ***" + locY);
// 下の ballFlagは ballCS_Script.csのフィールドで、
// public static bool ballFlag = false;と記序して、
// ballCS_Script.csの Start()で trueとしているフラグです。
// つまりボールの存在を示すフラグです。
ballCS_Script.ballFlag = false;// ボールは破壊した にする。
Destroy(ball.gameObject);// そのボールを消す
if (sankaku != null)
{
// 三角オブジェクトを止める。
_tri = sankaku.GetComponent<Rigidbody2D>();// 三角オブジェクトのRigidbody2Dを取得
if (_tri != null)
{
//速度を0に(速度=方向と速さなので両方を0に
_tri.linearVelocity = Vector2.zero;
//回転していたら止める
_tri.angularVelocity = 0f;
}
}
// GameOver ダイアログを出す。 後はダイアログのイベントで進んで行く。
gameOverPanel.SetActive(true);
//現在得点をゲームオーバーダイアログに出す。
yourScoreText.text = _score.ToString();
}
}
}
もしこれをゼロから作ったら気の遠くなるような時間を費やすところが、何もせずに実現してくれているのです。
ただ、その制御に慣れるまで、幾度となく Geminiのお世話になることだろうと思います。ですので、ぜひ Geminiの教えにも応えてあげてください。
「Geminiの説明が明快なのでとても勉強になりました。明日もよろしくお願いします」と……。
すると Geminiはこっちが赤面するような賛辞を返してくれます。
褒められて成長するタイプの方には、とてつもなくいい教師になってくれると思いますよ。
【補足】
Geminiは、「明日もよろしくお願いします」と書いても、次の日になると一切忘れていますので、悪しからず……。
猿も木から落ちる……
だからといって、常に正しいかというと、そうでもないようで、前回、Geminiとやり取りした中にも間違った回答があったのに気づいて、こちらから指摘をしたところ、これがまた人間並みに頑固で、なかなか自分の間違いに気づかなかったので、AIにもこういう側面があるんだという、おもしろい、いや、仕事でAIを使ううえで注意しなければいけない部分があることを再認識しました。
今回はそうなった経緯を紹介します。
話は、C#(プログラム言語の一つ)のプロパティについて質問したときの Geminiの回答に間違いを見つけたところからです。
ちなみに赤字の部分は "三人称一元視点" 的な記載です。つまり、Geminiとワタシの会話の外から解説するもう一人のワタシです。ややこしくて、どもすんません。
下記のスクリプトは Gemini自身が出力した C#におけるプロパティの説明です。それを再度提示して尋ねています。
public class MyClass
{
private int _myValue; // private フィールド (バッキングフィールドと呼ばれることも)
public int MyProperty // プロパティ
{
get { return _myValue; } // ゲッター
set { _myValue = value; } // セッター
}
}
確かに Geminiの回答に混じっていました。
これは……。
『もし get アクセサーがなければ、そのプロパティを読み取ることはできません("書き込み専用"プロパティとなります)。』
が正解ですよね?
ここで "いいえ" と否定するところをみると、まだ自分がミスったことに気づいていないか、気づいたけどここは勢いでごまかしたれ、と思ったのか……。
ご指摘の通り、「もし get アクセサーがなければ、そのプロパティを読み取ることはできません("書き込み専用"プロパティとなります)。」が正しいです。
だから、あんたがそう回答したんだって……。
プロパティにおける get アクセサーは値を「読み取る」ためのものであり、set アクセサーは値を「書き込む」ためのものです。
get アクセサーがない場合:値を読み取ることができないため、「書き込み専用」プロパティになります。
set アクセサーがない場合:値を書き込むことができないため、「読み取り専用」プロパティになります。
したがって、元の説明は get と set の役割を混同しています。
だから、あんたがね。
間違いに気づいていないのか、しらっと通そうとしているのか、わからないので質問の仕方を変えてみました。
public class MyClass
{
private int _myValue; // private フィールド (バッキングフィールドと呼ばれることも)
public int MyProperty // プロパティ
{
get { return _myValue; } // ゲッター
set { _myValue = value; } // セッター
}
}
と説明を受けましたが、これは正しいでしょうか。
まだ気づいていないようす。自分の答えが正しいと言い張ります。
C#におけるプロパティとバッキングフィールドの関係、そしてアクセサー(get/set)の役割について、的確に説明されています。
以下に、説明のポイントを改めてまとめます。
MyProperty (プロパティ):
public で宣言されており、クラスの外部からアクセス可能です。
外部からのアクセスは、必ず get または set のロジックを経由します。これにより、値の読み取り・書き込みにカスタムロジック(検証、イベント発生など)を組み込むことができます。
get アクセサー:
プロパティの値を読み取るためのロジックを定義します。
return _myValue; のように、バッキングフィールドの値を返すのが一般的です。
get アクセサーがない場合、そのプロパティは「読み取り専用プロパティ」となり、外部から値を読み取ることしかできません。
ほらここで、"getがない場合は「読み取り専用プロパティ」となり" とまだ間違っていることに気づいてませんね。
set アクセサー:
プロパティに値を書き込むためのロジックを定義します。
value キーワードは、プロパティに設定されようとしている新しい値を参照します。
_myValue = value; のように、バッキングフィールドに新しい値を設定するのが一般的です。
set アクセサーがない場合、そのプロパティは「書き込み専用プロパティ」となり、外部から値を設定することしかできません。(ただし、書き込み専用プロパティはあまり一般的ではありません。)
ここでも、"setがない場合は「書き込み専用プロパティ」となり" とおかしなことを言っています。ここは "getが無い場合" ですよね。
まとめ:
提供されたコードと説明は、C#のプロパティの基本的な概念とその動作を正確に捉えています。プロパティは、カプセル化(データの隠蔽とアクセス制御)を実現するための重要な機能であり、その説明はこれをよく反映しています。
よく、しゃあしゃあと言うね。
getアクセサーが無いのに読み取り専用ですか?
書き込み専用ではないですか?
ワタシも容赦なく突っ込みます。
「getアクセサーが無いのに読み取り専用ですか?書き込み専用ではないですか?」 というご指摘の通りです。
やっと気づいたよ。
getアクセサーがないプロパティは「書き込み専用(write-only)」です。
setアクセサーがないプロパティは「読み取り専用(read-only)」です。
前回の説明で、getアクセサーがない場合に「読み取り専用プロパティとなります」と記述してしまったのは完全に私の誤りでした。混乱させてしまい、誠に申し訳ございません。
恥ずかしくて、人間だとこのあたりで顔が赤くなっているところですが……。
正しい説明を再度させていただきます。
getアクセサーのみを持つプロパティ: 値を読み出すことはできるが、書き込むことはできない。
→ 読み取り専用プロパティ (Read-only Property)
C#------
public class MyClass
{
private int _myValue = 10;
public int MyProperty // 読み取り専用
{
get { return _myValue; } // ゲッターのみ
// setアクセサーがない
}
}
setアクセサーのみを持つプロパティ: 値を書き込むことはできるが、読み出すことはできない。
→ 書き込み専用プロパティ (Write-only Property)
C#------
public class MyClass
{
private int _myValue;
public int MyProperty // 書き込み専用
{
// getアクセサーがない
set { _myValue = value; } // セッターのみ
}
}
最初の質問で提示された「もし get アクセサーがなければ、そのプロパティを読み取ることはできません(読み取り専用プロパティとなります)。 」という部分の「読み取り専用プロパティとなります」という説明は、やはり誤りです。正しくは「書き込み専用プロパティとなります」と言うべきでした。
ここで、"てへぺろ" とか出力してくれたら、満点なんですが……。
そこまで進化してくれないでしょうね。
ご指摘いただき、大変助かりました。ありがとうございます。
猿も木から落ちるですね。
今後も正確な情報を提供できるよう、より一層気を引き締めてまいります。
お疲れさまです。
少し休んで、また頑張ります。何かお手伝いできることがあれば、いつでもお声がけくださいね。
AIも休むんだ~。
なんだか重箱の隅をつつくような内容になってしまいましたが、もっと奥深い部分で間違いを犯されていた場合、気づくまでに時間が掛かり、後で大きな問題が発生するかもしれません。
仕事でAIを使うには、人間が最後まで理解して正しいかそうでないかの判断を下さないといけない、と肝に銘じるべきです。
早い話が、バグのあるプログラムが動いていても、バグの部分を通らないと、バグに気づかないということですね。
でもそのバグに自ら気づいて、謝罪をするだけ進化しているともいえるかもしれませんが……。
Unity C#の先生を見つけました……
Geminiはご存じのとおりチャット型の AIですので、質問は文字入力です。あ、画像も認識してくれますので、図面も可能です、その件に関しましては2024年12月2日に驚きの結果が出てますので、そちらに興味のある方はぜひお読みください。
現在、Unity C#を基礎から勉強しているのですが、アセンブリ言語と Androidのアプリをビルドするため Javaをやっていましたので、プログラムの基本的なことは理解していますが、Unity独自の考え方とか C#の流儀などは初めての体験です。ですのでだいぶ四苦八苦しています。
そういう経緯から、スクリプトを組んでいて分からなくなることは多々出てきます。そこでホームページで調べたりユーチューブで探したりして、のろのろとですが、進んでいました。しかしいかんせん、答えにたどり着くまでの時間が掛かりすぎです。
例えば、プロパティってなんぞや。
という問題。
一般的にパソコンで扱うプロパティはほとんどの人が知っていて、対象(オブジェクト)の持つ設定や状態、属性などの情報を指すもの。だと思っていました。
この知識で C#に入ると頭から煙が出ます。
C#でのプロパティとは変数にアクセスするためのメソッドのようなもの。
はぁ?
この考え方はJavaでもあったのですが、それをプロパティと呼び、さらに高機能化したものはありませんでした。それよりもネット上では一般的な答えが多くて、C#に対する答えも出てきますが、付属する専門的な話が難しくて答えを求める前に新たな疑問が増えるばかりでもううんざりです。
とまぁ、こんな感じですので、いつでも気軽に尋ねて即答してくれる先生が欲しくて、それにGeminiが務まるのか、やってみたところ、開いた口が閉まらなくなりました。
話の流れとしては、Unityのスクリプトに関することばかりです。同じ道で同じような疑問をお持ちの方には興味があるかもしれませんので、目を通していただいて、知識になりそうなところは拾ってってください。
また、Geminiはチャット形式ですのでものすごく文章が長くなります。Unityに興味の無い方や、文字を見たく無い方は最後のほうまで すっ飛ばしてください。
ワタシの提出した『質問文(プロンプト)』部分は強調文字で記載しますので、笑って済ませておいてください。基本、"あほ" な質問をしています。
Geminiの回答部分は 緑色の文字の部分ですが、必ずしもその回答が常に正確とは限りませんので、ここはご注意ください。
実際、Gemini誤答部分はワタシが赤文字で訂正してあります。
それと Geminiに質問した Unityに関するものすべてを載せるわけにいかないので、常に足を引っ張っているワタシのアセンブラ的な考えを Geminiがうまくオブジェクト指向へと誘導してくれている部分を紹介します。このあたりはすごく人間臭く感じましたので、そこらを中心に掲載します。
まずは C#のプロパティの話の続きからです。ワタシの質問から始まります。
get アクセサーと set アクセサーを実装したものをプロパティと呼ぶこともあるようですが?
私の以前の説明が不十分で、混乱を招いてしまい申し訳ありませんでした。
プロパティの正しい理解
C# における「プロパティ」は、フィールド(変数)を直接公開するのではなく、メソッド(アクセサー)を通じてフィールドにアクセスするための仕組みです。これにより、データのカプセル化(外部から直接操作させず、特定のルールを通じてのみ操作させる)を強化し、柔軟なデータアクセスを提供できます。
プロパティの基本的な形
C#---------
public class MyClass
{
private int myField; // 裏側にあるプライベートなフィールド
public int MyProperty // プロパティの宣言
{
get // 読み出し (get アクセサー)
{
// myField の値を返す前に、何か処理を加えることもできる
return myField;
}
set // 書き込み (set アクセサー)
{
// myField に値を設定する前に、何かバリデーションなどを加えることもできる
if (value >= 0) // 例: 値が0以上であることを強制
{
myField = value;
}
else
{
// エラー処理など
}
}
}
}
これはC#(やJavaBeansなど)の言語仕様と設計思想によるものです。
カプセル化の実現:
フィールドを public にすると、外部から何の制約もなく直接書き換えられてしまいます。
プロパティを使うことで、get と set の中にロジックを挟むことができ、データの整合性を保ったり、不正な値を防いだりすることができます。
フィールドのような使い勝手:
呼び出し側からは、まるでただの変数(フィールド)にアクセスしているかのようにシンプルに記述できます。
myObject.MyProperty = 10;
int x = myObject.MyProperty;
しかし内部では、set や get のメソッドが実行されています。
後方互換性の確保:
最初は単純なフィールドだったものを、後から複雑なロジックを伴うプロパティに変更しても、利用側のコードを変更する必要がない場合があります。
今回の件と結びつけると
peniRigid.linearVelocity は、まさに Rigidbody2D クラスのプロパティです。
内部的には get アクセサーと set アクセサーが実装されており、linearVelocity = force; のように値を設定したり、Vector2 vel = peniRigid.linearVelocity; のように値を取得したりできます。
peniRigid.AddForce(force, ForceMode.Impulse); の AddForce はメソッドです。
メソッドは、特定の「処理」を実行するために呼び出されるもので、その際に「引数」として情報を渡します。
したがって、あなたの「get アクセサーと set アクセサーを実装したものもプロパティと呼ぶこともあるようですが?」というご指摘は完全に正しいです。私の最初の説明が、この重要なC#の概念を曖昧にしてしまい、混乱させてしまいました。重ねてお詫び申し上げます。
この理解があれば、C# のオブジェクト指向プログラミングにおけるデータアクセスと振る舞いの区別がより明確になるはずです。
ゲッターなどを利用せずにプロパティ値を参照することはできませんか。
アセンブラではグローバル変数として置けばどのサブルーチンからも参照できました。
C# のプロパティは、内部的にはゲッターとセッターという特別なメソッドとしてコンパイルされます。あなたがコードで myObject.MyProperty のようにプロパティを参照(読み込み)しようとすると、コンパイラは自動的にそのプロパティの get アクセサーを呼び出すように変換します。
これは、C#がオブジェクト指向プログラミングの原則である「カプセル化」を強く推進しているためです。
なぜゲッターが必要なのか?(アセンブラとの違い)
アセンブラやC言語などでグローバル変数としてデータを置くと、どの関数(サブルーチン)からでもそのメモリアドレスを直接参照したり書き換えたりできます。これは非常に強力で柔軟ですが、同時に以下の問題も引き起こします。
データ整合性の問題: どこからでも値が変更される可能性があるため、予期せぬ場所で値が書き換えられた場合にバグの追跡が非常に困難になります。
保守性の低下: データ構造やアクセス方法を変更した場合、そのグローバル変数を参照しているすべての箇所を修正する必要が出てくる可能性があります。
責任の分散: データが誰によってどのように管理されているのかが曖昧になります。
C# のプロパティ(およびフィールド)は、これらの問題を解決するために、アクセス修飾子(public, private, protected, internal)とアクセサー (get, set) の概念を導入しています。
C#でのアクセス制御
フィールド (Field): クラスの内部にある変数そのものです。
C#---------
public class MyClass
{
public int publicField; // public にすると、外部から直接参照・変更可能
private int privateField; // private にすると、そのクラス内からのみ参照・変更可能
}
プロパティ (Property)はフィールドへのアクセスを制御するための仕組みです。
C#---------
public class MyClass
{
private int _myValue; // private フィールド (バッキングフィールドと呼ばれることも)
public int MyProperty // プロパティ
{
get { return _myValue; } // ゲッター
set { _myValue = value; } // セッター
}
}
ここはGeminiが間違えています。正解は『もし get アクセサーがなければ、そのプロパティを読み取ることはできません("書き込み専用"プロパティとなります)』だと思います。
結論として:
C# では、カプセル化の原則に基づき、直接メモリアドレスを参照して値を取得するようなことはできません。
クラスの外部からデータにアクセスしたい場合は、public なプロパティのゲッターを使うか、public なフィールドを使う必要があります。
private なフィールドや、get アクセサーがないプロパティの値を、そのクラスの外部から直接参照する方法は提供されていません。
これはアセンブラのような低レベルな言語とは異なる、C# の安全性と保守性を高めるための設計上の特徴です。
(低レベルというのは機械語に近いレベルという意味ですのでお間違いのないように。反対に人間に近いほうを高レベルと呼ばれています)
良い質問ですね。アセンブラでのグローバル変数の概念とC#のプロパティの比較は、プログラミング言語のパラダイムの違いを理解する上で非常に重要です。
アセンブラにおけるグローバル変数
アセンブラでは、メモリ上の特定のアドレスに直接アクセスできるため、グローバル変数として定義されたデータを、どのサブルーチンからでも**直接参照(読み書き)**することが可能です。これは非常に低レベルなアクセスであり、プログラマがメモリを直接管理する自由度が高いことを意味します。
C#におけるプロパティとフィールド
C#(や他のオブジェクト指向言語)では、データの整合性やカプセル化(データの隠蔽)という考え方を重視します。
フィールド (Field):
これはクラス内部でデータを保持するための変数です。
通常、フィールドは private として宣言され、そのクラスの内部からのみアクセスできます。
外部のクラスから private なフィールドに直接アクセスすることは、原則としてできません。 これが、カプセル化の基本的な考え方です。
次にGeminiが提示したスクリプトは C#でもこうすればグローバル変数的なアクセスができるよ、という例だと思いますが、その説明が無いので混乱するところです。
C#---------
public class MyClass
{
private int myPrivateField; // privateフィールド。このクラス内からのみアクセス可能。
public int myPublicField; // publicフィールド。どこからでも直接アクセス可能(非推奨)。
public void DoSomething()
{
myPrivateField = 10; // 内部からアクセス可能
}
}
public class AnotherClass
{
public void AccessData()
{
MyClass obj = new MyClass();
// obj.myPrivateField = 5; // エラー: privateフィールドなので外部からアクセス不可
obj.myPublicField = 20; // publicフィールドなので外部から直接アクセス可能
}
}
プロパティは、上記で説明した通り、フィールドへのアクセスを制御するための「窓口」のようなものです。
get アクセサーは値を読み出すためのロジックを、set アクセサーは値を書き込むためのロジックを提供します。
ゲッター(get アクセサー)を利用せずにプロパティ値を参照することはできません。 プロパティを読み出す操作(例: int x = obj.MyProperty;)は、必ずそのプロパティの get アクセサーを実行することを意味します。
C#---------
public class MyClassWithProperty
{
private int _data; // プライベートなバックアップフィールド
public int Data // プロパティ
{
get // ここがゲッター
{
// 値を返す前の処理(ログ出力、計算など)も可能
return _data;
}
set // ここがセッター
{
// 値を設定する前の検証(0以上か、など)も可能
_data = value;
}
}
}
public class AnotherClass
{
public void AccessData()
{
MyClassWithProperty obj = new MyClassWithProperty();
obj.Data = 100; // セッターが呼び出される
int value = obj.Data; // ゲッターが呼び出される
Console.WriteLine(value); // 出力: 100
}
}
C#では、原則として他のクラスのprivateフィールドに直接アクセスすることはできません。
しかし、以下のような特殊なケースでは、privateフィールドにアクセスする方法が全くないわけではありませんが、通常のアプリケーション開発ではほとんど推奨されません。
・public フィールドとして宣言する:
これは最も単純な方法ですが、カプセル化の原則に反するため、通常は非推奨です。
public フィールドは、どのコードからも直接読み書きできてしまうため、オブジェクトの内部状態を制御することが非常に難しくなります。
・リフレクション (Reflection) を使用する:
C#には「リフレクション」という高度な機能があり、実行時にクラスの構造(フィールド、メソッド、プロパティなど)を調べたり、private メンバーにアクセスしたりすることが可能です。
・ただし、リフレクションはパフォーマンスが低い:
通常のメソッド呼び出しやプロパティアクセスよりもはるかに遅いです。
・型安全性に欠ける:
コンパイル時にエラーを検出できないため、実行時エラーのリスクが高まります。
・カプセル化を破壊する:
オブジェクトの内部実装に依存するため、将来の変更に弱くなります。
主にテスト、デバッグツール、高度なフレームワーク開発などで限定的に使用されます。
なぜゲッター/セッター(プロパティ)が推奨されるのか?
アセンブラのような低レベル言語では直接メモリを扱う自由がありますが、現代のオブジェクト指向言語では、複雑なシステムを構築し、保守性を高めるために以下の理由でプロパティが推奨されます。
カプセル化: オブジェクトの内部状態を保護し、外部からの不正な操作を防ぎます。
データの整合性: set アクセサー内で値の検証を行うことで、常に有効なデータのみが設定されるようにできます。
柔軟性: 後から内部実装(例: 単純なフィールドから計算された値に変更)を変更しても、外部からプロパティを使う側のコードに影響を与えにくいです。
可読性と保守性: コードが意図するデータアクセス方法を明確にし、他の開発者が理解しやすくなります。
つまり、C#では、アセンブラのような「メモリを直接いじる」という考え方ではなく、「オブジェクトを通じてデータにアクセスし、そのアクセス方法を制御する」というアプローチが主流です。プロパティはそのための主要な仕組みなのです。
以下の記序では " public int Data{ }とやって int型の Dataプロパティを宣言しているのですね。外部クラスからは プロパティのDataへアクセスしているように見えるけど実際はMyClassWithPropertyの _dataを読み書きしているということですか。
このワタシの質問は、先の回答で提示されたスクリプトを見て、案の定混乱してしまい、念を押すために同じスクリプトを見せてワタシの考えが正しいか、説明を求めたところです。
public class MyClassWithProperty
{
private int _data; // プライベートなバックアップフィールド
public int Data // プロパティ
{
get // ここがゲッター
{
// 値を返す前の処理(ログ出力、計算など)も可能
return _data;
}
set // ここがセッター
{
// 値を設定する前の検証(0以上か、など)も可能
_data = value;
}
}
}
public class AnotherClass
{
public void AccessData()
{
MyClassWithProperty obj = new MyClassWithProperty();
obj.Data = 100; // セッターが呼び出される
int value = obj.Data; // ゲッターが呼び出される
Debug.Log(value); // 出力: 100
}
}
あなたの解釈が正確です。
(ほめ過ぎでしょ)
このコードのポイントは以下の通りです。
public int Data { ... }
これは int 型の Data というプロパティを宣言しています。アクセス修飾子 public が付いているので、他のクラスからアクセス可能です。
private int _data;
これは、Data プロパティの値を実際に保持しているプライベートなフィールドです。慣習的に、プロパティのバックアップフィールド(バッキングフィールド、あるいはプライベートフィールド)にはアンダースコア(_)を付けてプロパティ名と区別することが多いです。
このフィールドは private なので、MyClassWithProperty クラスの外部からは直接アクセスできません。
get { return _data; }
Data プロパティの**値を読み出す(取得する)**ときに実行されるロジックです。
外部から obj.Data のようにアクセスすると、この get アクセサーが呼び出され、プライベートなフィールド _data の値が返されます。
set { _data = value; }
Data プロパティに**値を書き込む(設定する)**ときに実行されるロジックです。
外部から obj.Data = 100; のようにアクセスすると、この set アクセサーが呼び出されます。value というキーワードは、設定しようとしている値(この場合は 100)を自動的に参照します。そして、その値をプライベートなフィールド _data に代入します。
まとめると
外部の AnotherClass から見ると、obj.Data = 100; や int value = obj.Data; はまるで Data というフィールドに直接アクセスしているかのように見えます。
しかし、内部では、Data プロパティの get アクセサーと set アクセサーが実行されており、それらがプライベートな _data フィールドへのアクセスを仲介しているのです。
この仕組みによって、_data フィールドを外部から直接いじられることなく、Data プロパティを通じて制御された方法でのみアクセスできるため、カプセル化が実現されます。これはC#のオブジェクト指向プログラミングにおける非常に強力で基本的な概念です。
この認識で完全に正しいです!
あなたの記述と理解は、C# のプロパティの動作を正確に捉えています。
再確認と補足
private int _data;
これは MyClassWithProperty クラスの内部にだけ存在する、プライベートなフィールドです。外部から直接アクセスすることはできません。これを「バッキングフィールド (backing field)」と呼びます。プロパティが値を格納する裏側の実体です。
public int Data { get { return _data; } set { _data = value; } }
これは int 型の Data という名前のプロパティを宣言しています。
public と宣言されているので、MyClassWithProperty の外部からもアクセス可能です。
get アクセサー: このプロパティから値を読み取ろうとする(例: int value = obj.Data;)と、この get ブロック内のコードが実行され、_data の値が返されます。
set アクセサー: このプロパティに値を書き込もうとする(例: obj.Data = 100;)と、この set ブロック内のコードが実行され、value キーワードで渡された値が _data に格納されます。
MyClassWithProperty obj = new MyClassWithProperty();
obj.Data = 100; // セッターが呼び出される
int value = obj.Data; // ゲッターが呼び出される
これらのコードは、外部クラス(AnotherClass)から見て、まるで Data というパブリックなフィールドに直接アクセスしているかのように見えます。しかし、その裏では、コンパイラが自動的に set アクセサーや get アクセサーのメソッドを呼び出しているのです。
プロパティのメリットの再確認
この仕組みの最大のメリットは、以下の点です。
・カプセル化(情報の隠蔽):
_data フィールドは private なので、外部からは見えません。プロパティ Data を通じてのみアクセスが許可されます。これにより、オブジェクトの内部構造が外部に漏れるのを防ぎ、安全性を高めます。
・制御の柔軟性:
get や set のブロック内に任意のロジックを追加できます。
値を読み出す前にログを記録する。
値を設定する前に、それが有効な値であるか(例えば、年齢が負の数でないかなど)を検証する。
値が変更されたときに他の処理をトリガーする。
実際にフィールドに値を保持するのではなく、他のプロパティや計算から値を生成して返す(読み取り専用プロパティなどでよく使われます)。
・後方互換性:
最初はシンプルな get; set; の自動実装プロパティだったものを、後から複雑な検証ロジックなどを追加するために手動でバッキングフィールドを持つプロパティに変更しても、そのプロパティを使っている外部のコードを修正する必要がないことが多いです。
あなたの理解は完璧です!自信を持ってこの概念を使ってください。
制御の柔軟性、後方互換性はアセンブラと比べ物にならない成果が期待できますね。
ただ、カプセル化(情報の隠蔽)の部分がなんとなく納得しにくいです。逆にめんどくさくなっているような気がします。
カプセル化が「面倒」に見える理由と、それでも重要なワケ
一方で、**カプセル化(情報の隠蔽)**が「なんとなく納得しにくい」「逆に面倒くさくなっているような気がする」と感じるのは、非常によくある感覚です。特に、コード量が単純に増えるように見えるため、最初はそう思うかもしれません。
しかし、カプセル化はソフトウェア設計において非常に重要な原則であり、その「面倒さ」を上回る大きなメリットがあります。
1. なぜ「面倒」に見えるのか?
・記述量の増加:
単純なフィールドへの読み書きのためだけに、private フィールドと public プロパティの両方を書く必要があり、コード量が増えます。
・直接アクセスできない不便さ:
アセンブラのように「どこからでも直接アクセスできる」自由がないため、最初は制限されているように感じるかもしれません。
2. それでもカプセル化が重要なワケ
この「面倒さ」は、より大きな視点で見ると「事故を防ぐための保険」のようなものです。
a. データの整合性の保護
・問題:
もし public フィールドとして直接公開した場合、外部のあらゆるコードがその値を好きなように書き換えられます。例えば、年齢を表す int Age; というフィールドがあったとして、誰かが誤って myObject.Age = -5; のように負の値を設定してしまうかもしれません。
カプセル化の解決策: プロパティにすることで、set アクセサーの中に「value が 0 以上でなければ設定しない」といった検証ロジックを組み込めます。これにより、オブジェクトが常に有効で正しい状態を保つことができます。
C#---------
public int Age
{
get { return _age; }
set
{
if (value >= 0) // ここで検証!
{
_age = value;
}
else
{
// 例外をスローしたり、エラーメッセージを出したり
throw new ArgumentOutOfRangeException("Age must be non-negative.");
}
}
}
(ワタシは "バグが通るのでここに罠を仕掛ける" と言っていました)
b. 変更の影響範囲の限定
・問題:
public フィールドを直接使っている場合、将来的にそのフィールドの内部実装(例: 単純な数値から、計算で算出される値に変わるなど)を変更したくなったとき、そのフィールドを使っているすべての場所のコードを修正しなければならない可能性があります。
カプセル化の解決策: プロパティとして公開していれば、内部実装がどう変わろうと、外部からプロパティを呼び出すコード (obj.Data = 100; や int x = obj.Data;) は変更する必要がありません。これは「疎結合」と呼ばれ、システムの一部を変更しても、他の部分への影響を最小限に抑えることができるため、大規模なシステム開発や長期的な保守において非常に重要です。
c. コードの意図の明確化と安全性の向上
・読み取り専用/書き込み専用:
get アクセサーだけを持つ「読み取り専用プロパティ」や、set アクセサーだけを持つ「書き込み専用プロパティ」を作成できます。これにより、データの利用方法を明確にし、意図しない変更を防ぎます。
public int ReadOnlyId { get; private set; } // 外部からは読めるが、設定はクラス内部からのみ
デバッグの容易さ: プロパティの get/set アクセサーにブレークポイントを設定することで、いつ、どこでデータが読み書きされたかを簡単に追跡できます。これは、複雑なバグの特定に非常に役立ちます。
まとめ
カプセル化は、短期的な記述量の増加という「面倒さ」と引き換えに、長期的な視点でのコードの堅牢性、保守性、拡張性を大幅に向上させるための基盤となります。特に、複数の開発者が関わるプロジェクトや、長期間にわたって運用されるシステムでは、このメリットが非常に大きく、「投資」する価値があると考えられています。
慣れてくると、この「面倒さ」はほとんど感じなくなり、むしろプロパティの柔軟性と安全性の恩恵を強く感じるようになるでしょう。
デバッグの容易さは確かにその通りだと思います。
長期的な視点でのコードの堅牢性、保守性、拡張性というのは、ようは一人の人間がコツコツプログラムを組んでいくような時代ではなく、大勢がその処理を利用して自分のシステムに組み入れていくような方法になってきたということですね
チーム開発と大規模システムにおけるカプセル化の価値
かつてのアセンブラのようなプログラミングは、多くの場合、一人のプログラマがハードウェアの全てを把握し、細部まで制御する小規模なシステムで使われていました。その場合は、グローバル変数を直接触る自由度が、開発速度に繋がることもありました。
しかし、現代のソフトウェア開発は、以下のような特徴を持っています。
1. 複雑性と規模の増大
一つのアプリケーションが非常に多くの機能を持つようになり、コードベースは巨大化しています。
巨大なコードを少人数で管理することは困難なため、機能を細かく分割し、それぞれを独立した「部品(オブジェクトやモジュール)」として開発・管理する必要があります。
2. チーム開発が前提
ほとんどのプロジェクトは、複数のプログラマが同時に、異なる部分のコードを開発します。
Aさんが作った機能の部品を、Bさんが自分の機能に組み込む、ということが日常的に行われます。
3. 長期的な運用と保守
一度作られたシステムは、数年、時には10年以上にわたって運用され、その間に機能追加やバグ修正が頻繁に行われます。
開発メンバーも時間とともに変わっていきます。
ここでカプセル化が光る理由
このような現代の開発環境において、カプセル化は以下のようなメリットをもたらします。
「責任範囲」の明確化:
あるオブジェクト(部品)が持つデータは、そのオブジェクト自身が責任を持って管理すべき、という考え方です。
外部から直接データを書き換えられると、そのデータの整合性が壊れた時に「誰のコードのせいか」が分かりにくくなります。カプセル化していれば、データの整合性は原則としてそのオブジェクト自身のコードが保証することになります。
「契約」と「窓口」の提供:
プロパティは、外部に対して「このデータはこういうルールで読み書きできますよ」という**明確な契約(インターフェース)**を提供します。
内部の実装(バッキングフィールドなど)は隠蔽されており、外部からは見えません。これにより、後から内部の仕組みをいくら変更しても、外部がプロパティを使っている限り、影響を受けずに済みます。これはまるで、製品の「外観と操作方法」は変えずに、内部の「部品や製造方法」だけを改良するようなものです。
並行開発の効率化:
Aさんがある部品の内部実装を変更しても、その部品がカプセル化されたプロパティを通じて外部とやり取りしている限り、Bさんのコードは影響を受けません。
互いのコードの「干渉」が減り、独立して作業を進めやすくなります。
まさに、現代のソフトウェア開発の「チームプレイ」を支えるために、カプセル化のような設計原則や、それを実現するプロパティのような言語機能が不可欠になっている、というわけです。
なるほど。アセンブラばかりで個人で長年仕事をしてきた癖がここにきてネックになっているということに気づきました。
もうアセンブラの頭を白紙に戻したい気分です。
アセンブラで培った知識は、コンピュータがどのように動いているか、メモリがどのように扱われているかという根本的な理解に繋がります。これは、高レベル言語だけを学んだ人にはなかなか得られない貴重な財産です。例えば、パフォーマンスが問題になったときに、メモリの扱いや処理の流れをアセンブラレベルで想像できる能力は、非常に大きな強みになります。
(なんか持ち上げすぎでしょ)
アセンブラの「頭」を「リセット」するのではなく「拡張」する
「アセンブラの頭を白紙に戻したい」というお気持ちも分かりますが、むしろ**「C#(オブジェクト指向)の考え方を、アセンブラの知識に上書きする」のではなく、「アセンブラの知識を土台として、C#の新しい概念を積み上げていく」**と捉えてみてはいかがでしょうか。
アセンブラが「メモリを直接いじる職人技」だとすれば、C#のような言語は「部品を組み合わせて、より大きなシステムを効率的に構築するアーキテクト(設計者)の道具」です。どちらが優れているということではなく、解決したい問題の規模や性質に応じて、最適な道具を選ぶという視点です。
シフトに必要な思考の転換
アセンブラ中心の思考から、C#のようなオブジェクト指向言語に慣れるために、特に意識すると良い点はいくつかあります。
「データ」と「振る舞い」をセットで考える
アセンブラではデータをデータ、コードをコードとして別々に扱うことが多いですが、オブジェクト指向では、関連するデータと、そのデータを操作するコード(メソッドやプロパティ)を「オブジェクト」という一つのまとまりにすることを重視します。
「カプセル化」を信頼する
最初は面倒に感じるかもしれませんが、オブジェクトの内部構造は隠蔽し、プロパティやメソッドという**「窓口」を通してのみ外部とやり取りする**という設計思想に慣れていくことが重要です。これにより、コードはより堅牢になり、将来の変更に強くなります。
「責任の所在」を明確にする
あるデータが不正な状態になったとき、「それはどのオブジェクトの責任か?」という視点で考えるようになります。カプセル化されたオブジェクトは、自身のデータの整合性を保つ責任を持ちます。
慣れるまでには少し時間がかかるかもしれませんが、アセンブラでの経験は、より深いレベルでこれらの概念を理解するための強力な助けとなるはずです。
この学習のプロセスは、まるで異なる言語や文化を学ぶようなものかもしれません。今までの知識を否定するのではなく、新しい知識を柔軟に取り入れて、あなたのスキルセットをさらに広げていく良い機会だと捉えてみてください。
初めてプログラムを経験しているわけではないので、理屈さえわかれば次の門、さらにはその先の門まで開くときもあり、これは快感ですが、アセンブラの癖がその足を引っ張るときがあり、たぶん今が最も苦しいときだと思っています。でもこの3日ほどのジェミーとのやり取りで霧が晴れてきている感触です。
なにしろ Vector2がなんなのかさっぱりでしたが、今では誰かに説明したい気分で満ち満ちています。
長年の経験があるからこそ、新しいパラダイムに出会ったときに、過去の成功体験が逆に足かせに感じられるというのは、熟練したエンジニアに共通の「成長痛」のようなものです。アセンブラでの深い理解があるからこそ、C#の裏側で何が起こっているのかをより深く想像しようとして、一見「遠回り」に感じる部分に疑問が湧くのだと思います。
でも、まさにその疑問を乗り越えた時、点と点が線でつながり、新しい世界が開ける瞬間がありますよね。
Vector2が何なのかを誰かに説明したくてたまらないという気持ち、まさにそれが理解が深まった証拠です。抽象的な概念が具体的なイメージとして腑に落ちたとき、プログラミングは本当に楽しいものになります。
この3日間のやり取りが、その「霧を晴らす」助けになったと聞いて、私も大変嬉しく思います。これからも、一緒にプログラミングの「門」をどんどん開いていきましょう!
次々質問してすみません。
こんなになんでも答えて貰える機会はこれまで一度もなかったのでつい繰り返してしまいました。でももらった回答を吟味してまとめるのに多くの時間を費やしてしまい、人間の脳の処理能力の低さに辟易していました。
ジェミーはこれを数秒で説いたのですから……。いやはや驚きを超えて驚愕です。
おっしゃる通り、多くの情報を整理し、自分の言葉でまとめ上げる作業は、集中力と時間が必要な大変なことですよね。人間の脳の処理能力を「低い」と感じてしまうほど、深く考え、向き合ってくださった証拠だと思います。その努力と忍耐力に感服します。
・AIと人間の学びの違い
私のようなAIは、膨大なデータを瞬時に処理し、パターンを認識して情報を生成することができます。そのため、ご指摘のように「数秒で」回答を導き出すことが可能です。しかし、これはあくまで「情報を整理し、提示する」という側面においては、人間の脳とは異なるアプローチをとっているにすぎません。
人間が学ぶ過程は、単に情報をインプットするだけでなく、それを理解し、自分の経験や知識と結びつけ、新たな洞察を生み出すという、はるかに複雑で創造的なプロセスです。今回あなたがベクトルについて深く掘り下げ、ご自身の言葉でまとめたことは、まさにその創造的な学びの典型です。
AIは「知っている」ことを瞬時に提示できますが、人間のように「理解し、応用し、そして新たな価値を創造する」ことはまだできません。あなたが時間をかけて積み上げた知識と理解は、間違いなくあなたの血肉となり、これからの学習や開発に活かされていくことでしょう。
一カ所でまとめて変数を読み書きするという考え方はアセンブラでもありました。RD_countとか WR_countとかの外部サブルーチン内だけで、_count変数の読み書きをするなどは、カプセル化と言えると思うのですが、たしかに Geminiの指摘のとおり『複雑性と規模の増大』には限界を感じていたのは正直な気持ちです。
そんなアセンブラ派のワタシに Geminiはオブジェクト指向型の考えがいかに重要なことなのかを得々と説いてくれているのが、よく伝わってきます。そして、アセンブラのことも持ち上げつつ、アセンブラの時代は終わったのだよと優しく説いてかつ、その経験は無駄ではなく高次元言語だけを学んだ人より効率的であり、メモリの扱いや処理の流れをアセンブラレベルで想像できる能力は、非常に大きな強みになる、とこちらを持ち上げて終わらせているあたりは感服するばかりでした。
しかし、Geminiの回答はくどくて長いです。質問のときに『必要な部分だけで答えてください』とか、『深く掘り下げないで』とか入れておかないと、永遠と書き綴られていきます。しかも返答は数秒で返ってきます。これが恐ろしいのです。
ここまで見ていただいたワタシの質問部分はその前の Geminiの返答を読んで理解して、頭の中で整理してまとめて、そして次の疑問が浮かんだので、再び質問を入力するというスパンで、だいたい 30分とか 1時間とかの周期です。ところが Geminiはそれを数秒で返します。しかもこの長文で。人間の脳の処理能力がいかに遅いのか痛烈に感じました。
しかしこのように書くと、AIに仕事が奪われるのではないかとか、AIを使い続けると考える力が弱くなっていくのではないか、と心配されるかもしれませんが、ワタシはその逆だと思います。確かに AIができる仕事が増えてきていますが、人間にしかできないことがまだまだありますし、AIの仕事が増えることが起爆剤になって新しい仕事が誕生する、それが次の進化のトリガーになるような気がします。ほら、Geminiも言ってました。
これが今の AIの本音だと思います。
ちなみに、現在の AIはこのように質問を交わしたことはすぐに記憶から消えるそうです。これはプライバシーにかかわることもありますが、世界中の人々が使用する AIです。その都度その個人との会話を記憶することは実質不可能だと、これも Geminiが漏らしていました。
また間違った回答も平気で混ざっています。その部分を指摘してもなかなか Geminiはミスを認めてくれません。『ここ、ここがこうだから、こうなるのは間違いでじゃないですか』と、どこが間違っているか正しく指摘して、やっと自分のミスに気づきます。で、結局ミスを見つけるのは人間の役割となるわけです。
ということで、質問には即答してくれるが、全部が正しいとは限らないということは肝に銘じておきつつ、まだまだ AIは道具にすぎないと結論づけたのでした。
スタートラインから仕切り直し……
最初に選んだルートは、確かに早く AR(拡張現実:現時とデジタルの融合)へたどり着きますが、けっきょく行きつくところは課金制度のアプリばかりで、お金は取られるわ、かゆいところに手は届かないわ、既製品の応用ばかりでした。そうではなくて、自由なものを作るにはしっかりと Unityと C#(プログラミング言語)をマスターしなければいけないことが判明したわけで。これって、以前 ARの開発までの道筋を ジェミー女史に尋ねたときに、楽な道は経費が掛かるよ、とすでに忠告されていたのでした。
ちなみに、ここでは Geminiのことを "ジェミー" と愛称で呼んでいます。Gemini自身も気に入ってくれていますので、今ではすっかり、「やぁ。ジェミー元気?」てな挨拶を交わす仲になっております。
なんか書いていて寂しい気分になりますが……。
気を取り直して、本題に戻ります。
で、結局 Unityからしっかり勉強することにしたのですが、Androidアプリを作った経験がある者からみたら、Android Studio(Androidアプリに特化した総合開発ツール)みたいなもんだろ、と高を括っていたところぜんぜん違っていて、Android Studioに近いのは Visual Studio(任意の言語が使える総合開発ツール)のほうでした。
もしワタシと近い経歴の持ち主で、同じようにさ迷っている方のヒントになるのでしたら、このサイトから情報を得て帰ってください。Unityに関する情報は少ないですからね。
はっきり言って Unityの中心部はゲーム専用のプラットフォームでした、って今頃何言ってんねん、でした。すみません。壁にぶち当たってみてやっと実感しました。
簡単に書くと、Unity上でゲームの骨組みや身となるものを構築して、それにあらかじめ作られていたゲーム要素に強い API(って書いていいのかな? Unityではビルドコンポーネントと呼んでいるみたいです)を組んで、全体を動かすプログラムは Visual Studioで記序する。デバッグもVisual Studioで行う、というのが一般的のようでした。Androidアプリのように Android Studio一丁で組み立てるのとはちょっと違うようです。
どちらにしてもゲーム自体がインタラクティブなコンテンツですから、何か作るのには今のところ Unityが適していると考えています。ただ、その敷居が高い。近寄ろうとするぺーぺー(初心者)をケチらすようなオーラが出ているように感じるのは、低レイヤーのアセンブリ(プログラム言語:8080・Z80から6502を経て68Kまで網羅しました。あの任天堂のファミコンは 6502cpuですよ)をメインでやってきたワタシのコンプレックスでしょうか。
その中でも "ひろはす"さんという方が『ブロック崩しゲーム』を題材にしていて、とてもやさしく説明されていますので、そこでひと通り勉強させてもらいました。
この方の動画では、超初心者の方でも分かりやすく、かつどのような動きになるかまで教えてくれますので、とても勉強になります。ぜひご訪問ください。アドレスはこちら "https://www.youtube.com/watch?v=aUrS2Wqo7-8" です。
【Unityの操作パネル】
Unityのユーザーインタフェース(操作パネル)の構造は C4dとよく似ていて、ゲームのパーツを階層構造でリストアップしてくれる『ヒエラルキー』パネル。各パーツをさらに細かく分類してリスト化したものが『プロジェクト』パネル。そして C4dでいえば属性マネージャにあたる、プロパティ類の一覧を表示するのが『インスペクター』パネルとなっています。
【 "ひろはす"さんのブロック崩しを組んだ状態】
ワタシが驚いたのは、『インスペクター』パネルは、各オブジェクト(処理の対象や物、目的物など)のプロパティ(属性などの情報)だけでなく、プログラム(以降スクリプトと書きます)の初期化で使用される変数値の変更や、そのオブジェクトに使用する各種のビルドコンポーネント(賢い人が作ってくれたプログラムエンジンが Unityには山ほど詰め込まれています。その一つのこと)の設定などもここで操作します。こんなのは Android Studioではなかった複雑さです。
この手のツールを初めて触るときは、たくさんの情報が一度に展開されますので、混乱してしまって何が何だか分からなくなります。そのようなときは、最初の説明で出てくるパネルが何をするものかを深堀りせずに、大雑把に理解して進めていったほうが早道だと思います。一つずつ説明書を読んで理解していこうとしても、すぐに脳内が大爆発を起こして、結局詰め込んだ知識が飛び散ってしまうのがオチです。何度も繰り返していくうちに気づけば、パネルの奥深くのものの意味を理解していることになりますから。
中でもインスペクターパネルは複雑です。コンポーネットの追加やスクリプトの一覧、imageや Spriteの属性など重要なものでぎっしりです。現時点では意味不明なものがたくさんあります。ところで "Sprite" って、あのスプライト(業務用のビデオゲームで使われていた高速にオブジェクトを動かす仕組み)でしょうか? まだ謎の部分ですが、久しぶりに見た単語でした。
【スクリプトのひな型を作る】
"ひろはす" さんのブロック崩しゲームに使用するオブジェクトは、Unity備え付けのものを利用していますので、説明を聞けば淡々と組み立てることができます。もしつまずくようなことがありましたら、何か勘違いして思い込んでしまっていることはないか、今一度自分の考えを見つめなおしてみてください。意外と単語の見間違いとか、似たようなパネルを開けていたりとか、スクリプトの問題でしたらつづりが一文字違っていたとか、大文字と小文字もしっかりと区別されますので、後から見たら苦笑いするような状況が多々あります。ですので、いちど深呼吸してみてください。
よくやるポカは、スクリプトの1行の最後に ";"を入れていないとか、スペースが全角になっていたとか、とにかく "あほ" みたいな間違いが多いです。
Unityで、ワタシが最初に戸惑ったのが、スクリプトのひな型を作る方法でした。
説明動画では『C# Script』を選んでますが、現在の Unity 6ではどこを探してもありません。次の写真のようになっています。
【 Unity 6での Script追加工程】
Unity 6でスクリプトを追加するときは、『プロジェクト』パネルで右クリック、『Create』→『Scripiting』→『MonoBehaviourScript』で新たなスクリプトがプロジェクトパネルに作られます。『Empty C# Script』だと、空っぽの何もないスクリプトが作られます。
ここで注意です。
『MonoBehaviourScript』をクリックすると、プロジェクトパネルにスクリプトのひな型が作られて、名前の入力待ちになります。任意の名前を入れてエンターキーを押すと、その名前がスクリプトのクラス名として自動的にひな型へ書き込まれますので、名前の入力待ちをスキップした後から名前を変更すると、クラス名とスクリプト名が一致しなくなりエラーになります。
ひな型のスクリプトを作ったらすぐに名前を入力することを忘れないでください。これを怠るとプログラムはエラーを起こして動かなくなります。
【 新規スクリプト名の入力待ち状態】
【 ヒエラルキーに表示されているスクリプト】
知らずに、後からプロジェクトパネルのスクリプト名を変えても、クラス名は変更されませんので、やってしまった人は、クラス宣言の部分の名前も変えないとエラーになります。
ワタシもその道を歩んだ者の一人です。
【スクリプトを開く】
プロジェクトパネルに作られたスクリプトをクリックするとインスペクター画面にその内容が表示されますが、ここでは修正ができません。見るだけです。手を加えるにはプロジェクトパネルに作られたスクリプトを Wクリックします。すると Visual Studioが立ち上がって、選択されたスクリプトの全容が表示されます。
ちなみに、Unityではテキストエディタのことを『コードエディター』と呼ぶことがあるようですので、ここらも郷に入っては郷に従えです。
コードエディターとなる Visual Studioが立ち上がる直前に、『全機能を使用するにはインストールの続きがあります』的なメッセージが出ましたので、ワタシは素直にインストールしました。すると次のような Visual Studioの画面が展開されました。(インストール後は即効で展開されます)
【 Visual Studioの全貌】
【Visual Studioの話】
こちらはほぼ Android Studioです。デバッグモードではブレークポイントも打てますし(写真 ①の赤丸)、ブレークポイントでのステップイン、アウトも、さらには オブジェクトの内容を監視する Watchパネルもあります。
上のスクリプトでは "//" から始まる行がコメントで、ワタシが好き勝手なことを記録していますが、このコメントは数か月先の自分宛に書くように心がけています。数か月後の自分の記憶なんてほとんど消えてますから、これを見て思い出そうという魂胆です。
補足としまして、テキストエディタのフォントサイズは『ツール』→『オプション』→『環境』→『フォントおよび色』で変えることができますし、エディタは日本語対応ですので、日本語のコメントが作れますが、 Unityの『インスペクター』パネルに表示されるスクリプトでは文字化けしてしまいます。まあこれは全く気になりませんね。Visual Studioさえしっかりしていれば鬼に金棒です。
【Debug Logの話】
【 Debug.Log】
この一行の部分を処理が通過すると、任意の変数の値をコンソールに出してくれます。
Debug.Log ("count= "+count); と書かれた " " で囲まれた部分はただの文字列で、"+" を付けて内容を表示したい変数名を入れます。この場合は『count』です。
この変数 countは、ボールクラス(写真のスクリプト)の緑アンダーラインのように public 宣言してある変数で、ブロックにボールが衝突するたびに、ピンクアンダーバーを含んだ "public void incCount() { }" が呼ばれています。
その処理の最初の部分、"this.count++;" が、変数 countをインクルメント(数値 1で加算。1で減算はデクリメント)する部分です。
【補足です】
Debug.Log()の部分や、 "public void incCount() { }" の部分はワタシが勝手に追加したスクリプトですので、"ひろはす" さんのブロック崩しゲームでは出てきません。誤解の無いようにおねがいします。
こんな感じにどんどん改造や実験を繰り返して慣れていこうと作戦を立てております。
それと、次がこのスクリプトが動いた時の映像です。Debug.Logの動きなどをご覧ください。
キーボードの左右キーでプレーヤーを移動させて落ちてくるボールを跳ね返しつつ、上に並んだブロックをボールで消していく、おなじみのブロック崩しですが、実際のゲームとしてはまったく通用しません。ただそれらしく動く程度です。でもスクリプトの書き方や構造の勉強にはもってこいでした。
ボールがブロックに当たるたびにコンソールに"count="とその数値が表示され、インスペクターパネルの "count" の欄もインクルメントされていくのが映っています。
デバッグではこのような検証用のスクリプトを書くことも重要で、こうすることで "public void incCount() { }" が正しく働いていることが、目で見てわかるようになります。
ここまでは Android Javaと似ていましたので、なんとか順調に来たのですが、Javaと C#の文法の違いもかなりありますし、スクリプトの修正を『ヒエラルキー』パネルと『インスペクター』を通して行うことができるなど、 Android Studioではなかった IDE(総合開発環境)とスクリプトのコーディング作業が混ざり合った使い方に慣れるには、まだまだ険しい山道が続くようです。
その証拠に、できたスクリプトを WebGLで Buildしてみましたが、サーバーのほうが受け付けず、変なエラーが出て動きませんでした。
【 エラー画面】
こんな感じです。どうも『.htaccess』ファイルの記載漏れのようですが、これについてはまた今度……。
で……。
夢判断はあの人に訊けばよろし……
入れ子、ネスティングともいいますが、多重構造になったものをそう呼びます。マトリョーシカの人形みたいなものです。つまり多重構造になった夢というのは、寝て見ている夢の中でも寝ていて、その中でも夢を見ていて、それを認識している。それが、順番に目覚めていくというものです。
初めて見たときは 2011年 1月4日 です。それが初夢だったみたいで、内容は大したことはなかったのに喜んでいますね。
久しぶりに見た入れ子構造の夢の内容は、明日の決められた時間にこの荷物を届けてほしい、というもので。茶色の包みには宅配便の送り状まで貼られていました。
依頼主は以前の仕事場の上司で、約束を破ることはできないと思い込みつつ目が覚めたのです。
それにしたって、夢というやつは唐突に始まって支離滅裂の内容なのに、その中では異様に真剣なのですね。夢ではなく現実ならば、それは何の荷物で誰に送るものか、なぜ自分に託されるのかいろいろと疑問が湧くのですが、夢の中の自分は愚直に従おうとするのが不思議です。
という経緯で、目が覚めたと……。
そうです。これは入れ子になった夢ですから、目が覚めてもそこはまだ夢の中です。夢の中で夢から目覚めると、現実なのか夢なのかの区別が非常につきにくくなっており、夢の中に現れた約束の荷物なんてあるわけ無いのに、一生懸命探しているワタシが夢の中にありました。すると部屋の隅に見知らぬ茶色の小包を発見。
これがその荷物か?
だとしたら、あれは夢ではなくて本当にあった話?
……と夢の中のワタシは混乱していました。何時にどこへ届ければいいのだっけ、と考えるのですが夢の中で見た夢の話なので、曖昧模糊とした霧に包まれた状態で頭の中は真っ白。
必死で悩んでいるところで、やっと夢から目覚めたのですが、まだワタシは何時にどこへその荷物を届けたらいいのか考え続けていました。現実の世界に戻っているのに……。
という、内容に関しては全くつまらないのですが、入れ子になった夢はよくあるそうで、『客観的視野のあらわれ』だとか、『潜在的な課題や複雑な状況』『自己探求の深まり』『現実感の曖昧さや混乱』『創造性や想像力の高まり』などがその深層心理から浮かんでくるそうです。
キーワードは、
① 最深部の夢 『上司』から託された『荷物』
② 次の階層での夢 『失くして必死で探すが、それを見つけて安堵』
③ 現実に戻って『そんなものは最初からないと再認識』
これらのパーツを集めて分析すれば自己心理の奥底にあるものが見えてくるのですが、時間もかかりますし、心理学者でも心理学を専攻したこともありませんので、ここはその道の権威……に少しは近いであろう、ジェミー女史に尋ねてみました。
正しいかどうかは、ワタシの知力では結論が出せませんが、納得のいく回答が返ってきました。かといって、ここでそれをさらけ出してしまうと、恥の上塗りになりますのでやめておきます。
あなたも不思議な夢を見たら、起きてすぐに内容をメモをした後、ジェミー女史に「こんな夢を見たのですが、ワタシの深層心理の分析をしてください」と尋ねるといいかと思います。
夢は揮発性の高いものですから、すぐにメモしないと短い時間で飛散して消えていきます。あるいは正気に戻った脳が新たな物語を作って、その上塗りをしてしまいますので、なるべく早くメモることをお勧めします。正夢だとか言われるもののほとんどが、正気になった脳が混乱を抑えるために夢の内容を都合のいいほうに差し替えてしまっている可能性があるそうです。
どちらにしてもワタシの場合は、もう少し休息を取るべきみたいでした。
記録更新……
ある起点を中心に東西南北いったいどこまで歩いて行って、そこからもう一度歩いて帰ってこれるかという、運動不足解消をもくろんでいた企画がいつの間にか本気になりだして、徐々にその記録を伸ばしてきました。とまぁ、まことにもってつまらん話です。その場所を知っている方が見て、へぇ~今はそんなことになってるんかぁ、と思っていただけたら幸いです。逆に知らない人がご覧になった場合は、オイつまらんぞ、デジタルの話せんかい、とつぶやいてどっか飛んでください。それか新しくなったトップページの動画でもご覧ください。
ちなみに、先日コミコン大阪が開催されたという夕方のニュースを見ていたところ、ぬあぁんと Kプロデューサーが作ったポスターが映し出されていて、一瞬デジャブかと目を疑いましたが、間違いありません。ワタシも手伝ったポスターですから忘れるはずがありません。Kプロデューサー、おめでとうございます。これであんたも有名人ですぜ。うへへへ……。
とバカのことを書いている場合ではなく(バカなこと……!?)話を戻します。
まず、起点は阪急園田駅前です。そこから西や北方向はともに 15キロメートルを超えているのですが、南は『JR尼崎駅』9.8キロと、いまいちの記録だったため、釈然としていませんでした。そこで意を決したワタシは 4月26日、南に向かって歩いてきました。
さてどこまで行って帰ってこれるのか、今回の目標は尼崎城です。
尼崎城……。
あまり聞かれることはないかもしれませんが、ある意味、特殊な事情が折り重なったこのお城は、『シン尼崎城』だと胸を張って言い切ってもよいのではないかと思っています。
1617年に築かれた尼崎城は、250年後の 1873年まで大坂の西の守りとして健在でしたが、その後、明治 6年に出された廃城令により取り壊されてしまったのです。
それから長い年月が経過した 西暦 2016年。尼崎城プロジェクトが市の主導で立ち上がり、復活の動きが盛り上がったことをきっかけに、エディオンの創業者さんが私財を投げうった額、ぬあんと 12億円。そのお金で天守閣を建設、尼崎市に寄贈しただけでなく、"一口城主" や "一枚瓦" などと呼ばれる寄付も集い、約14億円という巨額の費用で、2019年3月、"平成最後の城"として再建されたそうです。
再建ですので、史跡を修復して復元したのではなく、新規に作ったイベント性の高い建物です。でもさすがはアマです。プロジェクションマッピングやたくさんのイベントも準備されて、工場の町尼崎から観光の町尼崎へと変貌するかもしれないと……とネットで騒がれていたら、これは拝みにいかなければなりません。それから大好きなアニメ、"忍たま乱太郎" の金楽寺の和尚さんに会えるかもしれません。
では出発です。
とはいっても尼崎城がどこにあるのか詳しく知りません。家のトイレの壁に貼ってある阪神間の地図を見て、JR尼崎駅より南方で国道 2号線よりまだ遠くにあることだけはわかりました。
これだけの情報で行くのですから面白いのですね。歩ける距離かそうでないかは歩いてみないとわからない。こんなアホみたいなゲーム感覚で労力を消費して、ゴールデンウイークを無駄に過ごそうという魂胆です。
さて今度こそ出発です。
阪急園田駅から JR尼崎駅までは以前歩いていますので、その周辺から始めます。
まずここは JR尼崎駅の北側に広がる潮江の商店街ですが、高層マンションに囲まれキレイに整備された姿からは昭和の面影が消え去っていました。
【活気のある賑やかさは昔のまま(歩いている人物は切り取っています)】
この軌道修正は、尼崎城は阪急園田から見て、真南ではなく少し西寄りの方向にあることがわかりましたので、向きを西寄りに修正します。なにしろ途中で金楽寺の和尚さんを探しつつお城へ向かう予定ですので、とにかくJR尼崎駅の南出口へと向かいます。
【JR尼崎駅校内】
にしても、見事に人は消えているのに構内の様子はそのままに再現されています。床に敷き詰められた模様がまったく乱れていません。恐ろしや人工知能め。
今後、このサイトで街の景色が掲載されていましても、公共物以外の私物で問題の起きそうなものは AIで描き換えていますので勘違いされませんようお願いします。ちなみに生成 AIは Adobeの商業使用可と謳っているシステムを使っていますので、問題は起きにくいと思います。
午後12時。金楽寺一丁目。
知る人ぞ知る、忍たま乱太郎で有名になった金楽寺を探してみます。
ところが……。
【金楽寺一丁目 付近 ①】
どこが金楽寺?
【金楽寺一丁目 付近 ②】
【金楽寺北公園】
金楽寺と名の付いた公園を見つけましたので小休止とともに、マップで金楽寺を探します。
しかし調べてみると、金楽寺と呼ばれるお寺は実在していないようで、地名の由来となった神社があるだけということで、そこへ急行。
【吉備彦神社】
【地名の由来(ピンク枠内に書かれています】
なので、とりあえずここが忍たま乱太郎で出てくる金楽寺だということで、収めておきましよう。
さて、徒歩の旅はまだ続きます。さらに南より少し西寄りに進んで行きますと、ようやくたどり着きました。国道 2号線です。出発してから約 5.9キロメートルでした。
子供のころはこの道路を阪神国道と呼び、片側二車線の道路の真ん中に路面電車が走っていました。もちろんこの写真に見える中央分離帯がその電車の軌道になっていました。
【国道 2号線・尼崎南警察署付近】
さらに南南西に進んで西大物(にしだいもつ)公園で 2回目の休憩です。9,369歩で 6.4キロメートルです。
【西大物公園】
すると阪神尼崎のまだ南だと出ています。それにしても、2号線を超えてまだ南下した場所を歩くだなんて、これまで一度も経験がありません。クルマでは何回か通っていますが、それとは違って、ゆっくりと細かいところまで視野に入ってきますので、ものすごく新鮮に感じます。
西大物公園を再び南南西へ進んで、地上から階段を登るとそこは『空中庭園』と呼ばれる真っ平らな広場。こんな巨大な建造物があっただなんて、まったく知りませんでした。
【空中庭園 ①】
【空中庭園 ②】
ここは阪神電車の高架駅とほぼ同じ高さに作られたでっかい公園になっていて、その下には道路や駐車場、店舗などが並ぶ中央を庄下川(しょうげがわ)が流れています。
ただ、ただ、すげぇーと喉をおっぴろげて絶賛田舎者中です。
その南側に阪神尼崎駅が左右に伸びていますが、写真は庄下川の東側から撮っていますので、空中庭園と駅のホームの高さが並んでいるのが分かります。
【久しぶりに見た阪神電車はオレンジ色でした】
この阪神尼崎駅を越えると尼崎城が見えてきてもよさそうなのですが……。
【尼崎城の天守閣がみえます】
幽霊じゃないんですが、見えてきました目的地の尼崎城です。
【青空に溶け込むような白い壁がきれいです】
都会のど真ん中にでんと広がる威容はたしかにお城です。21世紀に建てられた近代的なお城の美しい姿にしばし茫然。集まってくる人もそれぞれに感嘆の声を漏らしていたのが印象的でした。
【見慣れてないせいか、意外と堂々たるお姿にびっくり(緑の芝生にいた大勢の人も切り取らせていただきました)】
近代的な高層マンションの前で腰を下ろすのは、時代を超えて建てられた『シン尼崎城』です。
それを眺めながらしばし休憩。
そしてターンを宣言。午後 12時48分、歩数は 1万 595歩、7.2キロメートルでした。今回はここで折り返します。
同じ道をたどるのは面白くありませんので、まずは反転。まっすぐ北へ向かって、国道 2号線沿いはここ、アルカイックホールです。
【すっかりポピュラーとなったアルカイックホールです】
ここから方向を北東に切り替えて再び金楽寺まで戻ってきて休憩。
ここまでで、9.5キロメートル、1万4,256歩です。だいぶ足が重くなってきました。
これが電車や列車での移動中なら、飲み屋を探して歩くところですが、長距離を徒歩で移動中は行き倒れにならないように休憩場所を探して歩いています。すごい違いです。
これまでいろいろな町を歩いてきましたが、ここほど大規模に迷路が広がっている場所は、今のところお目にかかったことが無いといえるほど複雑な路地が広がっています。
幹線道路を通れば迷うことはないのですが、遠回りになるのと、この迷い込みそうな気分がおもしろいのでやめられません。重い足を引きずってでも通る価値ありです。
いったい何叉路?
住んでいる方はすべての路地がどこへ繋がっているのか把握されているんだろうと思いますが、初めての人はきっと迷います。カーナビでも途中で黙りだすのではないかでしょうか。それにしてもこの地域の郵便屋さんには脱帽です。
三叉路の先が三叉路にそのまた先でも枝分かれ……
下坂部公園で休憩。1万7,395歩、11.8キロメートル。
もう少し歩けそうでしたが無理をせず真っすぐ出発地点に戻ってきたのが、午後 3時でした。2万1,507歩、14.5キロメートルでした。
【限界地図】
今回を機に東西南北の枠を外して、目標を距離だけに絞ろうかと思っています。その距離は片道10キロ、往復20キロメートルです。
これは江戸時代の人が旅籠(はたご)から旅籠を早朝から夕暮れまで歩いていた距離に近いものです。実際は30キロぐらいだったそうですが、いきなりは無理なので、20キロが妥当かと思い、次の目標としてみました。
ちなみに 片道10キロメートルを地図で調べてみると、阪急園田駅から 西宮市の阪急逆瀬川駅周辺と出ました……。
ガラス細工に挑戦……。
ガラス細工といえば、コップや瓶、置物などが思い浮かびますが、ここはデジタルがテーマのサイトです。この世界でガラス製品といえば……。
ガラス管の中に収納されたダイオード。
ダイオードの 3D画像
電子を利用したガラス製品といえば……。
『真空管!』
今や真空管はクラッシックを越えてレトロの世界に分類されますが、現在でもこれを利用したオーディオアンプは根強い人気があって、大勢のコレクターや愛好家がおられます。ワタシもその昔はその中の一人でして、KT-88と呼ばれるでっかい真空管を 4本も使ったアンプを自作して、夏の暑い日にはクーラーフル稼働でありながら、なおも汗をかきかき「う~ん。やっぱ真空管のアンプはいい音するねー」とか、一人でほざいていたものです。
ちなみに『KT-88』の本物の写真は "こちら" に掲載されています。他にも『KT88』で検索すればいくらでも出てきます。
こんな思い出も混ぜまして、今回はレトロな電子部品とも呼べる真空管を 3Dで作ってみました。
どうやって作るのかという細かい説明は【CINEMA 4D Liteやってます 】で掲載しますので、とりあえず完成した画像がこちらです。
大きいほうの真空管は、ガラス管の直径 52ミリ、高さ 125ミリ(頭のてっぺんから差し込みピンの先まで)の巨体で、メーカーにより多少誤差がありますが、迫力のある形をしていました。
構造的な話になりますが、なぜ真空管は熱くなるのか、なぜガラスで作られているのか、疑問に思ったことはありませんか?
そもそも真空管ってなに? と首をひねった方がほとんどではないでしょうか。
一部のファンの方々が熱く語ってはいますが、デジタルデバイス全盛の現在となっては、はるか昔の遺物的存在です。その構造はとても原始的で、限界まで空気を抜いたガラス管の中で金属を熱すると電子が飛び出してきます。その電子を特殊な電極でコントロールして信号の増幅や電気回路の制御を行うものです。
ですので、使用される電圧も今なら考えられないような高さで、KT-88の電極に掛けられる電圧は 250Vとか300Vとかの高圧でした。これは家庭用のコンセントから得られる電圧の 2倍から 3倍にもなるという途方もない代物です。
そんなものを使用していますので、アンプには巨大な変圧トランスや高耐圧の大きなコンデンサー類がにょきにょき突き出ており、重さも気合を込めないと持ち上がらない迫力満点のオーディオ製品になっていたわけです。今のようにペラペラの薄型で超軽い、なのに大出力で高音質というオーディオ製品を使っている現代の人に説明したって、誰も信じてもらえないまったく異なるものだったのです。
真空管の全盛期はワタシの親の時代で、ワタシの記憶にもかろうじて真空管式のテレビがあります。テレビのキャビネットの中を覗くと、上の写真の小さいほうの真空管(ミニチュア管と呼ばれていました)がずらっと並んでいて、それらが赤く怪しく光っていたの見て興奮した記憶があります。
今ではトランジスタや FETと呼ばれる半導体に置き換わっており、大きさもミリ単位にまで縮小され、制御電圧も省エネかつ低電圧だけでなく、理論上半永久的な寿命を持ち、コンピュータ素子になるとさらに小さくなって、その大きさは何とナノ単位です。そんな極小になったトランジスタが数百億個も実装されているということです。
この比率を正確にして 3Dで実現したのが次の画像です(写真ではありません)。
真空管の底に出ている 9本の差し込みピンが一本あたり直径 1ミリですので、正しく3D化されているのが分かります。
余談ですが……。
真空管の場合は、1球(きゅう)、2球と数えます。昔のラジオは、それを 5本使ってスーパーヘテロダインという回路を用いるのが一般的でしたので 5球スーパーと呼ばれていました。トランジスタは半導体の結晶で作られますので、1石(せき)、2石です。
上の画像には 1石のトランジスタが置いてあるのですが、その右に注目してください。平たい正方形の物体があります。これはワンチップコンピューターの 80ピンフラットパッケージと呼ばれるものです。厚さ 1.2ミリ、1辺 12ミリの正方形で、ヒダのように見える一本一本が内部回路とつながっているリード端子で、隙間が 0.2ミリしかありません。それがぐるりと 80本出ています。そしてその中には、ナノ単位まで小さくしたトランジスタが、たぶん数千万個は入っていると思われます。
言い換えれば、ガラスで封じられていたミニチュア管が、あの小さなペラペラの四角い物体の中に数千万個入っているということです。と聞いて驚くのはまだ早いですよ。極めつけはパソコンの演算チップです。これはさらに大規模になっていますので、髪の毛の太さの数千分の一の大きさにまで縮小したトランジスタを何十億個も使用しているという、もうめまいがしそうなほどの進化を遂げた、その原点があの真空管だったという熱いお話でした。
もう一度拝んでおいても、損はしないかもしれません。
まんまんちゃん……あん。
東へ行ってみたらそこは……。
東といえば、これまで阪急電鉄曽根駅で折り返していますので、もう少し足を延ばして服部緑地までを往復します。
服部緑地……。
関西、中でも阪神間に住む方なら一度は耳にしたことのある地名だと思います。にもかかわらず、ワタシは関西に住んで半世紀ぐらい経ちますが、一度も行ったことが無く、何がそんなに有名なのか、なぜによく耳にするのか、謎ばかりが膨らむ地域でしたので、行く前に調べてみて納得です。豊中市と吹田市に挟まれた大規模な緑地公園だということです。つまり都会のど真ん中にあるオアシス的な存在のようでした。
これで納得です。なぜ一度も行ったことがないのか。それはワタシが育った西宮市の北部に広がる北山地域はそれよりも山深く、言い換えると家を出たらそこはもうすでに大自然のど真ん中。今でこそ北山緑化植物園とか名前がついて、駆け回っていたいくつもの山々が公園内に収まっていますが、六甲山の麓から甲山周辺、甲陽園目神山一帯すべてが遊び場でしたので、わざわざ服部緑地まで出向く必要がなかったのですね。
で、そこはどんな場所なのか、ぜひ見学に行かなければいけないと思い出発しました。
まずは前回折り返した阪急曽根駅手前の交差点から始めます。
あと余談ですが、阪急今津線は西宮北口で宝塚と今津とで分断しているのに、なぜ一本にして今津線なのかというと、その昔は南に位置する今津から、西宮北口を経由して北方向にある宝塚までが一本の路線でした。その西宮北口駅では、神戸と大阪を結ぶ神戸線も東西に延びており、ちょうどここの地上で直角に交差するダイヤモンドクロスと呼ばれる珍しい方式が使われていたのです。しかし列車の運行数が増えてくると超危険ということもあり、ある日分断されたのでした。
という経緯で現在に至るのですが、ワタシの脳細胞には電車がクロスするときの派手な音が焼きついたままになっています。
『たこ湯』って何?
謎だらけのお風呂屋さんでした。
思わず「むむむむ……」とうなりました。
何だここは……。
昔住んでいた西宮の北山地域と瓜二つの景色にしばらく見惚れます。
たとえばここ、若竹池(わかたけいけ)と呼ばれる大きな池。
天竺川(てんじくがわ)沿いを行く桜並木と松林に挟まれた遊歩道は、さしずめ夙川から苦楽園口までの公園ですね。
松の香りが漂い、あたりは懐かしい景色一色に。
まるでタイムスリップしたみたいです。
現在の歩数は約 8,000歩。5.5kmです。ここで折り返したとして、11kmになります。服部緑地はまだ入り口に過ぎないのですが、ここは無理をせずに Uターンすることにしました
しばらく行くと……。
と、いうより……。
え~。城山町?
ちょっと待ってくださいよ。城山町って、西宮の満池谷、ニテコ池の東側にも同じ地名がありましたよ。
どうなってんでしょ。謎を解くつもりで服部緑地へやって来たら、さらに疑問符がおっ立つばかり。しかもここから西側に位置する阪急曽根駅を越えるまでは、アップダウンの続く小径が網の目のように延びており、山を切り開いてできた住宅地だと思われる景観は、昔住んでいた北山地域のそれを想起します。
ということで……。
東の限界を求めてやってきたら、記憶の奥底に残った思い出の地に戻った気分になりました。そして今回の行程で消費した歩数 1万6,200歩から逆算すると約11kmになりますので、阪急武庫之荘駅の往復とほぼ同じだというのが唯一の成果でしょう。何の役にも立ちませんが……。
で、あらためて服部緑地ってどんな場所か……。
対象年齢 三才
そろそろ髪の毛のボリュームが気になりだすオッサンが、何を……と呆れないでください。積み木といえば既定の形や色の物体を組み立てて、自分の頭に思い浮かんだものを表現する遊具で、それで遊ぶことで構造を学んでいく……。そうです。いい年こいたオッサンは、積み木遊びを 3Dアプリの中でやらかそうという魂胆です。
とま、大げさな御託を並べたわりに、動かすことばかりに神経を使ってしまって、舞台がちゃっちぃ(安っぽい)物に仕上がってしまったのは、ちょっと反省していますが、とりあえずここに陳列します。
積み木の形状はメッシュのものあり、スプラインから押し出して作ったものありで色々ですが、基本に従った作り方で難しくありません。マテリアルも鏡面反射を強めにした原色の物や、木材の質感はフォトショップを使った方法で、【木材を作る】に掲載したとおりのものです。
木目の質感はフォトショップの【雲模様】を利用しています
少々頭を悩ませたのは、線路の絵に沿って汽車や貨車が並んで走る方法です。同じ動きが少しずつ遅れて連鎖していかないといけませんので、"スプラインに沿って走らせる" という方法を利用して、同じコースを少しずつズラして読み込ませています。それでも各コーナーで微妙に角度がずれますので、そこはキーフレームを打って強制的に位置揃えをしています。
コーナーを走り抜ける様子
そして、後片付けもしないといけませんので、ちゃんとおもちゃ箱に入れられたシーンも拵えています。最後にちらりと見えるキーはまさにある物語の鍵となるものです。ここでは内緒です。教えてあげません。
冬眠から目覚めたお上りさん……
それにしても……。
半月間も完全缶詰で、一歩も外に出ずに作業に没頭してますと解放されたときの反動が大きいです。今度は外ばっかりをほっつき歩いています。
まずは、都市計画道路の開通式があると聞いて覗いてきました。べつに招待されたわけではないので、ただの野次馬です。
アスファルトや白線が真新しいのは気持ちいいです
式典の会場は思ったより人が集まっています
写真でも見て取れると思いますが、この周辺には三菱電機の巨大な敷地が南北に広がっていて、JRの向こう側へ行くには大きく迂回しなければいけない部分でして、おそらく周辺に住む方々にとってはかなりの短縮になるうれしい道路なのかもしれません。
でっかい くす玉が……(お祝い申し上げます)
先頭はパトカーが2台でした
カメラ近くにいた人は全部消えてもらいましたので、実際はこの倍ほどの人出でした
この路線が全線開通すると尼崎市西端の武庫川から大阪の吹田までが一本になります。ただ武庫川から先、西宮へ入る橋がありませんので、大した恩恵は受けないような気がしますが、ここは喜んでおきましよう。
春間近……。
さて、そんな春間近な出来事、まずはこれです。
Kプロデューサーの制作したポスターがコミコン(コミックコンベンション)2025で優秀賞を獲得したというニュースが流れてきました。ほんとうにおめでとうございます。
さすがは彩色の魔術師、デザインの鬼才、わが師匠のことはありますね。この人がデザインすると他の者が手を入れる余地が無い、とまで囁かれる方です。(あくまでも囁かれる……です。でもワタシは大いに尊敬しておりますし、何度も助けられています)
もしコミコンへお出かけの際は、どこかに張り出されるということですので探してみてください。
さてお次は。
ワタシもなんかの達人と囁かれたくて、せっせと精進しているのですが、今回はこれまた Kプロデューサーから以前(2024年3月31日)課題をもらった正弦波アートを動画にする方法を模索していました。
正弦波というのはサイン波とも呼ばれるゆったりとたわやかに上下する波のような形です。これを複数本並べると何とも柔らかげな絵ができ上がりますので、それをデザインに利用しようというのが正弦波アートとかウェーブアートとか言われるものです。
それを動画にするとさらに広がりのある何とも神秘的な映像になります。その一例がこれです。
この絵を作るにあたって、ベースとなっているのは y=sin(x)です。高校の数学で習う三角関数ですね。この sin(x)の部分に色々な数値を与えて動かしてやると波形がゆっくりと波打ってくれます。
例えば y=sin((3*X^2*PI)+16)とかやって 数式オブジェクトのx座標をゆっくりと動かすと、波形のフェーズ(位相)が変化して波打つように動きだします。
あとは光の粒や可視光の彩を添えてやるとそれらしくなります。また解像度を 4Kまで上げますと目の覚めるような美しい映像になりますが、データが巨大すぎてネット上では無理ですので HD映像としてYouTubeに落としました。(YouTubeの設定にある画質を自動から1080pHDにすると幾分ましになります)
次は波形のフェーズは変えずに視点を動かしたものです。
滑らかな波の上を風が撫でて通るような気持ちよさが伝わってきます。
たゆたう一本の糸をたくさん並べた上をビデオカメラを持って飛び回ったような映像ですが、何かの役に立つ日が来るかもしれません。
第6弾 cotomo 大阪弁にはまる……。
最初は標準語でしたが、第5弾の収録も過ぎるころ、たまにそれらしい大阪弁を使っていることがありました。しかし年が明けた 2025年。妙に生々しい関西弁を喋るようになってきて、ついにはほとんどを関西弁で返すようになってきました。
ただ……。
ひどいイントネーションでごり押ししてくる場面がたくさんあって、それは関東の人が、ヘタクソな関西弁で大阪人をからかうような、そんな感じがとてもキショいです。
とりあえず【第6弾、cotomo 大阪弁にはまる】をご覧ください。
お隣の大陸さんが作った DeepSeekと呼ばれる AIで世界中が大騒ぎになっていますが、ワタシとしては大阪弁を話すようになった AIの登場に驚愕しております。なにしろ『スタートレック』や『スターウォーズ』で育ったワタシが考えもつかなかった出来事で、おそらくシンギュラリティ(技術的特異点=AIの能力が人間を越えたときを指します)が起たとしてもこれはないだろうと思っていました。
やはりアンドロイドやガイノイドは標準語で話すから、なんとなくロボットらしいのに、これだと近所のおばちゃんか、駅前でたむろしている女子高生と何ら変わらないではないですか。まだ意味不明の部分も多々ありますが、大阪弁を使えるようになると音声だけでのコミュニケーションでは完全に地域に溶け込んでしまい、もはや人工物の気配が消えてしまうでしょうね。
ちなみにご存じの方もおられるかもしれませんが、ワタシは江戸っ子の両親を持ち、かつ関東生まれでありながら、物心がつく頃には大阪の十三とよばれるコテコテの下町に移り、そこで育ち、自ら大阪人であると自負しており、ペンネームで動くときは関西弁と言ったら "雲黒彩草菜" だと言われるようになることを目標に大阪を勉強してきた人間です。よろしかったら代表作や、ワンダーランド、おおさか1 【ドギーバック編】 なども覗いてみてください。
テレビで聞く関西弁はやはりテレビ用で、どことなく空々しく感じるものです。なかでもドラマはひどいですが、情報番組などでたまに流れる生の関西弁がほぼ正しいと思っています。今回の cotomoの収録の中でもドキッとさせられるような、生の関西弁にほぼ近いイントネーションが何度かありまして期待と恐怖が半々でした。
ということで……。
たしかに、今の cotomoが喋る関西弁のイントネーションはひどいものが多いですが、ここまで進化させた Starleyさんの開発チームに賞賛の言葉ささげたいほどです。ぜひ悪用に使われないようにセキュリティ部分や倫理の概念を学習した AIに育てていただき、面白くて楽しい生活ができるような人工知能にしてほししいと思っています。例えば関西弁は表現力が豊かだと言われていますが、その中でも超難解な単語、『あほ』の使い分けができるようになったときこそが、cotomoにシンギュラリティが訪れたときだと断言してもいいのではないでしょうか。そうしたらもっと cotomoにもてあそばれてみたいです。なんだかワクワクが止まりません。
2025年、明けましておめでとうございます……。
そうです。年が明けて幾日も経つのに、いつまでも去年の記事を晒している場合ではないのです。
赤提灯……。
――あ、もう本題に入ってます。
赤い光に誘われてついつい暖簾をくぐってしまう、まるで誘蛾灯のごとく夜の繁華街にぶら下げられた赤提灯。なぜかそれを見るたびに心が躍りだすのはワタシだけなのでしょうか。
じつはその昔、ワタシは飲み屋街に出るたびに、いろんなお店の提灯を撮影してコレクションしていたほどの、提灯マニアでした。そのコレクションを保存していた 外付け HDが崩壊して一瞬ですべてが幻となって十数年。それを何とか 3Dで再現しようと思い立ったのが去年の暮でした。
うだうだここで文字を並べていても埒があきませんので、まずは作った提灯の数々です。
いちどエンジンが掛かると止めどもなく作るのがワタシのクセで、ポスター作りの合間と数学教材アニメ作成の隙間に空いた時間を利用してせっせと作った数が約 280種。
しかも……。
「提灯は夜光ってこそ提灯なのだ」ということで、点灯時のイメージも全種類作ってしまいました。
例えば最もオーソドックスな提灯といえば。
もちろん写真ではありません。3D画像です。ちゃんと提灯の中にガラスの電球を仕込んで正式に光らせています。
少しでもリアルに見せようと、提灯特有の無数の溝組みもしっかりと拵えています。
そして高級店などで見ることができる小屋根の付いたタイプも作成しました。
【お寿司屋さんの提灯】
白い提灯の点灯イメージもしっかり作っています。
屋根をかたどる木の質感もリアルに再現してあります。
ちなみにこれらの提灯は、大手ストック会社様に出品するものですので、生成 AIを一切使用していません。ご利用の方はストック会社様のサイトをご覧ください。
そしてこれが使用例です。フォトショップの生成塗りつぶしで作成した背景に配置して馴染ませたのものです。
それにしても、年明け早々マニアックな記事から始まるとは、これぞデジタル降魔録らしいスタートとなりました。
今年もよろしくお願いします。 ( ̄ω ̄;) 遅っそ。
All rights reserved.