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

Unity スクリプトでのオブジェクトの移動

0.0 はじめに オブジェクトを移動させる方法はいろいろとありますが、代表的な方法をまとめたいと思います。 Unityでオブジェクトを移動させるには、大きく2つの方法があります。 1つは、座標を変更して移動させる方法。もう1つは、オブジェクトに力を加えて移動させる方法です。 1.0 座標を変更させることによる移動 transformを使用して座標を直接変更します。オブジェクトを移動させるのに一番簡単で単純な方法です。ただし物理演算を無視した座標の変更は自然な動きに反しますので注意しましょう。 1.1 positionの変更による移動 直接座標を変えて移動するシンプルな方法です。 ?ポイント transform.position(transform.position.x または y, z)には直接値を代入出来ないので注意が必要です。 Vector3(Vector2)の変数を介してtransform.positionを変更します。 test1.cs Vector3 pos = transform.position; // 現在のポジションを代入 pos.x = 1.0f; // x座標変更 pos.y = 2.0f; // y座標変更 pos.z = -1.0f; // z座標変更 transform.position = pos; // 変更後の座標を代入 または下記のように変更します。 test2.cs transform.position = new Vector3(1.0f, 2.0f, -1.0f); 1.2 Translate関数を使った移動 transform.Translate(x, y, z)を使用してオブジェクトの現在の位置を基準に移動する方法です。 Translate()の引数で指定したベクトルx・y・z分だけオブジェクトの位置を移動させることができます。 test3.cs transform.Translate(1.0f, 2.0f, -1.0f); 1.3 Vector3.MoveTowards関数を使った移動 Vector3クラスにMoveTowards関数があります。MoveTowards関数は現在地から目的地まで一定速度で移動させてくれる関数です。引数には順番に “current” に現在地(Vector3)、”target” に目的地(Vector3)、”maxDistanceDelta” に1フレームの距離(一定速度)をfloatで指定します。 test4.cs Vector3 current = transform.position; Vector3 target = new Vector3(10, -5, 0); float step = 2.0f * Time.deltaTime; transform.position = Vector3.MoveTowards(current, target, step); 1.4 Vector3.Lerp関数を使った移動 Vector3クラスにはLerp関数もあり、これを使用してオブジェクトを移動させることができます。 Lerp(a, b, t)関数の引数は a : 始まりの位置, b : 終わりの位置, t : aからの現在の位置の割合です。 ?ポイント tが0の時はaの地点、tが1の時はbの地点です。 test5.cs Vector3 start = transform.position; Vector3 target = new Vector3(10, -5, 0); float timer = 0; timer += Time.deltaTime; transform.position = Vector3.Lerp(start, target, timer); // timerの変化分だけ移動させる(1秒で目的地) 2.0 力を加えることによる移動 オブジェクトにRigidbody(リジッドボディ)コンポーネントを追加することで、物理演算で移動させることができます。 InspectorウインドウでAdd Componentボタンを押して検索窓でRigidbodyを検索して追加しましょう。※2Dの場合はRigidbody 2Dを選びます。 ?ポイント RigidbodyにはUse Gravity、Rigidbody2DにはGravity Scaleのパラメータがあり、重力の影響を調節できます。 2.1 速度を変更するVelocity関数を使う 一定の速度でオブジェクトを移動させたり、移動する速度を制限することができます。 test6.cs Rigidbody rb = GetComponent<Rigidbody>(); rb.velocity = Vector3.right * 2f; // 速さを直接入れる 2.2 力を加え加速度を変更するAddForce関数を使う オブジェクトに力を加えて物理演算を元に移動させることができます。現実世界と同じようにオブジェクトを自然な動きで移動させることができます。衝突のふるまいなど物理現象を使用している場合はこのAddForce関数を使いましょう。 ?ポイント 加える力が小さいとオブジェクトがうまく動かない場合があります。この場合はオブジェクトの質量を軽くするか、与える力を大きくすることで、オブジェクトを移動させることができます。 test7.cs Rigidbody rb = GetComponent<Rigidbody>(); rb.AddForce(1.0f, 2.0f, -1.0f); // 加える力のベクトルをVectorで入れる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

親GameObjectの影響を排除したscale算出方法

