20211128のUnityに関する記事は6件です。

Hierarchyにあるオブジェクトのパスを取得する

アニメーションをエディターから作ろうとした時に、 あれ・・・?これってパスの取得できなくね・・・? っておもったので、プログラミング初心者がパスを取得できるようにしてみました VRC用の拡張Editorを作ってみようの方で使いたいので、ここに軽く説明を残しておこうと思います 無駄なことをやってるかもしれないので、安定したコードを探しているのであれば、今回のコードの使用はお勧めできません お勧めはできませんが、その場しのぎにはなると思います 作ったコード private static string GetHierarchyPath(GameObject targetObj) { List<GameObject> objPath = new List<GameObject>(); objPath.Add(targetObj); for (int i = 0; objPath[i].transform.parent != null; i++) objPath.Add(objPath[i].transform.parent.gameObject); string path = objPath[objPath.Count - 1].gameObject.name; for (int i = objPath.Count - 2; i >= 0; i--) path += "/" + objPath[i].gameObject.name; return path; } メソッドの呼び出し string path = GetHierarchyPath(GameObject); コードの説明 最初にListで変数を作り、ターゲットのゲームオブジェクトを入れます リストができたら、for文を使って、オブジェクトの親がある時はループするようにします 最初のオブジェクトは、一番最初に入れたターゲットのゲームオブジェクトで、 一度ループすると、ターゲットの親が次のターゲットのゲームオブジェクトになります また、ループする度にゲームオブジェクトをリストに追加します 次にStringで変数を作り、リストに入れたオブジェクトを[.Count - 1]で、一番後ろに入っているゲームオブジェクトの名前を追加します string変数ができたら、for文を使って、今さっき追加したリストを、逆からstring変数に追加していきます ループが終わり、値を返してあげればできあがり!!って感じです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Mac] UnityのスクリプトをVisual Studio Codeで開く

Macの手順はWindowの手順と微妙に違ったのでメモします。 1. [Unity] → [Preferences] 2. [External Tools] を選び、図のドロップダウンからVisual Studio Codeを選ぶ。 以上です。 確認環境 Unity 2019.4.31f1 Personal MacBook Pro (16-inch 2019) macOS Monterey 12.0.1 参考文献 UnityでVisual Studio Codeを使用できるようにするまでの手順 https://qiita.com/riekure/items/c45868f37a187f8e1d69 Unity Editor のスクリプトファイルを VSCode で開く方法 https://qiita.com/Futo_Horio/items/c7874e7afaaf12b28d6f
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクトを上下にゆらゆらさせる

