3Dプリント購入所感

※この記事は ICT Advent Calender 2020 19日目の記事です。 昨日18日は、ウエハラの記事でした。

ツイステッドワンダーランド、面白そうですね。 初見でもツイステッドワンダーランンドの世界観やキャラが分かりやすくまとめられていて面白かったです。 個人的には アズール・アーシェングロットとエペル・フェルミエがビジュアルだとタイプそうでした。 今度詳しく教えて欲しいです。

自己紹介

今年オンラインLTに一度だけ顔を出しただけなので、初めての人がいるかと思いますので軽く自己紹介をします。

f:id:potato0022:20201219020713p:plain 情報通信システム工学科 5年 のぽてとです。

一応ゲームエンジニアです。Unityや2D・3DCGなどが少しできます。

使用言語

c#

使用ツール

Unity / ClipStudioPaint / Blender2.8 / 3DCoat / ZBrush

ゲームやVRコンテンツ、メディア系の会社に行くので、そういう分野に興味がある方はDMください。

今回は、3Dプリンターを購入したため所感やオススメ教えてと言われたので、現状の所感をまとめました。

3Dプリンターを購入した

自身への誕生日祝いとして、3Dプリンターを衝動買いしたので、その所感などを書いていきます。

今回購入したのは、光造形方式3Dプリンター Nova3D Bene4 Monoです。

3Dプリンターとは

現状3Dプリンターは種類は大きく分けて、この5つの方式が主流になっています。 一般的に有名なのは熱溶解積層方式の3Dプリンターだと思います。(フィラメント樹脂を溶かして少しづつ面を重ねていくやつです)

  1. 光造形方式

2.インクジェット方式

3.粉末燃結方式

4.熱溶解積層方式

5.粉末固着(接着)方式

今回、私が購入したのは、1.光造形方式の3Dプリンターです。

下の図のような感じで、ビルドプラットフォームにさかさまに造形されていきます。

f:id:potato0022:20201219031638j:plain

仕上がり

造形物めちゃめちゃ綺麗です。熱溶解積層方式にくらべ、細部の再現度がかなり高いです。

f:id:potato0022:20201219031656j:plain

メンテナンス

光造形めどくさというのがメンテナンス面における本音です。

光造形は造形時、熱溶解積層方式フィラメントの代わりにuvレジン液を用います。 通常、レジン液はIPA(イソプロピルアルコール)という、危険物に該当する薬品で機械や造形物についたレジン液を洗浄します。 このIPAという薬品は排水溝に流せず、一般的には紙に給水し燃えるゴミに出さなければなりません。(匂いは結構きついです)

Nova3Dでは、公式からIPAの代わりに水で洗浄できる水洗いUVレジン液を取り扱っています。 これは、IPAの代わりに水で洗浄できるUVレジン液です。

これにより、格段にメンテナンスが楽になります。

スライサーソフト

ココが今回の一番の肝です。

Nova3Dの製品は、専用のスライサー(3Dモデルを印刷用のデータに加工するアプリケーション)のNovaMakerというソフトが配布されています。 所感ですが、あまり良くないです。

個人的にはChituBoxというソフトをオススメします。

NovaMakerがChituBoxに比べてなにがダメかというと、モデルの空洞化ができません。 それにより消費レジンが減らせず、印刷時の平面積が大きいため失敗するリスクが高まります。

NovaMaker f:id:potato0022:20201219043805p:plain ChituBox f:id:potato0022:20201219043809p:plain

現状、Nova3D Bene4は有志が開発したChituBoxのプラグインがあります。 しかし、Nova3D Bene4 MonoはChituBoxのプラグインがなく現状NovaMakerのみの対応です。

まとめ

精密なモデルを造形したいなら光造形はかなりオススメです。 しかし、後処理やメンテナンス等の面倒な作業があるため、注意が必要です。

現状Nova3DBene4が僕が光造形でオススメする商品です。