階層構造になっているGameObjectで、親のscaleを変更したときに子のサイズは変わってほしくないことがありました。 こういう場合のlocalScaleの算出方法について、検討した案を残しておきます。 案1: まずは正攻法 親の影響を打ち消すスケール算出(正攻法版) var localScale = this.transform.localScale; var lossyScale = this.transform.lossyScale; this.transform.localScale = new Vector3( localScale.x / lossyScale.x, localScale.y / lossyScale.y, localScale.z / lossyScale.z); すぐに思い付くし、理解しやすいし、良いと思います。 …でも長いしなんだか冗長でもやもやする。 x, y, zを間違えそうでちょっと怖いのもある。 もう少しすっきり書ける方法は無いのだろうか…? 案2: インデクサ利用 Vector3にはインデクサが用意されているので、これを使ってみます。 親の影響を打ち消すスケール算出(インデクサ利用版) var localScale = this.transform.localScale; var lossyScale = this.transform.lossyScale; var scaleUnaffectedByParents = Vector3.zero; Enumerable.Range(0, 3).ToList().ForEach(i => scaleUnaffectedByParents[i] = localScale[i] / lossyScale[i]); this.transform.localScale = scaleUnaffectedByParents; x, y, zを間違える可能性が無いのが良いですね。 割り算の記述も一箇所になってそれなりにすっきりはしましたが…以下の部分があと一歩足りないように感じてしまいます。 マジックナンバーが登場する。 Vector3のプロパティにインデクサでアクセスするというのがいまいちしっくり来ない。 案3: Transformのメソッド活用 こんなやり方で算出することも可能です。 親の影響を打ち消すスケール算出(Transformのメソッド活用版) // localScaleを表すベクトルをワールドの向きに変換 var worldDirectedLocalScale = this.transform.TransformDirection(this.transform.localScale); // ワールド上で上記ベクトルを示す場合のローカル上での表現方法を算出 // これがlocalScale設定値の大きさをワールド上で実現するために必要なlocalScaleとなる var scaleUnaffectedByParents = this.transform.InverseTransformVector(worldDirectedLocalScale); this.transform.localScale = scaleUnaffectedByParents; 無駄に複雑になってしまいましたが、これってUnityエキスパートの方ならすぐに理解できるものなのでしょうか? 解説 絵を描いてみました。 バブルの中に入ったUnityちゃんはscale1倍。そしてバブルがx, y共にscale2倍だったとします。 (表現しやすいので2Dで考えます) 親のscaleの影響を排除したいということは、「local scale = world scale」となってほしいのです。 つまり、今のlocalScaleの値がworldScaleとなるような値を、localScaleに設定できれば良いのです。 設定したいlocalScale → ワールドへの変換 → (x, y) = (1, 1) となってほしい。ということは、 (x, y) = (1, 1) → ワールドからローカルへの変換 → 設定したいlocalScale しかしこれだけだと、ローカルスペースとワールドスペースの軸の向きが異なる場合に上手くいきません。 ということで、向きを合わせる必要があります。 結果的に以下の手順で算出することになります。番号を画像内の数字と一致させています。 UnityちゃんのlocalScaleを取得すると(x, y) = (1, 1)が取得できる。 これをワールドスペース上での向きに変換する。 45度左に傾いているUnityちゃんの中での(x, y) = (1, 1)の方向は、ワールドスペース上では(x, y) = (0, 1.4)となる。 このベクトルがワールドスペースにあるときにローカルスペースではどう表記するのか?がlocalScalに設定すべき値となるので、ベクトルをローカルスペースに変換する。 これでほしい値は算出できるのですが…より理解しやすい書き方があるのにこれだけ解説が必要となる案は悪手だよね、ということで没になりました。 ベクトルや、ワールドスペースとローカルスペースについての理解を深めるためのクイズとしては機能するかもしれません。 ということで、案1か2の書き方にするしか無さそうです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HoloLens2で位置情報(WiFi)を取得する