ゆっくりその場から上下に動きます インスペクタのspeedで上下運動のスピードを変えられます using System.Collections; using System.Collections.Generic; using UnityEngine; public class UpDownLoop : MonoBehaviour { Vector3 startPos; public float speed = 1.0f; void Start() { startPos = transform.position; } void Update() { float sin = Mathf.Sin(Time.time * speed) +startPos.y; //ゲーム開始からの経過時間を1~-1に変換 transform.position = new Vector3(startPos.x,sin,startPos.z); } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

任意のオブジェクトをエモく回転&ふんわり上昇させる

MVなんかでよくある、フワ…とオブジェクトが上昇してく演出を再現しました。 回転もさせられます。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class RiseUpper : MonoBehaviour { Vector3 startPos; public float x = 0.5f; public float y = 0.5f; public float z = 0.5f; public float speed = 0.005f; //上昇スピード void Update() { transform.Rotate(x,y,z); transform.position = new Vector3(0, startPos.y, 0); startPos.y += speed; } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UniRxとは?(UniRx導入に悩んでいる人向け)

00. この記事の目的 この記事の目的はUniRxを導入または学習を検討している方に軽く概要を掴んで頂いて検討材料にしていただければなと思い書き始めました。そのため、細かなUniRxの書き方等はこの記事に含まれていません。 01. UniRxとは? 通常、UnityではReactive Extensions(以降Rx)は機能しません。そこで、Yoshifumi KawaiさんによりをUnity向けにRxの概念とさまざまなユーティリティを追加し、再実装しなおしたものがUniRxになります。それ故、Rxの概念を理解していることがUniRxを使用する上で非常に重要になってきます。 まとめ ・UniRx = unity + Reactive Extensions 02. Rx(Reactive Extensions)とは? ①Rxの定義 Rxとは監視可能なシーケンスを使用して「非同期」「イベント」ベースのプログラム制作を目的として制作されたライブラリーで、Observerパターンと言うデザインパターンによって構成されています。 ここでよくある間違いについてですが、 Rxと関数型リアクティブプログラミング(functional reactive programming)が混同されることがよくありますがこれらは異なるものであるということに注意してください。Rxの公式サイトでもこのふたつの違いについて、「関数型リアクティブプログラミングは時間の経過に伴い連続的に変化する値によって変化していくのに対して、Rxは時間の経過とともに放出される離散型の動きをする。」と説明されており、二つが別のものであることを理解できます。 まとめ ・Rxは複雑な非同期処理やイベント処理、時間が関係する処理を、 LINQ形式で簡単かつ宣言的に記述できる。 ・Reactive Extensions ≠ 関数型リアクティブプログラミング 03. Observerパターンとは? ObserverパターンはSubject(監視対象)とObserver(観測者)の2つの役割から成り、監視対象の状態が変化した際に観測者に通知されるデザインパターンのことを言い、状態変化に応じた処理を記述する際に好まれる書き方とされています。 Example: オークションを例に挙げると観測者が入札者となり、競売人が監視対象となります。下記の図のように初めに13番の札を持つ人が入札した際Subjectの入札金額に変更が起こります(監視対象の状態変化)。次に入札金額の変更を競売人がオークション対象者に通知します(観測者への通知)。 (https://sourcemaking.com/design_patterns/observer) ここまでで、ObserverパターンはObserverがSubjectを観察するものなんだと思った方もいると思うのですが、実際は 『Subjectが各Observerを管理する』というのが正しい認識になるので注意してください。 まとめ ・Observerパターンとは監視しているオブジェクトに発生するイベントについて複数のオブジェクトに通知するサブスクリプションメカニズムを定義できる動作設計パターン。 ・Observerは受け身でSubjectがObserverへの参照をもつ。 04. 結局UniRxって導入するべきなの? UniRx導入を検討している方が一番気になるところはここだと思います、私もUniRxを勉強するにあたり色々な記事等を読みましたが、基本的に書かれている内容はUniRxの良い点がほとんどした。逆に疑いたくなるレベルでした、しかし、不安とは裏腹に少なくとも私にとってはUniRxは非常に便利なものでした。 悪い点 悪い点① 学習コストが高い 私が読んだ記事にUniRxは学習コストが非常に高いと言った内容が書かれたものがありました。実際高いと言ったら高いのかも?抽象的な言い方だったのではっきり言うと、UniRx自体の学習コストは全く高くないです。しかし、一定数UniRxを勉強し始めた時に「難しくない?」「学習コスト高!!」と感じる人もいると思います。このように感じる人の原因は「C#のevent」「メッセージパッシング」「非同期処理」「unityのUpdate」「シーケンス(LINQ)」「Rx」について理解が足りていないことにあると思います。もし、どれかひとつでも当てはまるようでしたらページ最後におすすめのサイトのURLを添付してあるので確認してみてください。 悪い点② UniRxそのものが少し重いことによる弊害 UniRxは1フレームに一回しか呼ばれない処理や非同期処理(Ex.通信、IO)といった負荷の重くない処理を得意としています。一方、1フレームに何度もインスタンス(Observable)の生成が行われるといった負荷の重い処理での利用には向いていません。理由は単に処理が重くなり場合によっては動かなくなるからです。 悪い点②に関しては一応悪い点としてあげていますが、unityのUpdateでも同じことが言えるのでUniRxだけの問題ではないと思います。 良い点 良い点① UniRxのオペレータによる従来のUpdateをストリーム化できる UniRxにはさまざまなオペレーターが用意されているのですが、それらのオペレーターによりunity従来のUpdateをストリーム化しロジックを明確に処理することが可能になります。加えて、変数のスコープの明確化やロジック単位で分割し処理を行うことが可能になったり例外処理が統一されるといったメリットもあります。 良い点② 従来のイベントにはできなかったことが可能に 発生したイベントに関する値の変化を監視し対応することが容易(Observerパターン)になります。加えて、従来のイベントではdelegateの定義が必要とされていましたが、UniRxではそれが不要になります。もうひとつ、これをメリットと捉えるかは時と場合によるとは思うのですがUniRxは後発的な処理です。 良い点③ 時間処理が容易に 私自身特にUniRx便利だなと感じたのが時間に関する処理です。例えば、イベントの発火タイミングの処理や時間に伴い変化する値の監視や非同期処理です。非同期処理のおかげで実行スレッドを容易に変更したり、フレーム処理が本当に容易になります。 補足 UniRxではイベントの処理や時間処理の便利機能を総称として「Observable」と読んでいます。 注意事項(チームプロジェクト向け) UniRxを全員が理解していることを前提で話を進めますが、チームでUniRxを導入してプロジェクトを進める際、スパゲティプログラムには気をつけてください。もともとUniRx自体は可読性も高く、書き方が統一されるためテストが非常にしやすいといったメリットがあるのですが、UniRxの特徴でもあるStreamとSubscribeを走らせる場所にルールを設けないとチームプロジェクトでは著しく可読性が低下しテストもしにくくなることが予想できます。 05. まとめ 私自身UniRxを勉強し始めた時はC#のイベントの理解とObserverパターンの利点について理解が甘くUniRxを勉強する前に周りみちをしました。UniRxの機能自体は便利なものが多く、わざわざUniRxで書かなくても良いのでは?という処理もありますがそれ以上にイベントや時間周りの便利機能のことを考えると導入した方が良いのではないかなと思います。特にunityのプログラミングレベルを上げたいと考えている方にはunityとC#の理解が深まるので是非とも学習を始めてほしいです。 おすすめサイト UniRxチュートリアル: https://qiita.com/toRisouP/items/00b8a5bb8e7b68e0686c Observerパターン(日本語): https://blog.xin9le.net/entry/2011/12/10/153032 C#の機能について網羅しているサイト(イベント & 非同期処理 & シーケンス): https://ufcpp.net/study/csharp/ メッセージパッキング: http://itdoc.hitachi.co.jp/manuals/3000/30003D0820/GD080321.HTM#ID00763 Reactive Extensions: https://atmarkit.itmedia.co.jp/fdotnet/introrx/introrx_01/introrx_01_01.html Functional Reactive programmingとは?(英語QAですが内容的は具体的に書いてあるためおすすめです。): https://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming/1030631#1030631
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NotNullAttributeで設定したオブジェクトをHierarchy上で確認できる機能拡張の作成

「Applibot Advent Calendar 2021」2日目の記事になります。 前日は @Sigsiguma さんの 「Unity TextMeshProにおけるダイナミックフォントの扱い」という記事でした! はじめに Unity開発中にこういった経験をしたことがありますか? ・SerializeFieldで設定したオブジェクトが参照されておらずUnity再生中に進行不能になってしまう ・オブジェクトを消したことによって、知らぬ間に別のオブジェクトが影響を受け、Inspector上でMissing表示になっている こういったNull Reference Exceptionを見たくない人の悩みを減らすため オブジェクトが参照されているかどうかをHierarchy上で確認できるような 環境を作りたいと思います。 この記事で載せているスクリプトをコピペすることで誰でも使うことができますのでぜひ導入してください! 概要 NotNullで設定したものをInspectorとHierarchy上で確認できるEditor拡張を作成します。 作業環境 Unity2020.3.22f1 ※それ以前のバージョンでも使える場合はございます。 実装の流れ 1.NotNullの属性を作成 2.Inspector上で確認できる機能の作成 3.Hierarchy上で確認できる機能の作成 1.NotNullの属性を作成 以下のスクリプトを作成します。 NotNullAttribute.cs using System; using UnityEngine; [AttributeUsage(AttributeTargets.Field)] public class NotNullAttribute : PropertyAttribute { } これにより、以下のように属性を書くことができるようになります。 Test.cs using UnityEngine; public class Test : MonoBehaviour { [NotNull, SerializeField] private GameObject _gameObject; } 2.Inspector上で確認できる機能の作成 ここからはEditor拡張になりますので、Editorディレクトリを作成してそこに以下のスクリプトを追加してください。 NotNullAttributeDrawer.cs using UnityEditor; using UnityEngine; /// <summary> /// Inspector上でNotNullのAttributeつけたもの変数がnullの場合、注意文を表示する /// </summary> [CustomPropertyDrawer(typeof(NotNullAttribute))] public class NotNullAttributeDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { position.height = base.GetPropertyHeight(property, label); EditorGUI.PropertyField(position, property, label); position.y += position.height; if (IsNull(property)) { EditorGUI.HelpBox(position, "参照してるオブジェクトがありません", MessageType.Error); } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return IsNull(property) ? base.GetPropertyHeight(property, label) * 2f : base.GetPropertyHeight(property, label); } /// <summary> /// 参照しているオブジェクトがnullかどうかを判定 /// </summary> private bool IsNull(SerializedProperty property) { if (property.isArray) { return property.arraySize == 0; } // オブジェクトを参照しないものは除く if (property.propertyType != SerializedPropertyType.ObjectReference) { return false; } return property.objectReferenceValue == null; } } 先程のTest.csをオブジェクトにAddComponentすると以下のように注意文言が表示されます。 注意文言があることで少し便利になりましたね! 3.Hierarchy上で確認できる機能の作成 これもEditor拡張になりますので、Editorディレクトリを作成してそこに以下のスクリプトを追加してください。 HierarchyExtension.cs using System.Reflection; using UnityEditor; using UnityEngine; public class HierarchyExtension : EditorWindow { [InitializeOnLoadMethod] private static void Initialize() { EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI; } // Hierarchy上表示する注意アイコンの大きさ private const int _ICON_SIZE = 16; private static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect) { // GameObject が取得できない場合は SceneAsset GameObject obj = EditorUtility.InstanceIDToObject(instanceId) as GameObject; if (obj == null) { return; } // 所持しているコンポーネント一覧を取得 Component[] components = obj.GetComponents<Component>(); // コンポーネントが一つもなければ返す if (components.Length <= 0) { return; } // すべてのコンポーネントを見る foreach (Component component in components) { // オブジェクトにつけられるスクリプトでなければ返す if (component is MonoBehaviour == false) { continue; } MonoBehaviour monoBehaviour = (MonoBehaviour) component; // SerializeFieldで表示しているものをみる foreach (FieldInfo fieldInfo in monoBehaviour.GetType() .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (fieldInfo.GetCustomAttributes(typeof(NotNullAttribute), false).Length <= 0) { continue; } // 注意アイコンを表示 object field = fieldInfo.GetValue(monoBehaviour); if (field == null || field.Equals(null)) { selectionRect.width = _ICON_SIZE; GUI.DrawTexture(selectionRect, EditorGUIUtility.Load("console.erroricon") as Texture2D); break; } } } } } 先程のTest.csをAddComponentしたオブジェクトがHierarchy上で以下のように表示されます。 もちろんオブジェクトを参照すれば注意マークは消えるようになっています。 これでNull Reference Exceptionを未然に防げるようになりましたね! 備考 Hierarchy上の警告表示について、親オブジェクトで閉じちゃうと注意マークが見えなくなります。 親のオブジェクトに警告マークをつけるような実装を追加でやっていましたが、Editorが重くなり過ぎたので断念しました、、、。 おわりに 今回はEditor拡張の作成について紹介しました。 個人的にこの機能は色んな場面で役立った印象でしたので、是非皆さんも使ってみてください。 以上、 「Applibot Advent Calendar 2021」 2日目の記事でした! 参考ブログ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む