Apple Vision Pro ゲーム開発unity navmesh
ar plane managerで平面検知した後、その平面を元にnavmeshをつくって、キャラを追従させる動きを作った。 でも全然動かなくて。 3時間くらい格闘して、 原因はapplevision proのy座標が高いことだとわかった。
cameraの位置を取得して、そこに向かわせているわけだけど、y座標が高すぎると、ai navigationは到達不可能と判断するわけ。
ColorfulBoxでgmailメール smtp
情報が少なくて簡単なのに時間かかりました。 ので、共有。
まず2パターンのやり方あります。
2.colorfulboxのsmtpサーバを使う
1のやり方は gmailのアカウント作って、アプリパスワード的なやつ作って、その設定をコードに書けば良い。 外部サーバーを使ってメール送ってるわけだから、サーバーによる差がなくて、情報いっぱい。
ので、2について! cpanelから電子メールってところがあるからそこから新しいアカウントを作ります。 そのあとメールの確認みたいなところから、 roundcubeっていうguiをopenします。 そしたら初期メールに必要な設定が全部書いてあります。
ぬまったところ!
$mail->SMTPSecure = 'ssl';
phpmailerのコードの一部ですね。 PHPMailer::ENCRYPTION_STARTTLSこれにしてました。 まじで2時間くらい気づかんかった。
初期メールを見ると、ポート番号とかssl/tlsとか書いてあるので、言われてみたら何してんねんってなるけどね笑
まとめ
これでグダるのはずい
合宿免許どうなんって話
合宿免許行きました。
合宿免許最悪とかいう意見きくと心配になりますよね。 でも通うのめんどいし。
安心して! おれは合宿免許めっっちゃ楽しかったです!
寮の環境は 別に悪くなかったです。場所によるんやろーけど。
スケジュールは最初キッツかったです。 学科がね。 でも、後半は暇でしたー。
仮免とか落ちたら延泊なるのはきつかったです。 意外と延泊の人多いです。
運転上手くいかん日でも、何コマも授業入っているのは ちょっときつかったです。 最初運転っていう作業がすごい疲れた。
日常生活は友達といったので、ずっと楽しかったです。
ご飯はしらん。自分らは自炊でした。 これは大変やった。
あと出会いはあります。 男友達も女友達もかなりできました。 (合宿終わったら遠距離になっちゃうけど) 合宿に来た人同士は、まじで仲良くなれます。 通いの人も、チャンス少なめやけど仲良くなれます。 複数で運転する授業とか、一緒になれる機会がちょこちょこあるので。
まとめ 合宿免許おもろいと思う
高校生が小説で稼ごうとした話
春休みバイトさぼってたら暇になったので 在宅金稼ぎしよう! ってなりました。
プログラミング、在宅バイト、ユーチューバー、転売屋 etc
いろいろ考えたけど、 小説家が手軽かなーって。 勝算めっちゃ薄い気がするけど笑
一週間ぐらい頑張ってどんくらい稼げるか試しました!
アルファポリスっていう小説投稿サイト使いました。 読まれることによってポイントが貯まってきます。
六個くらい小説書きました。 未完なんですけどね。
大体一作品20,000文字くらいかな
アルファポリスってシステムが特殊で、 効率よく稼ぐために意識せんなんことが結構あります。 調べたら出てくる。
で!結果!
26円稼ぎました!
時給は計算しません萎えます。 でも、意外と稼いでません? 正直、五円くらいかなーって思ってました。
十二月に小説書きまくって、 ちょっとずつ公開していくっていうのを一月までやってました。 で、今四月。
12月 10円 1月 15円 2月 1円 3月〜 0円
でしたね。
正直、おれの小説全然読まれてないです。 でも20円稼げるんで、 そこそこ頑張ったらお小遣い稼げる? ってかんじです。
文字書くの好きな人は 意外とありだと思います!
まとめ くそ時給やけど、継続すれば稼げそう。 (俺は継続しない)
高校生がプログラミングで稼ぐ話
プログラミングを学んでいて、どうせならお金に繋げたいなって思ってLancersで仕事を受注しました。
sns てきなwebアプリを作ってくれって依頼でした。 (3,4万で) 勉強がてらやるので2,3万という激安価格でやりますよーって言ったら、 まじでやることに。
reactがよかったけど、phpがいいって言われたのでとりあえずそれで。 二週間くらいでプロトタイプ提出。 すると、改善点が十個くらい送られてきました。 これの繰り返しで、作業始めてから、四ヶ月くらい経ってます。 (一ヶ月くらいで終わらせます!とか依頼者に言ってました笑)
世間は甘くないっていうの知りました。 作業すればするほど、時給下がっていくのがつらい。
あと、依頼者って基本的に知識がないので、説明不足だとすれ違いがいっぱい生じて気まずくなります笑
それと、機能の追加要求が思ったより多かったり。 自分では修正できないからしょうがないことなんだろうけど。
愚痴みたいになった笑 だるいけど、経験にはなっているかなと思います。 やってみないとわからない苦悩がいっぱい。
レンタルサーバーとか使わせてくれたのはデカかった。
1回目だから、お金目的とゆうより経験目的に比重を置いて受注したけど、
しょうじき ちょっと後悔します!
やっぱお金!大事!
なのである程度仕事を選ぶことをお勧めします。 プログラミングできる高校生って社会的にそこそこレアなので 自信持ってお金いっぱいもらいましょう。
lancersながめてると、 今やっている仕事よりもちょろそうなのに、値段3倍くらいのやつとかあります。 僕の失敗を生かしてください。
まとめ
Lancersで"うまく"やれば稼げると思うよ!
TypeScript 粒子アニメーション
粒子のアニメーションを作る。
particle.jsとかは使わずに自力で実装する。
こちらの記事を参考にしまくる。
参考にした記事はjsで書いているが、
僕はreactで開発していたので、tsxに書き直した。
import "./Article.css" import React, { useEffect, useRef } from 'react'; const Article: React.FC = () => { const canvasRef = useRef<HTMLCanvasElement>(null); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; console.log(canvas); const ctx = canvas.getContext('2d'); if (!ctx) return; let intParticle = 0; let aryParticle: any[] = []; let canvasSize: { width: number; height: number } = { width: 0, height: 0 }; function init() { calc(); draw(); } window.onresize = function () { calc(); }; function calc() { // Canvas要素が初期化される前にCanvasに関する処理を実行しないようにする if (!canvas) return; canvasSize.width = canvas.width = document.body.clientWidth; canvasSize.height = canvas.height = document.body.clientHeight; intParticle = Math.floor((canvas.width / 300 * 10) + (canvas.height / 300 * 10)); if (aryParticle.length < intParticle) { create(aryParticle.length); } } function create(start: number) { // Canvas要素が初期化される前にCanvasに関する処理を実行しないようにする if (!canvas) return; for (let i = start; i < intParticle; i++) { aryParticle.push({ position: { x: random(0, canvas.width), y: random(0, canvas.height) }, direction: { x: random(0.3, 2, true) * ((random(0, 1) ? -1 : 1)), y: random(0.3, 2, true) * ((random(0, 1) ? -1 : 1)) }, circle: 2 }); } } function random(min: number, max: number, deci = false) { let result = Math.random() * (max + 1 - min) + min; return (deci) ? result : Math.floor(result); } function draw() { // Canvas要素が初期化される前にCanvasに関する処理を実行しないようにする if (!canvas) return; // Canvas要素が初期化される前にCanvasに関する処理を実行しないようにする if (!ctx) return; ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < intParticle; i++) { let _p = aryParticle[i]; ctx.beginPath(); ctx.fillStyle = "#ffffff"; ctx.arc(_p.position.x, _p.position.y, _p.circle, 0, 2 * Math.PI); ctx.fill(); aryParticle[i].position.x += _p.direction.x; aryParticle[i].position.y += _p.direction.y; if (_p.position.x < 0 || _p.position.x > canvas.width) { aryParticle[i].direction.x *= -1; } if (_p.position.y < 0 || _p.position.y > canvas.height) { aryParticle[i].direction.y *= -1; } if (_p.position.x < -_p.circle) aryParticle[i].position.x = _p.circle; if (_p.position.x > canvas.width + _p.circle) aryParticle[i].position.x = canvas.width - (_p.circle * 2); if (_p.position.y < -_p.circle) aryParticle[i].position.y = _p.circle; if (_p.position.y > canvas.height + _p.circle) aryParticle[i].position.y = canvas.height - (_p.circle * 2); for (let _i = 0; _i < intParticle; _i++) { let _n = aryParticle[_i]; if (i != _i) { let _dist = Math.abs(_p.position.x - _n.position.x) + Math.abs(_p.position.y - _n.position.y); if (_dist < 200) { ctx.beginPath(); ctx.globalAlpha = ((_dist) > (100) ? 1 : 1 - (((100) - (_dist)) / (100))); ctx.strokeStyle = "#ffffff"; ctx.moveTo(_p.position.x, _p.position.y); ctx.lineTo(_n.position.x, _n.position.y); ctx.stroke(); } } } } requestAnimationFrame(draw); } init(); return () => { window.onresize = null; }; }, []); return ( <div> <p>article</p> <canvas id="canvas" ref={canvasRef}></canvas> </div>); }; export default Article;
これを実行します。
このときArticle.cssの#canvasの背景をちゃんと設定しないと、 粒子と色が被ってなにも見えなくなります。
はじめcanvasの背景色が白だったので、なにもみえず、うんこ漏らしました。 デバッグで粒子の描画がちゃんと行われていること、 ディベロッパーツールでcanvasの設定が正しいことを確認し、 canvasの背景か!って閃きました。

解説
const canvas = canvasRef.current; const ctx = canvas.getContext('2d');
useRefでhtml要素を参照する
canvas要素はgetContextメソッドをもっており、これによって描画を行うためのオブジェクトを返す。
ctx.clearRect(0, 0, canvas.width, canvas.height);
指定した短形ないのピクセルを消去します。座標と幅、高さが引数です。
ctx.beginPath(); ctx.fillStyle = "#ffffff"; ctx.arc(_p.position.x, _p.position.y, _p.circle, 0, 2 * Math.PI); ctx.fill();
beginPathは描画のためのパスを初期化します。 これをしないと、fillごとにパスを変える、 つまり色を変えることができなくなるみたいです。
ctx.fillStyle = "#ffffff";: fillStyleプロパティは、描画される図形の塗りつぶしの色を指定します。 白色(#ffffff)ですね。
ctx.arc(p.position.x, p.position.y, _p.circle, 0, 2 * Math.PI);: arcメソッドは、円を描画するためのメソッドです。
引数には中心のx座標、中心のy座標、半径、開始角度、終了角度が指定されます。
ここでは、p.position.xとp.position.yで円の中心座標が指定されており、_p.circleで円の半径が指定されています。
また、0から2πまでの角度を指定していますので、円の全体が描画されます。
ctx.fill();: fillメソッドは、描画された図形を塗りつぶします。
ctx.globalAlpha = ((_dist) > (100) ? 1 : 1 - (((100) - (_dist)) / (100))); ctx.strokeStyle = "#ffffff"; ctx.moveTo(_p.position.x, _p.position.y); ctx.lineTo(_n.position.x, _n.position.y); ctx.stroke();
globalAlphaプロパティは、描画される図形の不透明度を指定します。 この値は0(完全に透明)から1(完全に不透明)の範囲で指定されます。 ここでは、2つのパーティクルの距離(_dist)が100未満の場合は1(完全に不透明)、それ以外の場合は1から距離に応じて不透明度が減少します。
strokeStyleプロパティは、描画される線の色を指定します。
moveToメソッドは、現在の描画位置を指定した座標に移動します。
lineToメソッドは、現在の描画位置から指定した座標までの直線を描画します。
ctx.stroke();: strokeメソッドは、描画された線を実際に描画します。
requestAnimationFrame(draw);
requestAnimationFrameは、ブラウザにアニメーションを描画するための適切なタイミングで指定した関数を呼び出すためのメソッドです。 draw関数の中で、drawを呼び出しているわけやんな。
window.onresize = function () { calc(); };
window.onresizeはウィンドウが変わったときのイベント。それを定義している。
振り返り
はじめてのjsアニメーションやったけど、意外と簡単だった。 cssのアニメーションとか、ライブラリを使ったアニメーションとかもやってみたい。