【Unity】CloudBuildをつかって作ったiOSアプリ(IPA)をコマンドラインでiTunesConnectにアップする.
ITunesConnectにアップロードする
p12ファイルとProvisioning Profileの作成は終わっていて,CloudBuildは動いているものとします.
こんな感じですね.
こういう状況になっていない人は,こちらの記事様がわかりやすいかと思います. macdays.hatenablog.com blog.naichilab.com
今回はCloudBuildからダウンロードできるIPAをiTunesConnectにアップロードする方法です.
CloudBuildを行うとIPAファイルをダウンロードできますが,直接iTunesConnectにアップロードする仕組みはないようです.
altool
altoolというものを使います.これはXcodeに付属しています.
簡単に使えるようにPATHにいれてしまうことをおすすめします.
パス名の途中にスペースがあるのでご注意ください.
export PATH=$PATH:/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Support/
ターミナルを開き直すか,以下のコマンドで更新します.
source ~/.bash_profile
これでaltoolが簡単に使えるようになりました.
アップロード
altool --upload-app -f NAME.ipa -u MAIL@ADDRESS -p PASS
大文字のところは適宜変えてください.
なお,Windowsの方はApplication Loaderというものを使う必要があるようです.(一ヶ月だけ無料です.)
ここで,PASSの部分ですが,App用パスワードが必要です.
設定していない方はこちらを参考に用意してください.
support.apple.com
以上になります.
参考
【Unity】キャラクターをポイントクラウド化するスクリプト
Meshtopologyを変更する
実際はMeshtopologyを変更するだけです.
こんなことができます.
youtu.be
つまり可愛くはなりません.
使い方
アタッチしてスクリプトの上で右クリックしてGo.
以上です.
終わったらRemoveComponentしてください.
ソースコード
Modify MeshTopology with one button.
解説みたいなもの
既存のモデルのメッシュをコピーしてから,トポロジを変更します.
コピーしないと既存のモデルのメッシュが壊れます.壊しました.
元のモデルのとこにメッシュのコピーが作られます.
点の大きさはまた別の処理が要ります.
このあたりです.
notargs様 wordpress.notargs.com
参考
Unity Forum
https://forum.unity.com/threads/how-do-i-duplicate-a-mesh-asset.35639/
【Unity】uGUIのImageに空間フィルタをかけるシェーダー
uGUIのImageに対するフィルタ処理をGPUでやれます.ご自由にお使いください.
フィルタ処理
ソーベルフィルタの例
マテリアルのプロパティを変えれば色々な3x3の空間フィルタがかけられます.
ソースコード
Unity ShaderLab "Custom/UI/Filtered" uGUIのImageに空間 ...
インスペクタ
Cutoutを0以外にすれば明るさが低い部分を切り捨てられます.
シェーダーだけで完結するためにマトリクスを作る部分で無駄があります.
ご了承ください.
【Unity】AudioListerを録音してwavにする
録音する
Unity内で鳴っている音をそのまま録音します.
ソースコードはこちら.
using System; using System.IO; using System.Text; using UnityEngine; [RequireComponent(typeof(AudioListener))] public class AudioListener2Wav : MonoBehaviour { private int m_outputRate = 44100; private bool m_isRecording = false; private FileStream m_stream; readonly private string m_fileName = "recTest.wav"; readonly private int m_headerSize = 44; float[] wave = new float[1024]; void Update () { if (!Input.GetKeyDown(KeyCode.R)) return; if (m_isRecording == false) { Debug.Log("rec started",this); m_isRecording = true; startWriting(m_fileName); } else { m_isRecording = false; writeHeader(); Debug.Log("rec stop", this); } } private void OnAudioFilterRead(float[] data, int channels) { if (!m_isRecording) return; convertAndWrite(data); } /// <summary> /// ストリームを0埋めして初期化 /// </summary> /// <param name="name">ファイルの名前</param> private void startWriting(string name) { m_stream = new FileStream(name, FileMode.Create); var emptyByte = new byte(); for (int i = 0; i < m_headerSize; i++) { m_stream.WriteByte(emptyByte); } } /// <summary> /// 変換してストリームに書き込む /// </summary> /// <param name="dataSource">書き込むデータ</param> private void convertAndWrite(float[] dataSource) { Int16[] intData = new Int16[dataSource.Length]; var bytesData = new byte[dataSource.Length*2]; int rescaleFactor = 32767; for (int i = 0; i < dataSource.Length; i++) { intData[i] = (short) (dataSource[i] * rescaleFactor); var byteArr = new byte[2]; byteArr = BitConverter.GetBytes(intData[i]); byteArr.CopyTo(bytesData, i * 2); } m_stream.Write(bytesData, 0, bytesData.Length); } /// <summary> /// ヘッダを書く /// 詳しくはwavのフォーマットを確認 /// http://www.graffiti.jp/pc/p030506a.htm /// </summary> private void writeHeader() { m_stream.Seek(0, SeekOrigin.Begin); Byte[] riff = Encoding.UTF8.GetBytes("RIFF"); m_stream.Write(riff, 0, 4); Byte[] chunkSize = BitConverter.GetBytes(m_stream.Length - 8); m_stream.Write(chunkSize, 0, 4); Byte[] wave = Encoding.UTF8.GetBytes("WAVE"); m_stream.Write(wave, 0, 4); Byte[] fmt = Encoding.UTF8.GetBytes("fmt "); m_stream.Write(fmt, 0, 4); Byte[] subChunk1 = BitConverter.GetBytes(16); m_stream.Write(subChunk1, 0, 4); UInt16 one = 1; UInt16 two = 2; Byte[] audioFormat = BitConverter.GetBytes(one); m_stream.Write(audioFormat, 0, 2); Byte[] numChannels = BitConverter.GetBytes(two); m_stream.Write(numChannels, 0, 2); Byte[] sampleRate = BitConverter.GetBytes(m_outputRate); m_stream.Write(sampleRate, 0, 4); Byte[] byteRate = BitConverter.GetBytes(m_outputRate * 4); // sampleRate * bytesPerSample*number of channels, here 44100*2*2 m_stream.Write(byteRate, 0, 4); UInt16 four = 4; Byte[] blockAlign = BitConverter.GetBytes(four); m_stream.Write(blockAlign, 0, 2); UInt16 sixteen = 16; Byte[] bitPerSample = BitConverter.GetBytes(sixteen); m_stream.Write(bitPerSample, 0, 2); Byte[] dataString = Encoding.UTF8.GetBytes("data"); m_stream.Write(dataString, 0, 4); Byte[] subChunk2 = BitConverter.GetBytes(m_stream.Length - m_headerSize); m_stream.Write(subChunk2, 0, 4); m_stream.Close(); } }
同じGameObjectにAudioListenerがいないと
OnAudioFilterReadがコールされません.(ハマりました)
使い方
- AudioListerのついたGameObjectにアタッチ
- Rボタンを叩く(録画開始)
- 再度Rボタンを叩く(録画終了)
参考
参考にした元のソースはこちらにあります.
ただしこちらはUnityScriptです.
https://forum.unity3d.com/threads/writing-audiolistener-getoutputdata-to-wav-problem.119295/
【Unity】DrawMesh初歩と動的Mesh生成
DrawMesh
APIはこれです.
これを使うことでアクティブなGameObjectを存在させずにMeshを描くことができます.
つまりその分軽量なわけです.
大抵は膨大な数(1,000,000とか)のパーティクルを扱う際に活躍する技術のようですが,
今回は初歩的に一つのMeshを描きます.
Meshは事前に用意せずに動的に生成してみます.
動的なMeshの生成に関してはこちらの記事がわかりやすいです.
コード
using UnityEngine; public class DynamicMeshUsingDrawMesh : MonoBehaviour { [SerializeField] Material m_mat; Mesh m_mesh; void Start () { // 動的Mesh生成 m_mesh = new Mesh(); m_mesh.vertices = new Vector3[] { new Vector3 (-0.5f, -0.5f), new Vector3 (0.5f, -0.5f), new Vector3 (0.5f, 0.5f), new Vector3 (-0.5f, 0.5f), }; m_mesh.uv = new Vector2[] { new Vector2(0,0), new Vector2(1f,0), new Vector2(1f,1f), new Vector2(0,1f), }; m_mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3, }; m_mesh.RecalculateNormals(); m_mesh.RecalculateBounds(); } private void Update() { Graphics.DrawMesh(m_mesh, Vector3.zero, Quaternion.identity, m_mat, 0); } }
マテリアルはなんでもいいですが,今回は適当に赤いマテリアルをつけます.
実行結果
動的にMeshを生成して描画できました.
Windowsでpthread
Windowsでpthreadのコンパイル
Windowsに環境をpthreadをコンパイルする環境を構築した際のメモ書きです.
参考にさせていただいたサイト様はこちら
【VC++】スレッド(pThread)を利用する環境を整える
私はVC++のようなIDEではなく,エディタとgccで行いましたが,基本は同じです.
pthread.h等々をダウンロード
Windowsにはpthreadのライブラリが標準で入っていません.
なのでこちらのリンクからライブラリ類をダウンロードし,インクルードパスにおいてあげることが必要です.
pthread win32
- includeの下に置くもの
- pthread.h
- sched.h
- semaphore.h
- libの下に置くもの
- libpthreadGC2.a
- libpthreadGCE2.a
- pthreadVC2.lib
- pthreadVCE2.lib
- pthreadVSE2.lib
- binの下に置くもの
- pthreadGC2.dll
- pthreadGCE2.dll
- pthreadVC2.dll
- pthreadVCE2.dll
- pthreadVSE2.dll
ボールドの部分は参考サイトにはありませんでしたが,私の環境では入れないとライブラリがなくコンパイルがうまくいきませんでした.
ちなみにインクルードパス諸々は次のコマンドで調べられます.
gcc -print-search-dirs
‘timespec’: ‘struct’ type redefinitionを解決する
windowsのtime.hには,既にtimespecが定義されていて,
pthread.hのインクルードガードはこれに対応していません.
したがって手っ取り早いのは,
#define HAVE_STRUCT_TIMESPEC #include <pthread.h>
こうしてしまうことです.
後はコンパイルするだけです.
gcc -o thread thread.c -lpthreadGC2