ぜひ、皆さんも購入して生活を豊かにしてみてください。

最後に

今年は某ウイルスのせいであまりICTに関われなかったですが、ゲーム制作や、2D・3DCG制作等聞きたいことがあれば気軽にDMでも飛ばしてください。

時代はマルチスレッドプログラミング🤚🤚🤚(だいぶ前から)

この記事はICT委員会 コロナに負けないぞブログリレーの6/3の記事です。


昨日はほなふく君の記事でした。

PC、組んでみませんか?

こういうパーツのレビューって結構助かりますよね。

PCの自作は、個人的感覚だとガンプラより簡単なので

是非組んでみてください。


次回はやがみあん先輩の記事です。

リンク

おいしそう。

僕も自粛期間中結構手のこんだ料理を作ったりしました。

自己紹介

初めまして、芋(@NoNameReUnder)です。

f:id:potato0022:20200602000154p:plain
これはVKet4で友人が撮ってくれた自画像です

普段はキャラモデリングやイラストの仕事をしたりしつつ、Unityを用いてゲームを作ったりしています。

VALORANT楽しい

使用ツール

Unity ZBrush Blender ClipStudioPaint

普段使いしている言語

Unity C#


新一年生(いるのかは把握していませんが)は、なんか変な人いるなくらいで覚えてもらえると嬉しいです。

急なダイレクトマーケティング「アライブサバイブ」

4人プレイのボードゲーム

¥1500 JPY 予定 f:id:potato0022:20200602074111p:plain

広報Twitter

内容物

同盟・戦争カード   5枚

資源カード      25枚

キャラクターカード   5枚

説明カード      1枚

ゲームの概要

このゲームは謎のウイルスにより荒廃した世界の中で、自身に割り振られたキャラクターの特性を使い資源を集めていきます。

しかし、この世界にはプレイヤー全員が生き残れるような資源は残っていません。

そのため、ほかのプレイヤーと組んだり、交渉したり、時には戦って生き残りましょう。


8月に販売開始する予定なので、発売したら是非買って遊んでみてください。

僕の春休みはこのボドゲのタスクで消えました。悲しいね、、、

JobSystemの解説

本題に戻ります。

今回はUnityを触ったことがある人に対する記事ですので、興味がない人はブラウザバックしてください。

読んでも面白くないからね。


事前に、以下の動画・スライドを見たことがある方は、ほんとに読む必要無いです。


Unite Europe 2017 - C# job system & compiler


Job Systemとは

f:id:potato0022:20200602072113j:plain

Unity2017で公開されたマルチスレッドプログラミング手法

JobSystemのここが良い

(割と)簡単に書ける

GCフリー

レースコンディション・デッドロックが起こりうる場面はあらかじめエラーをはいてくれる(安全)

IL2CPPコンパイラを用いたマルチスレッドプログラムの最適化によるパフォーマンス向上

2017のデモでは、200,000個のGameObjectを動かした際のパフォーマンス比較ではシングルスレッド実行時の116倍の速さをみせています

JobSystemの注意点

データ構造はstructのみ

すべてが早くなるわけではない

Jobの発行にもコストは必要なので、発行しすぎるとかえって重くなる

Job Systemは、Unityがデータ指向の考えに代わってきており、

Unity2019から公開されたECSとの連携を目的として設計されているため、構造が少し特殊です。

サンプルコード

任意のGameObjectをマルチスレッドで動かすためのサンプルコードを下記に記述しています。

using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Jobs;

public sealed class BounceCube5 : MonoBehaviour 
{
    /// <summary>
    /// 動かすオブジェクトのTransform格納用配列
    /// </summary>
    [SerializeField] Transform[] targets;

