チリペヂィア リンクフリー。サンプルコードなどは関連記事内でライセンスについて明示されない限り商用利用なども自由に行って構いませんが、自己責任でお願いします。またこれら日記内容の著作権自体は放棄していません。引用部分については引用元の権利に従ってください。 2015-07-20T11:22:00+09:00 tiri_tomato Hatena::Blog hatenablog://blog/8454420450077302291 Doxygenのレイアウト出力する-lオプションが失敗した hatenablog://entry/8454420450102016743 2015-07-20T11:22:00+09:00 2015-07-21T18:06:49+09:00 ので、ソースパッケージの方に入ってるlayout_default.xmlをコピーしたらそれで良かったという話。ちなみに、Doxygenなんじゃらほいって人はがぞーけんさくしてみると、Doxygenとはコードコメントの自動文書化ツールで、どんなHTMLヘルプが作れるかだいたいわかります*1。で表示項目や順番なんかをいじくりたい時は、表示内容の全てをxmlで指定するわけですが、もちろんゼロベースで書くのはしんどいため、Doxygenに問い合わせてひな形を得る必要があります。それがドキュメントにもある通り doxygen -lでデフォルトのレイアウトxmlがDoxygenLayout.xmlとして出… <p>ので、ソースパッケージの方に入ってるlayout_default.<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>をコピーしたらそれで良かったという話。</p><p>ちなみに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Doxygen">Doxygen</a>なんじゃらほいって人は<a href="https://www.google.co.jp/search?q=doxygen&tbm=isch">&#x304C;&#x305E;&#x30FC;&#x3051;&#x3093;&#x3055;&#x304F;</a>してみると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Doxygen">Doxygen</a>とはコードコメントの自動文書化<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>で、どんなHTMLヘルプが作れるかだいたいわかります<a href="#f-4c466175" name="fn-4c466175" title="細かい見た目も結構カスタマイズできます。ただリッチに画像を多用したり今どき風にオシャレなレイアウトにしたりするのはわりと苦手です。Web出力専用ではないためWeb以外とも互換のききそうな範囲でしかカスタマイズできない感じ。">*1</a>。</p><p>で表示項目や順番なんかをいじくりたい時は、表示内容の全てを<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>で指定するわけですが、もちろんゼロベースで書くのはしんどいため、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Doxygen">Doxygen</a>に問い合わせてひな形を得る必要があります。それがドキュメントにもある通り</p> <pre class="code" data-lang="" data-unlink>doxygen -l</pre><p>でデフォルトのレイアウト<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>がDoxygenLayout.<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>として出力できる事になってますが…失敗しちゃったんですね。</p><p>症状としては<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>が謎の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%B3%A1%BC%A5%C9">エンコード</a>で出力されてしまい、大量のエンコ不能な空白に混じってとぎれとぎれに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%B9%A5%AD%A1%BC">アスキー</a>文字が出現する感じです。その文字列自体は人間なら読んで読めないことは無いという印象…もちろん<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>としては崩壊しているので根気よく手修正する必要があります。でも量が多いのでその方法はすぐサジを投げました。なおDoxygen1.8.10/<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>.1-64bit環境で、32bit版も64bit版も大差なかったです。あとなんか出力する<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>ファイル名を少し変えると空白の量が変化していました。ナンダコレ…。</p><p>ついでにちょっとソース追いかけてみたんですが、layout_default.<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>をベースにヘッダーファイル化してそれをリソースとしてビルドしてるようで、-lオプションを実行するとその<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>リソースを内部の独自ストリーム出力クラスでutf8出力する流れっぽいので、やはりどっかでエンコ失敗してる気配(勘)。ストリーム出力のところが一番怪しいです(勘)。</p><p>とは言え、個人的には<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>さえゲットできればいいやという事で、内部フロー的にやっぱこのlayout_default.<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>で良いのねと大方推測できたため捜査を打ち切りました。そもそもの目的だった、ツリービューのレイアウトを編集できたので良かったです(小並</p><p>もし同様のお悩みをお抱えでしたらソースをDLすると良いかもよ!</p><p>なんか<a class="keyword" href="http://d.hatena.ne.jp/keyword/Doxygen">Doxygen</a>はクソ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>みたいな日記になってしまいましたがどっこい神<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>なのでオススメですよ!<a href="#f-362ca4df" name="fn-362ca4df" title="日本語pdf出力しようとすると地獄の道をたどることになりますがWebヘルプを作る場合は実にスイーツ">*2</a>。</p> <div class="footnote"> <p class="footnote"><a href="#fn-4c466175" name="f-4c466175" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">細かい見た目も結構カスタマイズできます。ただリッチに画像を多用したり今どき風にオシャレなレイアウトにしたりするのはわりと苦手です。Web出力専用ではないためWeb以外とも互換のききそうな範囲でしかカスタマイズできない感じ。</span></p> <p class="footnote"><a href="#fn-362ca4df" name="f-362ca4df" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">日本語pdf出力しようとすると地獄の道をたどることになりますがWebヘルプを作る場合は実にスイーツ</span></p> </div> tiri_tomato Enterするまで入力を反映しないテキストボックス再考 hatenablog://entry/8454420450097187152 2015-06-29T10:54:00+09:00 2015-06-29T18:55:08+09:00 Unityのエディタ拡張で、入力フィールドのエンターやフォーカスロストを見張るTips修正版。 <p>PropertyDrawerって結局バグってEditor継承するしかないよね(白目)</p><p>さておき。</p><p>掲題のネタが必要になって以前書いた記事を見直したんですが、あまりにもブン投げ記事だったので書き直し。</p><p>今回はアプライ遅延コントロールを<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>並べる事も考慮して挑戦です<a href="#f-28a09af7" name="fn-28a09af7" title="これで配列カスタマイズも安心">*1</a>。ついでにフォーカスロストのタイミングを検知&反映する方法も。</p><p>こういうのがあったとして。<br /> <script src="https://gist.github.com/81f64d83fdb8741b8903.js"> </script><br /> 普通にエディタを書いたらこんな感じだと思います。<br /> <script src="https://gist.github.com/0c082f7ad0ed152a1224.js"> </script></p><br /> <p>まず第一に今、気の利いた処理が必要ではないなら、これから続く、ややこしい記事を読むのは今すぐにやめてPropertyField使ってしまうのが一番楽だと思います。でもそういうわけにもいかず、例えば次のようなケース…</p> <ul> <li>GameObject.OnValidate()じゃなくエディタ側でValidationしたい <ul> <li>無効な入力でも無駄にUndo.RecordObject()撃たず帳消しにしたい</li> <li>入力データを反映する時、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E6%A1%BC%A5%B6%A5%D3%A5%EA%A5%C6%A5%A3">ユーザビリティ</a>等の観点から配列メンバを逐一ソートしておきたい</li> </ul></li> <li>配列エディタの配列数入力フィールドの自作で入力遅延しないと、文字を消した瞬間に配列長ゼロでリストがクリアされちゃう事故とか</li> </ul><p>こんなケースでは、入力途中でも逐一現在の入力値を返す<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>コントロールをそのまま使う事は出来ません。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>で制御して、GameObjectへの反映を遅延させる必要があります。</p><p>まずUnityの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>リファレンスに書いてあるのは</p> <ol> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>.SetNextControlName()で入力フィールドに任意の名前を与え</li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>.GetNameOfFocusedControl()で実際にフォーカスされているか確認</li> </ol><p>ただ、それだけだとニッチーモサッチーモなので、次のような記録変数を仕込みました。</p> <pre class="code lang-cs" data-lang="cs" data-unlink>[CustomEditor(<span class="synStatement">typeof</span>(EnteringApply))] <span class="synType">public</span> <span class="synType">class</span> EnteringApplyEditor : Editor { <span class="synComment">// 現在編集中のコントロール名</span> <span class="synType">string</span> editControlName; <span class="synComment">// 現在編集中のコントロールに表示している値</span> <span class="synType">object</span> editControlValue; </pre><p>端的に言えば、<b>反映を遅延する=入力<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%A4%A5%EA%A5%A2%A5%B9">エイリアス</a>の一時的なバッファ管理。</b>入力フィールドに一意な名前を与える条件で、かつ、カーソルは1か所だけ。だったら入力状態をobject型にキャストしてしまえば、もうこれ以上のバッファリングも要らないかな多分。</p><p>実際に先ほどの2つのフィールドを同時に扱ってみます。<br /> <script src="https://gist.github.com/66b6f4585ad810f138c2.js"> </script></p><p>うん…ほんのちょっとだけ長いね(震え声)</p><p>そんなわけでクラス化はした方が良いと思いますが<a href="#f-6436b9f9" name="fn-6436b9f9" title="こういったフラグ地獄になっている個所では、クラス化は見た目とか精神衛生面の問題にとどまらない話。いちいちブレークするよりもToString()のオーバーライドで逐一ログに出す方が状態の変化チェックがラクなんですよね…">*2</a>あんまりキレイにまとまらなかったので非公開…。型キャストに絡んで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%A7%A5%CD%A5%EA%A5%C3%A5%AF">ジェネリック</a>、さらに比較処理カスタマイズにデリゲートとか渡し始めるとなかなかシンプルにはまとまらんですよ…</p><br /> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20150628/20150628081634.png" alt="f:id:tiri_tomato:20150628081634p:plain" title="f:id:tiri_tomato:20150628081634p:plain" class="hatena-fotolife" itemprop="image"></span><br /> スクショとったけど見た目にまったく変化の無い話であった。</p> <div class="footnote"> <p class="footnote"><a href="#fn-28a09af7" name="f-28a09af7" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">これで配列カスタマイズも安心</span></p> <p class="footnote"><a href="#fn-6436b9f9" name="f-6436b9f9" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">こういったフラグ地獄になっている個所では、クラス化は見た目とか精神衛生面の問題にとどまらない話。いちいちブレークするよりもToString()のオーバーライドで逐一ログに出す方が状態の変化チェックがラクなんですよね…</span></p> </div> tiri_tomato AnimationCurveを近似する折れ線を適度に生成 hatenablog://entry/8454420450098029062 2015-06-18T19:56:00+09:00 2015-06-19T07:24:55+09:00 (…誰得?)とりあえず ある区間内で一定よりもキツい角度で曲がってたら前後二つに分けて再帰する。 あんまり細かくなったらやめる。 ていうお決まり感あふれる作戦にて候*1。さて挿入を繰り返すという手順から純粋に理論的に考えますと、データ構造はリンクリストが妥当です。が、今回はパフォーマンスの定石として配列リストにします。というのもAnimationCurveの実態は制御点つまりkeyframeの配列で、最初からこの区間の数が決まっています。で、区間ごとに分割した配列リストにするのがわりと簡単で、しかも分割数もそんなに増えないでしょう多分*2。 使い方 AnimationCurve curve =… <p>(…誰得?)</p><p>とりあえず</p> <ul> <li>ある区間内で一定よりもキツい角度で曲がってたら前後二つに分けて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a>する。</li> <li>あんまり細かくなったらやめる。</li> </ul><p>ていうお決まり感あふれる作戦にて候<a href="#f-f1c4fee4" name="fn-f1c4fee4" title="なんかいかにも情報学部の課題とかでありそう">*1</a>。</p><p>さて挿入を繰り返すという手順から純粋に理論的に考えますと、データ構造はリンクリストが妥当です。が、今回はパフォーマンスの定石として配列リストにします。というのもAnimationCurveの実態は制御点つまりkeyframeの配列で、最初からこの区間の数が決まっています。で、区間ごとに分割した配列リストにするのがわりと簡単で、しかも分割数もそんなに増えないでしょう多分<a href="#f-b1e32745" name="fn-b1e32745" title="例えば最悪100分割を目途に再帰分割していくとして、3つの制御点に挟まれた2つの区間だとします。すると理想的に半分で分かれる曲線だと区間当たり最悪でも50分割が目安になります。さらに、そもそも滑らかに補間する曲線なんだから、曲線の中心から半分はほとんど分割しないエリアが存在する事がほぼ期待できます。分割数は体感的にだいたい、最悪ケースの4~6割程度でしょうか。とするとこの場合ブロックコピーの発生する挿入コストで想定する配列の長さは25個とかそんなもんです。一方で、floatとかVector2程度の要素にいちいち細切れのヒープをGCに要求しまくる事は安定してヘビー(少なくとも10~100個程度のブロックコピーに比べれば。だいたいこのサイズの配列なら何百文字かの文字列型を切った貼ったするのと大差ない)。これが配列リストを採用する理由になります。">*2</a>。</p><p><script src="https://gist.github.com/aaf9f42dd57ec158c0a4.js"> </script></p><p></p> <div class="section"> <h5>使い方</h5> <pre class="code lang-cs" data-lang="cs" data-unlink> AnimationCurve curve = <span class="synStatement">new</span> AnimationCurve(); <span class="synComment">// 最悪でも100分割に制限し、1度以上曲がってたら再帰分割する</span> AnimationCurveDivider.DividedResult divided = <span class="synStatement">new</span> AnimationCurveDivider.DividedResult(curve, <span class="synConstant">100</span>, <span class="synConstant">1</span>); <span class="synComment">// divided.points /* 配列リストを取得 */</span> <span class="synComment">// divided.points.Length /* 区間の数 */</span> <span class="synComment">// divided.points[0] /* 最初の区間を取得 */</span> <span class="synComment">// divided.points[0].Count /* 最初の区間に何個のVector2要素が並んでいるか */</span> <span class="synComment">// divided.points[0][0] /* 最初の区間の先頭のVector2要素を取得 */</span> <span class="synComment">// divided.pointsCount /* divided.points[n].Countの合計 */</span> <span class="synComment">// divided.valueMax/Min /* 全ての要素のyの最大/最小。</span> <span class="synComment">// (x要素の最小はAnimationCurveの最初のkeyframe.timeまたは配列リスト最初のVector2.x) */</span> <span class="synComment">// (x要素の最大はAnimationCurveの最後のkeyframe.timeまたは配列リスト最後のVector2.x) */</span> <span class="synComment">// divided.ToArray() /* 配列リストを1つのVector2[]に統合して返す。 */</span> </pre><p><br /> 昨日の直線描画サンプルを適当にいじって…(もちろんコレ以外にも多少いじる)</p> <pre class="code lang-cs" data-lang="cs" data-unlink> Keyframe headKey = obj.sourceCurve.keys[<span class="synConstant">0</span>]; Keyframe endKey = obj.sourceCurve.keys[obj.sourceCurve.length - <span class="synConstant">1</span>]; Vector2 center = <span class="synStatement">new</span> Vector2((headKey.time + endKey.time) * <span class="synConstant">0.5f</span>, (divided.valueMax + divided.valueMin) * <span class="synConstant">0.5f</span>); <span class="synType">float</span> width = System.Math.Max(endKey.time - headKey.time, <span class="synConstant">0.1f</span>); <span class="synType">float</span> height = System.Math.Max(divided.valueMax - divided.valueMin, <span class="synConstant">0.1f</span>); GL.LoadPixelMatrix(center.x - width * <span class="synConstant">0.5f</span>, center.x + width * <span class="synConstant">0.5f</span>, center.y - height * <span class="synConstant">0.5f</span>, center.y + height * <span class="synConstant">0.5f</span>); GL.Begin(GL.LINES); GL.Color(Color.white); GL.Vertex(divided.points[<span class="synConstant">0</span>][<span class="synConstant">0</span>]); <span class="synStatement">for</span> (<span class="synType">int</span> indexAry = <span class="synConstant">0</span>; indexAry &lt; divided.points.Length; indexAry++) { <span class="synType">int</span> indexList = (indexAry == <span class="synConstant">0</span> ? <span class="synConstant">1</span> : <span class="synConstant">0</span>); <span class="synType">int</span> indexListMax = divided.points[indexAry].Count; <span class="synStatement">if</span> (indexAry == (divided.points.Length - <span class="synConstant">1</span>)) indexListMax--; <span class="synStatement">for</span> (; indexList &lt; indexListMax; indexList++) { GL.Vertex(divided.points[indexAry][indexList]); GL.Vertex(divided.points[indexAry][indexList]); } <span class="synStatement">if</span> (indexAry == (divided.points.Length - <span class="synConstant">1</span>)) GL.Vertex(divided.points[indexAry][indexListMax]); } GL.End(); GL.PopMatrix(); </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20150618131001" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20150618/20150618131001_120.jpg" alt="f:id:tiri_tomato:20150618131001p:image:medium" title="f:id:tiri_tomato:20150618131001p:image:medium" class="hatena-fotolife" itemprop="image"></a></span><br /> (数字は分割数)<br /> <br /> </p> </div> <div class="section"> <h5>コード読むのが面倒な人にロジックとかもうちょっと詳しく</h5> <p>ある区間が与えられて、その区間の最初→最後に向かうベクトルA、最初→中間に向かうベクトルBを計算して、どちらも長さを正規化すると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C6%E2%C0%D1">内積</a>Dotがその角度差を示すコサインになります。いわゆる<a href="http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0CCsQFjAB&url=http%3A%2F%2Fja.wikipedia.org%2Fwiki%2F%25E3%2583%2599%25E3%2582%25AF%25E3%2583%2588%25E3%2583%25AB%25E3%2581%25AE%25E3%2581%25AA%25E3%2581%2599%25E8%25A7%2592&ei=zTyCVf_2E5Xe8AWt7Ihw&usg=AFQjCNHxYIINhHAalSdaZHgj1p1WNnnh7w&sig2=arLejT3ZeSEAtwE03NLDLg&bvm=bv.96041959,d.dGc">&#x30D9;&#x30AF;&#x30C8;&#x30EB;&#x306E;&#x306A;&#x3059;&#x89D2;</a>という奴です。この角度差がその区間をまだ分割するべきかどうかの目安になっています。</p><p>また、keyframe~keyframeの1区間当たり、最初の1回だけは角度計算を飛ばして分割に挑戦します。この曲線の性質上、1区間内でS字までは描きます。3次曲線の真ん中みたいな感じで。<b>本当はくねっていて分割すべき曲線なのに、たまたま、始点→中間の向きが始点→終点の向きと一致してしまい、角度判定で1度も分割されない</b>事態が有りえます。なので最初の一度は角度計算を飛ばして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a>処理に突入し、それでも一度も分割される事なく戻って来たら、最初の一回分の始点→中間・始点→終点の角度を判定して、本当に曲がってない直線のようなら中間点を削除しています。</p><p>それと…AnimationCurveの妙な仕様で、普通のドロー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>だと、垂直以上の角度を設定した時は横軸方向に戻る感じで曲がりくねるもんですが、UnityのAnimationCurveでは妙な垂直グラフになるという挙動をします。これは今回は面倒なのでスルーする事にします。バグったりはしませんが、最小分割単位でしか再現しませんので、垂直な角度は再現できませんね。微妙に斜めになります。</p><p>こんなところでしょうか。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-f1c4fee4" name="f-f1c4fee4" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">なんかいかにも情報学部の課題とかでありそう</span></p> <p class="footnote"><a href="#fn-b1e32745" name="f-b1e32745" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">例えば最悪100分割を目途に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a>分割していくとして、3つの制御点に挟まれた2つの区間だとします。すると理想的に半分で分かれる曲線だと区間当たり最悪でも50分割が目安になります。さらに、<b>そもそも滑らかに補間する曲線</b>なんだから、曲線の中心から半分はほとんど分割しないエリアが存在する事がほぼ期待できます。分割数は体感的にだいたい、最悪ケースの4~6割程度でしょうか。とするとこの場合ブロックコピーの発生する挿入コストで想定する配列の長さは25個とかそんなもんです。一方で、floatとかVector2程度の要素にいちいち細切れのヒープを<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>に要求しまくる事は安定してヘビー(少なくとも10~100個程度のブロックコピーに比べれば。だいたいこのサイズの配列なら何百文字かの文字列型を切った貼ったするのと大差ない)。これが配列リストを採用する理由になります。</span></p> </div> tiri_tomato カスタムエディタのEditorクラスでRenderTexture hatenablog://entry/8454420450097905395 2015-06-17T11:15:52+09:00 2015-06-20T12:32:47+09:00 なんでインスペクタにDrawLineメソッドないんじゃー!! Handles.DrawLineでよかった。とりあえずRenderTargetのサンプルとして読んでください(目逸らし)そう言えばUnity5になってから無料版でもRenderTargetが解禁されています。って事はEditorのレンダリングで使っても良いと。というわけでプレビューのところに対角線を一本引いてみようと思います。*1こんなクラスがあるとして using UnityEngine; public class DrawLineTestComponent : MonoBehaviour { } そこで、こういうエディタを定義し… <p><s>なんでインスペクタにDrawLine<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>ないんじゃー!!</s><br /> <span style="color: #ff0000"><span style="font-size: 150%">Handles.DrawLineでよかった。</span></span><span style="font-size: 80%">とりあえずRenderTargetのサンプルとして読んでください(目逸らし)</span></p><p>そう言えばUnity5になってから無料版でもRenderTargetが解禁されています。</p><p>って事はEditorの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>で使っても良いと。</p><p>というわけでプレビューのところに対角線を一本引いてみようと思います。<a href="#f-2f49b816" name="fn-2f49b816" title="実はまず最初、こちら([http://tips.hecomi.com/entry/2014/06/23/222805:title])のサイトを参考にDrawRect()をGUIUtility.RotateAroundPivot()する方法を試したんですが、うちの環境で対角線を引こうとすると、なぜか半分くらいの長さになってしまうケースが発生。いろいろ試してみたところ縦長ウィンドウ表示にすると半分程度まで縮んでしまい、逆に横長ウィンドウに潰すとだいたいちゃんと表示できる:でもちょっと長さが足りない、という感じだったので、回転する前のインスペクタ描画に渡される矩形の幅で勝手にクリッピングされてしまうんじゃないかと推測。試しに矩形幅で描画したらほぼ同じ描画結果になったんよね…DrawTextureなら良かったんかねぇ…→6/20追記:回転前の矩形から逆算してクリッピングに引っかからないように分割描画してみたらうまくいった。インスペクタの狭い部分でGUIUtility.RotateAroundPivot()する作戦は今となってはアレかもしれない。やっぱHandle使うべきか…">*1</a></p><p>こんなクラスがあるとして</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synType">public</span> <span class="synType">class</span> DrawLineTestComponent : MonoBehaviour { } </pre><p><br /> そこで、こういうエディタを定義して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D3%A5%E5%A1%BC%B5%A1%C7%BD">プレビュー機能</a>を盛り込んでいきます。</p> <pre class="code lang-cs" data-lang="cs" data-unlink>[CustomEditor(<span class="synStatement">typeof</span>(DrawLineTestComponent))] <span class="synType">public</span> <span class="synType">class</span> DrawLineTestEditor : Editor { <span class="synType">public</span> <span class="synType">override</span> <span class="synType">bool</span> HasPreviewGUI() { <span class="synStatement">return</span> <span class="synConstant">true</span>; } <span class="synType">public</span> <span class="synType">override</span> GUIContent GetPreviewTitle() { <span class="synStatement">return</span> <span class="synStatement">new</span> GUIContent(<span class="synConstant">&quot;DrawLineTest&quot;</span>); } <span class="synType">public</span> <span class="synType">override</span> <span class="synType">void</span> OnPreviewGUI(Rect r, GUIStyle background) { <span class="synComment">/// ...</span> } } </pre><p><br /> まずシェーダを用意します。GL.Lineで色を付けて描画するにはシェーダとマテリアルをセットする必要があります。で、それは洋モノの開発ネット上で散見されるお決まりのパターンがあるのでそのまま持ってきます<a href="#f-56934239" name="fn-56934239" title="初出誰やねん状態">*2</a>。<br /> <br /> </p> <pre class="code lang-cs" data-lang="cs" data-unlink> <span class="synType">static</span> Material mat; <span class="synType">void</span> OnEnable() { <span class="synStatement">if</span> (mat == <span class="synConstant">null</span>) { <span class="synComment">// シェーダーの名前は適当に冗長化した方が良いかも。</span> mat = <span class="synStatement">new</span> Material(<span class="synConstant">&quot;Shader </span><span class="synSpecial">\&quot;</span><span class="synConstant">Lines/Colored Blended</span><span class="synSpecial">\&quot;</span><span class="synConstant"> {&quot;</span> + <span class="synConstant">&quot;SubShader { Pass { &quot;</span> + <span class="synConstant">&quot; Blend SrcAlpha OneMinusSrcAlpha &quot;</span> + <span class="synConstant">&quot; ZWrite Off Cull Off Fog { Mode Off } &quot;</span> + <span class="synConstant">&quot; BindChannels {&quot;</span> + <span class="synConstant">&quot; Bind </span><span class="synSpecial">\&quot;</span><span class="synConstant">vertex</span><span class="synSpecial">\&quot;</span><span class="synConstant">, vertex Bind </span><span class="synSpecial">\&quot;</span><span class="synConstant">color</span><span class="synSpecial">\&quot;</span><span class="synConstant">, color }&quot;</span> + <span class="synConstant">&quot;} } }&quot;</span>); mat.hideFlags = HideFlags.HideAndDontSave; mat.shader.hideFlags = HideFlags.HideAndDontSave; } } </pre><p><br /> いよいよRenderTextureを生成して描画します。一気にいきます。</p> <pre class="code lang-cs" data-lang="cs" data-unlink> RenderTexture previewImage; <span class="synComment">// OnDisableで削除</span> <span class="synType">void</span> OnDisable() { <span class="synStatement">if</span> (previewImage != <span class="synConstant">null</span>) previewImage.Release(); } <span class="synType">public</span> <span class="synType">override</span> <span class="synType">void</span> OnPreviewGUI(Rect r, GUIStyle background) { <span class="synType">int</span> w = (<span class="synType">int</span>)r.width; <span class="synType">int</span> h = (<span class="synType">int</span>)r.height; <span class="synStatement">if</span> (previewImage == <span class="synConstant">null</span>) { previewImage = <span class="synStatement">new</span> RenderTexture(w, h, <span class="synConstant">0</span>, RenderTextureFormat.ARGB32); previewImage.hideFlags = HideFlags.HideAndDontSave; previewImage.Create(); } <span class="synStatement">else</span> <span class="synStatement">if</span> ((previewImage.width != w) || (previewImage.height != h)) { previewImage.Release(); <span class="synComment">// サイズ変更する時は事前にRelease()</span> previewImage.width = w; previewImage.height = h; previewImage.Create(); } <span class="synStatement">if</span> (previewImage.IsCreated() == <span class="synConstant">false</span>) <span class="synStatement">return</span>; <span class="synComment">// ???</span> RenderBuffer regColorBuffer = Graphics.activeColorBuffer; RenderBuffer regDepthBuffer = Graphics.activeDepthBuffer; Graphics.SetRenderTarget(previewImage); GL.Clear(<span class="synConstant">false</span>, <span class="synConstant">true</span>, Color.clear); mat.SetPass(<span class="synConstant">0</span>); <span class="synComment">// マテリアル設定</span> GL.PushMatrix(); GL.LoadPixelMatrix(<span class="synConstant">0</span>, w, h, <span class="synConstant">0</span>); <span class="synComment">// 画面座標っぽく座標指定できて便利</span> GL.Begin(GL.LINES); GL.Color(Color.white); GL.Vertex(<span class="synStatement">new</span> Vector3(<span class="synConstant">0</span>, <span class="synConstant">0</span>)); <span class="synComment">// 画面左上から</span> GL.Vertex(<span class="synStatement">new</span> Vector3(w, h)); <span class="synComment">// 右下まで対角線いっぱいに直線描画</span> GL.End(); GL.PopMatrix(); Graphics.SetRenderTarget(regColorBuffer, regDepthBuffer); GUI.DrawTexture(r, previewImage); } </pre><p><br /> 見たまんまなのであんまり説明は要らないかなぁ…</p><p>SetRenderTarget()でターゲット変更する前に、Graphics.activeColorBuffer/DepthBufferで元の描画先を保存しておいて後で戻すのが推奨かな。それと<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>的な用途であればGL.LoadPixelMatrix()が超便利なのでオススメ。</p><p>結果<br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20150617110223" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20150617/20150617110223_120.jpg" alt="f:id:tiri_tomato:20150617110223p:image:medium" title="f:id:tiri_tomato:20150617110223p:image:medium" class="hatena-fotolife" itemprop="image"></a></span></p><p>んー。まぁ描画品質は若干お察し。本気でやるなら余白ありの透過テクスチャ使って、余白分太めにポリゴン描画して、テクスチャサンプリングで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%F3%A5%C1%A5%A8%A5%A4%A5%EA%A5%A2%A5%B7%A5%F3%A5%B0">アンチエイリアシング</a>するとかそんな感じになると思うんだけどそこまでするかどうかは微妙かなぁ。</p> <div class="footnote"> <p class="footnote"><a href="#fn-2f49b816" name="f-2f49b816" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">実はまず最初、こちら(<a href="http://tips.hecomi.com/entry/2014/06/23/222805">Unity &#x306E; Editor &#x62E1;&#x5F35;&#x3067;&#x30A4;&#x30F3;&#x30B9;&#x30DA;&#x30AF;&#x30BF;&#x306B;&#x30B0;&#x30E9;&#x30D5;&#x3092;&#x63CF;&#x753B;&#x3059;&#x308B;&#x65B9;&#x6CD5;&#x3092;&#x8272;&#x3005;&#x8ABF;&#x3079;&#x3066;&#x307F;&#x305F; - &#x51F9;&#x307F;Tips</a>)のサイトを参考にDrawRect()をGUIUtility.RotateAroundPivot()する方法を試したんですが、うちの環境で対角線を引こうとすると、なぜか半分くらいの長さになってしまうケースが発生。いろいろ試してみたところ縦長ウィンドウ表示にすると半分程度まで縮んでしまい、逆に横長ウィンドウに潰すとだいたいちゃんと表示できる:でもちょっと長さが足りない、という感じだったので、回転する前のインスペクタ描画に渡される矩形の幅で勝手に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D4%A5%F3%A5%B0">クリッピング</a>されてしまうんじゃないかと推測。試しに矩形幅で描画したらほぼ同じ描画結果になったんよね…DrawTextureなら良かったんかねぇ…→6/20追記:回転前の矩形から逆算して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D4%A5%F3%A5%B0">クリッピング</a>に引っかからないように分割描画してみたらうまくいった。インスペクタの狭い部分でGUIUtility.RotateAroundPivot()する作戦は今となってはアレかもしれない。やっぱHandle使うべきか…</span></p> <p class="footnote"><a href="#fn-56934239" name="f-56934239" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">初出誰やねん状態</span></p> </div> tiri_tomato Editorクラスの寿命とか hatenablog://entry/8454420450097276427 2015-06-11T22:44:48+09:00 2015-06-16T23:58:40+09:00 まったりUnity記事再開。あまり気にしたことが無かったんだけどUnityEditor.Editorでインスペクタ拡張する時のEditorクラスの寿命メモ。GameObjectが選択される時:Editor.Awake()→Editor.OnEnable() GameObjectが非選択になる時:Editor.OnDisable()→Editor.OnDestroy()ちなみに、エディタでコードを変更するとUnityに戻った時に再コンパイルが自動で働きますが、既にGameObjectが選択中だった場合はAwake()とOnDestroy()が呼ばれません。GameObject選択中再コンパイル:… <p>まったりUnity記事再開。</p><p>あまり気にしたことが無かったんだけどUnityEditor.Editorでインスペクタ拡張する時のEditorクラスの寿命メモ。</p><p>GameObjectが選択される時:Editor.Awake()→Editor.OnEnable()<br /> GameObjectが非選択になる時:Editor.OnDisable()→Editor.OnDestroy()</p><p>ちなみに、エディタでコードを変更するとUnityに戻った時に再<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>が自動で働きますが、既にGameObjectが選択中だった場合はAwake()とOnDestroy()が呼ばれません。</p><p>GameObject選択中再<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>:旧Editor.OnDisable()→新Editor.OnEnable()</p><p>で呼ばれます。つまりEditorの内部メンバーの初期化チェック/リソース解放はEnable/Disableに書くべき?というかもはやEditorでAwake/OnDestroyが呼ばれる意味が分からんですねコレ。</p> <div class="section"> <h5>Start/Update</h5> <p>呼び出されません。</p> </div> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%B9%A5%C8%A5%E9%A5%AF%A5%BF">コンストラクタ</a>とデストラクタ</h5> <p>Editorは選択されるたびに新規生成され、Awake()前に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%B9%A5%C8%A5%E9%A5%AF%A5%BF">コンストラクタ</a>が呼ばれます。つまり本当はこんな感じ。</p><p>GameObjectが選択される時:<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%B9%A5%C8%A5%E9%A5%AF%A5%BF">コンストラクタ</a>→Awake()→OnEnable()<br /> GameObjectが非選択になる時:OnDisable()→OnDestroy()→デストラクタ</p><p>が、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%B9%A5%C8%A5%E9%A5%AF%A5%BF">コンストラクタ</a>ではリソース生成も出来るようですが、デストラクタでのリソース解放、例えばDestroyImmediate()やRenderTexture.Release()は出来ません。エラーログが出ます。ゲームリソースの解放にはOnDisable()かOnDestroy()を使います。びみょい。</p> </div> <div class="section"> <h5>まとめ</h5> <ul> <li>Editor.OnEnable()で初期化チェックまたはOn~<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>()の度に毎回未初期化チェックする</li> <li>Editor.OnDisable()で解放する。<s>OnDestroy()でも可</s><small><span style="color: #999999">いやいや駄目じゃん。既フォーカス状態だとDestroy呼ばれないって自分で書いてるのに!プライベートリソース解放はOnDisable()で。</span></small></li> <li>そもそもGameObjectのフォーカスが去るだけでEditorは丸ごと破棄されている。</li> </ul> </div> <div class="section"> <h5>staticでhide系に設定したEditor用のリソース</h5> <p>TextureとかMaterialとか、この手のリソースをEditorで静的保持している時、hideFlagを設定しないとシーンの保存で「リークしてる!」と怒られるので設定する事になると思います。これらは一体どういう扱いになっているのでしょうか。</p><p>まずエディタでコードを変更してUnityに戻ると再<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>/チェックが働きますが静的な変数はこれで全部nullに戻ってしまいます。変更して無いコードも含め全てです。</p><p>初期化はやり直せばいいだけですが古い静的リソースはどうすりゃ良いのか。hide状態だからFind系は使えないし旧Editorの静的フィールドはリセットされてしまいます…これ、おそらく多少の時差はあるかもしれませんがコッソリ削除してもらえるようです。</p><p>その時の実験が以下。</p><p>Editorからnew GameObject()して、hideAndDontSaveを設定して、OnDisable、OnDestroy、デストラクタでログを出力するMonoBehaviorをくっつけたんですが、再<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>契機でデストラクタだけログが出ました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/GC">GC</a>タイミングの誤差があるのでいまいち明確なフローがつかめなかった感。</p><p>個人的には、静的オブジェクトの解放契機で複雑な事をするのは避けて、あとはUnityを信じるしかないかなぁというドンブリ感の強い結論に至りました。</p> </div> tiri_tomato C#でCSV読む hatenablog://entry/8454420450078219211 2014-12-28T01:56:36+09:00 2015-04-14T10:39:59+09:00 DOBONをうろついていたら久しぶりに目から鱗が落ちたですよCSV形式のファイルをDataTableや配列等として取得する: .NET Tips: C#, VB.NET 「改行混じり」CSV、行中のダブルクオートが偶数になるまで行結合を繰り返すだけで読めるってよ…。はえ?…。ほ、本当だーッ!?CSVって基本的にはセルをカンマで区切り、ROWはそのまんま改行で表現する書式。なんですが、意外と面倒くさいのはダブルクオーテーションで囲むと、区切り文字のカンマのみならず改行文字までセル内に含ませることが出来る仕様。どうしたものか。しかもダブルクオーテーション自体のエスケープにも対応しなくちゃいけない。… <p>DOBONをうろついていたら久しぶりに目から鱗が落ちたですよ</p><p><a href="http://dobon.net/vb/dotnet/file/readcsvfile.html">CSV&#x5F62;&#x5F0F;&#x306E;&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x3092;DataTable&#x3084;&#x914D;&#x5217;&#x7B49;&#x3068;&#x3057;&#x3066;&#x53D6;&#x5F97;&#x3059;&#x308B;: .NET Tips: C#, VB.NET</a><br /> <b>「改行混じり」<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSV">CSV</a>、行中のダブルクオートが偶数になるまで行結合を繰り返すだけで読めるってよ</b></p><p>…。</p><p>はえ?</p><p>…。</p><p>ほ、本当だーッ!?</p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/CSV">CSV</a>って基本的にはセルをカンマで区切り、ROWはそのまんま改行で表現する書式。なんですが、意外と面倒くさいのはダブルクオーテーションで囲むと、区切り文字のカンマのみならず改行文字までセル内に含ませることが出来る仕様。どうしたものか。しかもダブルクオーテーション自体のエスケープにも対応しなくちゃいけない。しかし、しかしである。</p><p>ミソは</p> <ul> <li>制御文字がカンマとダブルクオートしかない</li> <li>カンマはダブルクオーテーションで囲ってエスケープ</li> <li>ダブルクオーテーションは2連続でエスケープ</li> </ul><p>だからダブルクオートが偶数になるまで行結合するだけ<a href="#f-77eb5fcc" name="fn-77eb5fcc" title="「1ROW分のデータ=全てのカンマが閉じた状態で最初に改行が現れるところ迄」なので、改行単位で読み込んでみてカンマ数が偶数になるところまで結合していけばよい、てわけで、言われてみれば簡単な話なんだけど…ふーむ。">*1</a>、妙案…。ちなみに2連続ダブルクオートにも対応したスプリット用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>が次のパターンだそう。</p> <pre class="code" data-lang="" data-unlink>(&#34;(?:[^&#34;]|&#34;&#34;)*&#34;|[^,]*),</pre><p>(ただし行末にカンマを一つ追加しないと最後の要素が取得できない<a href="#f-fb0f509a" name="fn-fb0f509a" title="アイテムの末尾サインとしてカンマを使う発想/C言語文字列のNULL終端記号とかEOFマークみたいなもん。">*2</a>)</p><p>しょえー。読込だけならライブラリとか持ってくる必要もないのか。では早速、<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSV">CSV</a>形式のテキストストリームをシーケンシャルリードしちゃうクラス書いてみます。</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> System; <span class="synStatement">using</span> System.Collections.Generic; <span class="synType">public</span> <span class="synType">class</span> CSVReader { <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">先頭末尾のダブルクオーテーションを切除します。標準の動作です。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> <span class="synType">bool</span> trimDQuot; <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">エスケープされているダブルクオーテーション(二重になっているダブルクーテーション)を1つに戻します。標準の動作です。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> <span class="synType">bool</span> formatEscapedDQuot; <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">コンストラクタ</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">param</span><span class="synIdentifier"> </span><span class="synType">name</span>=<span class="synConstant">&quot;reader&quot;</span><span class="synIdentifier">&gt;</span><span class="synComment">読込むCSVデータ。StringReaderかStreamReaderを想定。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">param</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> CSVReader(System.IO.TextReader reader) { <span class="synStatement">this</span>.reader = reader; trimDQuot = <span class="synConstant">true</span>; formatEscapedDQuot = <span class="synConstant">true</span>; } <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">CSVから一行を読んで返します。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">returns</span><span class="synIdentifier">&gt;</span><span class="synComment">行にデータがあれば、1行分のセルの配列をstring[]として返します。セルが一つもない空行の場合は空の配列が返ります。EOFに達するとNULLが返ります。ダブルクオーテーションの処理はtrimDQuotメンバとformatEscapedDQuotメンバを参照してください。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">returns</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> <span class="synType">string</span>[] ReadLine() { <span class="synType">int</span> ctQuot = <span class="synConstant">0</span>; <span class="synType">string</span> mergedLine = <span class="synConstant">null</span>; <span class="synStatement">while</span> (-<span class="synConstant">1</span> &lt; reader.Peek()) { <span class="synComment">// ダブルクオーテーションの数が偶数になるまでReadLineをマージしていけば改行交じりを処理できる。</span> <span class="synType">string</span> getLine = reader.ReadLine(); <span class="synComment">// 連結</span> <span class="synStatement">if</span> (mergedLine == <span class="synConstant">null</span>) mergedLine = getLine; <span class="synStatement">else</span> mergedLine += (System.Environment.NewLine + getLine); <span class="synComment">// クオーテーションカウント</span> ctQuot += (getLine.Length - getLine.Replace(<span class="synConstant">&quot;</span><span class="synSpecial">\&quot;</span><span class="synConstant">&quot;</span>, <span class="synType">string</span>.Empty).Length); <span class="synStatement">if</span> ((ctQuot % <span class="synConstant">2</span>) == <span class="synConstant">0</span>) <span class="synComment">// 偶数ブレイク判定</span> { ctQuot = <span class="synConstant">0</span>; <span class="synComment">// カウンタ初期化(しなくても良いっちゃ良い)</span> <span class="synStatement">break</span>; } } <span class="synStatement">if</span> (mergedLine == <span class="synConstant">null</span>) <span class="synStatement">return</span> <span class="synConstant">null</span>; <span class="synStatement">else</span> <span class="synStatement">if</span> (mergedLine.Length == <span class="synConstant">0</span>) <span class="synStatement">return</span> <span class="synStatement">new</span> <span class="synType">string</span>[<span class="synConstant">0</span>]; List&lt;<span class="synType">string</span>&gt; split = <span class="synStatement">new</span> List&lt;<span class="synType">string</span>&gt;(); <span class="synStatement">foreach</span> (System.Text.RegularExpressions.Match match <span class="synStatement">in</span> regexSplitter.Matches(mergedLine + <span class="synConstant">','</span>)) { <span class="synType">string</span> item = match.Value; split.Add(item.Substring(<span class="synConstant">0</span>, item.Length - <span class="synConstant">1</span>)); <span class="synComment">// remove comma</span> } <span class="synStatement">if</span> (trimDQuot) { <span class="synStatement">for</span> (<span class="synType">int</span> index = <span class="synConstant">0</span>; index &lt; split.Count; index++) { <span class="synType">string</span> item = split[index]; <span class="synStatement">if</span> ((<span class="synConstant">0</span> &lt; item.Length) &amp;&amp; (item[<span class="synConstant">0</span>] == <span class="synConstant">'&quot;'</span>) &amp;&amp; (item[item.Length - <span class="synConstant">1</span>] == <span class="synConstant">'&quot;'</span>)) { split[index] = item.Substring(<span class="synConstant">1</span>, Math.Max(<span class="synConstant">0</span>, item.Length - <span class="synConstant">2</span>)); } } } <span class="synStatement">if</span> (formatEscapedDQuot) { <span class="synStatement">for</span> (<span class="synType">int</span> index = <span class="synConstant">0</span>; index &lt; split.Count; index++) { split[index] = split[index].Replace(<span class="synConstant">&quot;</span><span class="synSpecial">\&quot;\&quot;</span><span class="synConstant">&quot;</span>, <span class="synConstant">&quot;</span><span class="synSpecial">\&quot;</span><span class="synConstant">&quot;</span>); } } <span class="synStatement">return</span> split.ToArray(); } <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> <span class="synType">string</span> splitterPattern = <span class="synConstant">&quot;(</span><span class="synSpecial">\&quot;</span><span class="synConstant">(?:[^</span><span class="synSpecial">\&quot;</span><span class="synConstant">]|</span><span class="synSpecial">\&quot;\&quot;</span><span class="synConstant">)*</span><span class="synSpecial">\&quot;</span><span class="synConstant">|[^,]*),&quot;</span>; <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> System.Text.RegularExpressions.Regex regexSplitter = <span class="synStatement">new</span> System.Text.RegularExpressions.Regex(splitterPattern, System.Text.RegularExpressions.RegexOptions.Multiline); <span class="synType">private</span> System.IO.TextReader reader; } </pre><p>テスト用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/CSV">CSV</a>をつくりーの(できるだけえげつないの)<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20141228/20141228014720.png" alt="f:id:tiri_tomato:20141228014720p:plain" title="f:id:tiri_tomato:20141228014720p:plain" class="hatena-fotolife" itemprop="image"></span></p><p>テストのコンソールプロジェクト作ってリソース追加しーの<a href="#f-9fc631e1" name="fn-9fc631e1" title="FileTypeは単なるTextで">*3</a><br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20141228/20141228014724.png" alt="f:id:tiri_tomato:20141228014724p:plain" title="f:id:tiri_tomato:20141228014724p:plain" class="hatena-fotolife" itemprop="image"></span></p><p>書きーの</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synType">static</span> <span class="synType">void</span> Main(<span class="synType">string</span>[] args) { CSVReader reader = <span class="synStatement">new</span> CSVReader(<span class="synStatement">new</span> System.IO.StringReader(Resources.CSVImportTest)); <span class="synType">string</span>[] getLine = <span class="synConstant">null</span>; <span class="synStatement">while</span> ((getLine = reader.ReadLine()) != <span class="synConstant">null</span>) { <span class="synStatement">for</span> (<span class="synType">int</span> index = <span class="synConstant">0</span>; index &lt; getLine.Length; index++) { <span class="synComment">// 改行分かりにくいから&lt;br&gt;に置換する。</span> getLine[index] = getLine[index].Replace(System.Environment.NewLine, <span class="synConstant">&quot;&lt;br&gt;&quot;</span>); } <span class="synComment">// アイテム同士をスラッシュで連結して表示する。</span> Console.WriteLine(<span class="synType">string</span>.Join(<span class="synConstant">&quot;/&quot;</span>, getLine)); } } </pre><p>走らせる。<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20141228/20141228014727.png" alt="f:id:tiri_tomato:20141228014727p:plain" title="f:id:tiri_tomato:20141228014727p:plain" class="hatena-fotolife" itemprop="image"></span></p><p>動いてるっぽい?改行コードとか、ちょっと不安なので使う際はお手元でも一通りテストしてくださいな<a href="#f-58994511" name="fn-58994511" title="って、当たり前か…Win8の2010で書いてますが、とくにSystem.Text.RegularExpressions.Regexクラスとか、改行のあたりの処理が他環境でどの程度安定するかわからんのですよねコレ。">*4</a></p><p>それでは皆様、良いお年を。</p><p><b>12/28 19:00追記</b><br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>の偶数カウンタctQuotですが、偶数達成時にゼロ初期化するのを忘れてました。「カウントアップした状態が偶数かどうか」だから理論的には初期化せずとも動くんですが気持ち悪いのでなおしました。</p><p><b>2015/04/14 追記</b><br /> ダブルクオーテーションのトリム処理のところ、空のセルおよび最終セルがダブルクオーテーション一つだけでEOFしてる場合のチェックを追加…うーむ<a class="keyword" href="http://d.hatena.ne.jp/keyword/gdgd">gdgd</a>で申し訳ないですハイ。</p> <div class="footnote"> <p class="footnote"><a href="#fn-77eb5fcc" name="f-77eb5fcc" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">「1ROW分のデータ=全てのカンマが閉じた状態で最初に改行が現れるところ迄」なので、改行単位で読み込んでみてカンマ数が偶数になるところまで結合していけばよい、てわけで、言われてみれば簡単な話なんだけど…ふーむ。</span></p> <p class="footnote"><a href="#fn-fb0f509a" name="f-fb0f509a" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">アイテムの末尾サインとしてカンマを使う発想/<a class="keyword" href="http://d.hatena.ne.jp/keyword/C%B8%C0%B8%EC">C言語</a>文字列のNULL終端記号とかEOFマークみたいなもん。</span></p> <p class="footnote"><a href="#fn-9fc631e1" name="f-9fc631e1" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">FileTypeは単なるTextで</span></p> <p class="footnote"><a href="#fn-58994511" name="f-58994511" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">って、当たり前か…<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>の2010で書いてますが、とくにSystem.Text.<a class="keyword" href="http://d.hatena.ne.jp/keyword/RegularExpressions">RegularExpressions</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Regex">Regex</a>クラスとか、改行のあたりの処理が他環境でどの程度安定するかわからんのですよねコレ。</span></p> </div> tiri_tomato 昨日のビルボードサンプルのエラー対応版 hatenablog://entry/8454420450077304033 2014-05-02T11:58:44+09:00 2014-12-17T12:52:49+09:00 前回の最後にちょろっと書いてる「GameObject.hideFlags = DontSaveでの問題」について。さらに追試。 Component.hideFlags Component.hideFlags≠GameObject.hideFlagsなので、コンポーネントだけDontSaveにしてみました。でもやはりロード時に Component MeshFilter could not be loaded when loading game object. Cleaning up! なーんて赤警告で表示されてしまいますた。 トップレベルのGameObjectがDontSaveならまったく問題な… <p><a href="http://d.hatena.ne.jp/tiri_tomato/20140501/1398897878">&#x524D;&#x56DE;</a>の最後にちょろっと書いてる「GameObject.hideFlags = DontSaveでの問題」について。</p><p>さらに追試。</p> <div class="section"> <h5>Component.hideFlags</h5> <p>Component.hideFlags≠GameObject.hideFlagsなので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>だけDontSaveにしてみました。でもやはりロード時に</p> <blockquote> <p>Component MeshFilter could not be loaded when loading game object. Cleaning up!</p> </blockquote> <p>なーんて赤警告で表示されてしまいますた。</p> </div> <div class="section"> <h5>トッ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D9">プレベ</a>ルのGameObjectがDontSaveならまったく問題ない模様</h5> <p>試行錯誤の結果、シーンの直下(親ナシ)の時だけはちゃんとフラグチェックして保存対象から除外しているようでした。そもそも<a href="https://docs.unity3d.com/Documentation/ScriptReference/HideFlags.DontSave.html">Unity&#x306E;DontSave&#x30D5;&#x30E9;&#x30B0;&#x306E;&#x8AAC;&#x660E;</a>を見てみると「んー?単にシーン越境するためだけのフラグ?」ともとれかねないのですが、この状況を見るに、親子ノードを辿って<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a>的に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B7%A5%EA%A5%A2%A5%E9%A5%A4%A5%BA">シリアライズ</a>保存する時はチェックが抜けているっぽい…<a href="#f-6c215eb8" name="fn-6c215eb8" title="保存するGameObjectの子に非保存GameObjectがぶら下がってるってそんなに異常な状態でもないと思うんだけどなぁ…非保存で保存をスキップする時に子配列のインデックス番号がズレると、エンドプログラマのスクリプトがバグる可能性が微粒子レベルで存在?それならそれでMissing扱いにしちゃえば…うぅーむ。">*1</a><br /> </p> </div> <div class="section"> <h4>プラン1(オススメ!)</h4> <p>「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%A3%A4%B7%A5%AA%A5%D6%A5%B8%A5%A7">隠しオブジェ</a>クトは単独でシーンに配置する」つまりオモテのオブジェクトの子にしない。transformが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a>的に反映されないので、オモテのオブジェクトが操作されたらウラのオブジェクトには逐一手動で反映します。削除もしないとリークします。日記の最後に、この方法で修正した版を書いておきます。</p> </div> <div class="section"> <h4>プラン2</h4> <p>この<a href="http://answers.unity3d.com/questions/609621/hideflagsdontsave-causes-checkconsistency-transfor.html">HideFlags.DontSave causes &quot;CheckConsistency: Transform child can&#39;t be loaded&quot; (Unity Bug?) / UnityAnswers</a>に書いてあるんですが、UnityEditor.AssetModificationProcessorを使ってシーン保存イベントを拾って、保存前に親子関係を切ったり削除してしまったりする手が考えられます。ただ、この方法で問題になったのが2点。</p> <div class="section"> <h5>課題1.いつ絶縁状態や削除状態から復帰させるか</h5> <p>これはまぁ、Editorクラスを継承してCustomEditor属性をつけてあげれば、選択時にOnSceneGUIが飛んでくるようになります。例えば保存時に消しても、ヒエラルキで選択すればOnSceneGUIが実行されてそこでプレビューオブジェクトの復帰処理がコールされる、という<a class="keyword" href="http://d.hatena.ne.jp/keyword/Shuriken">Shuriken</a>ライクな仕様とか。背景用だとイマイチなものの、エフェクト用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%EB%A5%DC%A1%BC%A5%C9">ビルボード</a>ならじゅうぶんです。</p><p>なら解決?と思いきや。</p> </div> <div class="section"> <h5>課題2.親オブジェクトに隠し子をつなげると「シーン変更」としてバレてしまう!</h5> <p>ところが、親子関係の復帰処理としてhiddenChild.transform.parent = ownerObject;って書いちゃうと、「シーンの保存対象であるownerObjectが変更された!」って事になって、そのままUnityを閉じると「変更を保存しますか?」の画面が出ちゃうんですね。コレ解決できませんでした。先述した「選択で再表示」の仕様とすると「保存時にプレビューメッシュが消えちゃうのはともかくとして、クリックして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%EB%A5%DC%A1%BC%A5%C9">ビルボード</a>を再表示させただけで変更として検知される」というのはちょっとわかりにくい気がします。小さなシーンならともかく、大きなシーンで全選択した中にこういう<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>が混ざっちゃってると、「アレ?俺なんか変更したっけ?」ってなりそう。</p><p>プラン2もなんか使い道がありそうなんですが、とりあえず今回はプラン1で解決します。</p> </div> </div> <div class="section"> <h4>プラン1方式の修正版</h4> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/Billboard">Billboard</a>.cs</h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synType">namespace</span> BillboardSystem { [ExecuteInEditMode()] <span class="synType">public</span> <span class="synType">class</span> Billboard : MonoBehaviour { <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">レンダリング時に使用するマテリアル</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> Material material; <span class="synType">private</span> <span class="synType">static</span> System.String hiddenChildName = <span class="synConstant">&quot;BillboardHiddenRenderer&quot;</span>; <span class="synType">private</span> GameObject renderObject; <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">状態を隠しレンダオブジェクトにコピーします(位置とレイヤーを転写)。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">void</span> CopyState() { <span class="synStatement">if</span> (renderObject != <span class="synConstant">null</span>) { Transform childTrans = renderObject.transform; childTrans.position = transform.position; childTrans.localScale = transform.lossyScale; childTrans.rotation = transform.rotation; renderObject.layer = gameObject.layer; } } <span class="synType">void</span> OnEnable() { <span class="synStatement">if</span> (renderObject == <span class="synConstant">null</span>) { renderObject = <span class="synStatement">new</span> GameObject(hiddenChildName); renderObject.hideFlags = HideFlags.HideAndDontSave; renderObject.AddComponent&lt;BillboardRenderer&gt;().ownerBillboard = <span class="synStatement">this</span>; CopyState(); } <span class="synStatement">else</span> renderObject.SetActive(<span class="synConstant">true</span>); } <span class="synType">void</span> OnDisable() { <span class="synStatement">if</span> (renderObject != <span class="synConstant">null</span>) renderObject.SetActive(<span class="synConstant">false</span>); } <span class="synType">void</span> OnDestroy() { <span class="synStatement">if</span> (Application.isEditor) DestroyImmediate(renderObject); <span class="synStatement">else</span> Destroy(renderObject); } <span class="synType">void</span> Update() { CopyState(); } } } </pre><p>BillboardRenderer.cs は昨日の記事のままで大丈夫です。</p> </div> </div><div class="footnote"> <p class="footnote"><a href="#fn-6c215eb8" name="f-6c215eb8" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">保存するGameObjectの子に非保存GameObjectがぶら下がってるってそんなに異常な状態でもないと思うんだけどなぁ…非保存で保存をスキップする時に子配列のインデックス番号がズレると、エンド<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A5%B0%A4%EB">バグる</a>可能性が微粒子レベルで存在?それならそれでMissing扱いにしちゃえば…うぅーむ。</span></p> </div> tiri_tomato UnityでShurikenぽいビルボードの作り方 hatenablog://entry/8454420450077304040 2014-05-01T07:44:38+09:00 2014-12-17T12:52:49+09:00 こんな感じに、スクリプトからリアルタイムに頂点を計算してビルボードを表示しようというサンプル。標準のパーティクルシステムでは描画できないエフェクト系のコンポーネントを作りたい人向け。(Unity 4.3.4.f1)エディタ表示だろうとカメラが複数あろうと大丈夫!(だと思う) 大事なところ OnWillRenderObject() の受信には MeshRenderer が必要 前後左右の複数のカメラから一斉に狙われても大丈夫な板ポリゴンをレンダするには、カメラごとにOnWillRenderObject()を呼んでもらって、その都度カメラにメッシュを向けてやればオッケーとなっています。 Unity… <p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20140430090958" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20140430/20140430090958.jpg" alt="f:id:tiri_tomato:20140430090958j:image:w360:left" title="f:id:tiri_tomato:20140430090958j:image:w360:left" class="hatena-fotolife hatena-image-left" style="width:360px" itemprop="image"></a></span>こんな感じに、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>からリアルタイムに頂点を計算して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%EB%A5%DC%A1%BC%A5%C9">ビルボード</a>を表示しようというサンプル。標準のパーティクルシステムでは描画できないエフェクト系の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>を作りたい人向け。(Unity 4.3.4.f1)</p><p><span class="deco" style="color:#FF0000;">エディタ表示だろうとカメラが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>あろうと大丈夫!(だと思う)</span><br clear="all"></p> <div class="section"> <h4>大事なところ</h4> <div class="section"> <h5>OnWillRenderObject() の受信には MeshRenderer が必要</h5> <p>前後左右の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CA%A3%BF%F4">複数</a>のカメラから一斉に狙われても大丈夫な板ポリゴンをレンダするには、カメラごとにOnWillRenderObject()を呼んでもらって、その都度カメラにメッシュを向けてやればオッケーとなっています。<br /> <a href="http://docs-jp.unity3d.com/Documentation/Manual/ExecutionOrder.html">Unity &#x30DE;&#x30CB;&#x30E5;&#x30A2;&#x30EB; / Unity Manual&gt;Advanced&gt;&#x30A4;&#x30D9;&#x30F3;&#x30C8;&#x95A2;&#x6570;&#x306E;&#x5B9F;&#x884C;&#x9806;</a><br /> で、OnWillRenderObjectの受信にはどうやらMeshRenderer<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>の登録が必要。MeshRendererは1つのGameObjectにつき1つまで。MeshRendererの取り合いを避けるため、隠し子GameObjectを作ります。今回は、エディタに表出する設定保持<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>A&隠し子オブジェクト側で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>とメッシュを管理する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>Bの二台体制でいきます。</p> </div> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/Billboard">Billboard</a>.cs</h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synType">namespace</span> BillboardSystem { [ExecuteInEditMode()] <span class="synType">public</span> <span class="synType">class</span> Billboard : MonoBehaviour { <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">レンダリング時に使用するマテリアル</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> Material material; <span class="synType">private</span> GameObject renderObject; <span class="synType">void</span> OnEnable() { <span class="synStatement">if</span> (renderObject == <span class="synConstant">null</span>) { renderObject = <span class="synStatement">new</span> GameObject(<span class="synConstant">&quot;hideChild for Billboard Renderer&quot;</span>); renderObject.hideFlags = HideFlags.HideAndDontSave; renderObject.transform.parent = transform; renderObject.transform.localScale = Vector3.one; renderObject.transform.localPosition = Vector3.zero; renderObject.transform.localRotation = Quaternion.identity; renderObject.AddComponent&lt;BillboardRenderer&gt;().ownerBillboard = <span class="synStatement">this</span>; } } } } </pre><p>有効化された時に隠し子オブジェクトの有無をチェックして無ければ作ります。その時、後述のBillboardRenderer<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>を追加して、自身への参照を渡します。</p><p>で、下記がそのBillboardRenderer<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8">コンポーネント</a>の実装例。</p> </div> <div class="section"> <h5>BillboardRenderer.cs</h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synType">namespace</span> BillboardSystem { [ExecuteInEditMode()] <span class="synType">public</span> <span class="synType">class</span> BillboardRenderer : MonoBehaviour { <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span><span class="synComment">親ビルボードを取得、設定します。</span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">public</span> Billboard ownerBillboard; <span class="synType">private</span> Mesh mesh; <span class="synType">private</span> MeshFilter meshFilter; <span class="synType">private</span> MeshRenderer meshRenderer; <span class="synType">void</span> OnEnable() { <span class="synStatement">if</span> (gameObject == <span class="synConstant">null</span>) <span class="synStatement">return</span>; <span class="synStatement">if</span> (mesh == <span class="synConstant">null</span>) { mesh = <span class="synStatement">new</span> Mesh(); mesh.name = <span class="synConstant">&quot;RuntimeMesh&quot;</span>; mesh.hideFlags = HideFlags.HideAndDontSave; } <span class="synStatement">if</span> (meshFilter == <span class="synConstant">null</span>) { meshFilter = gameObject.AddComponent&lt;MeshFilter&gt;(); meshFilter.sharedMesh = mesh; } <span class="synStatement">if</span> (meshRenderer == <span class="synConstant">null</span>) meshRenderer = gameObject.AddComponent&lt;MeshRenderer&gt;(); } <span class="synType">void</span> OnDisable() { <span class="synStatement">if</span> (mesh != <span class="synConstant">null</span>) mesh.Clear(); } <span class="synType">void</span> OnDestroy() { <span class="synStatement">if</span> (Application.isEditor) DestroyImmediate(mesh); <span class="synStatement">else</span> Destroy(mesh); } <span class="synType">void</span> OnWillRenderObject() { mesh.Clear(); <span class="synStatement">if</span> ((Camera.current == <span class="synConstant">null</span>) || (Camera.current.transform == <span class="synConstant">null</span>)) <span class="synStatement">return</span>; <span class="synComment">// カメラ平面にX,Y軸として映る単位ワールドディレクションを取得</span> Vector3 meshHorizontalDirection = Camera.current.transform.TransformDirection(Vector3.right); Vector3 meshVerticalDirection = Camera.current.transform.TransformDirection(Vector3.up); <span class="synStatement">if</span> (ownerBillboard != <span class="synConstant">null</span>) meshRenderer.material = ownerBillboard.material; <span class="synComment">// オブジェクトの中心から、ビルボードの端点を決定します。基本的にワールド座標における1のサイズですが、lossyScaleのx,yもオマケします。</span> Matrix4x4 worldToLocalMatrix = transform.worldToLocalMatrix; Vector2 lossyScale = transform.lossyScale; Vector3 vH = worldToLocalMatrix * (meshHorizontalDirection * (<span class="synConstant">0.5f</span> * lossyScale.x)); Vector3 vV = worldToLocalMatrix * (meshVerticalDirection * (<span class="synConstant">0.5f</span> * lossyScale.y)); Vector3[] vertices = <span class="synStatement">new</span> Vector3[] { -vH - vV, <span class="synComment">//左下</span> -vH + vV, <span class="synComment">//左上</span> vH + vV, <span class="synComment">//右上</span> vH - vV, <span class="synComment">//右下</span> }; mesh.vertices = vertices; mesh.colors32 = <span class="synStatement">new</span> Color32[] { Color.white, Color.white, Color.white, Color.white }; mesh.uv = <span class="synStatement">new</span> Vector2[] { <span class="synStatement">new</span> Vector2(<span class="synConstant">0</span>, <span class="synConstant">0</span>), <span class="synComment">//左下</span> <span class="synStatement">new</span> Vector2(<span class="synConstant">0</span>, <span class="synConstant">1</span>), <span class="synComment">//左上</span> <span class="synStatement">new</span> Vector2(<span class="synConstant">1</span>, <span class="synConstant">1</span>), <span class="synComment">//右上</span> <span class="synStatement">new</span> Vector2(<span class="synConstant">1</span>, <span class="synConstant">0</span>), <span class="synComment">//右下</span> }; <span class="synType">int</span>[] tris = <span class="synStatement">new</span> <span class="synType">int</span>[] { <span class="synConstant">0</span>, <span class="synConstant">1</span>, <span class="synConstant">2</span>, <span class="synConstant">2</span>, <span class="synConstant">3</span>, <span class="synConstant">0</span> }; mesh.subMeshCount = <span class="synConstant">1</span>; mesh.SetTriangles(tris, <span class="synConstant">0</span>); mesh.RecalculateNormals(); } } } </pre> </div> </div> <div class="section"> <h4>お借りした素材</h4> <ul> <li>FreeAsset "Dead Tower Scene" (3D Models/Enviroments/Fantasy)</li> <li>写研 BA-90</li> </ul> </div> <div class="section"> <h4>でもシーンロードで変なログが出る。</h4> <p>ヨシヨシデキタと思ったら、こんなログががが</p> <blockquote> <p>CheckConsistency: Transform child can't be loaded</p> </blockquote> <p>ちょっと調べてみると3.xから放置されているGameObject.hideFlagにDontSaveを設定すると生じるバグの模様。…次の日記で対応版書く。</p> </div> tiri_tomato GUIStyle.contentOffset hatenablog://entry/8454420450077304044 2014-04-01T18:48:18+09:00 2014-12-17T12:52:52+09:00 サンプルが見当たらなくてお試し。(Unity Win 4.3.4f1) using UnityEngine; using UnityEditor; public class TestEditorWindow : UnityEditor.EditorWindow { [MenuItem("Assets/TestEditorOpen")] static void Open() { EditorWindow.GetWindow<TestEditorWindow>(); } void OnGUI() { GUIContent okContent = new GUIContent("OK"); GUIS… <p>サンプルが見当たらなくてお試し。(Unity Win 4.3.4f1)</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synStatement">using</span> UnityEditor; <span class="synType">public</span> <span class="synType">class</span> TestEditorWindow : UnityEditor.EditorWindow { [MenuItem(<span class="synConstant">&quot;Assets/TestEditorOpen&quot;</span>)] <span class="synType">static</span> <span class="synType">void</span> Open() { EditorWindow.GetWindow&lt;TestEditorWindow&gt;(); } <span class="synType">void</span> OnGUI() { GUIContent okContent = <span class="synStatement">new</span> GUIContent(<span class="synConstant">&quot;OK&quot;</span>); GUIStyle style = EditorStyles.miniButton; Vector2 size = style.CalcSize(okContent); Debug.Log(style.contentOffset); GUILayout.Button(okContent, style); <span class="synComment">// 普通に描画</span> style = <span class="synStatement">new</span> GUIStyle(EditorStyles.miniButton); style.contentOffset = size * <span class="synConstant">0.5f</span>; GUILayout.Button(okContent, style); <span class="synComment">// オフセットして描画</span> } } </pre><pre class="code" data-lang="" data-unlink>(0.0, 0.0) UnityEngine.Debug:Log(Object) TestEditorWindow:OnGUI() (at Assets/Editor/TestEditorWindow.cs:17) UnityEditor.DockArea:OnGUI()</pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20140401183901" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20140401/20140401183901.png" alt="f:id:tiri_tomato:20140401183901p:image:left" title="f:id:tiri_tomato:20140401183901p:image:left" class="hatena-fotolife hatena-image-left" itemprop="image"></a></span>だいたい想像通りだけど…<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AF%A5%EA%A5%C3%A5%D4%A5%F3%A5%B0">クリッピング</a>されないのね。<br clear="all"><b>4/2 09:41追記</b><br /> ちなみに、GUIStyle.clippingというメンバを見かけたので</p> <pre class="code lang-cs" data-lang="cs" data-unlink>style.contentOffset = size * <span class="synConstant">0.5f</span>; style.clipping = TextClipping.Clip; </pre><p>という具合で試してみたものの、とくに変化ナシ</p> tiri_tomato Toggleボタンの見た目カスタム hatenablog://entry/8454420450077304046 2014-03-19T09:22:14+09:00 2014-12-17T12:52:54+09:00 UnityでToggleボタンを自作するのにどんな画像を用意すればよいのかよくわからなかったので試しに並べてみました。そういやホバーイメージってないよね。なるほど言われてみれば確かにこんな感じ。 void OnGUI() { System.Collections.Generic.Dictionary<System.String, Texture2D> drawItems = new System.Collections.Generic.Dictionary<string, Texture2D>(); drawItems.Add("0.active", EditorStyles.toggle.a… <p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20140318185333" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20140318/20140318185333.png" alt="f:id:tiri_tomato:20140318185333p:image:left" title="f:id:tiri_tomato:20140318185333p:image:left" class="hatena-fotolife hatena-image-left" itemprop="image"></a></span>UnityでToggleボタンを自作するのにどんな画像を用意すればよいのかよくわからなかったので試しに並べてみました。そういやホバーイメージってないよね。なるほど言われてみれば確かにこんな感じ。<br clear="all"></p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synType">void</span> OnGUI() { System.Collections.Generic.Dictionary&lt;System.String, Texture2D&gt; drawItems = <span class="synStatement">new</span> System.Collections.Generic.Dictionary&lt;<span class="synType">string</span>, Texture2D&gt;(); drawItems.Add(<span class="synConstant">&quot;0.active&quot;</span>, EditorStyles.toggle.active.background); drawItems.Add(<span class="synConstant">&quot;1.focused&quot;</span>, EditorStyles.toggle.focused.background); drawItems.Add(<span class="synConstant">&quot;2.hover&quot;</span>, EditorStyles.toggle.hover.background); drawItems.Add(<span class="synConstant">&quot;3.normal&quot;</span>, EditorStyles.toggle.normal.background); drawItems.Add(<span class="synConstant">&quot;4.onActive&quot;</span>, EditorStyles.toggle.onActive.background); drawItems.Add(<span class="synConstant">&quot;5.onFocused&quot;</span>, EditorStyles.toggle.onFocused.background); drawItems.Add(<span class="synConstant">&quot;6.onHover&quot;</span>, EditorStyles.toggle.onHover.background); drawItems.Add(<span class="synConstant">&quot;7.onNormal&quot;</span>, EditorStyles.toggle.onNormal.background); Vector2 toggleSize = EditorStyles.toggle.CalcSize(GUIContent.none); Rect drawPosition = <span class="synStatement">new</span> Rect(<span class="synConstant">0</span>, <span class="synConstant">0</span>, toggleSize.x, toggleSize.y); Rect labelPosition = <span class="synStatement">new</span> Rect(toggleSize.x, <span class="synConstant">0</span>, position.width - toggleSize.x, toggleSize.y); <span class="synStatement">foreach</span> (System.Collections.Generic.KeyValuePair&lt;System.String, Texture2D&gt; item <span class="synStatement">in</span> drawItems) { GUI.DrawTexture(drawPosition, item.Value); GUI.Label(labelPosition, item.Key); drawPosition.y += toggleSize.y; labelPosition.y += toggleSize.y; } } </pre> <div class="section"> <h5>ついでにminiButton</h5> <p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20140319091814" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20140319/20140319091814.png" alt="f:id:tiri_tomato:20140319091814p:image:left" title="f:id:tiri_tomato:20140319091814p:image:left" class="hatena-fotolife hatena-image-left" itemprop="image"></a></span>ボタンの場合はborderとstretchの設定も重要っぽいのでちょっと書き足して。ボーダーをゼロにしたバージョンだと端まで余さずストレッチするので、枠までボケちゃうところがポイント。<br clear="all"></p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synType">void</span> OnGUI() { System.Collections.Generic.Dictionary&lt;System.String, Texture2D&gt; drawItems = <span class="synStatement">new</span> System.Collections.Generic.Dictionary&lt;<span class="synType">string</span>, Texture2D&gt;(); drawItems.Add(<span class="synConstant">&quot;0.active&quot;</span>, EditorStyles.miniButton.active.background); drawItems.Add(<span class="synConstant">&quot;1.focused&quot;</span>, EditorStyles.miniButton.focused.background); drawItems.Add(<span class="synConstant">&quot;2.hover&quot;</span>, EditorStyles.miniButton.hover.background); drawItems.Add(<span class="synConstant">&quot;3.normal&quot;</span>, EditorStyles.miniButton.normal.background); drawItems.Add(<span class="synConstant">&quot;4.onActive&quot;</span>, EditorStyles.miniButton.onActive.background); drawItems.Add(<span class="synConstant">&quot;5.onFocused&quot;</span>, EditorStyles.miniButton.onFocused.background); drawItems.Add(<span class="synConstant">&quot;6.onHover&quot;</span>, EditorStyles.miniButton.onHover.background); drawItems.Add(<span class="synConstant">&quot;7.onNormal&quot;</span>, EditorStyles.miniButton.onNormal.background); Vector2 buttonSize = EditorStyles.miniButton.CalcSize(<span class="synStatement">new</span> GUIContent(<span class="synConstant">&quot;OK&quot;</span>)); Rect drawPosition = <span class="synStatement">new</span> Rect(<span class="synConstant">0</span>, <span class="synConstant">0</span>, buttonSize.x, buttonSize.y); Rect labelPosition = <span class="synStatement">new</span> Rect(buttonSize.x, <span class="synConstant">0</span>, position.width - buttonSize.x, buttonSize.y); <span class="synStatement">foreach</span> (System.Collections.Generic.KeyValuePair&lt;System.String, Texture2D&gt; item <span class="synStatement">in</span> drawItems) { GUI.DrawTexture(drawPosition, item.Value); GUI.Label(labelPosition, item.Key); drawPosition.y += buttonSize.y; labelPosition.y += buttonSize.y; } <span class="synComment">// ボーダーの有無テスト。ボーダー幅の太さだけ拡大縮小の対象にならないというのがポイント。</span> GUIStyle buttonStyle = <span class="synStatement">new</span> GUIStyle(EditorStyles.miniButton); buttonStyle.border = <span class="synStatement">new</span> RectOffset(); <span class="synComment">// ボーダーの設定をゼロでクリア。</span> GUI.Button(drawPosition, <span class="synConstant">&quot;OK&quot;</span>); <span class="synComment">// 標準の描画</span> GUI.Label(labelPosition, <span class="synConstant">&quot;Border:&quot;</span> + EditorStyles.miniButton.border.ToString()); drawPosition.y += buttonSize.y; labelPosition.y += buttonSize.y; GUI.Button(drawPosition, <span class="synConstant">&quot;OK&quot;</span>, buttonStyle); <span class="synComment">// ボーダーゼロで描画。枠線がボケる。</span> GUI.Label(labelPosition, <span class="synConstant">&quot;Border:Zero&quot;</span>); drawPosition.y += buttonSize.y; labelPosition.y += buttonSize.y; <span class="synComment">// ストレッチ設定もログ。</span> GUI.Label(labelPosition, <span class="synConstant">&quot;stretchHeight/Width:&quot;</span> + buttonStyle.stretchHeight.ToString() + <span class="synConstant">&quot;/&quot;</span> + buttonStyle.stretchWidth.ToString()); } </pre> </div> tiri_tomato エディタカスタマイズで押せないボタンを描く Part2 hatenablog://entry/8454420450077304051 2014-03-18T10:06:28+09:00 2014-12-17T12:52:57+09:00 前にエディタカスタマイズで押せないボタンを描くで描画スタイルを淡色にするコード書いたんですが、もっとスマートなのがライブラリにあったwなんで見つけきれなかったんだろう。 EditorGUI.BeginDisabledGroup() void OnGUI() { EditorGUI.BeginDisabledGroup(true); // trueにするとDisableになる。(falseにするといつも通り入力可能になる) GUILayout.Button("DisableButton"); // disableに描画される。もちろんクリックできない。 EditorGUI.EndDisabled… <p>前に<a href="http://d.hatena.ne.jp/tiri_tomato/20131226/1388042315">&#x30A8;&#x30C7;&#x30A3;&#x30BF;&#x30AB;&#x30B9;&#x30BF;&#x30DE;&#x30A4;&#x30BA;&#x3067;&#x62BC;&#x305B;&#x306A;&#x3044;&#x30DC;&#x30BF;&#x30F3;&#x3092;&#x63CF;&#x304F;</a>で描画スタイルを淡色にするコード書いたんですが、もっとスマートなのがライブラリにあったwなんで見つけきれなかったんだろう。</p> <div class="section"> <h5><a href="https://docs.unity3d.com/Documentation/ScriptReference/EditorGUI.BeginDisabledGroup.html">EditorGUI.BeginDisabledGroup()</a></h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synType">void</span> OnGUI() { EditorGUI.BeginDisabledGroup(<span class="synConstant">true</span>); <span class="synComment">// trueにするとDisableになる。(falseにするといつも通り入力可能になる)</span> GUILayout.Button(<span class="synConstant">&quot;DisableButton&quot;</span>); <span class="synComment">// disableに描画される。もちろんクリックできない。</span> EditorGUI.EndDisabledGroup(); GUILayout.Button(<span class="synConstant">&quot;EnableButton&quot;</span>); } </pre><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20140318095910" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20140318/20140318095910.png" alt="f:id:tiri_tomato:20140318095910p:image" title="f:id:tiri_tomato:20140318095910p:image" class="hatena-fotolife" itemprop="image"></a></span><br /> なーんだこれで良いんじゃん。良いんじゃん。</p><p>それにしても<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>のUIは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A1%BC%A5%F3%A5%B7%A5%E7%A5%C3%A5%C8">スクリーンショット</a>を<a class="keyword" href="http://d.hatena.ne.jp/keyword/PNG">PNG</a>にすると、フルカラーでもランレングスでテキメン圧縮が効くなー…上の奴で4-5kbくらい。タイトルバーのカラーがないからフォーカス状態がちょっとわかりにくいんだけども。<a class="keyword" href="http://d.hatena.ne.jp/keyword/jpeg">jpeg</a>だと画質にもよるけど10kくらいだからかなり良いと思うの。</p> </div> tiri_tomato PC自作日記パーツリスト hatenablog://entry/8454420450077304061 2014-03-14T01:05:27+09:00 2014-12-17T12:52:59+09:00 以前の構成は静穏とかカケラも考えていなかったんですが、末期はさすがに爆音すぎるんじゃないかという印象を抱いていたので、作業用DTの範囲内でやや静穏気味に寄せました。 システムまわり INTEL Core i5-4570S BOX(1150/2.90GHz/6M/C4/T4) ASRock H87M (H87 1150 mATX DR3) ADT AX3U1600W4G11-DD (DDR3 PC3-12800 4GBx2) たまたま見つけたドスパラのセット売り\3,9300。相性も問題なくホクホク。3Dでデカいデータを使う場合、内部の配列のアドレス計算が32bitをオーバーしてツールが吹っ飛ぶ… <p>以前の構成は静穏とかカケラも考えていなかったんですが、末期はさすがに爆音すぎるんじゃないかという印象を抱いていたので、作業用DTの範囲内でやや静穏気味に寄せました。</p> <div class="section"> <h5>システムまわり</h5> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/INTEL">INTEL</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Core%20i5">Core i5</a>-4570S BOX(1150/2.90GHz/6M/C4/T4)</li> <li>ASRock H87M (H87 1150 mATX DR3)</li> <li>ADT AX3U1600W4G11-DD (DDR3 PC3-12800 4GBx2)</li> </ul><p>たまたま見つけた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C9%A5%B9%A5%D1%A5%E9">ドスパラ</a>のセット売り\3,9300。相性も問題なくホクホク。3Dでデカいデータを使う場合、内部の配列のアドレス計算が32bitをオーバーして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>が吹っ飛ぶ、という話はわりと聞いていたので<a href="#f-673f325b" name="fn-673f325b" title="え?て思うかもしれませんが、単に1万三角形なら頂点数3万オーバーするわけで、この時点でSHORT_MAX(16bit)をぶっちぎりますね。今どきコンシューマだと1万ポリなんて1キャラで使うし、さらに背景オブジェクトを含め、しかも配列のインデックスではなく、構造体サイズ倍したアドレスオフセット計算だったとしたらINT32_MAXの壁ってそんなに高くはありません。まぁゲームの場合はステージなどは部分ロードするのでそんなに酷いことにはならんはずなんですが、一応は…">*1</a>、以前からOSを64bit化したいなーとは思っていたのですが、それならそれでメモリを何G乗せるか、という点についてMAX16GBのシステムに4GBはちょっとケチかな〜?どうしよっかな〜?と迷っていたところ、このセットを見つけ8Gに。</p> </div> <div class="section"> <h5>FAN</h5> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00CS9LL6S/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/413RoEuPD8L._SL160_.jpg" class="hatena-asin-detail-image" alt="GELID 【HASWELL対応】 スリムヒーロー SlimHero 全高59mmCPUクーラー CC-Shero-01-A" title="GELID 【HASWELL対応】 スリムヒーロー SlimHero 全高59mmCPUクーラー CC-Shero-01-A"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00CS9LL6S/assoctiritoma-22/">GELID 【HASWELL対応】 スリムヒーロー SlimHero 全高59mmCPUクーラー CC-Shero-01-A</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> GELID</li><li><span class="hatena-asin-detail-label">発売日:</span> 2013/05/24</li><li><span class="hatena-asin-detail-label">メディア:</span> Personal Computers</li><li><a href="http://d.hatena.ne.jp/asin/B00CS9LL6S/assoctiritoma-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>いきなりこれで組んだのでリテールと比べてどうなのかわかりませんが、多分リテールよりも静かで冷えてるんだろうなという印象で、少なくとも前のAthlon64X2+リテールよりもCPUが低温。騒音は比べるまでもなく。というかi5のリテールFAN小さすぎるだろコレ…。</p> </div> <div class="section"> <h5>ストレージ</h5> <p>システムを256GBの<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>に入れます。128Gだと開発用<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>の容量がとれないので…。その代りメインの作業用HDDは1プラッタ1TB。1TBは容量的には心もとないですが、現在のところこのゾーンが信頼性・応答性・コスト・流通量に優れたゾーン。とくに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%AF%A5%B9%A5%D7%A5%ED%A1%BC%A5%E9">エクスプローラ</a>を拡張するタイプのバージョン管理<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>を入れると、細切れな差分データのシークでまごつくとファイルブラウズの応答速度が不安定になるため、作業HDDもとにかくシンプルタフ&シークパフォーマンスになり、容量の優先順位が下がるわけです。</p> <ul> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%E9%A5%F3%A5%BB%A5%F3%A5%C9">トランセンド</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a> TS256GSSD340</li> <li>WesternDegital WDRed WD10EFRX</li> </ul><p>なんか最近はストレージもメーカー保証付いててスゴイ。それにしても<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/UEFI">UEFI</a>-<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>の組み合わせは噂通り超速起動。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C3%CF%BF%CC">地震</a>時のシャットダウンも安心。</p> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>で組みなおして割とヨカッタパーツ</h4> <p>ぶっちゃけ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C9%A5%B9%A5%D1%A5%E9">ドスパラ</a>万歳で終わりそうだったんでサプライパーツレビュー。</p> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%F7%B3%D8%A5%C9%A5%E9%A5%A4%A5%D6">光学ドライブ</a>外して、メッシュカバーに変更。吸気強化。</h5> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00EVBBJO0/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/414gF9uSHyL._SL160_.jpg" class="hatena-asin-detail-image" alt="アイネックス 5インチベイ メッシュベゼル PF-002A" title="アイネックス 5インチベイ メッシュベゼル PF-002A"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00EVBBJO0/assoctiritoma-22/">アイネックス 5インチベイ メッシュベゼル PF-002A</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/AINEX">AINEX</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2014/12/08</li><li><span class="hatena-asin-detail-label">メディア:</span> Personal Computers</li><li><a href="http://d.hatena.ne.jp/asin/B00EVBBJO0/assoctiritoma-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>アホくさいけど効果はありそう。ティッシュをかざしてみたらちゃんと吸気してます。主張のない実用デザインは好きですが、これが思っていたよりもしっくりとヨカッタヨカッタ。吸気弱いミドルはやっぱこういうの要るなぁ…。</p> </div> <div class="section"> <h5>スロットインタイプの<a class="keyword" href="http://d.hatena.ne.jp/keyword/SATA">SATA</a>マウンタ</h5> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B008JB6DBM/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/41FirymELvL._SL160_.jpg" class="hatena-asin-detail-image" alt="Sharkoon 3.5/2.5インチデュアル・リムーバブルケース SATA QuickPort Intern Multi SHA-SATA-QPI-MLT" title="Sharkoon 3.5/2.5インチデュアル・リムーバブルケース SATA QuickPort Intern Multi SHA-SATA-QPI-MLT"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B008JB6DBM/assoctiritoma-22/">Sharkoon 3.5/2.5インチデュアル・リムーバブルケース SATA QuickPort Intern Multi SHA-SATA-QPI-MLT</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> Sharkoon</li><li><span class="hatena-asin-detail-label">メディア:</span> Personal Computers</li><li><span class="hatena-asin-detail-label">購入</span>: 4人 <span class="hatena-asin-detail-label">クリック</span>: 4回</li><li><a href="http://d.hatena.ne.jp/asin/B008JB6DBM/assoctiritoma-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div><a class="keyword" href="http://d.hatena.ne.jp/keyword/SATA">SATA</a>接続で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%C3%A5%C8%A5%B9%A5%EF%A5%C3%A5%D7">ホットスワップ</a>!<a class="keyword" href="http://d.hatena.ne.jp/keyword/SATA">SATA</a>接続で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%C3%A5%C8%A5%B9%A5%EF%A5%C3%A5%D7">ホットスワップ</a>!!ズットマエカラヤリタカッタンダー!!!これさえあれば内臓の作業用HDDが1TBでも問題ない。蓋付/直挿し/スロットインで、ON/OFF付のマウンタなら何でもヨカッタんですが、この製品絶対に写真詐欺だろうなぁと思っていたのですが、思っていたほどではなく雰囲気もまぁまぁ良い。ちょっとフタが硬くて丁寧に扱った方が良いんですが、そもそもHDDを雑に扱うなという話。そう言えば、AHCIでセットアップしただけではなぜか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%C3%A5%C8%A5%B9%A5%EF%A5%C3%A5%D7">ホットスワップ</a>できず。Mt.Naka氏の<a href="http://mt-naka.com/hotswap/index_jpn.htm">HotSwap!</a>という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>を使用。ありがたや。これで裸族台をバックヤードへ収納。あぁ、しかし<a class="keyword" href="http://d.hatena.ne.jp/keyword/SATA">SATA</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%C3%A5%C8%A5%B9%A5%EF%A5%C3%A5%D7">ホットスワップ</a>機能、OSの再設定でも存分に役立ってくれましたよ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%C3%A5%C8%A5%B9%A5%EF%A5%C3%A5%D7">ホットスワップ</a>、サイッコォウ…<a href="#f-464f580f" name="fn-464f580f" title="ただしこの製品、付属のケーブルにSATA3が明記されていないのが怖かったので気になる人は別途入手した方がよろしいかと。ケースのエアフロー的にもケーブルは丁度良い長さにした方が良いですし。裸族台も片付けたくなるほどダサくはないんですが、ただACアダプタ含めケーブルがゴチャつくのは…">*2</a><br /> </p> </div> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B8%A5%AF%A1%BC%A5%EB">ロジクール</a>K270</h5> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B004W1KCCO/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/41IQBT37oiL._SL160_.jpg" class="hatena-asin-detail-image" alt="LOGICOOL ワイヤレスキーボード Unifying対応レシーバー採用 K270" title="LOGICOOL ワイヤレスキーボード Unifying対応レシーバー採用 K270"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B004W1KCCO/assoctiritoma-22/">LOGICOOL ワイヤレスキーボード Unifying対応レシーバー採用 K270</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%B8%A5%AF%A1%BC%A5%EB">ロジクール</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2011/04/28</li><li><span class="hatena-asin-detail-label">メディア:</span> Personal Computers</li><li><span class="hatena-asin-detail-label">購入</span>: 33人 <span class="hatena-asin-detail-label">クリック</span>: 97回</li><li><a href="http://d.hatena.ne.jp/asin/B004W1KCCO/assoctiritoma-22" target="_blank">この商品を含むブログ (37件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>1000円無線キーボード。今までガワが共通デザインになっているK200使ってましたが、この子は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AD%A1%BC%A5%C8%A5%C3%A5%D7">キートップ</a>のシボが削れてツヤツヤになるほど打っても印字が消えないほどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BB%A8%C1%F0">雑草</a>ガッツを見せてくれました。まだまだ使えますが、その点に期待して無線バージョンの後継機にあたるK270に乗り換えてみました。こちらネットでも評判の通りバッチリです。ただコストダウンでNumLockとかのLEDまで省かれてるのはちと不便か。とりあえず卓上からまた一本ケーブルを減らせます。</p> </div> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/WinXP">WinXP</a>→<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>で組みなおした総括</h4> <p>単にOSが変わったというよりは、もっとハード的な仕様の進歩や技術に対する値段の変動が反映された世代交代になったなぁという感じ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>もむしろこれくらいじゃなきゃ今回で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>への移行も含めて考えていたかも。それにしてもログインまで10秒もかからないとか便利すぎて最初は慣れませんでしたw</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-673f325b" name="f-673f325b" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">え?て思うかもしれませんが、単に1万三角形なら頂点数3万オーバーするわけで、この時点でSHORT_MAX(16bit)をぶっちぎりますね。今どきコンシューマだと1万ポリなんて1キャラで使うし、さらに背景オブジェクトを含め、しかも配列のインデックスではなく、構造体サイズ倍したアドレスオフセット計算だったとしたらINT32_MAXの壁ってそんなに高くはありません。まぁゲームの場合はステージなどは部分ロードするのでそんなに酷いことにはならんはずなんですが、一応は…</span></p> <p class="footnote"><a href="#fn-464f580f" name="f-464f580f" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">ただしこの製品、付属のケーブルにSATA3が明記されていないのが怖かったので気になる人は別途入手した方がよろしいかと。ケースのエアフロー的にもケーブルは丁度良い長さにした方が良いですし。裸族台も片付けたくなるほどダサくはないんですが、ただACアダプタ含めケーブルがゴチャつくのは…</span></p> </div> tiri_tomato PC自作日記故障究明編 hatenablog://entry/8454420450077304067 2014-03-13T00:25:44+09:00 2014-12-17T12:53:03+09:00 そういえば、実は今回壊れたのはマザボだけではございませんでした。それは電源…。ANTECのEA-500(Greenじゃない廃盤になってる古い方)。 http://www.links.co.jp/items/antec-power/antec-ea500.html 時は2006年、80Plusがまだクラス分けされていなかった頃の電源である…。さすがAntec、よく動いていたものだ…おかげで「わりと壊れるPC部品」の上位ランカーであることをスッカリ忘れていたよ!それなりに怪しいとは思っていましたが、単体無負荷の状態でアナログテスターを当てて端子電圧が来てるかどうか軽くテストしたんですが、まだ普通に… <p>そういえば、実は今回壊れたのは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>だけではございませんでした。それは<b>電源</b>…。</p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/ANTEC">ANTEC</a>のEA-500(Greenじゃない廃盤になってる古い方)。<br /> <a href="http://www.links.co.jp/items/antec-power/antec-ea500.html">http://www.links.co.jp/items/antec-power/antec-ea500.html</a><br /> 時は2006年、80Plusがまだクラス分けされていなかった頃の電源である…。</p><p><b>さすが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Antec">Antec</a>、よく動いていたものだ…</p><p><span class="deco" style="color:#FF0000;">おかげで「わりと壊れるPC部品」の上位ランカーであることをスッカリ忘れていたよ!</span></b></p><p>それなりに怪しいとは思っていましたが、単体無負荷の状態でアナログテスターを当てて端子電圧が来てるかどうか軽くテストしたんですが、まだ普通に数値が出てたんですよね。で、楽観視していました。まぁ確かに、放熱板近辺の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%B2%F2%A5%B3%A5%F3%A5%C7%A5%F3%A5%B5">電解コンデンサ</a>が3つほど、明らかに<span class="deco" style="font-weight:bold;color:#FF0000;">パンパン</span>だったんですがね!</p><p>で、あわててチョイスした後継はコルセアのCX430M。今回は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B8%F7%B3%D8%A5%C9%A5%E9%A5%A4%A5%D6">光学ドライブ</a>や内臓フロッピーを外し、CPUも省電力気味で組んでいるため、そう大きいのも要らんという方向で、メーカー的にも同格あるいは親戚筋、3年保証も付いてる電源の中で、お安い子をチョイスしたらコレに。<div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ALYP2XK/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/41SghtIGgfL._SL160_.jpg" class="hatena-asin-detail-image" alt="Corsair CP-9020058-JP (CX430M)" title="Corsair CP-9020058-JP (CX430M)"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B00ALYP2XK/assoctiritoma-22/">Corsair CP-9020058-JP (CX430M)</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> CORSAIR</li><li><span class="hatena-asin-detail-label">メディア:</span> Personal Computers</li><li><a href="http://d.hatena.ne.jp/asin/B00ALYP2XK/assoctiritoma-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>電源トラブルは今回のように多少連鎖が疑われる故障シナリオを描くケースが多いので、コストと保証のバランスを見るとこのへんじゃないかしら(もしくはもう1サイズ上の500wか)。さすがにコレ以上ケチるのは、アキバべったりな住民的ギャンブルになりそうだし。</p><p>電源負荷テストは難しいということで、とりあえず今回からは保証付パーツは購入日と保証状態についてGoogleDriveにメモを残しました。期限切れてたら切れてたで遠慮なく分解できまする。</p> tiri_tomato UnityでVisual Studio Expressのソリューションを開くスクリプト hatenablog://entry/8454420450077304069 2014-03-12T18:48:32+09:00 2014-12-17T12:53:11+09:00 (Unity4.3.4f1Win)母艦組み直しで32bitXP→64bitWin8移行。思ったよりトラブルなく移行できたんですが、ついに「うにゃにゃ!?」ってなりました。 SyncMonoDevProjectでVisual Studio Expressが起動できない? なぜか今までの設定ではExpressが起動できない。ここでひっかかったか。 今まで:UnityとMonoDevelop日本語対応状況再確認 http://d.hatena.ne.jp/tiri_tomato/20130725/1374713075 いろいろ調べてみると、要するにArgumentsの"$(File)"のところ、一部… <p>(Unity4.3.4f1Win)</p><p>母艦組み直しで32bitXP→64bitWin8移行。思ったよりトラブルなく移行できたんですが、ついに「うにゃにゃ!?」ってなりました。</p> <div class="section"> <h4>SyncMonoDevProjectで<a class="keyword" href="http://d.hatena.ne.jp/keyword/Visual%20Studio">Visual Studio</a> Expressが起動できない?</h4> <p>なぜか今までの設定ではExpressが起動できない。ここでひっかかったか。</p> <blockquote> <p>今まで:<span class="deco" style="font-style:italic;">Unityと<a class="keyword" href="http://d.hatena.ne.jp/keyword/MonoDevelop">MonoDevelop</a>日本語対応状況再確認</span><br /> <a href="http://d.hatena.ne.jp/tiri_tomato/20130725/1374713075">http://d.hatena.ne.jp/tiri_tomato/20130725/1374713075</a></p> </blockquote> <p>いろいろ調べてみると、要するにArgumentsの"$(File)"のところ、一部のエディタ<a href="#f-2354b04a" name="fn-2354b04a" title="標準のMonoとか有償版のVSとか">*1</a>を除き、そのまま文字列引数として投げられているようです。イミガワカラナイ…当然ファイル名として$(File)なんて無効。そんな変な起動オプションに対応するエディタもありません。もう少し状況を整理。</p><p><b>ひとつ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ファイルをダブルクリックした時の動作は今まで通り正常。</b><br /> Sync〜メニューではなく、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>ファイルをダブルクリックで開く時は$(File)はきちんと作動する模様。しかしソリューションが開くわけじゃないので、入力補完は作動せず(でもこの仕様は今まで通り。やっぱりソリューション開く前にファイル単体開いちゃうとダメだった)。</p><p><b>ひとつ、Sync〜で$(File)が渡されることにより起動エラーが表示されたエディタとか</b></p> <ul> <li>Start "" %1 (バッチファイル)</li> <li>VS Express 2010</li> <li>VS Express 2013 for Desktop</li> </ul><p><b>ひとつ、とくにエラー表示とかはないけどソリューションやファイルは開けず、ただ起動するだけのエディタ</b></p> <ul> <li>XamarinStudio 4.2.3(最新Mono相当) </li> </ul><p>うーん<b>「Sync〜」は基本的にデバッガをリンクする前提</b>っぽい。ただUnityがそのへん対応しない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>でソリューション開こうとすると$Fileの置換機能が作動しない感じ。しかも外部<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>の設定は、Sync〜の*.slnオープンと*.csのダブルクリックの両方の設定を兼ねているのでややこしい。</p><br /> <p>…やはりしょうがないやうです。書きます。</p><p>まずコレ。</p> </div> <div class="section"> <h4>$(File)作動したりしなかったり対策バッチファイル</h4> <p>Unityのメニューから、Preferences>External Tools>External Script Editorに次のような*.batファイルを設定します。</p> <pre class="code" data-lang="" data-unlink>if exist %1 start &#34;&#34; %1</pre><p>見たまんま。バッチでexistするとファイルパスの確認ができるので、Sync〜によって変な引数が飛んできたらif文で抜けるよろし。これでcsダブルクリック時の動作はとりあえず確保。EditorAttachingもどうせ動かないのでチェックをfalseにしておきます。</p><p>で、こうするとSync〜でソリューションが開けないので、さらにソリューション開くメニュー<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を書きまする<a href="#f-4b92f144" name="fn-4b92f144" title="$(File)が問題だからスクリプト書くほどでもないような気もするんだけどなぁ。Unityの設定側でSyncとダブルクリックを分離可能にして$(Project)とかにすれば良いような気も。">*2</a>。</p> </div> <div class="section"> <h4>ソリューションを開くEditor<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a></h4> <p><span class="deco" style="color:#FF0000;"><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>専用で申し訳ない。</span>(<a href="#f-d8466f19" name="fn-d8466f19" title="プロセス間でのGUIアクティブ化処理、OSの違いを超えて一般化とかはさすがに難しいんだろうなぁ〜。">*3</a>)</p><p><仕様></p> <ul> <li>このcsを適当なEditorフォルダに保存するとSync〜メニューの下に、Open Solution Fileという名前のメニューが追加されます</li> <li>Open Solution Fileをクリックするとソリューションファイル開きます。<br>すでに開いている場合は、そのプロセスのエディタウィンドウに切り替えます。</li> <li><b>いわゆる設定はプログラム冒頭に直接ハードコード</b>してるので、そのへんの変更は直接<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>を書き換えて下さい(外部<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>のパスとか、ウィンドウの検索条件とか)。</li> <li><b>本当は設定ファイルとか対応した方がカッコイイんですが疲れたので適当に書き散らかして逃げます。</b>この問題はすぐに修正されそうな気がしないでもないし。</li> <li>参考にしたDobon様(他やまほどのDobon記事。ほとんどの<a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a>パートがコピペェ…)<br><a href="http://dobon.net/vb/dotnet/process/appactivate.html">http://dobon.net/vb/dotnet/process/appactivate.html</a></li> </ul><p><コード></p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synComment">// このプログラムはUser32.dll使いまくりなのでWindows専用です。</span> <span class="synStatement">using</span> System.Runtime.InteropServices; <span class="synStatement">using</span> UnityEngine; <span class="synStatement">using</span> UnityEditor; <span class="synType">public</span> <span class="synType">class</span> OpenCSSolution { <span class="synComment">// 開きたい外部ツールのパス。</span> <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> System.String openPath = <span class="synConstant">&quot;C:</span><span class="synSpecial">\\</span><span class="synConstant">Program Files (x86)</span><span class="synSpecial">\\</span><span class="synConstant">Microsoft Visual Studio 10.0</span><span class="synSpecial">\\</span><span class="synConstant">Common7</span><span class="synSpecial">\\</span><span class="synConstant">IDE</span><span class="synSpecial">\\</span><span class="synConstant">VCSExpress.exe&quot;</span>; <span class="synComment">// (↑わかる人だけ:バッチファイルとかShellあるいは関連付けやその他ランチャーを経由して開くのはヤメテ!/それやるとC#から直接プロセスが見えない=多重起動検知が面倒くさい)</span> <span class="synComment">// 検索するウィンドウのタイトルの一部。とりあえずウィンドウタイトルが、以下の文字列に完全一致する部分を持つウィンドウを探知する。</span> <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> System.String partOfTitle = <span class="synConstant">&quot;Microsoft Visual C# 2010 Express&quot;</span>; <span class="synComment">// 子ウィンドウの列挙を含めるかどうか。true=含める/false=含めない。デフォでは含めないけど、見つからないのならtrueにすると見つかるかも?</span> <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> <span class="synType">bool</span> includeChildWnd = <span class="synConstant">false</span>; <span class="synComment">// ソリューションファイルが同じディレクトリに複数見つかる時の選別モード。SeeAlso:SolutionPathSelectMode</span> <span class="synType">private</span> <span class="synType">static</span> <span class="synType">readonly</span> SolutionPathSelectMode solutionFileSelectMode = SolutionPathSelectMode.Longest; <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synComment">/// ソリューションファイルが同じディレクトリに複数見つかる時の選別モード。ようするに[Project].slnか、[Project]-csharp.slnか選択。</span> <span class="synComment">/// </span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synType">private</span> <span class="synType">enum</span> SolutionPathSelectMode { <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synComment">/// もっとも短いファイル名のものを選択。例えば[Project].slnと[Project]-csharp.slnでは[Project].slnが選択される。</span> <span class="synComment">/// </span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> Shortest = <span class="synConstant">0</span>, <span class="synComment">/// </span><span class="synIdentifier">&lt;</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> <span class="synComment">/// もっとも長いファイル名のものを選択。例えば[Project].slnと[Project]-csharp.slnでは[Project]-csharp.slnが選択される。</span> <span class="synComment">/// </span><span class="synIdentifier">&lt;/</span><span class="synStatement">summary</span><span class="synIdentifier">&gt;</span> Longest = <span class="synConstant">1</span> } <span class="synType">private</span> <span class="synType">class</span> ProcessWindowDetector { <span class="synType">public</span> ProcessWindowDetector(System.Diagnostics.Process proc) { EnumWindows(EnumWindowCallBack, proc.Id); } <span class="synType">public</span> System.IntPtr detectedWindowHandle { <span class="synStatement">get</span> { <span class="synStatement">return</span> m_detectedWindowHandle; } } <span class="synType">public</span> System.String detectedWindowText { <span class="synStatement">get</span> { <span class="synStatement">return</span> m_detectedWindowText; } } <span class="synType">private</span> <span class="synType">delegate</span> <span class="synType">bool</span> EnumWindowsDelegate(System.IntPtr hWnd, <span class="synType">int</span> lparam); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> System.IntPtr GetWindowLong(System.IntPtr hWnd, <span class="synType">int</span> nIndex); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">extern</span> <span class="synType">static</span> <span class="synType">bool</span> EnumWindows(EnumWindowsDelegate lpEnumFunc, <span class="synType">int</span> lparam); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, CharSet = CharSet.Auto, SetLastError = <span class="synConstant">true</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">int</span> GetWindowText(System.IntPtr hWnd, System.Text.StringBuilder lpString, <span class="synType">int</span> nMaxCount); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, CharSet = CharSet.Auto, SetLastError = <span class="synConstant">true</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">int</span> GetWindowTextLength(System.IntPtr hWnd); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, CharSet = CharSet.Auto, SetLastError = <span class="synConstant">true</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">int</span> GetClassName(System.IntPtr hWnd, System.Text.StringBuilder lpClassName, <span class="synType">int</span> nMaxCount); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, SetLastError = <span class="synConstant">true</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">uint</span> GetWindowThreadProcessId(System.IntPtr hWnd, <span class="synStatement">out</span> <span class="synType">int</span> lpdwProcessId); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> SetForegroundWindow(System.IntPtr hWnd); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> System.IntPtr GetForegroundWindow(); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, SetLastError = <span class="synConstant">true</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> BringWindowToTop(System.IntPtr hWnd); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] <span class="synType">static</span> <span class="synType">extern</span> System.IntPtr SetFocus(System.IntPtr hWnd); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, SetLastError = <span class="synConstant">true</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> SetWindowPos(System.IntPtr hWnd, <span class="synType">int</span> hWndInsertAfter, <span class="synType">int</span> x, <span class="synType">int</span> y, <span class="synType">int</span> cx, <span class="synType">int</span> cy, <span class="synType">int</span> uFlags); <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SWP_NOSIZE = <span class="synConstant">0x0001</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SWP_NOMOVE = <span class="synConstant">0x0002</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SWP_NOZORDER = <span class="synConstant">0x0004</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SWP_SHOWWINDOW = <span class="synConstant">0x0040</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SWP_ASYNCWINDOWPOS = <span class="synConstant">0x4000</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> HWND_TOP = <span class="synConstant">0</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> HWND_BOTTOM = <span class="synConstant">1</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> HWND_TOPMOST = -<span class="synConstant">1</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> HWND_NOTOPMOST = -<span class="synConstant">2</span>; [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> ShowWindow(System.IntPtr hWnd, <span class="synType">int</span> nCmdShow); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> ShowWindowAsync(System.IntPtr hWnd, <span class="synType">int</span> nCmdShow); <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SW_SHOWNORMAL = <span class="synConstant">1</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SW_SHOW = <span class="synConstant">5</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">int</span> SW_RESTORE = <span class="synConstant">9</span>; [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> IsIconic(System.IntPtr hWnd); [DllImport(<span class="synConstant">&quot;kernel32.dll&quot;</span>)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">uint</span> GetCurrentThreadId(); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> AttachThreadInput( <span class="synType">uint</span> idAttach, <span class="synType">uint</span> idAttachTo, <span class="synType">bool</span> fAttach); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, EntryPoint = <span class="synConstant">&quot;SystemParametersInfo&quot;</span>, SetLastError = <span class="synConstant">true</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> SystemParametersInfoGet( <span class="synType">uint</span> action, <span class="synType">uint</span> param, <span class="synStatement">ref</span> <span class="synType">uint</span> vparam, <span class="synType">uint</span> init); [DllImport(<span class="synConstant">&quot;user32.dll&quot;</span>, EntryPoint = <span class="synConstant">&quot;SystemParametersInfo&quot;</span>, SetLastError = <span class="synConstant">true</span>)] [<span class="synStatement">return</span>: MarshalAs(UnmanagedType.Bool)] <span class="synType">private</span> <span class="synType">static</span> <span class="synType">extern</span> <span class="synType">bool</span> SystemParametersInfoSet( <span class="synType">uint</span> action, <span class="synType">uint</span> param, <span class="synType">uint</span> vparam, <span class="synType">uint</span> init); <span class="synType">private</span> <span class="synType">const</span> <span class="synType">uint</span> SPI_GETFOREGROUNDLOCKTIMEOUT = <span class="synConstant">0x2000</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">uint</span> SPI_SETFOREGROUNDLOCKTIMEOUT = <span class="synConstant">0x2001</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">uint</span> SPIF_UPDATEINIFILE = <span class="synConstant">0x01</span>; <span class="synType">private</span> <span class="synType">const</span> <span class="synType">uint</span> SPIF_SENDCHANGE = <span class="synConstant">0x02</span>; <span class="synType">private</span> <span class="synType">static</span> System.IntPtr GetParentWnd(System.IntPtr hWnd) { <span class="synStatement">return</span> GetWindowLong(hWnd, -<span class="synConstant">8</span>); } <span class="synType">public</span> <span class="synType">static</span> <span class="synType">void</span> ActiveWindow(System.IntPtr hWnd) { <span class="synStatement">if</span> (hWnd == System.IntPtr.Zero) { <span class="synStatement">return</span>; } <span class="synComment">//ウィンドウが最小化されている場合は元に戻す</span> <span class="synStatement">if</span> (IsIconic(hWnd)) { ShowWindowAsync(hWnd, SW_RESTORE); } <span class="synComment">//AttachThreadInputの準備</span> <span class="synComment">//フォアグラウンドウィンドウのハンドルを取得</span> System.IntPtr forehWnd = GetForegroundWindow(); <span class="synStatement">if</span> (forehWnd == hWnd) { <span class="synStatement">return</span>; } <span class="synComment">//フォアグラウンドのスレッドIDを取得</span> <span class="synType">int</span> procId = <span class="synConstant">0</span>; <span class="synType">uint</span> foreThread = GetWindowThreadProcessId(forehWnd, <span class="synStatement">out</span> procId); <span class="synComment">//自分のスレッドIDを収得</span> <span class="synType">uint</span> thisThread = GetCurrentThreadId(); <span class="synType">uint</span> timeout = <span class="synConstant">200000</span>; <span class="synStatement">if</span> (foreThread != thisThread) { <span class="synComment">//ForegroundLockTimeoutの現在の設定を取得</span> <span class="synComment">//Visual Studio 2010, 2012起動後は、レジストリと違う値を返す</span> SystemParametersInfoGet(SPI_GETFOREGROUNDLOCKTIMEOUT, <span class="synConstant">0</span>, <span class="synStatement">ref</span> timeout, <span class="synConstant">0</span>); <span class="synComment">//レジストリから取得する場合</span> <span class="synComment">//timeout = (uint)Microsoft.Win32.Registry.GetValue(</span> <span class="synComment">// @&quot;HKEY_CURRENT_USER\Control Panel\Desktop&quot;,</span> <span class="synComment">// &quot;ForegroundLockTimeout&quot;, 200000);</span> <span class="synComment">//ForegroundLockTimeoutの値を0にする</span> <span class="synComment">//(SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)を使いたいが、</span> <span class="synComment">// timeoutがレジストリと違う値だと戻せなくなるので使わない</span> SystemParametersInfoSet(SPI_SETFOREGROUNDLOCKTIMEOUT, <span class="synConstant">0</span>, <span class="synConstant">0</span>, <span class="synConstant">0</span>); <span class="synComment">//入力処理機構にアタッチする</span> AttachThreadInput(thisThread, foreThread, <span class="synConstant">true</span>); } <span class="synComment">//ウィンドウをフォアグラウンドにする処理</span> SetForegroundWindow(hWnd); SetWindowPos(hWnd, HWND_TOP, <span class="synConstant">0</span>, <span class="synConstant">0</span>, <span class="synConstant">0</span>, <span class="synConstant">0</span>, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS); BringWindowToTop(hWnd); ShowWindowAsync(hWnd, SW_SHOW); SetFocus(hWnd); <span class="synStatement">if</span> (foreThread != thisThread) { <span class="synComment">//ForegroundLockTimeoutの値を元に戻す</span> <span class="synComment">//ここでも(SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)は使わない</span> SystemParametersInfoSet(SPI_SETFOREGROUNDLOCKTIMEOUT, <span class="synConstant">0</span>, timeout, <span class="synConstant">0</span>); <span class="synComment">//デタッチ</span> AttachThreadInput(thisThread, foreThread, <span class="synConstant">false</span>); } } <span class="synType">private</span> System.IntPtr m_detectedWindowHandle = System.IntPtr.Zero; <span class="synType">private</span> System.String m_detectedWindowText = System.String.Empty; <span class="synType">private</span> <span class="synType">bool</span> EnumWindowCallBack(System.IntPtr hWnd, <span class="synType">int</span> lparam) { <span class="synComment">// process id check</span> <span class="synType">int</span> procId = <span class="synConstant">0</span>; GetWindowThreadProcessId(hWnd, <span class="synStatement">out</span> procId); <span class="synStatement">if</span> (lparam != procId) <span class="synStatement">return</span> <span class="synConstant">true</span>; <span class="synComment">// parent window check</span> <span class="synStatement">if</span> (includeChildWnd == <span class="synConstant">false</span>) { <span class="synStatement">if</span> (GetParentWnd(hWnd) != System.IntPtr.Zero) <span class="synStatement">return</span> <span class="synConstant">true</span>; } <span class="synComment">// get window title</span> System.String wndText = System.String.Empty; <span class="synType">int</span> textLen = GetWindowTextLength(hWnd); <span class="synStatement">if</span> (<span class="synConstant">0</span> &lt; textLen) { System.Text.StringBuilder tsb = <span class="synStatement">new</span> System.Text.StringBuilder(textLen + <span class="synConstant">1</span>); GetWindowText(hWnd, tsb, tsb.Capacity); wndText = tsb.ToString(); } <span class="synComment">// window title check</span> <span class="synStatement">if</span> (System.String.IsNullOrEmpty(partOfTitle) == <span class="synConstant">false</span>) { <span class="synStatement">if</span> (wndText.IndexOf(partOfTitle) &lt; <span class="synConstant">0</span>) <span class="synStatement">return</span> <span class="synConstant">true</span>; } m_detectedWindowText = wndText; m_detectedWindowHandle = hWnd; <span class="synStatement">return</span> <span class="synConstant">false</span>; } } <span class="synType">static</span> System.String lastOpenPath = System.String.Empty; <span class="synType">static</span> System.Diagnostics.Process lastStartedProcess = <span class="synConstant">null</span>; [MenuItem(<span class="synConstant">&quot;Assets/Open Solution File&quot;</span>)] <span class="synType">static</span> <span class="synType">void</span> OpenSolutionFile() { System.String solutionPath = Application.dataPath; solutionPath = solutionPath.Remove(solutionPath.Length - <span class="synConstant">&quot;Assets&quot;</span>.Length); System.String[] files = System.IO.Directory.GetFiles(solutionPath, <span class="synConstant">&quot;*.sln&quot;</span>, System.IO.SearchOption.TopDirectoryOnly); System.String targetPath = <span class="synConstant">null</span>; <span class="synStatement">if</span> (solutionFileSelectMode == SolutionPathSelectMode.Shortest) { <span class="synStatement">if</span> (files.Length &lt;= <span class="synConstant">0</span>) targetPath = System.String.Empty; <span class="synStatement">else</span> { <span class="synStatement">foreach</span> (System.String file <span class="synStatement">in</span> files) { <span class="synStatement">if</span> ((targetPath == <span class="synConstant">null</span>) || (file.Length &lt; targetPath.Length)) targetPath = file; } } } <span class="synStatement">else</span> { targetPath = System.String.Empty; <span class="synStatement">foreach</span> (System.String file <span class="synStatement">in</span> files) <span class="synStatement">if</span> (targetPath.Length &lt; file.Length) targetPath = file; } <span class="synStatement">if</span> (System.IO.File.Exists(targetPath)) { <span class="synStatement">if</span> ((lastStartedProcess != <span class="synConstant">null</span>) &amp;&amp; (lastStartedProcess.HasExited == <span class="synConstant">false</span>)) { ProcessWindowDetector procWnd = <span class="synStatement">new</span> ProcessWindowDetector(lastStartedProcess); <span class="synStatement">if</span> (lastOpenPath == targetPath) { <span class="synStatement">if</span> (procWnd.detectedWindowHandle != System.IntPtr.Zero) { ProcessWindowDetector.ActiveWindow(procWnd.detectedWindowHandle); } <span class="synStatement">else</span> { EditorUtility.DisplayDialog(<span class="synConstant">&quot;エディターウィンドウの切り替えに失敗&quot;</span>, <span class="synConstant">&quot;エディターウィンドウが発見できません。</span><span class="synSpecial">\n</span><span class="synConstant">エディターウィンドウの検索設定を再設定してください。&quot;</span>, <span class="synConstant">&quot;OK&quot;</span>); } <span class="synStatement">return</span>; } <span class="synStatement">if</span> (EditorUtility.DisplayDialog(<span class="synConstant">&quot;エディタを開き直しますか?&quot;</span>, <span class="synConstant">&quot;変更は破棄される可能性があります。&quot;</span>, <span class="synConstant">&quot;変更を破棄して再オープン&quot;</span>, <span class="synConstant">&quot;キャンセル&quot;</span>) == <span class="synConstant">false</span>) <span class="synStatement">return</span>; <span class="synStatement">if</span> (lastStartedProcess.CloseMainWindow() == <span class="synConstant">false</span>) { lastStartedProcess.Close(); } lastStartedProcess.WaitForExit(<span class="synConstant">5000</span>); } lastStartedProcess = System.Diagnostics.Process.Start(openPath, lastOpenPath = targetPath); } } } </pre> </div><div class="footnote"> <p class="footnote"><a href="#fn-2354b04a" name="f-2354b04a" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">標準のMonoとか有償版のVSとか</span></p> <p class="footnote"><a href="#fn-4b92f144" name="f-4b92f144" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">$(File)が問題だから<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>書くほどでもないような気もするんだけどなぁ。Unityの設定側でSyncとダブルクリックを分離可能にして$(Project)とかにすれば良いような気も。</span></p> <p class="footnote"><a href="#fn-d8466f19" name="f-d8466f19" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">プロセス間での<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>アクティブ化処理、OSの違いを超えて一般化とかはさすがに難しいんだろうなぁ〜。</span></p> </div> tiri_tomato Win8ProDSP入れてみた感想 hatenablog://entry/8454420450077304077 2014-03-08T15:29:17+09:00 2014-12-17T12:53:11+09:00 これイイと思うんですが何故ウケないのか。 WinXPからいきなりWin8へ。いわゆる母艦の組みなおしが完了し、Win8を動かし始めました。うーん。個人的には好きですがWin8うーん。しかしこのトキメキの無さはなんだ。 モダンUI 毒にも薬にもなっていないリボンUI。一方モダンUIの方は良くも悪くもそれなりに毒か薬。個人的には、せっかくOS買うならどこかしら変容したOSが欲しいので、その点はウレシイかな、という感じ。 でも結局はスマホとは違う作業用のUI これ、Win史上かつてないほど遠回りしないUIだと思います。なにしろ私がそういうUIが好きでXPをそういう風にカスタムしてたんです*1が、Wi… <div class="section"> <h5>これイイと思うんですが何故ウケないのか。</h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/WinXP">WinXP</a>からいきなり<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>へ。いわゆる母艦の組みなおしが完了し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>を動かし始めました。うーん。個人的には好きですが<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>うーん。</p><p><b>しかしこのトキメキの無さはなんだ。</b><br /> </p> </div> <div class="section"> <h4>モダンUI</h4> <p>毒にも薬にもなっていないリボンUI。一方モダンUIの方は良くも悪くもそれなりに毒か薬。個人的には、せっかくOS買うならどこかしら変容したOSが欲しいので、その点はウレシイかな、という感じ。</p> <div class="section"> <h5>でも結局は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>とは違う作業用のUI</h5> <p>これ、Win史上かつてないほど<b>遠回りしないUI</b>だと思います。なにしろ私がそういうUIが好きでXPをそういう風にカスタムしてたんです<a href="#f-6cdecde8" name="fn-6cdecde8" title="スタートメニューは整理してもバージョンアップで紐付けが切れるので、グループ整理可能なアプリランチャーで目的別にショートカットリンクをまとめてショートカットキーから呼び出します。それとAltTabカスタマイズ用のツールを入れて、やはりキーボードでサクサク切り替えます。Webブラウズはブックマークを使わずスピードダイヤル。すると、なんだかんだで今のModernUIとだいたい似たような使用感になります。">*1</a>が、<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>はそのへんなんにもしなくても出来上がってる感じで、非常にセットアップが楽ちんです。ヨカッタヨカッタ。</p><p>ただ基本的には、見た目に反して新UIは作業用UIなんですよね。タッチUI系統にスイッチするルートメニューでもありますが、単に全画面+2画面化されたスタートメニューでもあり。プログラムがバージョンアップするたびにプログラムグループが混乱していき、アプリを増やすほど目的に見合ったアプリを探し出す行為が困難になっていく事をダイレクトに改善あるいは隠蔽するためのUIです。つまりシステムの実装状態によらず、ユーザーの目的と実装を直結する。ただ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>系UIのように見えて<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>系UIとは根本的に違います。例えばメトロUIのは次のようなシーンにマッチしません。</p> <ul> <li>触って動いて楽しさを覚えるユーザー体験</li> <li>検索しようとヤフーに行って、芸能ニュースリンクで気になるタイトルがあったから、横道に逸れてクリック</li> <li>掲示板やタイムラインにはりついて暇つぶし</li> <li>考えながら操作を辿っていく</li> </ul><p>例えばXPは非常にダサくて雑多なUIで、カラフルなブロック玩具で組まれた九龍城さながらの様相を呈し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CB%BF%B5%F0%C2%E7%B7%C7%BC%A8%C8%C4">某巨大掲示板</a>のようなカオスなユースにはよくマッチしていました。また<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>UIの多くは、ゴロ寝しながら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>を傾けたりこすったり、リッチな入力装置がないだけに、ある意味では遠回りで無駄な操作を長々と行うので、このへんのユーザ体験をダラダラ続ける感じにはよくマッチしていました(<a href="#f-f3e91cf0" name="fn-f3e91cf0" title="ほとんど多くのユーザーにとってプライベートシーンのコンピューティングなんて本当はそれくらいで十分、その操作をわかりやすく楽しめるようにまとめてあるのがスマホ進歩性の要と言えます">*2</a>)。しかしモダンUIはうまく使えば使うほど、淡白かつクイックに目的が達成されます。スワイプ系やレイアウトはイマイチまとまってないんですが、実は意外とキーボード操作と相性が抜群<a href="#f-4d521e85" name="fn-4d521e85" title="ただしTab送りとかAlt拡張系を手に覚えさせていないと苦労すると思う。">*3</a>。モダンUIモードからMSアカウントモードに入ると完全なタッチ系に入るものの、スタートメニュー自体はただ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A8%A5%AF%A5%B9%A5%D7%A5%ED%A1%BC%A5%E9">エクスプローラ</a>にアイコンが並んでいるのとあまり変わらず、キーだけで操作するのにも慣れてしまえば「あ、アレやろう」と思いつく端から吸い付くように即アプリ起動(マシン性能に余裕さえあれば)。ひたすらキーをたたく作業がエンドレスに続きます。</p><p>こうしてみるとメトロの本質は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>とは競合しません。ただ見た目は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>っぽいUIなので、ある意味では「ものすごく伝わらない」「誤解を生むデザイン」。もっと言うと今までの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>に比べ圧倒的に洗練された外観。かつてなく雑多さに欠ける清潔な雰囲気は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B1%A5%EC%A5%F3%CC%A3">ケレン味</a>好きなオタにも向かない。となると、本当に産業用のパーソナルコンピューティングに絞っている印象です。実際今の<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows">Windows</a>はそういうポジションなのでなんとも言えませんが…。</p><p>あんまり広げてもしょうがないので次のお題。</p> </div> </div> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>にVS2010Express</h4> <p>毎回簡単には成功しない2010のインストール。なんで2010かと言うと今までのデスクトップアプリ開発は2010までで対応ストップらしい<a href="#f-2c348f46" name="fn-2c348f46" title="チラッと見た感じ、2010:デスクトップアプリ開発最終版/2012〜:メトロアプリ対応版/2013〜:WindowsStore対応版なのかな">*4</a>ので一応2010インストールをメモっておきたかったのです。</p> <ol> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/VC%2B%2B">VC++</a>>VC#><a class="keyword" href="http://d.hatena.ne.jp/keyword/VB">VB</a>の順でインストール</li> <li>一旦マクロソフトアップデート>いろいろアップデートされますが、VS2010SP1のインストールには失敗するようです。</li> <li><a href="http://www.microsoft.com/ja-jp/download/details.aspx?id=23691">&#x3053;&#x3053;</a>からSP1のisoファイルを落としてきてマウント、Setup.exeをたたくと成功。</li> <li>もう一回<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%AF%A5%ED%A5%BD%A5%D5%A5%C8">マイクロソフト</a>アップデートかけてSP1にもパッチを当てます。</li> </ol><p>とりあえずWin7SDKは諦め。winsdk_<a class="keyword" href="http://d.hatena.ne.jp/keyword/amd64">amd64</a>.<a class="keyword" href="http://d.hatena.ne.jp/keyword/msi">msi</a>が無いとかなんとか言われてなぜかうまくいきませんが…困り次第どうにかしよう。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-6cdecde8" name="f-6cdecde8" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">スタートメニューは整理してもバージョンアップで紐付けが切れるので、グループ整理可能なアプリランチャーで目的別にショートカットリンクをまとめてショートカットキーから呼び出します。それとAltTabカスタマイズ用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>を入れて、やはりキーボードでサクサク切り替えます。Webブラウズはブックマークを使わずスピードダイヤル。すると、なんだかんだで今のModernUIとだいたい似たような使用感になります。</span></p> <p class="footnote"><a href="#fn-f3e91cf0" name="f-f3e91cf0" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">ほとんど多くのユーザーにとってプライベートシーンのコンピューティングなんて本当はそれくらいで十分、その操作をわかりやすく楽しめるようにまとめてあるのが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>進歩性の要と言えます</span></p> <p class="footnote"><a href="#fn-4d521e85" name="f-4d521e85" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">ただしTab送りとかAlt拡張系を手に覚えさせていないと苦労すると思う。</span></p> <p class="footnote"><a href="#fn-2c348f46" name="f-2c348f46" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">チラッと見た感じ、2010:デスクトップアプリ開発最終版/2012〜:メトロアプリ対応版/2013〜:WindowsStore対応版なのかな</span></p> </div> tiri_tomato DynabookSS1600にPuppyLinux入れる方法 hatenablog://entry/8454420450077304081 2014-03-05T07:07:04+09:00 2014-12-17T12:53:13+09:00 前回の続き。とりあえず今回は強気に現在の最新版571JPをチョイスしています(*1)。XPは今回バッサリ消すことにます(デュアルブートはしない)。 本日の「ちくわしか持ってねぇ!」 USB-IDE(2.5インチ)変換アダプタ 適当な母艦 なんで必要な時に限って変なアダプタしか持ってないのでしょう。3.5サイズのUSB-IDE変換アダプタが死んでいなければCDブート出来たんですが。 PuppyをSS1600に読み込ませる方法 はじめます。SS1600はOSセットアップに関してはクセが強いので注意点がいくつかあります。まずPuppyはUSBメモリブートするのが人気なんですが、SS1600はメモリブ… <p><a href="http://d.hatena.ne.jp/tiri_tomato/20140304/1393886707">&#x524D;&#x56DE;</a>の続き。とりあえず今回は強気に現在の最新版571JPをチョイスしています(<a href="#f-263a3415" name="fn-263a3415" title="処理の軽さだけで言えば431JPの方が軽いらしいです。でもSS1600くらいの数値なら5系でもPuppyのアイドルプロセス自体が重い感じはしないです。普段はサクサクだけどYoutubeとか見ると途端に死ぬ感じなのでOSはネックではないだろうなぁと。">*1</a>)。XPは今回バッサリ消すことにます(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%E5%A5%A2%A5%EB%A5%D6%A1%BC%A5%C8">デュアルブート</a>はしない)。</p> <div class="section"> <h4>本日の「ちくわしか持ってねぇ!」</h4> <ul> <li>USB-<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>(2.5インチ)変換アダプタ</li> <li>適当な母艦</li> </ul><p>なんで必要な時に限って変なアダプタしか持ってないのでしょう。3.5サイズのUSB-<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>変換アダプタが死んでいなければCDブート出来たんですが。</p> </div> <div class="section"> <h4>PuppyをSS1600に読み込ませる方法</h4> <p>はじめます。SS1600はOSセットアップに関してはクセが強いので注意点がいくつかあります。</p><p>まずPuppyは<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>ブートするのが人気なんですが、SS1600はメモリブートには非対応です。そもそもブート(インストール)手順において、おそらくフロッピー以外のUSBドライブを利用するのは難しい気がします(ただUSB-CDドライブは望みがあると思うんですが、今回は設備が無くって未検証)。それと、1.Puppyローダーをフロッピーからブート2.Puppyローダー経由で<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>からPuppyロードしようとすると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>の検索処理に行ったまま帰って来なくなる、という現象が起きました。この時、USB端子に<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>をとりあえず挿しておけば、該当のUSBコントローラの列挙までは成功します。と言っても<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>を3つ持っていなければ、いずれ空のUSBスロットにぶち当たって止まります。もしかすると「SS1600はCF挿さなきゃXPインストール出来ないよ問題」の再来かもしれません(<a href="#f-90ed39c6" name="fn-90ed39c6" title="TOSHIBAロゴでHomeキー連打すると選択可能になるブートデバイスリストには、HDD/CD/LAN/FDDといった項目が表示されていて、またUSB-FDDによるローダーのブートまでは成功を確認(ただしBIOSにほど近いローダ状態からUSBメモリ列挙にトライすると死ぬ)。だったらUSB-CDならそれだけで簡単にイケるんじゃないかな?かな?(未検証)というわけです">*2</a>)。一応これを回避するには、中の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>-HDDにPuppyのシステムCDのファイル構造をコピーした<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を作り、トッ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A5%D9">プレベ</a>ルに"IDEHD"という<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B3%C8%C4%A5%BB%D2">拡張子</a>ナシの空ファイルを作っておき、FD<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D6%A1%BC%A5%C8%A5%ED%A1%BC%A5%C0">ブートローダ</a>ーのメニューから「USBを列挙せず、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>/ATAPIのみ検索してロードする」というモードで起動させればIDEHDファイルを符丁にしてうまく行くんですが、<b>そもそも中のHDD取り出して直接書き込むくらいなら、LiveCD相当の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>をHDDの中に作ろう。</b><br /> </p> <div class="section"> <h5>1.中のメインHDDをフォーマットして二つの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>に分割、LiveCD(ブートCD)相当の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を作る。</h5> <p>上述の通り、結局中の<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>に直接Puppyを入れることになるなら、<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>に直接ブート<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>作った方がスマート。SS1600からHDDを取り出しましょう。母艦にUSB-<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>変換でつないで、PuppyLinuxのブートCDのisoとだいたい同じかそれより大きな<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>をFAT32で適当に確保。あとは、そこに<a class="keyword" href="http://d.hatena.ne.jp/keyword/MBR">MBR</a>ごとブートCDのisoデータを書き込んでやればオッケーです。母艦がWinの場合、LinuxLiveUSBCreatorを使います。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>だと、うーん…(<a class="keyword" href="http://d.hatena.ne.jp/keyword/unetbootin">unetbootin</a>がUSB-HDD<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>への書き込みが出来ないので)…ターミナルから一度unmountしてddコマンド叩けばイケるんじゃないかしら?</p> </div> <div class="section"> <h5>2.HDD戻して起動するだけ</h5> <p>HDDを元に戻して電源を入れると、バッチリPuppyが起動するはず!あとは好みに応じてHDDの空いた<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>にフルインストールするとか、起動設定いじるとかして下さい。あと、アプリのインストールなどでRAMの容量不足を言われる時はユーザー設定ファイルのサイズを拡大しないといかんのですが、そのために一度ユーザー設定ファイルの保存場所を明示的に指定した後Puppyを再起動する必要があるみたい。</p><p>なんかもうこれPuppyの記事ではなく、SS1600に<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>をムリヤリ突っ込む記事ですな。</p> </div> </div><div class="footnote"> <p class="footnote"><a href="#fn-263a3415" name="f-263a3415" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">処理の軽さだけで言えば431JPの方が軽いらしいです。でもSS1600くらいの数値なら5系でもPuppyのアイドルプロセス自体が重い感じはしないです。普段はサクサクだけど<a class="keyword" href="http://d.hatena.ne.jp/keyword/Youtube">Youtube</a>とか見ると途端に死ぬ感じなのでOSはネックではないだろうなぁと。</span></p> <p class="footnote"><a href="#fn-90ed39c6" name="f-90ed39c6" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text"><a class="keyword" href="http://d.hatena.ne.jp/keyword/TOSHIBA">TOSHIBA</a>ロゴでHomeキー連打すると選択可能になるブートデバイスリストには、HDD/CD/LAN/<a class="keyword" href="http://d.hatena.ne.jp/keyword/FDD">FDD</a>といった項目が表示されていて、またUSB-<a class="keyword" href="http://d.hatena.ne.jp/keyword/FDD">FDD</a>によるローダーのブートまでは成功を確認(ただし<a class="keyword" href="http://d.hatena.ne.jp/keyword/BIOS">BIOS</a>にほど近いローダ状態から<a class="keyword" href="http://d.hatena.ne.jp/keyword/USB%A5%E1%A5%E2%A5%EA">USBメモリ</a>列挙にトライすると死ぬ)。だったらUSB-CDならそれだけで簡単にイケるんじゃない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%AB%A4%CA%A1%A9%A4%AB%A4%CA%A1%A9">かな?かな?</a>(未検証)というわけです</span></p> </div> tiri_tomato もう一度SS1600再生。今度はLinux! hatenablog://entry/8454420450077304085 2014-03-04T07:45:07+09:00 2014-12-17T12:53:14+09:00 このへんで記事にしているリース落ちのDynabookSS1600(いわゆる古〜いビジネスB5)。なんだかんだで手放す機会を逸してしまい、そろそろXP期限でどうしましょう。 Winの処理が重くてキツいんだったらPuppyLinuxが良いよ! ネットを巡回してるとこんな意見がチラホラ見られます。Linuxには軽量ディストリビューションという小振りなパッケージがあるらしい(小さなものではFDで完結するようなものまで)。Puppyはそんな軽量Linuxの一つで容量はCDサイズ。「情報が少ない」と言うものの「そうかな結構あるよ?」という感じ。日本語版もあるし、Puppyの名前は知恵袋サイトにまで出てきま… <p><a href="http://d.hatena.ne.jp/tiri_tomato/archive?word=%2A%5BSS1600%5D">&#x3053;&#x306E;&#x3078;&#x3093;</a>で記事にしているリース落ちのDynabookSS1600(いわゆる古〜いビジネスB5)。なんだかんだで手放す機会を逸してしまい、そろそろXP期限でどうしましょう。</p> <div class="section"> <h4>Winの処理が重くてキツいんだったらPuppyLinuxが良いよ!</h4> <p>ネットを巡回してるとこんな意見がチラホラ見られます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>には軽量<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>という小振りなパッケージがあるらしい(小さなものではFDで完結するようなものまで)。Puppyはそんな軽量<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>の一つで容量はCDサイズ。「情報が少ない」と言うものの「そうかな結構あるよ?」という感じ。日本語版もあるし、Puppyの名前は知恵袋サイトにまで出てきます。このXP期限をバネに普及がまた進むんじゃないかと思うとなかなか有望株。</p> <div class="section"> <h5>どのPuppyが良い?</h5> <p><a href="http://puppylinux-food.zohosites.com/導入・インストール.html#.UxUD8NciQnV">こちらのサイト</a>がすんごいわかりやすいです。いまのところ、Win2000=4系最終版、XP=5系最新版がオススメですが、5系は550だけCPUのPAEを要求するのに気をつけて下さい(SS1600はPAE非対応なので550は入れられない)。</p><p>まさかSS1600の性能で<a class="keyword" href="http://d.hatena.ne.jp/keyword/Vista">Vista</a>以後のWinがサクサク動くとは思えないので、早速PuppyLinux入れてみようそうしよう。ちなみに私は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>は<a class="keyword" href="http://d.hatena.ne.jp/keyword/Mac">Mac</a>しか使った事のないペーペーですので素人クサいのはあしからず。</p> </div> </div> <div class="section"> <h4>やった感想(実際どれくらい使えたか)</h4> <p>インストール成功したので、最初にオチ(実際の使用感)から書いておきます。なお、ウチのSS1600はテコ入れで投入した<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>がすぐ壊れたので、現在のSS1600は普通のドライブに戻してあり、メモリは+1G足してあります。参考までに、<a href="http://dynabook.com/pc/catalog/ss/04020316/spec.htm">SS1600 10L/2 &#x306E;&#x6027;&#x80FD;&#x306F;&#x30B3;&#x30C1;&#x30E9;&#x3002;</a></p> <div class="section"> <h5>インターネット接続</h5> <p>問題なし。余っていたLAN-W300N/U2S(Logitecの1000円<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%B5%C0%FELAN">無線LAN</a>)も挿してみたけど普通につながりました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>様々。</p> </div> <div class="section"> <h5>グラフィックとオーディオ</h5> <p>このリストの中では一番懸念していた部分ですが、なんか何もしなくても普通にイケました。まぁ<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a>チップだしね。</p> </div> <div class="section"> <h5>動画はやっぱ無理</h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Youtube">Youtube</a>も無理。コマ飛びどころじゃありません。CPUクロックとメモリのバス速度が足りません。それも圧倒的に。音楽だけならどうにかこうにか。まー元からそういう世代のビジネスB5ではあります。</p> </div> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> + GoogleDrive & GoogleDocs</h5> <p>やった一応動いた!サクサクとは言えないものの、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%EB%A1%BC%A5%D7%A5%A6%A5%A7%A5%A2">グループウェア</a>端末程度としてならなんとか動きそう!(なお<a class="keyword" href="http://d.hatena.ne.jp/keyword/HTML5">HTML5</a>のサイト見ないなら<a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a>の方が軽いので<a class="keyword" href="http://d.hatena.ne.jp/keyword/Opera">Opera</a>でアクセスして問題があれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a>で見ると良い感じ)</p> </div> <div class="section"> <h5>総括</h5> <p>さすがにXPよりはサクサク!PuppyかわいいよPuppy。XPノート再生にPuppyというのは確かにアリ。でも画面ヤケ+バッテリー寿命をお金出してまで第一線に復帰させるほどではないかなぁ(贅沢)。<a class="keyword" href="http://d.hatena.ne.jp/keyword/IDE">IDE</a>-CF変換(DMA対応タイプ)+ジャンクのCFという疑似<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>で起動し、<a class="keyword" href="http://d.hatena.ne.jp/keyword/RAID">RAID</a>つきのHDDタワーを買ってきてUSBでつなぎ、ホームサーバーの制御器として使い潰すのが良いかもしれません。Puppyの運用に必要なストレージ容量としては、システム+アプリ+個人設定で2〜4Gあたりが必要じゅうぶん量かなーと思いました。逆に言えば「いまや性能が絶望的」という理由でジャンク扱いされている爆安完動ノートをゲットしてくれば、わざわざ高価なシステム付きの<a class="keyword" href="http://d.hatena.ne.jp/keyword/NAS">NAS</a>じゃなくてもホームサーバは立てられそうな気がします。</p><p>インストール過程についてはまた次回。</p> </div> </div> tiri_tomato PC自作日記 hatenablog://entry/8454420450077304090 2014-03-02T12:01:33+09:00 2014-12-17T12:53:16+09:00 とりあえずXP期限切れ+消費増税を目前に母艦(このへんで記事にしているXPマシン)が突然壊れてしまいました。電源スイッチ無反応。「あぁーコレはまずマザボがやられてしまったパターン」かと分解してみると、細かい部分に結構ホコリがたまっていました。3.5インチのマルチカードリーダー(フロッピー付)の奥がとくに酷かったっす。メモリーカードメディアを突っ込むスロットの奥!吸気の貧弱なケースなので、思ってもみなかったところを吸気経路にしてしまっていたか…そして端子間に生じる電位差マジ怖す。*1確かにこのところUSB機器が1.0接続されちゃったり認識トラブルを起こしたり起こさなかったり怪しい状態でした。分か… <p>とりあえずXP期限切れ+消費<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%FD%C0%C7">増税</a>を目前に母艦(<a href="http://d.hatena.ne.jp/tiri_tomato/20120802">&#x3053;&#x306E;&#x3078;&#x3093;</a>で記事にしているXPマシン)が突然壊れてしまいました。電源スイッチ無反応。</p><p>「あぁーコレはまず<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>がやられてしまったパターン」かと分解してみると、細かい部分に結構ホコリがたまっていました。3.5インチのマルチカードリーダー(フロッピー付)の奥がとくに酷かったっす。メモリーカードメディアを突っ込むスロットの奥!<b>吸気の貧弱なケースなので、思ってもみなかったところを吸気経路にしてしまっていたか…そして端子間に生じる電位差マジ怖す。<a href="#f-e4960dda" name="fn-e4960dda" title="なぜこういう部分にホコリがたまるのか、暇なので説明します。平たく言うと、レディー状態の端子には電気信号や電力を渡すための電圧(水道における水圧のようなもの)がかかっています。もちろん非接続で露出している端子は、見た目の通りに直接的には通電してない断絶状態。水道で例えるなら、固い土の中で水道管が途切れてるような状態です。キャップも無いのに大丈夫?と思うかもしれませんが土に阻まれてそんなにしみ出したりはしないですけれど、やっぱり多少は漏れてます。で、土がモゾモソ動いて”途絶されているべき水道管をたまたま連結しちゃう”事があります。これがいわゆるホコリのような微小物質が電気回路を連結しちゃった状態ですな。やはり圧がかかっている状態が長く続くと、できるだけ回路を連結する方向で状態が整いやすく、またその物理状態を維持しやすくなるので、やっぱり定期的に電源を落として掃除しろって話になります。">*1</a></b></p><p>確かにこのところUSB機器が1.0接続されちゃったり認識トラブルを起こしたり起こさなかったり怪しい状態でした。分かっていれば、カードリーダのクチ(スロットの入り口)に掃除機を当ててホコリを吸っちゃえば一発なんですが、ペンライトで照らすまではなかなかわからない部分ですね。スロットにカバーついてる製品もあんまり無いし。</p><p>せっかくなので<a class="keyword" href="http://d.hatena.ne.jp/keyword/Win8">Win8</a>を自作で組み直したり<a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a>入れてみたりする日記をしばらくしたためていく事にします。</p> <div class="section"> <h5>手始めに部品の買い方メモ</h5> <p>ケーブル・マウンタ・小物類は大手量販店の圧勝です。自作専門店は、独特の保証の強さを生かしてメモリやチップなどコア部品を中心に敢闘中。</p> <ul> <li>調べてみるとヨドの自作小物は意外と安い。</li> <li>ヨドとビックはポイント還元率を含めると<a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>より安く、レビューでもなんぼかポイントもらえます。</li> <li>CPU/MB/MEMあたりはとくにこだわらなければ結局セット売りが安定?(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A1%BC%A5%DC%A1%BC%A5%C9">マザーボード</a> セットで検索するとチラホラ)</li> </ul><p>「今時自作なんてしなくても良いんじゃないの?」という視点でも調べたんですが、チップ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%DC%A1%BC%A5%C9">オンボード</a>のビデオ性能がいまだに酷い感じです。いつかチップ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%DC%A1%BC%A5%C9">オンボード</a>でじゅうぶんな時代が来ると言われ続けてはや何年。このところは<a class="keyword" href="http://d.hatena.ne.jp/keyword/Intel">Intel</a>のIrisというシリーズが頑張ってるようなんですが、それも単に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>性能だけで言えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/nVidia">nVidia</a>のGTモバイル系の方がずっと優秀で、しかも<a class="keyword" href="http://d.hatena.ne.jp/keyword/nVidia">nVidia</a>のGTMは自作用MBのラインナップにはあまり顔を出さないんですよね(だいたい省スペース問題を頑張って解決するくらいなら、場所に余裕さえあるなら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B0%A5%E9%A5%DC">グラボ</a>挿すほうが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>が良いわけですし<a href="#f-cc4464ed" name="fn-cc4464ed" title="というか、そもそもこの問題があるからこそ、「あくまでもCPUのオマケ」の範囲でのハイエンド技術を狙い撃ちしているのがIrisと。言われてみればスマホのGL性能も「オマケ機能でこんなに動くんだねスゴイね!」という暗黙の文脈ってありますよね…オンボのチップ性能は目覚ましい進化を遂げているのも疑いないですが、据え置きマシン用の部品として考えると、電力消費や発熱の問題ってそこまでシビアじゃなく、コストと性能のバランスだけで見てしまうとかなりイマイチな感じです。">*2</a>)。使い回す事が可能なRadeon5770が今手元にあるとなると、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A5%F3%A5%DC%A1%BC%A5%C9">オンボード</a>にコイツの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>性能をぶっこ抜いて欲しいのですが微妙に難しそう…なら、5770使い回して浮いたお金でシステムドライブを<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>にしたいのが正直なところです。加えて言えば、今は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%FD%C0%C7">増税</a>前の駆け込みセールの雰囲気があるのでどっちかと言えば自作した方が部品単位でお得感が出やすいのかなという見積もりの印象もあります。</p> </div> <div class="section"> <h5>なんか<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>ばっかり壊れるな</h5> <p>このところ「なんかやたら<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>壊れるな」って気がします。HDDの故障トラブルに関しては要素が複合的すぎるので別とすると、個人的に今までの故障パターンですと「省スペースPCで発熱問題の顕在化、また場所が確保出来ずに小型化した電源がお粗末で構成部品の寿命に悪影響」「初期の<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a>とかこなれていないものは決まって短寿命あるいは相性問題の巣窟」「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D0%A1%BC%A5%AF%A5%ED%A5%C3%A5%AF">オーバークロック</a>系の遊び方をすると相性問題はテキメン顕在化」とか。逆に言えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%BC%AB%BA%EEPC">自作PC</a>でも電源や冷却構成に気を配り、変な部品に手を出さず<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D0%A1%BC%A5%AF%A5%ED%A5%C3%A5%AF">オーバークロック</a>とかもせず、各種保険をうまく使って相性問題を回避してしまえば、解消出来ない<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DC%A5%C8%A5%EB%A5%CD%A5%C3%A5%AF">ボトルネック</a>はほぼ存在せず「寿命についても信頼のおける<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>の良い作業環境一丁上がり!」。しかしそうなると消去法で「<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>の寿命(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C5%C5%B2%F2%A5%B3%A5%F3%A5%C7%A5%F3%A5%B5">電解コンデンサ</a>の限界)」という死因が支配的になってきてるなーという印象です。</p> </div> <div class="section"> <h5><a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a>ファンには申し訳ないけれどソケット規格は少ない方が…</h5> <p>CPUメーカーが淘汰されたため、必然的にソケット規格が淘汰されました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>も各メーカーでソケットの絞り込みによるラインナップの絞り込みが生じています。それにつけてもCPUが高い!CPUは独占化+規格淘汰でメーカー一人勝ちのシナリオです。一方、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>は製品を売っているメーカーが多く、規格淘汰によってラインナップが絞られた分が全て価格競争に反映されているのか、お買い得な印象。仮に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>が消耗品であってもぶっちゃけそれほど気にならないくらい。<a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a>には悪いんですが、CPU乱立期に比べれば今の状態は自作派には優しいかもしれません。私の経験上、CPUは変な事しなければあまり壊れるような部品ではなく<a href="#f-774b188c" name="fn-774b188c" title="設計やユーザーの使い方、あるいは現実的な諸々の問題で潰そうと思えばいくらでも潰せますけれど、本当は半導体自体、配慮して使う分には理論上の寿命は半永久的なはず。AMDについては、お買い得感があって好きだったんですが御愁傷様でした。nVidiaはDXの規格ハンドリング権限があるはずなのに案外イケてない製品も多く、大手的横綱感がクサすぎるので、次もRadeon買おうと思っています。頑張れAMD、頑張れATi。">*3</a>、安い部品を使い潰して高級部品を使い回すコスト計画が立てやすい状態になっています。さらには固体<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%C7%A5%F3%A5%B5">コンデンサ</a>化の波が来ており、次の自作はそのへん<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%B6%A5%DC">マザボ</a>寿命が伸びるのではないかと楽しみ。</p><p>つづく</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-e4960dda" name="f-e4960dda" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">なぜこういう部分にホコリがたまるのか、暇なので説明します。平たく言うと、レディー状態の端子には電気信号や電力を渡すための電圧(水道における水圧のようなもの)がかかっています。もちろん非接続で露出している端子は、見た目の通りに直接的には通電してない断絶状態。水道で例えるなら、固い土の中で水道管が途切れてるような状態です。キャップも無いのに大丈夫?と思うかもしれませんが土に阻まれてそんなにしみ出したりはしないですけれど、やっぱり多少は漏れてます。で、土がモゾモソ動いて”途絶されているべき水道管をたまたま連結しちゃう”事があります。これがいわゆるホコリのような微小物質が電気回路を連結しちゃった状態ですな。やはり圧がかかっている状態が長く続くと、できるだけ回路を連結する方向で状態が整いやすく、またその物理状態を維持しやすくなるので、やっぱり定期的に電源を落として掃除しろって話になります。</span></p> <p class="footnote"><a href="#fn-cc4464ed" name="f-cc4464ed" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">というか、そもそもこの問題があるからこそ、「あくまでもCPUのオマケ」の範囲でのハイエンド技術を狙い撃ちしているのがIrisと。言われてみれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>のGL性能も「オマケ機能でこんなに動くんだねスゴイね!」という暗黙の文脈ってありますよね…オンボのチップ性能は目覚ましい進化を遂げているのも疑いないですが、据え置きマシン用の部品として考えると、電力消費や発熱の問題ってそこまでシビアじゃなく、コストと性能のバランスだけで見てしまうとかなりイマイチな感じです。</span></p> <p class="footnote"><a href="#fn-774b188c" name="f-774b188c" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">設計やユーザーの使い方、あるいは現実的な諸々の問題で潰そうと思えばいくらでも潰せますけれど、本当は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C8%BE%C6%B3%C2%CE">半導体</a>自体、配慮して使う分には理論上の寿命は半永久的なはず。<a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a>については、お買い得感があって好きだったんですが御愁傷様でした。<a class="keyword" href="http://d.hatena.ne.jp/keyword/nVidia">nVidia</a>はDXの規格ハンドリング権限があるはずなのに案外イケてない製品も多く、大手的<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B2%A3%B9%CB">横綱</a>感がクサすぎるので、次も<a class="keyword" href="http://d.hatena.ne.jp/keyword/Radeon">Radeon</a>買おうと思っています。頑張れ<a class="keyword" href="http://d.hatena.ne.jp/keyword/AMD">AMD</a>、頑張れ<a class="keyword" href="http://d.hatena.ne.jp/keyword/ATi">ATi</a>。</span></p> </div> tiri_tomato 家なき鳥、星をこえる hatenablog://entry/8454420450077304096 2014-03-01T07:43:48+09:00 2014-12-17T12:53:18+09:00 テロリスト・ハキムを主役にしたプラネテスのスピンオフ小説。家なき鳥、星をこえる プラネテス作者: 幸村誠,常盤陽出版社/メーカー: 講談社発売日: 2007/11/15メディア: 単行本購入: 1人 クリック: 56回この商品を含むブログ (21件) を見る 感想 Amazonのレビューとかでもチラチラ書かれてますけど本当に詰めが勿体ない印象です。ネタバレを避けて言うなら、編集者の作家デビューってのにも驚きなんですが、それ故に原作者に気が引けたんじゃないかなぁという印象でした。語り口は丁寧。ラノベっぽくなりすぎず、淡々と楽しめましたが最終的には消化不良な印象で、うーん、惜しい。テーマはもうその… <p>テロリスト・ハキムを主役にした<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%CD%A5%C6%A5%B9">プラネテス</a>のスピンオフ小説。<div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4063647102/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/51QcjuWXQDL._SL160_.jpg" class="hatena-asin-detail-image" alt="家なき鳥、星をこえる プラネテス" title="家なき鳥、星をこえる プラネテス"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4063647102/assoctiritoma-22/">家なき鳥、星をこえる プラネテス</a></p><ul><li><span class="hatena-asin-detail-label">作者:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%AC%C2%BC%C0%BF">幸村誠</a>,常盤陽</li><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%B9%D6%C3%CC%BC%D2">講談社</a></li><li><span class="hatena-asin-detail-label">発売日:</span> 2007/11/15</li><li><span class="hatena-asin-detail-label">メディア:</span> 単行本</li><li><span class="hatena-asin-detail-label">購入</span>: 1人 <span class="hatena-asin-detail-label">クリック</span>: 56回</li><li><a href="http://d.hatena.ne.jp/asin/4063647102/assoctiritoma-22" target="_blank">この商品を含むブログ (21件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div></p> <div class="section"> <h5>感想</h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>のレビューとかでもチラチラ書かれてますけど本当に詰めが勿体ない印象です。ネタバレを避けて言うなら、編集者の作家デビューってのにも驚きなんですが、それ故に原作者に気が引けたんじゃないかなぁという印象でした。語り口は丁寧。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E9%A5%CE%A5%D9">ラノベ</a>っぽくなりすぎず、淡々と楽しめましたが最終的には消化不良な印象で、うーん、惜しい。テーマはもうそのまんまなんですが、あんまり星をこえられた感がありません。いや、これからこえていくのかな?うーん。</p><p>こうしてみるとコミックス版のオチが秀逸だったなぁと思わされます。コミック最終巻は結構駆け足気味にもかかわらず、弟の成長、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A5%C3%A5%AF%A5%B9%A5%DF%A5%B9">ロックスミス</a>のサラッとした業の描き方とか小道具として出てくる愛車のチョイスとか、宇宙的な巨視感と相まってうまく回収されてるんですよね。この本もそういう感じにオチてれば良かったのに。</p> </div> tiri_tomato Gradientの制御点は8個までらしい hatenablog://entry/8454420450077304098 2014-02-15T09:08:42+09:00 2014-12-17T12:53:19+09:00 Gradient.SetKeysにセットできる制御点の個数はアルファもカラーも8個が限度みたいです。GradientEditorを使ってて「アレレ?」と思い、試しにスクリプトから無理やり制御点をセットしてみると、こんな例外が。 Max number of color keys is 8 (given 99) Max number of alpha keys is 8 (given 99) 自由長に対応するのもコード量自体はそれほどたいしたことないはずなのに、ちょっち予想外。こういう処理はいかにも要素数に線形で処理負荷が増えるもんだと思っていたのですが、それより単に実行速度を重視したんだろうと勝… <p>Gradient.SetKeysにセットできる制御点の個数はアルファもカラーも8個が限度みたいです。GradientEditorを使ってて「アレレ?」と思い、試しに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>から無理やり制御点をセットしてみると、こんな例外が。</p> <blockquote> <p>Max number of color keys is 8 (given 99)</p> </blockquote> <blockquote> <p>Max number of alpha keys is 8 (given 99)</p> </blockquote> <p>自由長に対応するのもコード量自体はそれほどたいしたことないはずなのに、ちょっち予想外。こういう処理はいかにも要<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%C7%BF%F4">素数</a>に線形で処理負荷が増えるもんだと思っていたのですが、それより単に実行速度を重視したんだろうと勝手に解釈します(<a href="#f-a7f201f0" name="fn-a7f201f0" title="仮にEvaluate処理を自作するとなると、time以下の最大のキーポイントとその次のキーポイントを探索する処理が必要になるはず(前後の二点間で線形補間するため)。配列数を完全自由長の仕様にして線形探査をベタ書きするすると、timeが検索後半の場合に結構アレな処理コストになる可能性があります。SetKeysメソッドがあって、ソートしてると言うのだから二分探査してるんでしょうけど。しかしそうなると今度は構造体を初期化するたびにソート処理を長々フックするのか、という問題ががが。ぶっちゃけ個人的には、そのへんの実行処理コストはしょうがない、どうしてもかかるだろう、くらいのつもりでしたが、まさかの個数制限仕様でした。">*1</a>)。しかし<a href="https://docs.unity3d.com/Documentation/ScriptReference/Gradient.html">&#x30C9;&#x30AD;&#x30E5;&#x30E1;&#x30F3;&#x30C8;</a>に「Note that the alpha and colors keys will be automatically sorted by time value and that it is ensured to always have a minimum of 2 color keys and 2 alpha keys.」って書くくらいだったらついでに「Keys are limited to up to 8 keys.」とかも書いておくれよぅ、という感じ。ドキュメントって、イケてない実装もそれならそれでキッパリ書いた方が、より文書化の意味があると思うんです。</p> <div class="footnote"> <p class="footnote"><a href="#fn-a7f201f0" name="f-a7f201f0" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">仮にEvaluate処理を自作するとなると、time以下の最大のキーポイントとその次のキーポイントを探索する処理が必要になるはず(前後の二点間で線形補間するため)。配列数を完全自由長の仕様にして線形探査をベタ書きするすると、timeが検索後半の場合に結構アレな処理コストになる可能性があります。SetKeys<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>があって、ソートしてると言うのだから二分探査してるんでしょうけど。しかしそうなると今度は構造体を初期化するたびにソート処理を長々フックするのか、という問題ががが。ぶっちゃけ個人的には、そのへんの実行処理コストはしょうがない、どうしてもかかるだろう、くらいのつもりでしたが、まさかの個数制限仕様でした。</span></p> </div> tiri_tomato 恥ずかしながらワタクシ、ポエム書こうとしたんですよ(技術系)。 hatenablog://entry/8454420450077304100 2014-02-13T07:20:34+09:00 2014-12-17T12:53:20+09:00 pplogっていう「ゆるふわポエム書いてね」ってサイトを見かけました。 最新のポエム記事一個だけ他の人から閲覧される 他の人の記事への反応は、スター的なものがつけられるだけ 検索とかはできない(ランダムジャンプのみ) 購読者(共感者やファン的なもの)にはなる事が出来る なるほど面白そう。さっそく書いてみよう。 マイポエム ハッ!…そういやオープンソース系ソフト界隈って未使用ナンチャラってあんまり見ないな。昔は「この引数は使用されていません」 「じゃあなんで有るんだよこの仕様wゼロでも突っ込んどくかwww」 ていういわゆる「未使用引数」とか結構ドンブリなのをよく見た気がする。まぁハード系だと、未… <p><a href="https://www.pplog.net/">pplog</a>っていう「ゆるふわポエム書いてね」ってサイトを見かけました。</p> <ul> <li>最新のポエム記事一個だけ他の人から閲覧される</li> <li>他の人の記事への反応は、スター的なものがつけられるだけ</li> <li>検索とかはできない(ランダムジャンプのみ)</li> <li>購読者(共感者やファン的なもの)にはなる事が出来る</li> </ul><p>なるほど面白そう。さっそく書いてみよう。</p> <div class="section"> <h5>マイポエム</h5> <blockquote> <p>ハッ!…そういや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%AA%A1%BC%A5%D7%A5%F3%A5%BD%A1%BC%A5%B9">オープンソース</a>系ソフト界隈って未使用ナンチャラってあんまり見ないな。</p><p>昔は「この引数は使用されていません」<br /> 「じゃあなんで有るんだよこの仕様wゼロでも突っ込んどくかwww」<br /> ていういわゆる「未使用引数」とか結構ドンブリなのをよく見た気がする。</p><p>まぁハード系だと、未使用<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%BF">レジスタ</a>とか残ってないと不安になる事もあるけどソフトの場合はそういうシバリも少ない。</p><p>バージョン管理とか、ようするに逐一差分をログして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A1%BC%A5%EB%A5%D0%A5%C3%A5%AF">ロールバック</a>もできる更新コミット用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C4%A1%BC%A5%EB">ツール</a>が充実したって事かな。</p><p>今見るのはコードの互換性のために残る形骸化した<a class="keyword" href="http://d.hatena.ne.jp/keyword/enum">enum</a>定数くらいか。</p> </blockquote> <p>ヤバイポエムムズカシイ。</p><p>とりあえず自分の普段の思考の中では、<font color="red">この絶妙にクダをまいてる感じは「とってもポエミィ」</font>な部類だと思ったんですが、アップする前にふとランダム検索で何十件かジャンプして「あかんコレ全然場違いだー!」と緊急停止。</p><p>さてポエムといえば厨2ですが、この厨2病もシェアするのが結構難しい気がしないでもありません。</p><p>いわゆる技術系人物の場合、例えば「厨2病」の発露も、内容の分類としては厨2ノートなんだけれど「ダメージ計算式(無駄に長いあたり素人臭)」「ロボの関節構造とか足の裏まで設定されてる」「アイテムリストが<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C9%BD%B7%D7%BB%BB">表計算</a>マクロでゲーム用のバランス調整機能が入ってる」「エロ画像フォルダの管理にバッチとかマクロ」とか、多分皆そんな感じじゃないかなーと勝手に思ってるんですが、しかしなんか一般的によく言うのとも若干違っているようで、このテの気持ちはどこに持って行けば良いのか。</p> </div> tiri_tomato Googleガジェット練習 hatenablog://entry/8454420450077304102 2014-01-31T10:55:50+09:00 2014-12-17T12:53:22+09:00 GoogleSitesってファイル公開用のホスティングに良いのかなーと思って、ふとGoogleガジェットに初挑戦。Webプログラミング的なものはほとんどやった事がないんですが、とりあえずツイートボタンです。現行のツイートボタン設置ページにあるフキダシつきのミニタイプと同じ挙動をする多分。 <?xml version="1.0" encoding="UTF-8" ?> <Module> <!-- Gadget Name --> <ModulePrefs title="Tweet Share Link Button" /> <!-- Definition of params from gadget… <p>GoogleSitesってファイル公開用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%B9%A5%C6%A5%A3%A5%F3%A5%B0">ホスティング</a>に良いのかなーと思って、ふと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Google">Google</a>ガジェットに初挑戦。Webプログラミング的なものはほとんどやった事がないんですが、とりあえずツイートボタンです。現行の<a href="https://about.twitter.com/resources/buttons#tweet">&#x30C4;&#x30A4;&#x30FC;&#x30C8;&#x30DC;&#x30BF;&#x30F3;&#x8A2D;&#x7F6E;&#x30DA;&#x30FC;&#x30B8;&#x306B;&#x3042;&#x308B;&#x30D5;&#x30AD;&#x30C0;&#x30B7;&#x3064;&#x304D;&#x306E;&#x30DF;&#x30CB;&#x30BF;&#x30A4;&#x30D7;</a>と同じ挙動をする多分。</p> <pre class="code lang-xml" data-lang="xml" data-unlink><span class="synComment">&lt;?</span><span class="synType">xml version</span>=<span class="synConstant">&quot;1.0&quot;</span><span class="synType"> encoding</span>=<span class="synConstant">&quot;UTF-8&quot;</span><span class="synType"> </span><span class="synComment">?&gt;</span> <span class="synIdentifier">&lt;Module&gt;</span> <span class="synComment">&lt;!-- Gadget Name --&gt;</span> <span class="synIdentifier">&lt;ModulePrefs </span><span class="synType">title</span>=<span class="synConstant">&quot;Tweet Share Link Button&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synComment">&lt;!-- Definition of params from gadget --&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;usePageURL&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Use Page URL&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;true&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;shareURL&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Share URL&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;usePageTitle&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Use the title of the page&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;true&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;tweetText&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Tweet Text&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;isShowCount&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Show count&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;true&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;via&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Via&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;recommend&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Recommend&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;hashtag&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Hashtag&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;isLarge&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Large button&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;false&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;isDnt&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Opt-out of tailoring Twitter&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;false&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;Content </span><span class="synType">type</span>=<span class="synConstant">&quot;html&quot;</span><span class="synIdentifier">&gt;</span> <span class="synType">&lt;![</span><span class="synStatement">CDATA</span><span class="synType">[</span> <span class="synConstant"> &lt;div id=&quot;content_div&quot;&gt;&lt;/div&gt;</span> <span class="synConstant"> &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');&lt;/script&gt;</span> <span class="synConstant"> &lt;script type=&quot;text/javascript&quot;&gt;</span> <span class="synConstant"> function main()</span> <span class="synConstant"> {</span> <span class="synConstant"> var prefs = new gadgets.Prefs();</span> <span class="synConstant"> var usePageURL = prefs.getBool(&quot;usePageURL&quot;);</span> <span class="synConstant"> var shareURL = prefs.getString(&quot;shareURL&quot;);</span> <span class="synConstant"> var usePageTitle = prefs.getBool(&quot;usePageTitle&quot;);</span> <span class="synConstant"> var tweetText = prefs.getString(&quot;tweetText&quot;);</span> <span class="synConstant"> var viaName = prefs.getString(&quot;via&quot;);</span> <span class="synConstant"> var recommend = prefs.getString(&quot;recommend&quot;);</span> <span class="synConstant"> var hashtag = prefs.getString(&quot;hashtag&quot;);</span> <span class="synConstant"> var element = document.getElementById('content_div');</span> <span class="synConstant"> var paramsOfA = new Array();</span> <span class="synConstant"> if ((usePageURL == false) &amp;&amp; (0 &lt; shareURL.length)) paramsOfA.push('data-url=&quot;' + shareURL + '&quot;');</span> <span class="synConstant"> if ((usePageTitle == false) &amp;&amp; (0 &lt; tweetText.length)) paramsOfA.push('data-text=&quot;' + tweetText + '&quot;');</span> <span class="synConstant"> if (0 &lt; viaName.length) paramsOfA.push('data-via=&quot;' + viaName + '&quot;');</span> <span class="synConstant"> if (prefs.getBool(&quot;isShowCount&quot;) == false) paramsOfA.push('data-count=&quot;none&quot;');</span> <span class="synConstant"> if (0 &lt; recommend.length) paramsOfA.push('data-related=&quot;' + recommend + '&quot;');</span> <span class="synConstant"> if (0 &lt; hashtag.length) paramsOfA.push('data-hashtags=&quot;' + hashtag + '&quot;');</span> <span class="synConstant"> if (prefs.getBool(&quot;isLarge&quot;) == true) paramsOfA.push('data-size=&quot;large&quot;');</span> <span class="synConstant"> if (prefs.getBool(&quot;isDnt&quot;) == true) paramsOfA.push('data-dnt=&quot;true&quot;');</span> <span class="synConstant"> var html = '&lt;a href=&quot;https://twitter.com/share&quot; class=&quot;twitter-share-button&quot; ' + paramsOfA.join(&quot; &quot;) + '&gt;Tweet&lt;/a&gt;';</span> <span class="synConstant"> element.innerHTML = html;</span> <span class="synConstant"> }</span> <span class="synConstant"> </span> <span class="synConstant"> gadgets.util.registerOnLoadHandler(main); </span> <span class="synConstant"> &lt;/script&gt;</span> <span class="synConstant"> </span><span class="synType">]]&gt;</span> <span class="synIdentifier">&lt;/Content&gt;</span> <span class="synIdentifier">&lt;/Module&gt;</span> </pre><p>あとはこの中身を<a class="keyword" href="http://d.hatena.ne.jp/keyword/utf-8">utf-8</a>として、"TweetButton.<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>"とか適当な名前の<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>で保存して、GoogleSitesとかからガジェットとして表示するだけ。パラメータの意味は本家のツイートボタンを見てください。あんまりツイートしない私には良く分からん機能がいっぱいだ!</p> <div class="section"> <h5>さんこー</h5> <p><a href="https://developers.google.com/gadgets/docs/basic?hl=ja">https://developers.google.com/gadgets/docs/basic?hl=ja</a><br /> <a href="https://about.twitter.com/resources/buttons#tweet">https://about.twitter.com/resources/buttons#tweet</a><br /> </p> </div> <div class="section"> <h5>ちゅうい</h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>本体をGoogleSitesとかで<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DB%A5%B9%A5%C6%A5%A3%A5%F3%A5%B0">ホスティング</a>する時は、<a class="keyword" href="http://d.hatena.ne.jp/keyword/xml">xml</a>は完全な公開状態にしとかないとガジェットとしてロードできない模様です(隠蔽状態でのガジェット開発はできない仕様)。</p> </div> <div class="section"> <h5>オマケ:動作がイマイチだった<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A5%D6">はてブ</a>ボタンの作りかけ残骸</h5> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A5%D6">はてブ</a>ボタンも書いてみたんですが全然動きません。というかbookmark_button.jsが全体的にダメくさいです。jsを流し読みしても、いかにもGoogleSitesやCajaに蹴られそうな部分がたくさん。GoogleSitesってiframeがほとんど使えないもんなぁ…。というか今の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A5%D6">はてブ</a>ボタンは、<a class="keyword" href="http://d.hatena.ne.jp/keyword/OpenSocial">OpenSocial</a>勢と並べるのにリッチすぎるのかもなぁ、と思ってちょっと見回してみると<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A5%D6">はてブ</a>ボタンをハブってるサイトがかなり増えてるのでこの状況は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA">はてな</a>的には随分よろしくないんではないかしら。</p> <pre class="code lang-xml" data-lang="xml" data-unlink><span class="synComment">&lt;?</span><span class="synType">xml version</span>=<span class="synConstant">&quot;1.0&quot;</span><span class="synType"> encoding</span>=<span class="synConstant">&quot;UTF-8&quot;</span><span class="synType"> </span><span class="synComment">?&gt;</span> <span class="synIdentifier">&lt;Module&gt;</span> <span class="synComment">&lt;!-- Gadget Name --&gt;</span> <span class="synIdentifier">&lt;ModulePrefs </span><span class="synType">title</span>=<span class="synConstant">&quot;Hatena Bookmark Button&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synComment">&lt;!-- Definition of params from gadget --&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;isSimple&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Simple Minimum&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;bool&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;false&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;sightAddress&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Sight Address&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;sightTitle&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Sight Title&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;string&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;counter&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;BookmarkCounter&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;display&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;enum&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synIdentifier">&lt;EnumValue </span><span class="synType">value</span>=<span class="synConstant">&quot;none&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;EnumValue </span><span class="synType">value</span>=<span class="synConstant">&quot;display&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;EnumValue </span><span class="synType">value</span>=<span class="synConstant">&quot;display-vertical&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;/UserPref&gt;</span> <span class="synIdentifier">&lt;UserPref </span><span class="synType">name</span>=<span class="synConstant">&quot;langMode&quot;</span><span class="synIdentifier"> </span><span class="synType">display_name</span>=<span class="synConstant">&quot;Language&quot;</span><span class="synIdentifier"> </span><span class="synType">default_value</span>=<span class="synConstant">&quot;jp&quot;</span><span class="synIdentifier"> </span><span class="synType">datatype</span>=<span class="synConstant">&quot;enum&quot;</span><span class="synIdentifier"> &gt;</span> <span class="synIdentifier">&lt;EnumValue </span><span class="synType">value</span>=<span class="synConstant">&quot;jp&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;EnumValue </span><span class="synType">value</span>=<span class="synConstant">&quot;en&quot;</span><span class="synIdentifier"> /&gt;</span> <span class="synIdentifier">&lt;/UserPref&gt;</span> <span class="synIdentifier">&lt;Content </span><span class="synType">type</span>=<span class="synConstant">&quot;html&quot;</span><span class="synIdentifier">&gt;</span> <span class="synType">&lt;![</span><span class="synStatement">CDATA</span><span class="synType">[</span> <span class="synConstant"> &lt;div id=&quot;content_div_hatena&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;</span> <span class="synConstant"> &lt;/div&gt;</span> <span class="synConstant"> &lt;script type=&quot;text/javascript&quot;&gt;</span> <span class="synConstant"> function hatenaLoadHandler()</span> <span class="synConstant"> {</span> <span class="synConstant"> // constants</span> <span class="synConstant"> var languageTable = new Array();</span> <span class="synConstant"> languageTable['jp'] = &quot;このエントリーをはてなブックマークに追加&quot;;</span> <span class="synConstant"> languageTable['en'] = &quot;Add this entry to Hatena Book Mark&quot;;</span> <span class="synConstant"> </span> <span class="synConstant"> // params</span> <span class="synConstant"> var paramsOfA = new Array();</span> <span class="synConstant"> var prefs = new gadgets.Prefs();</span> <span class="synConstant"> var element = document.getElementById(&quot;content_div_hatena&quot;);</span> <span class="synConstant"> var isSimple = prefs.getBool(&quot;isSimple&quot;);</span> <span class="synConstant"> var sightAddress = prefs.getString(&quot;sightAddress&quot;);</span> <span class="synConstant"> var sightTitle = prefs.getString(&quot;sightTitle&quot;);</span> <span class="synConstant"> var counter = prefs.getString(&quot;counter&quot;);</span> <span class="synConstant"> var langMode = prefs.getString(&quot;langMode&quot;);</span> <span class="synConstant"> </span> <span class="synConstant"> paramsOfA.push('href=&quot;http://b.hatena.ne.jp/entry/' + sightAddress + '&quot; class=&quot;hatena-bookmark-button&quot;');</span> <span class="synConstant"> </span> <span class="synConstant"> if (sightTitle != &quot;&quot;) paramsOfA.push('data-hatena-bookmark-title=&quot;' + sightTitle + '&quot;');</span> <span class="synConstant"> </span> <span class="synConstant"> if (isSimple)</span> <span class="synConstant"> {</span> <span class="synConstant"> paramsOfA.push('data-hatena-bookmark-layout=&quot;' + (counter != 'none') ? 'simple' : 'simple-balloon' + '&quot;');</span> <span class="synConstant"> }</span> <span class="synConstant"> else</span> <span class="synConstant"> {</span> <span class="synConstant"> var layouts = { 'none' : 'standard-noballoon', 'display' : 'standard-balloon', 'display-vertical' : 'vertical-balloon' };</span> <span class="synConstant"> paramsOfA.push('data-hatena-bookmark-layout=&quot;' + layouts[counter] + '&quot;' );</span> <span class="synConstant"> paramsOfA.push('data-hatena-bookmark-lang=&quot;' + langMode + '&quot;');</span> <span class="synConstant"> }</span> <span class="synConstant"> </span> <span class="synConstant"> paramsOfA.push('title=&quot;' + languageTable[langMode] + '&quot;');</span> <span class="synConstant"> </span> <span class="synConstant"> var html = '&lt;a target=&quot;_blank&quot;' + paramsOfA.join(&quot; &quot;) + '&gt;&lt;img src=&quot;http://b.st-hatena.com/images/entry-button/button-only@2x.png&quot; alt=&quot;' + languageTable[langMode] + '&quot; width=&quot;20&quot; height=&quot;20&quot; style=&quot;border: none;&quot; /&gt;&lt;/a&gt;';</span> <span class="synConstant"> element.innerHTML = html;</span> <span class="synConstant"> }</span> <span class="synConstant"> gadgets.util.registerOnLoadHandler(hatenaLoadHandler);</span> <span class="synConstant"> &lt;/script&gt;</span> <span class="synConstant"> &lt;script type=&quot;text/javascript&quot; src=&quot;http://b.st-hatena.com/js/bookmark_button.js&quot; charset=&quot;utf-8&quot; async=&quot;async&quot;&gt;&lt;/script&gt;</span> <span class="synConstant"> </span><span class="synType">]]&gt;</span> <span class="synIdentifier">&lt;/Content&gt;</span> <span class="synIdentifier">&lt;/Module&gt;</span> </pre><p>そういう私もいい加減Tipsは<a class="keyword" href="http://d.hatena.ne.jp/keyword/github">github</a>に上げろと言われそう。</p> </div> tiri_tomato Readmeを書くことは良いことずくめなんじゃないか hatenablog://entry/8454420450077304105 2014-01-22T18:40:30+09:00 2014-12-17T12:53:27+09:00 意外とReadmeを書こうという記事を見たことがあんまり無いので書いてみます。Readmeの唯一の欠点は、「基本的にあまり読まれない」ことなんですが、でもそれ以外では良い事がたくさんあると思います。作る前から/作りながら書いても良いと思う。でも書いてみて初めてわかることばかりなので、自分の経験からメリットを書いてみます。 一つ。最初から最後の事を考えておくべきだ。 とりとめがなくなることを防ごう。リリースするためにプログラムを書いて、少なくとも最後にはReadmeを添えよう。ただの趣味ならいいけど。 一つ。ある程度の著作権知識も身につく フリーだとしても公開物は全てライセンスを考えておかなきゃ… <p>意外とReadmeを書こうという記事を見たことがあんまり無いので書いてみます。</p><p>Readmeの唯一の欠点は、「基本的にあまり読まれない」ことなんですが、でもそれ以外では良い事がたくさんあると思います。作る前から/作りながら書いても良いと思う。でも書いてみて初めてわかることばかりなので、自分の経験からメリットを書いてみます。</p> <div class="section"> <h5>一つ。最初から最後の事を考えておくべきだ。</h5> <p>とりとめがなくなることを防ごう。リリースするためにプログラムを書いて、少なくとも最後にはReadmeを添えよう。ただの趣味ならいいけど。</p> </div> <div class="section"> <h5>一つ。ある程度の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C3%F8%BA%EE%B8%A2">著作権</a>知識も身につく</h5> <p>フリーだとしても公開物は全てライセンスを考えておかなきゃいけない。Readmeに含めるかは微妙だけどどっちみち必要。コピペするにしても少しは読まなきゃいけないし、多少はググらなきゃいけない。実はそれだけでもけっこう知識が身につく。</p> </div> <div class="section"> <h5>一つ。<a class="keyword" href="http://d.hatena.ne.jp/keyword/YAGNI">YAGNI</a>の基準に出来る。</h5> <p>ある機能の拡張方針で悩んでいるとする。そんな時は、Readmeに使い方を書きやすいように設計しよう。落ち着いて操作手順を推敲したとする。Readmeはただのテキストだから詰め込める情報は結構少ないけど、それでもその制約下でうまく簡単に説明できない時は、そのア<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%C7%A5%A2">イデア</a>はちょっと<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%EC%A5%B2">アレゲ</a>な疑いがある(<a href="#f-d4650e33" name="fn-d4650e33" title="だいたいゼロベースの時はトップダウンでニーズを出してボトムアップで実装するんだけど、拡張を考える時はボトムアップ可能な範囲でトップダウンのうち拾えるところを拾う構図になる事が多くて、そうやってぼちぼち穴埋めしていくと、実装者としてはご満悦なんだけど、パッケージ全体としてはよくわからん感じになりやすい。そこをもう一度、「純粋なトップダウンの視点でまとまっているかどうか=Readmeに書けるかどうか」で考えてみると良い。ディレクターやコミッターにマイルストーン相談する前にある程度目星がつくと思う。">*1</a>)。</p> </div> <div class="section"> <h5>一つ。やむなくアレな仕様を採用せざるを得ないとして、被害を最小限にするため、詳しい使い道をプログラムの外の手順書や注意書きにしてしまう手もあるじゃない</h5> <p>たまに、アレな仕様だけどハードの制約とかで採用せざるを得ない場合。そのアレな追加仕様のせいでいろんなところに修正項目が大きく波及してしまうなら、ちっと考えてみて、もしそれがレアケースとかなら、何もボタン一個でプログラムが内部で全てファジーに対応するとか、専用の特殊モードが発動するような話ではなく、手順書に注意書きを目立つように、あるいは検索可能に残しておくだけで良かったりするんじゃないの?</p> </div> <div class="section"> <h5>一つ。エラーメッセージ一覧</h5> <p>きちんとしたプログラムはエラーに強い。エラー設計がきちんとされているなら、エラーメッセージ一覧を作るのもきっと簡単。そしてその一覧はユーザーにとってすごくありがたい。一方、エラー時のシナリオがボロボロなプログラムはエラーメッセージ一覧を作るのも大変だ。一覧がなければユーザーはマニュアルを自分でスミズミまで読み直す羽目になる。よくない。</p><p>他にもあるんじゃないかなと思いますが、とりあえずこんなところです。なんかすんごい泥臭い話になっちゃったな…</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-d4650e33" name="f-d4650e33" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">だいたいゼロベースの時は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%C3%A5%D7%A5%C0%A5%A6%A5%F3">トップダウン</a>でニーズを出して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DC%A5%C8%A5%E0%A5%A2%A5%C3%A5%D7">ボトムアップ</a>で実装するんだけど、拡張を考える時は<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DC%A5%C8%A5%E0%A5%A2%A5%C3%A5%D7">ボトムアップ</a>可能な範囲で<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%C3%A5%D7%A5%C0%A5%A6%A5%F3">トップダウン</a>のうち拾えるところを拾う構図になる事が多くて、そうやってぼちぼち穴埋めしていくと、実装者としてはご満悦なんだけど、パッケージ全体としてはよくわからん感じになりやすい。そこをもう一度、「純粋な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C8%A5%C3%A5%D7%A5%C0%A5%A6%A5%F3">トップダウン</a>の視点でまとまっているかどうか=Readmeに書けるかどうか」で考えてみると良い。ディレクターやコミッターに<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%EB%A5%B9%A5%C8%A1%BC%A5%F3">マイルストーン</a>相談する前にある程度目星がつくと思う。</span></p> </div> tiri_tomato エディタ専用のリソースロード関数 hatenablog://entry/8454420450077304112 2014-01-05T19:29:39+09:00 2014-12-17T12:53:28+09:00 AssetDatabase.LoadAssetAtPath()がResources.Load()と違って、プロジェクトのルートパスからの相対パスを完全に指定しなきゃいけないとなると、Editorフォルダに突っ込んで非ビルド用(≒エディタ専用)リソースにしようと思ったらEditorフォルダの親フォルダをちょっと動かしただけでも破綻しちゃうから困ったな。 正月早々しょうもないTipsを貼って遊びます。Reources.Load()ではEditorフォルダにアクセスできないし、AssetDatabase.LoadAssetAtPath()は曖昧検索しません。つまり、"Editor/Sample.pn… <div class="section"> <h4>AssetDatabase.LoadAssetAtPath()がResources.Load()と違って、プロジェクトのルートパスからの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C1%EA%C2%D0%A5%D1%A5%B9">相対パス</a>を完全に指定しなきゃいけないとなると、Editorフォルダに突っ込んで非ビルド用(≒エディタ専用)リソースにしようと思ったらEditorフォルダの親フォルダをちょっと動かしただけでも破綻しちゃうから困ったな。</h4> <p>正月早々しょうもないTipsを貼って遊びます。</p><p>Reources.Load()ではEditorフォルダにアクセスできないし、AssetDatabase.LoadAssetAtPath()は曖昧検索しません。つまり、"Editor/Sample.<a class="keyword" href="http://d.hatena.ne.jp/keyword/png">png</a>"は"MyAsset/Editor/Sample.<a class="keyword" href="http://d.hatena.ne.jp/keyword/png">png</a>"に引っ越す事が出来ません(いや、引越しのたびに文字列定数を書き換えれば別ですが、いくらなんでもアレすぎ)。ので、AssetDatabase版のあいまい検索を自作。</p><p>AssetDataBase使うのでEditorフォルダの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>に書いてください。</p> <div class="section"> <h5>使い方</h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synComment">// 第二引数は検索から除外したいフォルダ名だよ!</span> System.Collections.Generic.List&lt;System.String&gt; paths = AssetDatabaseFindPaths(<span class="synConstant">&quot;アセット名とか/Editor/EditorOnlyTexture.png&quot;</span>, <span class="synConstant">&quot;Resources&quot;</span>); Texture2D tex = AssetDatabase.LoadAssetAtPath(paths[<span class="synConstant">0</span>], <span class="synStatement">typeof</span>(Texture2D)) <span class="synStatement">as</span> Texture2D; </pre> </div> <div class="section"> <h5>実装</h5> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synStatement">using</span> UnityEngine; <span class="synStatement">using</span> UnityEditor; <span class="synType">public</span> <span class="synType">static</span> System.Collections.Generic.List&lt;System.String&gt; AssetDatabaseFindPaths(System.String path, <span class="synStatement">params</span> System.String[] exclude_directories) { <span class="synStatement">if</span> (exclude_directories == <span class="synConstant">null</span>) exclude_directories = <span class="synStatement">new</span> <span class="synType">string</span>[] {}; System.Collections.Generic.List&lt;System.String&gt; ex_dirs = <span class="synStatement">new</span> System.Collections.Generic.List&lt;<span class="synType">string</span>&gt;(exclude_directories.Length); <span class="synStatement">foreach</span> (System.String exclude_directory <span class="synStatement">in</span> exclude_directories) { System.String ex_dir = exclude_directory.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); ex_dir = ex_dir.Trim(System.IO.Path.AltDirectorySeparatorChar); <span class="synStatement">if</span> (System.String.IsNullOrEmpty(ex_dir)) <span class="synStatement">continue</span>; ex_dirs.Add(System.IO.Path.AltDirectorySeparatorChar + ex_dir + System.IO.Path.AltDirectorySeparatorChar); } System.Collections.Generic.List&lt;System.String&gt; finds = <span class="synStatement">new</span> System.Collections.Generic.List&lt;<span class="synType">string</span>&gt;(); <span class="synStatement">if</span> (<span class="synConstant">0</span> &lt; path.Length) { path = path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); <span class="synStatement">if</span> (path[<span class="synConstant">0</span>] != System.IO.Path.AltDirectorySeparatorChar) path = System.IO.Path.AltDirectorySeparatorChar + path; System.String[] sources = AssetDatabase.GetAllAssetPaths(); <span class="synStatement">foreach</span> (System.String src <span class="synStatement">in</span> sources) { System.String formatted_src = System.IO.Path.AltDirectorySeparatorChar + src.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); <span class="synStatement">if</span> (formatted_src.EndsWith(path, System.StringComparison.OrdinalIgnoreCase)) { <span class="synType">bool</span> isExclude = <span class="synConstant">false</span>; <span class="synStatement">foreach</span> (System.String ex_dir <span class="synStatement">in</span> ex_dirs) { <span class="synStatement">if</span> (isExclude = (-<span class="synConstant">1</span> &lt; src.IndexOf(ex_dir, System.StringComparison.OrdinalIgnoreCase))) <span class="synStatement">break</span>; } <span class="synStatement">if</span> (isExclude == <span class="synConstant">false</span>) finds.Add(src); } } <span class="synComment">// directory depth sort, and dictionary sort.</span> finds.Sort((left, right) =&gt; { <span class="synType">int</span> leftDepth = <span class="synConstant">0</span>, rightDepth = <span class="synConstant">0</span>; <span class="synStatement">foreach</span> (System.Char ch <span class="synStatement">in</span> left) <span class="synStatement">if</span> (ch == System.IO.Path.AltDirectorySeparatorChar) leftDepth++; <span class="synStatement">foreach</span> (System.Char ch <span class="synStatement">in</span> right) <span class="synStatement">if</span> (ch == System.IO.Path.AltDirectorySeparatorChar) rightDepth++; <span class="synType">int</span> ret = leftDepth.CompareTo(rightDepth); <span class="synStatement">if</span> (ret == <span class="synConstant">0</span>) ret = System.String.Compare(left, right); <span class="synStatement">return</span> ret; }); } <span class="synStatement">return</span> finds; } </pre><p>これでアセット名をつけたフォルダ配下のEditorフォルダに画像を置いて、エディタからロードできます。というかテクスチャのインポート設定にExcludeOnBuildフラグみたいなの欲しいです。今年もよろしくウマー。</p> </div> </div> tiri_tomato 誤差を抑えてパーセント小数値を入力するテキストフィールド hatenablog://entry/8454420450077304114 2013-12-30T09:11:25+09:00 2014-12-17T12:53:31+09:00 そういやdecimalとかあったね!(ブクマを参照のこと) テキストフィールドでfloatをパーセント入出力させる方法。浮動小数点って適当に100倍して100で割ると、わりと誤差が出ちゃうんですね。 例) 99.9 % と入力したら 99.899999999 % と表示される、などdoubleで逃げられないかと思いきや案外難しく、どうしたものか*1と見送っていたんですが、はてなでブクマした記事を読んでdecimalの存在を思い出しました。c#にはdecimalあるジャン! private static System.Text.RegularExpressions.Regex regexPerc… <div class="section"> <h4>そういやdecimalとかあったね!(ブクマを参照のこと)</h4> <p>テキストフィールドでfloatをパーセント入出力させる方法。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C9%E2%C6%B0%BE%AE%BF%F4">浮動小数</a>点って適当に100倍して100で割ると、わりと誤差が出ちゃうんですね。<br /> 例) 99.9 % と入力したら 99.899999999 % と表示される、など</p><p>doubleで逃げられないかと思いきや案外難しく、どうしたものか<a href="#f-6ead5651" name="fn-6ead5651" title="固定小数点と文字列の相互変換の手作りとか面倒くさいよなー、と">*1</a>と見送っていたんですが、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A4%CF%A4%C6%A4%CA">はてな</a>でブクマした記事を読んでdecimalの存在を思い出しました。<a class="keyword" href="http://d.hatena.ne.jp/keyword/c%23">c#</a>にはdecimalあるジャン!</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synType">private</span> <span class="synType">static</span> System.Text.RegularExpressions.Regex regexPercentTextPerser = <span class="synStatement">new</span> System.Text.RegularExpressions.Regex(<span class="synConstant">&quot;[</span><span class="synSpecial">\\</span><span class="synConstant">+</span><span class="synSpecial">\\</span><span class="synConstant">-]?(([0-9]*</span><span class="synSpecial">\\</span><span class="synConstant">s*</span><span class="synSpecial">\\</span><span class="synConstant">.</span><span class="synSpecial">\\</span><span class="synConstant">s*[0-9]+)|([0-9]+))&quot;</span>, System.Text.RegularExpressions.RegexOptions.Compiled | System.Text.RegularExpressions.RegexOptions.Singleline); <span class="synType">public</span> <span class="synType">static</span> <span class="synType">float</span> PercentField(Rect position, GUIContent label, <span class="synType">float</span> <span class="synStatement">value</span>) { System.String formattedText = System.Math.Round(((<span class="synType">decimal</span>)<span class="synStatement">value</span> * <span class="synConstant">100</span>), <span class="synConstant">6</span>).ToString(); <span class="synStatement">if</span> (<span class="synConstant">0</span> &lt;= formattedText.IndexOf(<span class="synConstant">'.'</span>)) formattedText = (formattedText.TrimEnd(<span class="synStatement">new</span> <span class="synType">char</span>[] { <span class="synConstant">'0'</span> })).TrimEnd(<span class="synStatement">new</span> <span class="synType">char</span>[] { <span class="synConstant">'.'</span> }); System.String getText = EditorGUI.TextField(position, label, formattedText + <span class="synConstant">&quot; %&quot;</span>); <span class="synType">decimal</span> decimalValue = <span class="synConstant">0</span>; <span class="synStatement">if</span> (<span class="synType">decimal</span>.TryParse(regexPercentTextPerser.Match(getText).Value.Trim(), <span class="synStatement">out</span> decimalValue)) decimalValue /= <span class="synConstant">100</span>; <span class="synStatement">return</span> (<span class="synType">float</span>)decimalValue; } </pre><p>ここではRound(decimal)使って6桁でファジーにまるめています(近いほうに丸める、あまり二進数的でない人間的な丸め<a href="#f-b25d86b1" name="fn-b25d86b1" title="ちなみに6桁は適当な数値です。これ以上長く表示されてもウザいかなと。">*2</a>)。不必要な小数点とゼロ表示も切除します。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C0%B5%B5%AC%C9%BD%B8%BD">正規表現</a>はわりと適当。ややこしいから空白判定のところ無くても良いかな?</p><p><span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20131230085527" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20131230/20131230085527.jpg" alt="f:id:tiri_tomato:20131230085527j:image:left" title="f:id:tiri_tomato:20131230085527j:image:left" class="hatena-fotolife hatena-image-left" itemprop="image"></a></span>DBやらないせいかdecimalは忘れてしまいます。<a class="keyword" href="http://d.hatena.ne.jp/keyword/Access">Access</a>/ExcelVBAが流入してるんだから、.Netはdecimal完備してるっちゃそうなんですね。そうかそうかdecimalって幾何演算でもUIのコーディングに使えるのか。<br clear="all"/>そういや<a class="keyword" href="http://d.hatena.ne.jp/keyword/c%2B%2B">c++</a>ってdecimalあったっけ???で思い出したんですが、<a href="http://en.cppreference.com/w/cpp/numeric/math/floor">cppreference.com&#x306E;Floor()&#x95A2;&#x6570;&#x306E;&#x30DA;&#x30FC;&#x30B8;</a>って、この↓<br /> <img src="http://upload.cppreference.com/mwiki/images/7/72/math-floor.svg"/>説明図を置いてくれるところが大好きです。ものすごく分かりやすい。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-6ead5651" name="f-6ead5651" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">固定小数点と文字列の相互変換の手作りとか面倒くさいよなー、と</span></p> <p class="footnote"><a href="#fn-b25d86b1" name="f-b25d86b1" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">ちなみに6桁は適当な数値です。これ以上長く表示されてもウザいかなと。</span></p> </div> tiri_tomato TextureFormatごとにコンストラクトとGetPixelとSetPixelを総当りしてみた hatenablog://entry/8454420450077304118 2013-12-29T07:58:14+09:00 2014-12-17T12:53:33+09:00 テストコード 場合によっては普通にキャッチできない例外をはくため、ひたすら「やってみる>例外吐くなら吐かせる」を繰り返します。コンソール荒れますw [ContextMenu("test")] private void test() { foreach(TextureFormat format in System.Enum.GetValues(typeof(TextureFormat))) { Texture2D tex = null; try { Debug.Log("try create:" + format.ToString()); tex = new Texture2D(1, 1, fo… <div class="section"> <h5>テストコード</h5> <p>場合によっては普通にキャッチできない例外をはくため、ひたすら「やってみる>例外吐くなら吐かせる」を繰り返します。コンソール荒れますw</p> <pre class="code lang-cs" data-lang="cs" data-unlink>[ContextMenu(<span class="synConstant">&quot;test&quot;</span>)] <span class="synType">private</span> <span class="synType">void</span> test() { <span class="synStatement">foreach</span>(TextureFormat format <span class="synStatement">in</span> System.Enum.GetValues(<span class="synStatement">typeof</span>(TextureFormat))) { Texture2D tex = <span class="synConstant">null</span>; <span class="synStatement">try</span> { Debug.Log(<span class="synConstant">&quot;try create:&quot;</span> + format.ToString()); tex = <span class="synStatement">new</span> Texture2D(<span class="synConstant">1</span>, <span class="synConstant">1</span>, format, <span class="synConstant">false</span>); Debug.Log(<span class="synConstant">&quot;try get pixel:&quot;</span> + format.ToString()); tex.GetPixel(<span class="synConstant">0</span>, <span class="synConstant">0</span>); Debug.Log(<span class="synConstant">&quot;try set pixel:&quot;</span> + format.ToString()); tex.SetPixel(<span class="synConstant">0</span>, <span class="synConstant">0</span>, <span class="synStatement">new</span> Color()); } <span class="synStatement">finally</span> { <span class="synStatement">if</span> (tex != <span class="synConstant">null</span>) DestroyImmediate(tex); } } } </pre><p>やってみた結果をまとめますと</p> <blockquote> <p>TextureFormat test targets.<br /> Alpha8<br /> ARGB4444<br /> RGB24<br /> RGBA32<br /> ARGB32<br /> RGB565<br /> DXT1<br /> DXT5<br /> RGBA4444<br /> PVRTC_RGB2<br /> PVRTC_RGB2<br /> PVRTC_RGBA2<br /> PVRTC_RGBA2<br /> PVRTC_4BPP_<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a><br /> PVRTC_4BPP_<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a><br /> PVRTC_RGBA4<br /> PVRTC_RGBA4<br /> ETC_RGB4<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/ATC">ATC</a>_RGB4<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/ATC">ATC</a>_RGBA8<br /> BGRA32<br /> ATF_<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a>_DXT1<br /> ATF_RGBA_JPG<br /> ATF_<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a>_JPG</p> </blockquote> <p>以上の対象にnewとGetPixel()とSetPixel()を繰り返すと、</p> </div> <div class="section"> <h5>new Texture2D に失敗するもの</h5> <ul> <li>ATF_<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a>_DXT1</li> </ul> <blockquote> <p>Invalid <a class="keyword" href="http://d.hatena.ne.jp/keyword/Flash">Flash</a> texture<br /> UnityEngine.Texture2D:.ctor(Int32, Int32, TextureFormat, Boolean)</p> </blockquote> <p>(コンストラクト例外?何が起こっているのやら本日一番のミステリー)</p> </div> <div class="section"> <h5>GetPixel() に失敗するもの</h5> <ul> <li>PVRTC_RGB2</li> </ul> <blockquote> <p>Unsupported texture format - needs to be ARGB32, RGBA32, BGRA32, RGB24, Alpha8 or DXT<br /> UnityEngine.Texture2D:GetPixel(Int32, Int32)</p> </blockquote> </div> <div class="section"> <h5>SetPixel() に失敗するもの</h5> <ul> <li>ARGB4444</li> </ul> <blockquote> <p>Unsupported texture format - needs to be ARGB32, RGBA32, RGB24 or Alpha8<br /> UnityEngine.Texture2D:SetPixel(Int32, Int32, Color)</p> </blockquote> <p>ドキュメントにはあまり詳しく書いてませんが、結構いろいろイケますね。<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D3%A5%C7%A5%AA%A5%AB%A1%BC%A5%C9">ビデオカード</a>とドライバにもよるのかも。</p><p>まぁ、でもやっぱりログに表示されている通りROMなら"ARGB32, RGBA32, BGRA32, RGB24, Alpha8 or DXT"、RAMなら" ARGB32, RGBA32, RGB24 or Alpha8"というのが安牌でしょうか。</p> </div> tiri_tomato 年末年始の自作系男子のあわせ買いにドライバーとかいかがでしょう hatenablog://entry/8454420450077304124 2013-12-28T10:16:37+09:00 2014-12-17T12:53:35+09:00 先日、玄関のドアクローザーの油圧ダンパーが抜けきっていたのを手前で交換したのですが、当然10年を軽く超える年代モノなので古いネジが固着しており、あわやナメきる直前までっ!あっ!?あばっ!あばばばばば!(*1) ボスケテAmazonサーン! アネックス(ANEX) ネジすべり止め液 No.40出版社/メーカー: 兼古製作所メディア: Tools & Hardware購入: 6人 クリック: 51回この商品を含むブログ (4件) を見るアネックス(ANEX) ビスブレーカードライバー +1x75 No.3960出版社/メーカー: 兼古製作所メディア: Tools & Hardware クリック: … <p>先日、玄関の<a href="http://ja.wikipedia.org/wiki/%E3%83%89%E3%82%A2%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B6">&#x30C9;&#x30A2;&#x30AF;&#x30ED;&#x30FC;&#x30B6;&#x30FC;</a>の油圧ダンパーが抜けきっていたのを手前で交換したのですが、当然10年を軽く超える年代モノなので古いネジが固着しており、あわやナメきる直前までっ!あっ!?あばっ!あばばばばば!(<a href="#f-55b3055a" name="fn-55b3055a" title="家族の衆目の手前つとめて冷静に対処しましたが、本当は内心大変に焦りました。原付の外装ネジとかならともかく、家のネジ穴なんて詰まったら大事だ!とくにウチの玄関扉は重すぎて、ドアクローザーもホームセンターにはない専用品。固定もキッチリしておきたいところ。">*1</a>)</p> <div class="section"> <h4><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DC%A5%B9%A5%B1%A5%C6">ボスケテ</a><a class="keyword" href="http://d.hatena.ne.jp/keyword/Amazon">Amazon</a>サーン!</h4> <p><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016VCIP2/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/41eJfTlCksL._SL160_.jpg" class="hatena-asin-detail-image" alt="アネックス(ANEX) ネジすべり止め液 No.40" title="アネックス(ANEX) ネジすべり止め液 No.40"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016VCIP2/assoctiritoma-22/">アネックス(ANEX) ネジすべり止め液 No.40</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> 兼古製作所</li><li><span class="hatena-asin-detail-label">メディア:</span> Tools & Hardware</li><li><span class="hatena-asin-detail-label">購入</span>: 6人 <span class="hatena-asin-detail-label">クリック</span>: 51回</li><li><a href="http://d.hatena.ne.jp/asin/B0016VCIP2/assoctiritoma-22" target="_blank">この商品を含むブログ (4件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div><div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016VE28S/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/319eiEQUqAL._SL160_.jpg" class="hatena-asin-detail-image" alt="アネックス(ANEX) ビスブレーカードライバー +1x75 No.3960" title="アネックス(ANEX) ビスブレーカードライバー +1x75 No.3960"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0016VE28S/assoctiritoma-22/">アネックス(ANEX) ビスブレーカードライバー +1x75 No.3960</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> 兼古製作所</li><li><span class="hatena-asin-detail-label">メディア:</span> Tools & Hardware</li><li> <span class="hatena-asin-detail-label">クリック</span>: 1回</li><li><a href="http://d.hatena.ne.jp/asin/B0016VE28S/assoctiritoma-22" target="_blank">この商品を含むブログ (1件) を見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>コレでなんとか助かりました。以前は自動車のウィンカーカバーで完全にやらかした事があり、ディーラーさんでドリルしてもらった事があります。その経験があるせいか今回は「あ、コレはいかんな!イカンパターンだぞよ!」と、なんとか思いとどまることが出来ました。この魔法のお薬が到着して問題のネジが回った瞬間、玄関中に「バキッ!」とスゲー音が響きましたよ。</p><p>こういう事って結構あるので、自作系男子なら事態に直面する前に「駐車料金あわせ」とか「送料無料化あわせ」に買っておくと吉かと思います。あ、優先度で言えば、滑り止め剤がまず重要です。この<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%D3%C4%CC%A5%C9%A5%E9%A5%A4%A5%D0%A1%BC">貫通ドライバー</a>は使ってみたものの、何百円かのただのアクリルグリップのベッセルでも充分と言えば充分そうだなと思いました(<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%D3%C4%CC%A5%C9%A5%E9%A5%A4%A5%D0%A1%BC">貫通ドライバー</a>もガンガン使えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B6%E2%C2%B0%C8%E8%CF%AB">金属疲労</a>で丸まっちゃうし、ベッセルの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%B9%A5%D1">コスパ</a>が頭一つ抜けてるのは成熟度も流通量も違うのでしょうがない)。ただこの<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B4%D3%C4%CC%A5%C9%A5%E9%A5%A4%A5%D0%A1%BC">貫通ドライバー</a>、個性的な見た目ですが意外と握り心地はしっくりきます。いかにもコレが好きな人は居そう。</p> </div> <div class="section"> <h4>そう言えば、ドライバービットもわりと折れる</h4> <p>よく2-3000円の工具セットとか、「メーカーのよくわかんないドライバーとかドライバービットセット」がよく入ってますね。で、とくにビットセットですが、安物だと冗談のように欠けたり折れたりネジれたりします。(例えば自転車のメンテ程度でも、マイナスドライバーが折れたりトルクスが欠けたりするんですよ<a href="#f-23c580f9" name="fn-23c580f9" title="今回の件で言えば、固着したネジとの格闘中にマイナスドライバーが折れて飛びました。安ドライバーを全力で押し付けながら、ドライバーのグリップをパイプレンチではさんでハンドル式で回す事により強引に回そうとしたら、ドライバーが固着ネジに負けて先端がボキッと。それで「あ、これアカン奴や」と。個人的にはこのように、何かの拍子で入手してしまう安ドライバーは、パテや接着剤のヘラにしてみたり事ある毎に積極的に人身御供にして消費しきってしまうようにしています。">*2</a>)。あんまりやらないほうが良いんですが、電動<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%D1%A5%AF">インパク</a>トとかラチェットハンドルで回す事もあるので、わりと普通のドライバーよりも強烈なネジリ負荷にさらされるんですよね。なのでビットも、少なくともビット一個あたりせめて100円くらいに置換しておきましょう。これくらいなら無茶な使い方をしても、「絶対死ぬ」が「結構死なない」まではレベルアップします。<div class="hatena-asin-detail"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B001VB8AI6/assoctiritoma-22/"><img src="http://ecx.images-amazon.com/images/I/51M%2BfzdaaWL._SL160_.jpg" class="hatena-asin-detail-image" alt="VESSEL(ベッセル) 交換用ビットセット トルクス TD-BS3" title="VESSEL(ベッセル) 交換用ビットセット トルクス TD-BS3"></a><div class="hatena-asin-detail-info"><p class="hatena-asin-detail-title"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B001VB8AI6/assoctiritoma-22/">VESSEL(ベッセル) 交換用ビットセット トルクス TD-BS3</a></p><ul><li><span class="hatena-asin-detail-label">出版社/メーカー:</span> Vessel(ベッセル)</li><li><span class="hatena-asin-detail-label">メディア:</span> Tools & Hardware</li><li><a href="http://d.hatena.ne.jp/asin/B001VB8AI6/assoctiritoma-22" target="_blank">この商品を含むブログを見る</a></li></ul></div><div class="hatena-asin-detail-foot"></div></div>あ、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%AC%A5%CD%A5%EC%A5%F3%A5%C1">メガネレンチ</a>とかはそんなに精度要らないから<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%BD%A1%BC">ダイソー</a>とか適当な安いのでも良いかも(高級なものをメンテしたければトルクレンチが欲しいとかあるかもしれませんが…)。それよりはモンキーとか可動部が多い奴は案外ガタがきやすいので、これはちょい高めのヘビー風がオススメです。とくに車バイク系で固着ボルトを相手にしたりすると、グリップをゴムハンマでドツいたりすることもありますから、そういう事をしてもガタが来ないモンキーは使いやすい気がします。</p> </div><div class="footnote"> <p class="footnote"><a href="#fn-55b3055a" name="f-55b3055a" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">家族の衆目の手前つとめて冷静に対処しましたが、本当は内心大変に焦りました。原付の外装ネジとかならともかく、家のネジ穴なんて詰まったら大事だ!とくにウチの玄関扉は重すぎて、ドアクローザーもホームセンターにはない専用品。固定もキッチリしておきたいところ。</span></p> <p class="footnote"><a href="#fn-23c580f9" name="f-23c580f9" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">今回の件で言えば、固着したネジとの格闘中にマイナスドライバーが折れて飛びました。安ドライバーを全力で押し付けながら、ドライバーのグリップをパイプレンチではさんでハンドル式で回す事により強引に回そうとしたら、ドライバーが固着ネジに負けて先端がボキッと。それで「あ、これアカン奴や」と。個人的にはこのように、何かの拍子で入手してしまう安ドライバーは、パテや接着剤のヘラにしてみたり事ある毎に積極的に人身御供にして消費しきってしまうようにしています。</span></p> </div> tiri_tomato エディタカスタマイズで押せないボタンを描く hatenablog://entry/8454420450077304129 2013-12-26T16:18:35+09:00 2014-12-17T12:53:38+09:00 もっとちゃんとした関数がありました。下記に記事を追加。 http://d.hatena.ne.jp/tiri_tomato/20140318/1395104788こちらの古い記事は、EditorGUI名前空間が使えない状況では一応使えるかな、ということで残しておきます。 淡色モードが案外サポートされてないので、勝手に作れって事でしょうか。 // 淡色表示用のスタイルを返す public static GUIStyle DimmedStyle(GUIStyle src) { GUIStyle dimmed = new GUIStyle(src); GUIStyleState[] styleSta… <blockquote> <p>もっとちゃんとした関数がありました。下記に記事を追加。<br /> <a href="http://d.hatena.ne.jp/tiri_tomato/20140318/1395104788">http://d.hatena.ne.jp/tiri_tomato/20140318/1395104788</a></p><p>こちらの古い記事は、EditorGUI<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>が使えない状況では一応使えるかな、ということで残しておきます。</p> </blockquote> <p>淡色モードが案外サポートされてないので、勝手に作れって事でしょうか。</p> <pre class="code lang-cs" data-lang="cs" data-unlink><span class="synComment">// 淡色表示用のスタイルを返す</span> <span class="synType">public</span> <span class="synType">static</span> GUIStyle DimmedStyle(GUIStyle src) { GUIStyle dimmed = <span class="synStatement">new</span> GUIStyle(src); GUIStyleState[] styleStates = <span class="synStatement">new</span> GUIStyleState[] { dimmed.normal, dimmed.active, dimmed.focused, dimmed.hover, dimmed.onActive, dimmed.onFocused, dimmed.onHover, dimmed.onNormal }; <span class="synStatement">foreach</span> (GUIStyleState state <span class="synStatement">in</span> styleStates) { <span class="synStatement">if</span> (state != <span class="synConstant">null</span>) { Color color = state.textColor; <span class="synStatement">if</span> (<span class="synType">float</span>.Epsilon &lt;= color.a) { color.a *= <span class="synConstant">0.25f</span>; state.textColor = color; } } } <span class="synStatement">return</span> dimmed; } </pre><p>これでEditorStyles.miniButtonとDimmedStyle(EditorStyles.miniButton)を描いてみるとこんな感じ。淡色ボタンの方は押せる必要は無いのでラベルとして<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>。<br /> <span itemscope itemtype="http://schema.org/Photograph"><a href="http://f.hatena.ne.jp/tiri_tomato/20131226161356" class="hatena-fotolife" itemprop="url"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/tiri_tomato/20131226/20131226161356.png" alt="f:id:tiri_tomato:20131226161356p:image" title="f:id:tiri_tomato:20131226161356p:image" class="hatena-fotolife" itemprop="image"></a></span></p> <pre class="code lang-cs" data-lang="cs" data-unlink>EditorGUILayout.BeginHorizontal(); GUILayout.Button(<span class="synConstant">&quot;miniButton&quot;</span>, EditorStyles.miniButton); GUILayout.Label(<span class="synConstant">&quot;dimmedButton&quot;</span>, DimmedStyle(EditorStyles.miniButton)); EditorGUILayout.EndHorizontal(); </pre><p>エディタ用の<a class="keyword" href="http://d.hatena.ne.jp/keyword/GUI">GUI</a>って「驚き最小の原則」があるので、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%B0%A5%E9%A5%DE">プログラマ</a>の実装に任せるのでは無く、出来れば画一的な<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>とかUnity側にあればうれしいんですが。</p> tiri_tomato System.Enum比較する時はCompareTo() hatenablog://entry/8454420450077304133 2013-12-24T18:38:53+09:00 2014-12-17T12:53:40+09:00 いやぁまぁ表題の通りなんですが、System.Enumと言えばEnum用に型と値を格納するコンテナクラスですね。ジェネリック化の難しいEnumをどうにかこうにか近い形に持って行ってくれるそれなりに便利なクラスですが、Nullableとかと違って比較演算子とかはオーバーライドされていないのでEquals()とかCompareTo()のメソッドを使わないと、System.Object.ReferenceEquals()が返ってきちまうぜ!ちょっとビックリしたぜ!…。あー、intなEnumがあったとして「int上は同値だけど素のintとEnumなintとの比較で一致させるかどうか」って話かなもしかし… <p>いやぁまぁ表題の通りなんですが、System.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Enum">Enum</a>と言えば<a class="keyword" href="http://d.hatena.ne.jp/keyword/Enum">Enum</a>用に型と値を格納するコンテナクラスですね。</p><p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B8%A5%A7%A5%CD%A5%EA%A5%C3%A5%AF">ジェネリック</a>化の難しい<a class="keyword" href="http://d.hatena.ne.jp/keyword/Enum">Enum</a>をどうにかこうにか近い形に持って行ってくれるそれなりに便利なクラスですが、Nullableとかと違って比較<a class="keyword" href="http://d.hatena.ne.jp/keyword/%B1%E9%BB%BB%BB%D2">演算子</a>とかはオーバーライドされていないのでEquals()とかCompareTo()の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%E1%A5%BD%A5%C3%A5%C9">メソッド</a>を使わないと、System.Object.ReferenceEquals()が返ってきちまうぜ!ちょっとビックリしたぜ!</p><p>…。</p><p>あー、intな<a class="keyword" href="http://d.hatena.ne.jp/keyword/Enum">Enum</a>があったとして「int上は同値だけど素のintと<a class="keyword" href="http://d.hatena.ne.jp/keyword/Enum">Enum</a>なintとの比較で一致させるかどうか」って話かなもしかして?いやそら安全のために型明示が常識なんだから型が厳密に一致しないなら不一致でええんでないの?(というかキャストしないと比較できない扱いでいいと思う)</p><p>ひとり焼肉がひとり筋肉に見えたので今日は早く寝ます!</p> tiri_tomato Unity、DirectX環境でのNormalMapの内部的なフォーマットお勉強 hatenablog://entry/8454420450077304137 2013-12-22T15:40:42+09:00 2015-05-09T13:11:06+09:00 スクリプトからメモリ上のTexture2DにSetPixelsを行って法線マップ画像を生成し、NormalDiffuseシェーダーのNormalMapとして設定したい時にちょっとひっかかったので、そのお話。基本的にUnityではGL系で一般的なNormalmapの形式(チャンネルの割り振りがRGBA=XYZW)に対応していますが、一度NormalmapとしてTextureをインポートしてしまうと、内部的には環境依存で暗黙のフォーマット変換を受けているケースがあります。 DXT5nmというフォーマットに変換されるかも Creating runtime normal maps using rend… <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>からメモリ上のTexture2DにSetPixelsを行って法線マップ画像を生成し、NormalDiffuseシェーダーのNormalMapとして設定したい時にちょっとひっかかったので、そのお話。</p><p>基本的にUnityではGL系で一般的なNormalmapの形式(チャンネルの割り振りがRGBA=XYZW)に対応していますが、一度NormalmapとしてTextureをインポートしてしまうと、内部的には環境依存で暗黙のフォーマット変換を受けているケースがあります。</p> <div class="section"> <h4>DXT5nmというフォーマットに変換されるかも</h4> <p><a href="http://forum.unity3d.com/threads/135841-Creating-runtime-normal-maps-using-renderToTexture"> Creating runtime normal maps using renderToTexture</a><br /> <a href="http://forum.unity3d.com/threads/101163-UnpackNormal%28fixed4-packednormal%29-role"> UnpackNormal(fixed4 packednormal) role ?</a><br /> ウチの<a class="keyword" href="http://d.hatena.ne.jp/keyword/Radeon">Radeon</a>挿したWin機では変換されてました。DXT5nはGA(緑と赤、軸で言えばYとW)要素だけのフォーマット(法線マップで重要じゃない要素を切ってメモリサイズを節約し、レンダする時にシェーダ上で復元するつもりの形式)。なお、</p> <ul> <li>NormalMapとして画像ファイルからインポートされる時、勝手に変換されている</li> </ul><p>というわけで、NormalmapとしてインポートされたテクスチャをDX環境でTexture2D.GetPixels()して<a class="keyword" href="http://d.hatena.ne.jp/keyword/PNG">PNG</a>に保存してみると、RGBA=YYYXでロードされているのが分かり、確かにZW要素が消えている結果になります(<a href="#f-4f19294c" name="fn-4f19294c" title="GetPixels()したあと、Aを1で埋めて色要素だけにした画像1、それとAをRGBに転写してAを1で埋めたA-Channelだけにした画像2をEncodeToPNG()して、それぞれ適当なファイルに書き出してみると、画像1が縦方向要素だけのグレースケールグラデーション、画像2が横方向だけのグレースケールグラデーションになり、XY要素しか残ってない状態に変換されている事が分かります。formatメンバは、DXTは定義されていないためか、ARGB32で返ってきましたw">*1</a>)。コレ自体は「あぁ、そりゃそうした方が効率イイネ」という感じですが、問題になるのはNormalDiffuseシェーダのテクスチャサンプリング計算です。Unityからは<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB">コンパイル</a>済みシェーダーしか読めないので、<a href="http://japan.unity3d.com/unity/download/archive">&#x30D3;&#x30EB;&#x30C8;&#x30A4;&#x30F3;&#x30B7;&#x30A7;&#x30FC;&#x30C0;&#x30FC;</a>落としてきてチェックしますと、</p> <div class="section"> <h5>NormalBumped.shader (Normal Dffuseシェーダ)</h5> <p>サンプリング時にマクロ処理が通されています。</p> <pre class="code lang-c" data-lang="c" data-unlink>o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); </pre> </div> <div class="section"> <h5>UnityCG.cginc</h5> <p>マクロ処理の実装は以下。</p> <pre class="code lang-c" data-lang="c" data-unlink><span class="synType">inline</span> fixed3 UnpackNormalDXT5nm (fixed4 packednormal) { fixed3 normal; normal.xy = packednormal.wy * <span class="synConstant">2</span> - <span class="synConstant">1</span>; <span class="synPreProc">#if defined(SHADER_API_FLASH)</span> <span class="synComment">// Flash does not have efficient saturate(), and dot() seems to require an extra register.</span> normal.z = sqrt(<span class="synConstant">1</span> - normal.x*normal.x - normal.y*normal.y); <span class="synPreProc">#else</span> normal.z = sqrt(<span class="synConstant">1</span> - saturate(dot(normal.xy, normal.xy))); <span class="synPreProc">#endif</span> <span class="synStatement">return</span> normal; } <span class="synType">inline</span> fixed3 UnpackNormal(fixed4 packednormal) { <span class="synPreProc">#if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)) &amp;&amp; defined(SHADER_API_MOBILE)</span> <span class="synStatement">return</span> packednormal.xyz * <span class="synConstant">2</span> - <span class="synConstant">1</span>; <span class="synPreProc">#else</span> <span class="synStatement">return</span> UnpackNormalDXT5nm(packednormal); <span class="synPreProc">#endif</span> } </pre><p>GLESや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%DE%A5%DB">スマホ</a>フラグが立っていない環境では<a class="keyword" href="http://d.hatena.ne.jp/keyword/DirectX">DirectX</a>モードということでNormalDiffuseの法線サンプリング計算はDXT5nを前提に「YW要素をXYZWのXYに変換し、Z要素をXYから復元して埋める」計算に切り替わってますね。この都合、もし<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>側で一般的なRGBA=<a class="keyword" href="http://d.hatena.ne.jp/keyword/XYZ">XYZ</a>(H)フォーマットで法線マップをリアルタイム生成して、マテリアルにセットすると、DX環境ではGAだけ読んで変なベクトルに変換されてしまいます(G→G,A→Rに移動して他の要素は消される)。GchannelにY、AchannelにXを割り当てるとウチでは問題なくなりますが、すると今度はGL環境で挙動が怪しくなりますね。スレにも出ている通り、とりあえずは"NormalDiffuseGL"なシェーダーを自前で用意してしまうのが一番簡単でしょうか。つまり…</p><p>NormalDiffuseのシェーダの例の場所を↓な感じに書き換えたシェーダーなら、紫色の法線マップをそのまま使用できます。</p> <pre class="code lang-c" data-lang="c" data-unlink><span class="synComment">// o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));</span> o.Normal = tex2D(_BumpMap, IN.uv_BumpMap) * <span class="synConstant">2</span> - <span class="synConstant">1</span>; </pre><p>このシェーダであれば、NormalMapモードとしてインポートされたテクスチャでなくても法線マップとして利用できます(<a href="#f-c61b6a32" name="fn-c61b6a32" title="その代わり、DX環境ではDXT5n使うよりはメモリの使用効率がちょっと悪いですし、既にNormalmapとしてインポートしてDXT5n変換されているテクスチャは使用できません。">*2</a>)。</p><p>一番良いのは、Texture2DをSetPixelsする時に<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>からシェーダー定数を読んで要素の埋め方をスイッチする方法だと思うんですけど、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>からシェーダー定数を読む方法が良く分かりません(<a href="#f-2ff63a1b" name="fn-2ff63a1b" title="判定用シェーダを書いて1pxレンダして出力された色を読むとかしか思いつきません。あるいは虹色の画像をNormalmap設定でインポートさせてテクスチャのRGB要素がグレースケールになっちゃってるか見るとか。">*3</a>)。ただ、↓を読む限り、その辺はあまりUnity的にも積極的ではないのかも。<br /> <a href="http://docs-jp.unity3d.com/Documentation/Components/SL-BuiltinMacros.html">Unity&#x30EA;&#x30D5;&#x30A1;&#x30EC;&#x30F3;&#x30B9; / &#x5B9A;&#x7FA9;&#x6E08;&#x307F;&#x30B7;&#x30A7;&#x30FC;&#x30C0;&#x3000;&#x30D7;&#x30EA;&#x30D7;&#x30ED;&#x30BB;&#x30C3;&#x30B5;&#x30DE;&#x30AF;&#x30ED;</a><br /> </p> </div> </div> <div class="section"> <h4>他、参考にしたリンク</h4> <ul> <li>簡単なグレースケールHeightマップからの法線マップ生成サンプル <ul> <li><a href="http://forum.unity3d.com/threads/33159-sobel-operator-height-to-normal-map-on-GPU">sobel operator - height to normal map on GPU</a></li> <li><a href="http://forum.unity3d.com/threads/5714-bumpmap-%28grayscale%29-to-normalmap-%28rgb%29">bumpmap (grayscale) to normalmap (rgb)</a></li> </ul></li> <li><a class="keyword" href="http://d.hatena.ne.jp/keyword/GIMP">GIMP</a>用NormalMap<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3">プラグイン</a>プロジェクト <ul> <li><a href="http://code.google.com/p/gimp-normalmap/">gimp-normalmap</a> (リアルタイム向けじゃないですがガッツリ系の変換処理で実際どんな事をするのか参考に)</li> </ul></li> </ul> </div><div class="footnote"> <p class="footnote"><a href="#fn-4f19294c" name="f-4f19294c" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">GetPixels()したあと、Aを1で埋めて色要素だけにした画像1、それとAを<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a>に転写してAを1で埋めたA-Channelだけにした画像2をEncodeToPNG()して、それぞれ適当なファイルに書き出してみると、画像1が縦方向要素だけのグレースケールグラデーション、画像2が横方向だけのグレースケールグラデーションになり、XY要素しか残ってない状態に変換されている事が分かります。formatメンバは、DXTは定義されていないためか、ARGB32で返ってきましたw</span></p> <p class="footnote"><a href="#fn-c61b6a32" name="f-c61b6a32" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">その代わり、DX環境ではDXT5n使うよりはメモリの使用効率がちょっと悪いですし、既にNormalmapとしてインポートしてDXT5n変換されているテクスチャは使用できません。</span></p> <p class="footnote"><a href="#fn-2ff63a1b" name="f-2ff63a1b" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">判定用シェーダを書いて1pxレンダして出力された色を読むとかしか思いつきません。あるいは虹色の画像をNormalmap設定でインポートさせてテクスチャの<a class="keyword" href="http://d.hatena.ne.jp/keyword/RGB">RGB</a>要素がグレースケールになっちゃってるか見るとか。</span></p> </div> tiri_tomato