はじめに HoloLens2で位置情報(WiFi)を取得してみました。 UWPの公式ドキュメントはこちら Get the user's location ドキュメントに書いてあるサンプルのMapControlは参考にならない MapControl MapControl C# Sample #WindowsUniversalSamples pic.twitter.com/ZXhIdoalDe— がちもとさん@熊本 (@sotongshi) June 13, 2021 ドキュメントのコードが書かれているのはこっち↓↓↓ Geolocation Geolocation C# Sample #WindowsUniversalSamples pic.twitter.com/2CuB9imPMi— がちもとさん@熊本 (@sotongshi) June 13, 2021 参考までに WindowsでGPS(みちびき含む)から現在の座標を調べてみる PowerAppsでも取得できる PowerAppsの信号(Signals)を試してみた 開発環境 Windows10 PC Unity 2019.4.1f1 MRTK 2.7.0(Microsoft.MixedReality.Toolkit.Unity.Foundation.2.7.0.unitypackage) 導入 1.Unityで新規プロジェクト作成。MRTKの設定、MapControlオブジェクト作成。位置情報を表示するため、MainCameraの下にTextMeshProのテキストを配置。 2.MapControlオブジェクトでAddComponent、MapController.csを作成。TextMeshProのテキストをMapControlのDebugTextにアタッチ。 MapController.cs using System.Collections; using System.Collections.Generic; using System; using System.Threading; using System.Threading.Tasks; using UnityEngine; #if UNITY_WSA && !UNITY_EDITOR using Windows.Devices.Geolocation; #endif using TMPro; public class MapController : MonoBehaviour { public TextMeshProUGUI debugText; private uint _desireAccuracyInMetersValue = 0; // Start is called before the first frame update async void Start() { debugText.text = "Initialization."; #if UNITY_WSA && !UNITY_EDITOR var accessStatus = await Geolocator.RequestAccessAsync(); switch (accessStatus) { case GeolocationAccessStatus.Allowed: debugText.text = "Waiting for update..."; Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = _desireAccuracyInMetersValue }; Geoposition pos = await geolocator.GetGeopositionAsync(); UpdateLocationData(pos); break; case GeolocationAccessStatus.Denied: debugText.text = "Access to location is denied."; break; case GeolocationAccessStatus.Unspecified: debugText.text = "Unspecified error."; UpdateLocationData(null); break; } #endif } #if UNITY_WSA && !UNITY_EDITOR private void UpdateLocationData(Geoposition position) { if (position == null) { debugText.text = "No data"; } else { debugText.text = position.Coordinate.Point.Position.Latitude.ToString() + "\n" + position.Coordinate.Point.Position.Longitude.ToString(); } } #endif } 3.Player SettingsのLocationにチェックを入れるのを忘れずに。HoloLens2のプライバシーの設定からアプリの位置情報をオンにする。 実行 HoloLens2で緯度・経度取れた。#HoloLens2 pic.twitter.com/g3aatLF0qm— がちもとさん@熊本 (@sotongshi) June 13, 2021 お疲れ様でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity + Android In-App Review pluginが動かない件の対策

こんにちは。virapture株式会社のもぐめっとです。 本日はAndroidでアプリ内レビューを表示することができるIn-App Review APIを動かそうとしたら動かなかったのでその解決tipsの紹介です。 どういうときに動くか In-AppReviewはストアからダウンロードした形でないと動くことがありません。 また、他にも下記のような条件があったりします。 ユーザー アカウントが内部テストトラックに含まれている。 ユーザー アカウントがメイン アカウントであり、Play ストアでそのアカウントが選択されている。 ユーザー アカウントが Play ストアからアプリをダウンロードした(アプリがユーザーの Google Play ライブラリに表示されている)。 現在、ユーザー アカウントがアプリをレビューしていない。 cf: つまり簡単に言うとテストするときは内部テストでリリースしないとテストができません!なんてやりづらいのでしょう! また、他にもUSBデバッグをOFFにしないと動かないといったこともあるみたいです。 ちなみに上記記事ではIn-AppReviewを出す前に1クッションいれた質問をいれてますが、In-AppReviewを出す前に質問を出すのはちょっとグレーです。 評価ボタンや評価カードを表示する前または表示中に質問をしない(「アプリを気に入りましたか?」といったユーザーの意見に関する質問や、「このアプリを 5 つ星と評価していただけますか?」といった予断を与える質問)。 更に動かない原因 先程説明した条件を満たしているのにも関わらず動かざることAndroidの如しで全くIn-App Reviewが表示されませんでした。 Crashlyticsで試しにログを飛ばしてみたらこんなエラーを飛んでいることが確認できました。 Non-fatal Exception: java.lang.Exception AndroidJavaException : java.lang.ClassNotFoundException: com.google.android.play.core.review.ReviewManagerFactory com.unity3d.player.UnityPlayer.nativeRender なぜかClassが見つからないようです。 解決法 ということで上記エラーを調べたら答えがありました。 つまり、proguardに妨害されてるので下記を除外すればおkとのこと。 -keep class com.google.android.play.core.** { *; } ということで自分のUnityプロジェクトのandroidのproguard設定に追記してビルドしたところ無事動くことが確認できました! まとめ produgardに設定を追加すればおk!! めんどくさがらずちゃんとcrashlyticsでロガーを仕込むことは大事だなと思いました。 最後に、ワンナイト人狼オンラインというゲームを作ってます!よかったら遊んでね! 他にもCameconやOffchaといったサービスも作ってるのでよかったら使ってね! また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存のUnityプロジェクトにgithubを導入する方法