    /// <summary>
    /// NativeArray<T>は
    /// JobSystemJobSystemでアクセスするための記述方
    /// デッドロックを防ぐため、値を渡すときにメモリアドレスを参照させるのではなく、
    ///値を複製し元の値とは別の独立した動きをとります。
    /// Gitのブランチのようなイメージです。
    /// この配列はECSとの連携を目的としているため、連続したメモリアドレスになっています。
    /// float型の配列velocityを用意
    /// </summary>
    NativeArray<float> velocity;
    /// <summary>
    /// RaycastCommand型配列command
    /// </summary>
    NativeArray<RaycastCommand> commands;
    /// <summary>
    /// RaycastHit型配列results
    /// </summary>
    NativeArray<RaycastHit> results;
    /// <summary>
    /// int型hitQueue
    /// </summary>
    NativeQueue<int> hitQueue;
    /// <summary>
    /// Job SystemでTransformにアクセスするための配列
    /// TransformAccessArray型愛列transformArray
    /// </summary>
    TransformAccessArray transformArray ;
    /// <summary>
    /// Struct IsHitGroundJob Jobの宣言
    /// </summary>
    IsHitGroundJob hitCheckJob;
    /// <summary>
    /// Job発行のためのJobHandleを宣言
    /// </summary>
    JobHandle handle;

    /// <summary>
    /// スクリプトをアタッチしているオブジェクトがActive状態になっていれば実行
    /// </summary>
    void OnEnable()
    {
        velocity = new NativeArray<float>(targets.Length, Allocator.Persistent);
        commands = new NativeArray<RaycastCommand>(targets.Length, Allocator.Persistent);
        results = new NativeArray<RaycastHit>(targets.Length, Allocator.Persistent);
        hitQueue = new NativeQueue<int>(Allocator.Persistent);

        transform.DetachChildren();

        for (int i=0; i< targets.Length; i++)
        {
            velocity[i] = -1;
        }
        transformArray = new TransformAccessArray(targets);

        hitCheckJob = new IsHitGroundJob()
        {
            raycastResults = results,
            result = hitQueue.ToConcurrent()
        };

    }
    /// <summary>
    /// スクリプトをアタッチしているオブジェクトが非Active状態になっていれば実行
    /// </summary>
    void OnDisable()
    {
        ///Jobの開放
        handle.Complete();

        ///メモリの開放
        ///メモリリークを防ぐため、必ず実行
        velocity.Dispose();
        commands.Dispose();
        results.Dispose();
        hitQueue.Dispose();
        transformArray.Dispose();
    }
    /// <summary>
    /// update関数実行後に実行
    /// </summary>
    void LateUpdate()
    {
        ///Jobの開放
        handle.Complete();

        // Raycastの開始点と位置を設定
        for (int i=0; i<transformArray.length; i++)
        {
            var targetPosition = transformArray[i].position;
            var direction = Vector3.down;
            var command = new RaycastCommand(targetPosition, direction);
            commands[i] = command;
        }

        // 移動のコマンドを設定
        var updatePositionJob = new UpdateVelocity()
        {
            velocitys = velocity
        };

        //GameObjectのTransformを設定
        //回転・位置を変更
        var applyTrans= new ApplyTrans()
        {
            velocitys = velocity
        };

        // 並列処理を実行(即完了待ち)
        // 終わったらコマンドに使ったバッファは不要なので破棄
        handle = RaycastCommand.ScheduleBatch(commands, results, 20);
        handle = hitCheckJob.Schedule(transformArray.length, 20, handle);
        handle = new ReflectionJob { velocitys = velocity, result=hitQueue }.Schedule(handle);
        handle = updatePositionJob.Schedule(transformArray.length, 20, handle);
        handle = applyTrans.Schedule(transformArray, handle);

        //Jobの開放
        handle.Complete();
    }

    struct UpdateVelocity : IJobParallelFor
    {
        public NativeArray<float> velocitys;

        void IJobParallelFor.Execute(int index)
        {
            velocitys[index] -= 0.098f ;
        }
    }

    struct ApplyTrans : IJobParallelForTransform
    {
        [ReadOnly] public NativeArray<float> velocitys;

