20210725のUnityに関する記事は5件です。

ML-AgentsをMacbook M1(Apple Silicon)インストール時にエラー起きたときの対処法

Macbook M1 で先駆者の記事を参考にML-Agentsを導入しようとしたら、ライブラリインストール時にエラーが出ました。そのエラーにどんな対処したかの備忘録になります。 サンプル(3Dball)を動かすところまでしか試していません。 TL;DR grpcio, h5pyライブラリをcondaでインストール PyTorch 1.8.0をインストール 最終目的 ML-Agents Release 18のインストールを行う。 その後、ML-AgentsのサンプルScene(Ball)の学習済みモデルでの推論、学習を行う。 自分の環境 Macbook Air (M1, 2020) macOS Big Sur ver11.2.2 Python 3.8.x (miniforgeで導入 参考: https://zenn.dev/karaage0703/articles/f3254b14898b4d) ML-Agentインストール手順 基本的には公式ドキュメントに従っていた。 https://github.com/Unity-Technologies/ml-agents/blob/release_18_docs/docs/Installation.md エラー発生箇所 1 ML-Agents用のAnaconda仮想環境に、ml-agentsとml-agents-envsのインストールを実行したところエラー発生。 Advanced: Local Installation for Development If you intend to make modifications to mlagents or mlagents_envs, you should install the packages from the cloned repository rather than from PyPi. To do this, you will need to install mlagents and mlagents_envs separately. From the repository's root directory, run: pip install torch -f https://download.pytorch.org/whl/torch_stable.html pip install -e ./ml-agents-envs pip install -e ./ml-agents エラー文章は長文だったので省略します。grpcio、h5pyインストール時にエラーが発生しているようでした。 エラー対処法 1 エラーが発生したライブラリをcondaでインストールしました。 pip, condaを混同して使っています。環境壊れる可能性があるので、もっといいやり方あれば教えて下さい。 conda install grpcio h5py エラー発生箇所 2 エラー発生箇所 1と同様。 エラー内容は、 ERROR: Could not find a version that satisfies the requiremet torch<1.9.0,>=1.6.0(from mlagents)(from versions: 0.1.2, 0.1.2.post1, 0.1.2 post2, 1.9.0 ERROR: No matching distribution found for torch<1.9.0,>=1.6.0 エラー対処法 2 原因はPyTorch1.9.0をインストールしていたからでした。 対処法はPyTorch 1.8.0をインストールすることです。自分はwheelファイルからインストールしました。 謎の先人によってwheelファイルが作成されているので、以下からダウンロードして~/Downloadsに配置しましょう。 https://drive.google.com/file/d/1e-7R3tfyJqv0P4ijZOLDYOleAJ0JrGyJ/view その後、以下のコマンドで既存のPyTorchをアンイストールして、PyTorch 1.8.0をインストールしましょう。 pip uninstall torch pip install ~/Downloads/torch-1.8.0a0-cp38-cp38-macosx_11_0_arm64.whl 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Oculus Integrationを使用しないUnityVRの入力スターターキット

準備 UnityVRテンプレートから超簡単にワールド内を移動できるようになります。 検証エディタ:Unity2021.1 UnityHubで新しいプロジェクトを作る際にテンプレート「VR」を選択して作成。 プロジェクト設定のXRPluginManagementでOculusをチェック 以下のスクリプトを適当にアセットフォルダに作成します。 VR_Input.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR; public class VR_Input : MonoBehaviour { public enum InputVRBool { Primary, Secondary, Trigger, Grip, Menu, PrimaryAxis }; public enum InputVRFloat { Trigger, Grip }; public static bool GetPresseButton(XRNode node, InputVRBool inputVRBool) { bool value = false; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { switch (inputVRBool) { case InputVRBool.Trigger: device.TryGetFeatureValue(CommonUsages.triggerButton, out value); break; case InputVRBool.Grip: device.TryGetFeatureValue(CommonUsages.gripButton, out value); break; case InputVRBool.Primary: device.TryGetFeatureValue(CommonUsages.primaryButton, out value); break; case InputVRBool.Secondary: device.TryGetFeatureValue(CommonUsages.secondaryButton, out value); break; case InputVRBool.PrimaryAxis: device.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out value); break; case InputVRBool.Menu: if (node == XRNode.LeftHand) { device.TryGetFeatureValue(CommonUsages.menuButton, out value); } break; } } } return value; } public static float GetAxis1D(XRNode node, InputVRFloat inputVRFloat) { float value = 0; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { switch (inputVRFloat) { case InputVRFloat.Trigger: device.TryGetFeatureValue(CommonUsages.trigger, out value); break; case InputVRFloat.Grip: device.TryGetFeatureValue(CommonUsages.grip, out value); break; } } } return value; } public static Vector2 GetAxis2D(XRNode node) { Vector2 value = Vector2.zero; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { device.TryGetFeatureValue(CommonUsages.primary2DAxis, out value); } } return value; } public static void Recenter() { var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(XRNode.CenterEye, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { device.subsystem.TryRecenter(); } } } } 次に、以下のスクリプトを作成、サンプルシーンにある「XRRig」というオブジェクトにくっつけます。 VR_BasicController.cs using UnityEngine; [RequireComponent(typeof(CharacterController))] public class VR_BasicController : MonoBehaviour { private CharacterController cc; [SerializeField] private float speed = 2; [SerializeField] private int angle = 30; private bool RT, LT; private Vector2 stickL; private Vector2 stickR; private float gravity = 20;//9.81f; void Start() { cc = GetComponent<CharacterController>(); VR_Input.Recenter(); } void Update() { stickL = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.LeftHand); stickR = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.RightHand); Move(); Rotate(); if (VR_Input.GetPresseButton(UnityEngine.XR.XRNode.RightHand, VR_Input.InputVRBool.PrimaryAxis)) { VR_Input.Recenter(); } } void Move() { cc.enabled = true; Vector3 direction = new Vector3(stickL.x, 0, stickL.y); Vector3 velocity = direction * speed; velocity.y -= gravity; velocity = transform.TransformDirection(velocity); cc.Move(velocity * Time.deltaTime); } void Rotate() { if (stickR.x < -0.25f && !LT) { LT = true; transform.Rotate(0, -angle, 0); } if (0.25f < stickR.x && !RT) { RT = true; transform.Rotate(0, angle, 0); } if (stickR.x == 0) { LT = false; RT = false; } } } 使い方 左スティックで移動 右スティックで回転 右スティック押し込みでリセンタリング(デバッグ時のみ) 余談 Oculus+UnityでVRやりたい場合はアセットストアから「Oculus Integration」をインポートすれば大体のことはできる。 が、そんなに機能要らない。。もっと簡単にスクリプトちょっとくっつけるだけでワールドを歩き回りたい! と思っていたらUnityがVRテンプレートを提供してくれてたので使わせてもらいました。入力関連はどんどんアップデートしてくれているので、 今後さらにシンプルに使えるようになれたらいいね。Unityさんマジ最高です。 参考 Unityマニュアル:Unity の XR 入力
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityVR入力スターターキット

準備 UnityVRテンプレートから超簡単にワールド内を移動できるようになります。 検証エディタ:Unity2021.1 UnityHubで新しいプロジェクトを作る際にテンプレート「VR」を選択して作成。 プロジェクト設定のXRPluginManagementでOculusをチェック 以下のスクリプトを適当にアセットフォルダに作成します。 VR_Input.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.XR; public class VR_Input : MonoBehaviour { public enum InputVRBool { Primary, Secondary, Trigger, Grip, Menu, PrimaryAxis }; public enum InputVRFloat { Trigger, Grip }; public static bool GetPresseButton(XRNode node, InputVRBool inputVRBool) { bool value = false; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { switch (inputVRBool) { case InputVRBool.Trigger: device.TryGetFeatureValue(CommonUsages.triggerButton, out value); break; case InputVRBool.Grip: device.TryGetFeatureValue(CommonUsages.gripButton, out value); break; case InputVRBool.Primary: device.TryGetFeatureValue(CommonUsages.primaryButton, out value); break; case InputVRBool.Secondary: device.TryGetFeatureValue(CommonUsages.secondaryButton, out value); break; case InputVRBool.PrimaryAxis: device.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out value); break; case InputVRBool.Menu: if (node == XRNode.LeftHand) { device.TryGetFeatureValue(CommonUsages.menuButton, out value); } break; } } } return value; } public static float GetAxis1D(XRNode node, InputVRFloat inputVRFloat) { float value = 0; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { switch (inputVRFloat) { case InputVRFloat.Trigger: device.TryGetFeatureValue(CommonUsages.trigger, out value); break; case InputVRFloat.Grip: device.TryGetFeatureValue(CommonUsages.grip, out value); break; } } } return value; } public static Vector2 GetAxis2D(XRNode node) { Vector2 value = Vector2.zero; var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(node, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { device.TryGetFeatureValue(CommonUsages.primary2DAxis, out value); } } return value; } public static void Recenter() { var inputdevice = new List<InputDevice>(); InputDevices.GetDevicesAtXRNode(XRNode.CenterEye, inputdevice); if (0 < inputdevice.Count) { foreach (var device in inputdevice) { device.subsystem.TryRecenter(); } } } } 次に、以下のスクリプトを作成、サンプルシーンにある「XRRig」というオブジェクトにくっつけます。 VR_BasicController.cs using UnityEngine; [RequireComponent(typeof(CharacterController))] public class VR_BasicController : MonoBehaviour { private CharacterController cc; [SerializeField] private float speed = 2; [SerializeField] private int angle = 30; private bool RT, LT; private Vector2 stickL; private Vector2 stickR; private float gravity = 20;//9.81f; void Start() { cc = GetComponent<CharacterController>(); VR_Input.Recenter(); } void Update() { stickL = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.LeftHand); stickR = VR_Input.GetAxis2D(UnityEngine.XR.XRNode.RightHand); Move(); Rotate(); if (VR_Input.GetPresseButton(UnityEngine.XR.XRNode.RightHand, VR_Input.InputVRBool.PrimaryAxis)) { VR_Input.Recenter(); } } void Move() { cc.enabled = true; Vector3 direction = new Vector3(stickL.x, 0, stickL.y); Vector3 velocity = direction * speed; velocity.y -= gravity; velocity = transform.TransformDirection(velocity); cc.Move(velocity * Time.deltaTime); } void Rotate() { if (stickR.x < -0.25f && !LT) { LT = true; transform.Rotate(0, -angle, 0); } if (0.25f < stickR.x && !RT) { RT = true; transform.Rotate(0, angle, 0); } if (stickR.x == 0) { LT = false; RT = false; } } } 使い方 左スティックで移動 右スティックで回転 右スティック押し込みでリセンタリング(デバッグ時のみ) 余談 Oculus+UnityでVRやりたい場合はアセットストアから「Oculus Integration」をインポートすれば大体のことはできる。 が、そんなに機能要らない。。もっと簡単にスクリプトちょっとくっつけるだけでワールドを歩き回りたい! と思っていたらUnityがVRテンプレートを提供してくれてたので使わせてもらいました。入力関連はどんどんアップデートしてくれているので、 今後さらにシンプルに使えるようになれたらいいね。Unityさんマジ最高です。 参考 Unityマニュアル:Unity の XR 入力
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityのLODグループでLevel of Detailサンプル作ってみた

オープンワールドゲーム作ってみたくないです? 著者はゼルダの伝説BotWからハマってGhost of Tsushimaは最高に好きです オープンワールドを支える重要な技術の一つがLevel of Detail(LOD)です これは被写体との距離などで表示するメッシュを切り替えることで カメラ内のポリゴン数を減らし描画負荷を抑える技術です Unityには簡単にLODを実現するツールがあるので 今回はこちらのサンプルを作りました 事前情報 Unity: 2020.3.11f1 LOD Group: https://docs.unity3d.com/ja/current/Manual/class-LODGroup.html 作業 Blenderでメッシュを用意 今回は高ポリゴン・中ポリゴン・低ポリゴンをBlenderで用意 青:UV SphereのSegments=12、Verts=182 緑:UV SphereのSegments=24、Verts:362 赤:UV SphereのSegments=48、Verts:722 Unityにそれぞれのメッシュを配置 UnityでEmptyObjectを配置し、子要素に3パターンのオブジェクトを追加 ※わかりやすく横に配置してますが座標は同じにしてください LOD Groupを設定 親要素に対しInspectorウィンドウでLOD Groupを追加します 各フォームの詳しい説明は公式ドキュメントがわかりやすく解説してるので省きます LOD Group: https://docs.unity3d.com/ja/current/Manual/class-LODGroup.html UnityのLOD Groupでは被写体が画面内で何%占めているかでメッシュの出しわけをします 上記画像だと100%ならLOD 0、60%ならLOD 1、30%ならLOD 2、10%なら表示しません 各ゲージ部分をクリックすると対象のオブジェクトまたはRendererを指定できます あとはカメラアイコンをスライドするとSceneビューにプレビューされます Sceneビューでカメラ移動しても反映されてると思います 比較 視覚的に球体の角張に差は殆どないのに statsのTriangle数とVertex数が激減してるのがわかります 感想 LOD Groupのおかげで非常に簡単にLODを体験できました ただ余りにも簡単かつ設定項目も少ないので 本格的に負荷軽減したいなら自作する必要がありそうです メリット ・簡単に作れるのでモック作成向け デメリット ・画面内の比率でメッシュ差し換えしているため、見切れてるときに低ポリゴンになる  →Fade Modeでメッシュ切り替えを滑らかにすると緩和されるかもしれません ・メモリにはすべてのメッシュが載ってる気がするのでメモリも節約したい場合には向かないかも  →Renderer指定にすれば動的ロードしてくれるかも?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityをGitHubでちゃんと管理する

UnityをGithubで管理したい。基本は下記リンクに倣って進めていくだけ。 参考:UnityでGitHubとGit LFSを使ったバージョン管理初期設定まとめ (参考その2:UnityプロジェクトをGit LFSでバージョン管理する 個人的なオススメの設定) 手順 上記リンクから、筆者好みにアレンジした手順を以下に記しておく。 Unityでプロジェクト作成 Unityの「Edit」→「Project Settings」で以下を設定 Editor / Asset Serialization / Mode ->「Force Text」 Version Control / Model ->「Visible Meta Files」 リモートから新規のリポジトリを作成(README gitignore等のチェックは外しとく) 作成したプロジェクトディレクトリをターミナルから $ git init (必要に応じて $ touch README.md) Unity用gitignoreのテンプレートをDLしてきて同ディレクトリに加える Unity用gitattributesのテンプレートをDLしてきて同ディレクトリに加える Git LFSで管理する場合はdiff=lfs merge=lfsの追記を忘れないこと それが面倒ならこっちを使う Git LFSを使うなら $ git lfs install $ git add . $ git commit -m "first commit" $ git branch -M main $ git remote add origin git@github.com:[Githubのユーザ名]/[リポジトリ名].git $ git push -u origin main つまづいたこと 筆者の環境ではいろいろと厄介なことが起こってしまった。それをメモしておく。 1. masterとmain問題 $ git branch -M mainをしなかったせいでこうなった。 $ git push -u origin main error: src refspec main does not match any Githubの仕様変更により、masterは廃止されmainへと置き換えられた…はずであった。 そのバージョン違い?で起こってしまうのがこの食い違い。 生成したリモートリポジトリのブランチ名はmain git initするときにできたブランチ名はmaster $ git branch * master # mainじゃない! という状況になっている。 $ git branch -m main # masterをmainにリネーム $ git config --global init.defaultBranch main # ついでに今後git initしたときに同じ症状が起こらないようにしておく こうすれば解決。もう一回pushしてみよう。 参考:Githubのデフォルトブランチがmainになった 2. WSL問題 SSHが通らない問題が発生して、pushできない人。 $ git push -u origin main The authenticity of host 'github.com (13.114.40.48)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'github.com,13.114.40.48' (RSA) to the list of known hosts. git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. ちなみにsshではなく$ git remote add origin https://github.com/[Githubのユーザ名]/[リポジトリ名].gitでやろうとしても弾かれた。 $ git push -u origin main Username for 'https://github.com': [Githubのユーザ名] Password for 'https://[Githubのユーザ名]@github.com': remote: Invalid username or password. # パスワード正しくてもこうなる fatal: Authentication failed for 'https://github.com/[Githubのユーザ名]/[リポジトリ名].git/' これを機に、以前から逃げ続けてきたGithubのSSH問題にケリをつけることにした。 とりあえず下記リンクに従ってSSHキーを生成する。 GitHubにssh接続できるようにする リンク先についてのメモ(思ったことの覚え書き)↓ 秘密鍵はわざわざid_rsa_githubなんてせず、普通にid_rsaでいい。また、もし既にid_rsaが生成済みならそれを使い回せばOK。(セキュリティ的に大丈夫かは知らん。) WSL使ってる人は、Windows側のSSHキー(C:\Users\[Windowsのユーザ名]\.ssh)とは別に、WSL側のホームディレクトリに別途SSHキーが必要(~/.ssh)。 リンク先の手順に従っていくと、WSL使ってるかつWSLのホームディレクトリの位置を変更してる人は以下のようになってしまう。 (パワーシェル使ってる人と、WSL使っててもホームディレクトリの変更をしてない人は大丈夫なはず。) $ ssh-add ~/.ssh/id_rsa @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0777 for 'XXX/.ssh/id_rsa' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key "XXX/.ssh/id_rsa": bad permissions どうやら、Windowsのパーミッションの仕様が(WSL視点だと)ガバガバなのが原因らしい。 解決法1 WSLでもgitでsshを使いたい 基本的には上に従えばOK。この手順だと、SSHキーは作り直しになるので注意。 仕組みをよく分かってない人はおとなしく解決法2へレッツゴー。 解決法2 基本的には解決法1とやってることは同じ。 だが、すでに生成したSSHキーをそのまま移行したい場合(筆者はそうだった)は以下のようにする。 参考:[WSL] Windows支配下に公開鍵, 秘密鍵を作ってしまうとpermissionを変更できない! $ mkdir /home/[WSLのユーザ名]/.ssh $ mv ~/.ssh/* /home/[WSLのユーザ名]/.ssh/ $ cd /home/[WSLのユーザ名]/.ssh/ $ chmod 644 id_rsa.pub $ chmod 644 known_hosts $ chmod 600 id_rsa $ chmod 700 ../.ssh/ $ cd ~ $ rmdir .ssh/ # 消せなかったら再起動してリトライ $ ln -s /home/[WSLのユーザ名]/.ssh ここまでできたら、もう一回以下を試してみる。 $ ssh-add ~/.ssh/id_rsa $ ssh -T github Hi [Githubのユーザ名]! You've successfully authenticated, but GitHub does not provide shell access. こうなれば成功。今度こそpushできるはず! まとめ WSLってめんどいね。でもパワーシェルは使いたくないから仕方ないね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む