【想定読者】 ・gitの導入が済んでいる方 ・githubのアカウントを持っている方 ・lfsの導入が済んでいる方 ・Unityプロジェクトを持っている方 (1) githubでリモートリポジトリを作成する。 Add .gitignoreにチェックを入れて、Unityを選択しておきましょう。 Public/Privateの設定は、他の人に公開しないならばPrivateに設定しましょう。 (2) 出来上がったリポジトリのURLを確認する。(3で使います) リポジトリを開いて一番最初に出てくる画面の、 緑色のCodeというボタンを押すと表示されるURLです。 (2021/6/13現在) (3) 自分のUnityプロジェクトにgitを導入する。 git init git remote add origin [2のurl] コマンドプロンプト(Macの場合はターミナル)で自分のUnityプロジェクトに移動し、上記のコマンドを実行する。 私の実行環境では、下記のようなフォルダです。 実行しても何も表示されないので、不安な方は「git remote -v」というコマンドを実行して、2のURLが表示されれば成功です。 (4) リモートの情報を取り込む git pull origin main (5) Unityプロジェクトの情報をリモートリポジトリに反映する git add . git commit -m "Add project" git push origin main [git add .]は、gitで管理するファイルを選択するコマンドです。[.]は全てという意味ですが、個別に指定したい場合はファイル名/フォルダ名を入力します。 [git commit -m "Add project"] 選択したファイルを実際にコミットするコマンドです。["Add project"]の部分は自由に決められるメッセージですが、あとで識別しやすいような文章を入れるのがおすすめです。 [git push origin main]実際にリモートリポジトリに反映するコマンドです。gitのバージョンによっては、[main]の部分を[master:main]とする必要があるかもしれません。 これは自分のmasterローカルブランチからmainリモートブランチへ送信するという意味です。 ローカルもリモートもどちらもmainの場合は、main:mainと書かずにmainと省略できます。 (6) lfsを導入する git lfs install git lfs track "*.png" [git lfs track]コマンドでlfsで管理するファイルを選択します。 [git lfs track "*.png"]コマンドでpngファイルを全てlfsで管理するように設定できます。 一度上記のコマンドを実行した後はカレントディレクトリに[.gitattributes]ファイルが出来上がるので、それを直接編集するのがおすすめです。 .gitattributesの例 *.cs diff=csharp text *.cginc text *.shader text *.mat merge=unityyamlmerge eol=lf *.anim merge=unityyamlmerge eol=lf *.unity merge=unityyamlmerge eol=lf *.prefab merge=unityyamlmerge eol=lf *.physicsMaterial2D merge=unityyamlmerge eol=lf *.physicsMaterial merge=unityyamlmerge eol=lf *.asset merge=unityyamlmerge eol=lf *.meta merge=unityyamlmerge eol=lf *.controller merge=unityyamlmerge eol=lf ## git-lfs ## #Image *.jpg filter=lfs diff=lfs merge=lfs -text *.jpeg filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text *.gif filter=lfs diff=lfs merge=lfs -text *.psd filter=lfs diff=lfs merge=lfs -text *.ai filter=lfs diff=lfs merge=lfs -text #Audio *.mp3 filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text *.ogg filter=lfs diff=lfs merge=lfs -text #Video *.mp4 filter=lfs diff=lfs merge=lfs -text *.mov filter=lfs diff=lfs merge=lfs -text #3D Object *.FBX filter=lfs diff=lfs merge=lfs -text *.fbx filter=lfs diff=lfs merge=lfs -text *.blend filter=lfs diff=lfs merge=lfs -text *.obj filter=lfs diff=lfs merge=lfs -text #ETC *.a filter=lfs diff=lfs merge=lfs -text *.exr filter=lfs diff=lfs merge=lfs -text *.tga filter=lfs diff=lfs merge=lfs -text *.pdf filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.dll filter=lfs diff=lfs merge=lfs -text *.unitypackage filter=lfs diff=lfs merge=lfs -text *.aif filter=lfs diff=lfs merge=lfs -text *.ttf filter=lfs diff=lfs merge=lfs -text *.rns filter=lfs diff=lfs merge=lfs -text *.reason filter=lfs diff=lfs merge=lfs -text *.lxo filter=lfs diff=lfs merge=lfs -text #Asset *.asset filter=lfs diff=lfs merge=lfs -text (7) lfsの導入をリモートリポジトリに反映する。 git add . git commit -m "Add lfs" git push origin main 備考 今回は全てコマンドで実行しましたが、SourceTreeなどのソフトを利用してもいいと思います。 git, github, lfsの導入方法は別の記事に残すかもしれないです。 Jenkinsを使ってgithubで管理しているUnityプロジェクトを一括でビルドする方法も記事にしたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む