        void IJobParallelForTransform.Execute(int index, TransformAccess transform)
        {
            transform.localRotation = Quaternion.Euler(transform.rotation.x + velocitys[index] * 180f, transform.rotation.y + velocitys[index] * 180f, transform.rotation.z + velocitys[index] * 180f);
            transform.localPosition += Vector3.up * velocitys[index];
        }
    }
    

    struct IsHitGroundJob : IJobParallelFor
    {
        [ReadOnly] public NativeArray<RaycastHit> raycastResults;
        [WriteOnly] public NativeQueue<int>.Concurrent result;

        void IJobParallelFor.Execute(int index)
        {
            if (raycastResults[index].distance < 1f)
            {
                result.Enqueue(index);
            }
        }
    }

    struct ReflectionJob : IJob
    {
        public NativeQueue<int> result;
        public NativeArray<float> velocitys;

        public void Execute()
        {
            while(result.TryDequeue(out int index))
            {
                velocitys[index] = 2;
            }
        }
    }
}

今回は、このスクリプトを用いて802個のオブジェクトを動かしてみました。 以下が実行結果です。 f:id:potato0022:20200602202517p:plain f:id:potato0022:20200602202513p:plain


動作結果

まとめ

Job SysytemはUnityプログラマーを目指す場合、確実に必要な知識です。

まずはオブジェクトごとに処理をするのではなく、まとめて計算できる箇所はどんどんまとめて処理をする書き方を身に着けていきましょう。

これは違うだろとうの意見があればコメントをくださると有り難いです。

ここまで読んでくださりありがとうございました。

ここまできた

ここまできたと言うべきか、ここからと言うべきか

ついこの間希望の会社に内々定を頂き、自身が目指す将来も定まってきた。

思えば、高専入学からはや4年。ずっと物を作り続けてきた。
なんなら学生の本分より、クリエイターとしての活動割合のほうが多かったのではないかと思っている。

入学1年目からプログラミングを始め、チーム開発を経験したり、デジタルアートを始めたり、魔改造作成した。
2年目は、ドローン飛ばしたり、チームでUnityを用いたゲーム開発をしたり、Live2Dで2Dアニメーションした。
3年目は、例年に引き続きゲームをチーム・個人で開発したり、3Dモデリング始めたり、サークルのCDジャケット描いたりした。
4年目は、vrアプリ開発をしたり、オリジナルボードゲームの挿し絵描いたり、vrmを用いたアクションゲームを制作していた。
5年目は、いったい何を創るんだろうか。


1年目の開発経験がそれ以降の個人・チーム開発の基礎にい活かされた。
入学1年目のデジタルアートのスキルがその後のゲーム開発や絵仕事に活かされた。
入学2年目のLive2Dのアニメーション制作経験がUnityのゲーム開発に活かされた。
入学3年目の3Dモデリングもまたゲーム開発に活かされたり、自身の現状の収入源になったりしている。
入学4年目のARやvrmでの開発が今の会社との縁を繋いでくれた。

僕は好きなことしかしてない。
なんなら好きなことしかしてこなかった。

でも今振り返ってみると全部繋がっている。
好きだから続けてこれて、その先に広がる新しい経験と好きを見つけることができた。

僕の、もの作りのルーツは幼少期に貰ったレゴブロックだったと思う。
始めて感情のおもむくままに形作っていくのが楽しいと知った。
それからは、親の協力のおかげで絵画教室やもの作り系のイベントなどに沢山つれていって貰った。
それなりに実績も貰い楽しいという記憶がある。
こういった経験のおかげで、もの作りは楽しいという感性を持ってもの作りの道を目指した。
ただ、純粋に何かを生み出すのが好きだった。

でも、入学3年目の個人ゲーム開発で、締め切り日の3連休を3徹して開発をおこない、提出後に椅子から立とうとして椅子ごと倒れてそこから数時間意識がとんでいた。
この時に「あ~、俺長生きできないなぁ」と思った。
(多分30とかで死ぬね、今のままだと)
その後すぐに考えたのは、「開発を辞めよう」ではなく「後どれくらい残っているかわからない時間で、あとどれくらいのものを作り出せるだろうか」という考えだった。
これによって時間的な制約を意識しだして、ただ純粋にもの作りを楽しむということにより勢いがついた。

考え方も、少し過激な判断をするようになったと思う。
(よく性格診断でクールとか一匹狼とかの判定を頂くことが多くなった)

僕はこれからも、もの作りをして新しい経験と好きを見つけていく。
そのなかで、多分死にかけることはやっぱりあると思う。
けど、僕は将来死ぬまで手を動かして、何かを作り出していると思う。

つくづくクリエイターってめんどくさい性質を持った生き物だなぁと文書を見たら思う。
でも、そこが良いからどうしようもない。


好きなこと・興味のあることはとことん自分がやってみたいところまでやってみて欲しい。
そうすれば新しい好きも見つかるし、それはきっと貴方の人生をより豊かにしてくれると思う。

大丈夫、少なくとも1例ここにやりたいことをやってそれを活かしてさらに新しいやりたいことを見つけることができた人がいるから。
頑張って、応援してるよ。

後書き
ここまで独白自己語りおじさんみたいな拙い文書を読んでくださってありがとうございます。

これは、まぁ後日談みたいなものなんですけど
今はICT委員会に所属させていただきながら講座とか趣味プロとかしてるんですけど
高専入学時に、初めは学校案内パンフレットに書かれていたジャグリング同好会に入部しようとしてたんですよ。
僕が入学したときに最後の同好会員が卒業してたので、同好会はなくなってましたが。

もし、同好会がなくなっていなければ僕はプログラミングをすることなく道端で大道芸をしていたりする未来もあったかもしれません。
巡り合わせって本当に面白いですね。

今年一年間を振り返って

※この記事はICT アドべントカレンダーの17日目の記事です。

どうもおはよう、こんにちは、こんばんはpotatoです。
アドベントカレンダー17日を担当させていただきます。
拙い言葉で書き記すので了承のほどお願いいたします。

昨日は後期中間テスト期間中に大会がかぶりかなりつらい開発をするも
起業賞を見事勝ち取ったマース先輩。偉大なるM言g…創z
大会ほんとにお疲れ様でした。その偉大な岸本先輩が書いた記事は
下のリンクから飛べます。

shi-o.hatenablog.com

この1年を振り返ってみて

 まず、初めに書くべきはやはりお礼でしょうか。

PC設定会でPCの設定をしてくれて、ICT委員会へ行くきっかけを与えて下さった

先輩方、プログラミングがわからない時にご指導して下さった先輩方、教授方、

そしてなにより ちーむまぐろの皆様へ、未熟な1年生を鍛え、

支えてくれた事に心からの深い感謝を。

 

この1年は、特に何も無い普通の1年間だった   と言うには、あまりに多くの事をこの1年で経験したように思えます。

この1年は自分のこれからの人生について確実に糧になった1年間だったと思っています。

 困難を前にした時に助けてくださった皆様に今一度深い感謝を。

本当にこの1年間有難うございました。

 

さて、ここからが今回のアドベントカレンダーの本編と言ってもいいのですが、そもそも1年生なので技術力ないから技術系の話が出来ないし、これといって面白いネタは無く……なんとかノリと勢いで頑張ります。

目次

  1. 今年したこと
  2. 今年の反省点
  3. 来年したいこと
  4. 今年度のICT
  5. 来年度のICTへ

 

1.今年したこと

まず、一通り触ったことの一覧を列挙していきたいと思います。

 1. C# 画面遷移と簡単なアプリケーションなら制作可能になった。

 2. C すいません昨日プロ4さわり始めたのでたいした進捗ありません。

     ゆるちて…。

 3.  c++ さらっとしかさわってないのでcinとかcoutしかわからないです。

 4. Ruby 基礎文法を勉強中 同じ実行結果でもかなり実装方法が存在するため

  大幅に時間がかかってます。

 5. CTF つん先輩にお世話になって少しだけセキュリティ関連を勉強してます。

 6. 鉄板・端材加工 主に鉄板の切断方法 雌ねじの作成法 雄ねじの作成法を

 理解しました。 来年度から鉄板も加工可能です。

 7. コイルガンは良いぞ! コイルガンちょこっとだけ作りました。

  春合宿までには完成させたいですね。

 8.3Dホログラムも作りました。はやく女の子作りたい…。

 

2.今年の反省点

   1.    まず、C#はコピペばかりしていたのできちんとした理解が得られていない。

    実装力があまり身についていない

   2.   C#半年触っていたせいで、C言語プロ2の範囲ほとんど忘れました。

   3.   あまり、1年生とコミュニケーションをとることが夏休み以降できなかった。

   4.   魔剤取り過ぎ?た?

      5.  チームメンバーの指示を意訳し間違えてしまったのできちんと意思疎通したい。

 

3.来年したいこと

  1. Python人工無能作成 機械学習 人工知能作成

        2.C#でアプリ開発

  3. 大会で最優秀賞を勝ち取る。

  4. 競プロ本戦参加

  5. 3Dホログラム

  6. セキュリティコンテスト参加

       7. プロ4・アルゴリズムとデータ構造を終える。

  8. 来年度の新一年生をメンターとして支えていきたい。

 

4.今年度のICT

 今年はメンターが一年生に長期的につけなくて、一年生と先輩方との間にすこし壁を感じました。

 僕個人はちーむまぐろが全員先輩だったことや、親しみやすい

 良い先輩達だったことで、そこまで話しかけずらいということは

 ありませんでしたが…。

 分からない事があると、すぐ聞くことのできる有能な先輩方がいるので、

 しっかり交流して欲しいです。

 開発に関しては、それぞれのチームが大会前まで割とのんびりと開発して、

 大会直前でラッシュをかけていたように感じます。毎年なんですかね?

 それから、教授がおっしゃっていたのですが、

 各チーム企画書を読み返したりして、

 そのアプリ開発の原点を常に再確認しながら開発に望んで欲しい

 

 本当にその通りだと感じます。

 開発中、開発の原点からそれた部分の開発をしてタスクをはやしてしまって

 本当に必要な部分の開発時間が減ってしまったり、メンバーの誰かの

 キャパを超えてしまったりすると本末転倒なのではないでしょうか?

 それから、幾つかのチームはタスクの振り分けが特定の個人に

 集中しすぎていたような気が端から見ていて感じました。

 

 まだ1年目の僕視点から見たことなのでそれは違うだろとか、

 何言ってんだずうずうしいぞこいつとかは心の中だけにしてください…。

 脆弱メンタルなので…。

 

5.来年度のICTへ

 リーダー人材の育成をして欲しい、とゆうかしましょう。

 LTとかで技術紹介してICT全体のスキルアップをはかりたいですね。

 教授にあまり負担をかけ過ぎないようにしたいですね。

 後輩育成を頑張りたいですね。

 デスマしないようタスクの振り分けをしっかりしていきたいですね。

 

----  最後に ------

 ここまで拙い長文を読んでくださってありがとうございました。

 来年がICTのみなさんにとって実りある一年になることを心からお祈りしています。

 

今日は他にも僕よりも圧倒的語彙力のある一年の女子二人が

記事を書いてくれますのでぜひ読んでください。

b-mk.hatenablog.com

  

rio-k827.hatenablog.com

明日は眠人先輩とroy-l&Shoです。僕の100倍くらい面白い記事を書いてくれるので

ぜひ読んでください。

nemu-sou.hatenablog.com

今年の振り返りと最近のこと - tip36のブログ

[//リンク3]