- 投稿日:2020-04-04T21:58:03+09:00
[Unity] LineRenderer の頂点数を指定する際に旧型式と怒られた話
こんにちは。
今回はUnityで開発中に少しつまずいた事を紹介しようと思います。
とりあえず実装したかったのは、ただ線を描写したかったのです。しかし、Unityのバージョンアップの際にどうやら頂点数の指定方法に変更があったみたい。とりあえずどう変更されたのかを最初に書いていきます。変更された構文
はい。見出し通り構文が変更されていたみたいです。下に比較して書いていきます。
バージョン 構文 例文 ver5.4以前 SetVertexCount([int]); Line.SetVertexCount(2); ver5.5 numPositions = [int]; Line.numPositions = 2; ver5.6以降 positionCount = [int]; Line.positionCount = 2; 上記の通りバージョン事に少しずつ違います。
何が厄介かというと、エラーではなく警告として怒られます。なので気づかない可能性があります。例のソースコード
まずは警告されるコードを書いていきます。
sample.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class DisplayLine : MonoBehaviour { // Start is called before the first frame update void Start() { // 線オブジェクト設定 LineRenderer line = gameObject.GetComponent<LineRenderer>(); // 線の幅を指定 line.startWidth = 0.1f; line.endWidth = 0.1f; // 頂点の数を指定 line.SetVertexCount(2); // 開始位置と終了位置を指定 line.SetPosition(0, Vector3.zero); line.SetPosition(1, new Vector3(1f, 1f, 0f)); } // Update is called once per frame void Update() { } }このソースコードでは最新バージョンのUnityでは警告がでます。
頂点の数を指定のコメントアウトされているコードが問題のコードです。
では、警告が来ないソースコードに変更しましょう。sample.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class addViewLine : MonoBehaviour { // Start is called before the first frame update void Start() { // 線オブジェクト設定 LineRenderer line = gameObject.GetComponent<LineRenderer>(); // 線の幅を指定 line.startWidth = 0.1f; line.endWidth = 0.1f; // 頂点の数を指定 line.positionCount = 2; // 開始位置と終了位置を指定 line.SetPosition(0, Vector3.zero); line.SetPosition(1, new Vector3(1f, 1f, 0f)); } // Update is called once per frame void Update() { } }このように書くことで警告は消えます。
最後に
今回、このような事態がおきてしまった理由は筆者が参考にした資料(ググった)内のソースコードの書き方のバージョンが以前のものであったことです。実際、開発をしていく上でこんなの日常茶飯事なので警告がでたことにそんなにひるまなくてもいいと思いますが、言語の仕様変更に対しては敏感である必要があると改めて感じることができました。いい勉強になりました。
ついでになんですが、筆者は大学生です。はい。バイトでエンジニアしてます。
インスタでは情報発信や記事の投稿通知、役立つ情報、日常を垂れ流したりしてますのでよかったらフォローしてください。多分フォロー返します。沢山の方と繋がれたらなとか思っています。
アカウント→taaa_kundayoでは、記事は以上になります。
ありがとうございました!!
- 投稿日:2020-04-04T21:58:03+09:00
Unity LineRenderer の頂点数を指定する際に旧型式と怒られた話
こんにちは。
今回はUnityで開発中に少しつまずいた事を紹介しようと思います。
とりあえず実装したかったのは、ただ線を描写したかったのです。しかし、Unityのバージョンアップの際にどうやら頂点数の指定方法に変更があったみたい。とりあえずどう変更されたのかを最初に書いていきます。変更された構文
はい。見出し通り構文が変更されていたみたいです。下に比較して書いていきます。
バージョン 構文 例文 ver5.4以前 SetVertexCount([int]); Line.SetVertexCount(2); ver5.5 numPositions = [int]; Line.numPositions = 2; ver5.6以降 positionCount = [int]; Line.positionCount = 2; 上記の通りバージョン事に少しずつ違います。
何が厄介かというと、エラーではなく警告として怒られます。なので気づかない可能性があります。例のソースコード
まずは警告されるコードを書いていきます。
sample.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class DisplayLine : MonoBehaviour { // Start is called before the first frame update void Start() { // 線オブジェクト設定 LineRenderer line = gameObject.GetComponent<LineRenderer>(); // 線の幅を指定 line.startWidth = 0.1f; line.endWidth = 0.1f; // 頂点の数を指定 line.SetVertexCount(2); // 開始位置と終了位置を指定 line.SetPosition(0, Vector3.zero); line.SetPosition(1, new Vector3(1f, 1f, 0f)); } // Update is called once per frame void Update() { } }このソースコードでは最新バージョンのUnityでは警告がでます。
頂点の数を指定のコメントアウトされているコードが問題のコードです。
では、警告が来ないソースコードに変更しましょう。sample.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class addViewLine : MonoBehaviour { // Start is called before the first frame update void Start() { // 線オブジェクト設定 LineRenderer line = gameObject.GetComponent<LineRenderer>(); // 線の幅を指定 line.startWidth = 0.1f; line.endWidth = 0.1f; // 頂点の数を指定 line.positionCount = 2; // 開始位置と終了位置を指定 line.SetPosition(0, Vector3.zero); line.SetPosition(1, new Vector3(1f, 1f, 0f)); } // Update is called once per frame void Update() { } }このように書くことで警告は消えます。
最後に
今回、このような事態がおきてしまった理由は筆者が参考にした資料(ググった)内のソースコードの書き方のバージョンが以前のものであったことです。実際、開発をしていく上でこんなの日常茶飯事なので警告がでたことにそんなにひるまなくてもいいと思いますが、言語の仕様変更に対しては敏感である必要があると改めて感じることができました。いい勉強になりました。
ついでになんですが、筆者は大学生です。はい。バイトでエンジニアしてます。
インスタでは情報発信や記事の投稿通知、役立つ情報、日常を垂れ流したりしてますのでよかったらフォローしてください。多分フォロー返します。沢山の方と繋がれたらなとか思っています。
アカウント→taaa_kundayo
URL:https://www.instagram.com/p/B-j3-RJjPWJ/?igshid=poq7k5z6eo3nでは、記事は以上になります。
ありがとうございました!!
- 投稿日:2020-04-04T20:28:43+09:00
Animation Rigging で 握手モーションをろくろ回しモーションに作り変える
Unityの公式動画でプロシージャルモーションを作る動画が配信されていたので試してみました。
右下が元のアニメーション、中央が新しく作ったモーションになります。
腰にMuluti-Parent Constraintを、
両手にTwo Bone IK Constraintを使用しました。
ろくろアニメーション部分は、ベースとなるろくろピボットオブジェクト上に手のコントロールポイントピボットオブジェクトを置き、ろくろピボットオブジェクトをY,Zで適当に回しています。
手の部分にも元のアニメーションを若干残すため、Weightを1より小さくしました。
動画の通りに両手のコントロールポイントを作成し、それをそのままろくろピボットオブジェクト上にのせてみたのですが、それではコントロールポイントがついてきてくれなかったため、ろくろピボットオブジェクトにスクリプトをアタッチし、手のコントロールポイントをピボットオブジェクトに追随させるようにしました。
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace RokuroHand { [System.Serializable] public class RokuroHandInfo{ public Transform pivotTr; public Transform targetTr; public bool disablePosition; }; public class RokuroHandCtrl : MonoBehaviour { [SerializeField] AnimationCurve m_acY=null; [SerializeField] AnimationCurve m_acZ = null; [SerializeField] RokuroHandInfo[] m_infoArr=null; float m_timer; // Start is called before the first frame update void Start() { m_timer = 0f; } // Update is called once per frame void Update() { m_timer += Time.deltaTime; float ty = m_acY.Evaluate((m_timer * 0.25f) %1f); float tz = m_acZ.Evaluate((m_timer * 0.33f) % 1f); transform.rotation = Quaternion.Euler(0f, ty * 200f, tz * 400f); foreach (RokuroHandInfo info in m_infoArr){ if (!info.disablePosition){ info.targetTr.position = info.pivotTr.position; } info.targetTr.rotation = info.pivotTr.rotation; } } } }また、ろくろを回す際にIK制御の左腕が体にめり込んでいたのですが、空のオブジェクトを作成しHINTのところに入れ、適当なPositionを入れることでめり込まなくなりました。
- 投稿日:2020-04-04T17:10:06+09:00
コルーチンの書き方がうまくいかずエラーが出てしまいます
Unityを使ってノベルゲームの制作に挑戦しているのですが1文字ずつ表示させるためのコルーチンでエラーが出てしまいます。エラーは
Assets\Scripts\Story\WriteTxt.cs(23,29): error CS0120: An object reference is required for the non-static field, method, or property 'WriteTxt.Timer()'
です。
コルーチン部分をコメント化すると正常に作動するのでたぶんコルーチン部分が間違っていると思うのですがアドバイスをお願いします。
Unityのバージョンは2019.3.71.fです。using System.Collections;
using System.Collections.Generic;
using UnityEngine;//文字送りに必要な者たち
using UnityEngine.UI;
using System.Text.RegularExpressions;public class WriteTxt : MonoBehaviour
{
public static void Write_Txt(int num)
{
//表示中の文字数を示す変数
int msg_count=0;//メッセージの初期化 MnageSt.messageText.text=""; while(MnageSt.senario[num].Length>msg_count) { MnageSt.messageText.text+=MnageSt.senario[num][msg_count]; msg_count++; StartCoroutine (Timer()); } } IEnumerator Timer () { yield return new WaitForSeconds (1); }}
- 投稿日:2020-04-04T15:59:02+09:00
簡単リモートアセット(Unity Addressable Asset System)を試してみた (その2)
前提
- unity 2018.4.19f1
- Addressables 1.7.5
- 前の記事「簡単リモートアセット(Unity Addressable Asset System)を試してみた (その1)」
やったこと
- エディタ拡張で、デフォルトグループ内のサブアセットをルートに展開します。
- 「Addressable Assets Systemを完全に理解する ~ Addressablesウィンドウから設定する」で紹介されていたスクリプトが最近のバージョンには整合しないようでした(
Addressables 1.7.5
で確認)ので、書き直しました。- なお、アセットがルートになくてもアクセスはできるので、ルートに展開する必然性はありません。
- また、このスクリプトは、デフォルトグループだけを対象にしています。
Assets/~/Editor/MoveToRoot.csusing System.Collections.Generic; using UnityEditor; using UnityEditor.AddressableAssets; using UnityEngine; public static class AddressableAssetsUtil { // サブエントリをルートへ展開して空になったフォルダを削除 [UnityEditor.MenuItem ("Assets/Addressables/MoveSubEntryToRoot")] public static void MoveSubEntryToRoot () { var entriesCount = 0; var assetsCount = 0; var settings = AddressableAssetSettingsDefaultObject.Settings; var entries = new List<UnityEditor.AddressableAssets.Settings.AddressableAssetEntry> (settings.DefaultGroup.entries); var assets = new List<UnityEditor.AddressableAssets.Settings.AddressableAssetEntry> { }; foreach (var entry in entries) { entry.GatherAllAssets (assets, false, true, true); if (assets.Count > 0 && entry.MainAsset.GetType () == typeof (UnityEditor.DefaultAsset)) { entriesCount++; Debug.Log ($"MoveSubEntryToRoot: entry {entriesCount}: {entry.address}"); foreach (var asset in assets) { assetsCount++; Debug.Log ($"MoveSubEntryToRoot: asset {assetsCount}: {asset.address}"); settings.MoveEntry (asset, entry.parentGroup); if (asset.address.StartsWith ("Assets/")) { asset.address = asset.address.Remove (0, 7); } } assets.Clear (); settings.RemoveAssetEntry (entry.guid); } } AssetDatabase.Refresh (); // アセットを更新 Debug.Log ($"MoveSubEntryToRoot: done (entries: {entriesCount}, assets: {assetsCount})"); } }公式ドキュメント
- Class AddressableAssetSettings
- MoveEntry(AddressableAssetEntry, AddressableAssetGroup, Boolean, Boolean)
- RemoveAssetEntry(String, Boolean)
- Class AddressableAssetGroup
- GatherAllAssets(List, Boolean, Boolean, Boolean, Func)
- Class AddressableAssetSettingsDefaultObject
- GetAllAssets(List, Boolean, Func, Func)
- Class AddressableAssetEntry
- 投稿日:2020-04-04T15:07:44+09:00
UnityのSliderで作ったHPバーが、角丸になってしまう時の解決方法
- 投稿日:2020-04-04T10:49:25+09:00
GitLab Runner で Unity の Android SDK が見つからない場合の対処法
GitLab Runner で Unity の Android SDK が見つからない場合の対処法
症状
GitLab Runner で Unity の Androidアプリのビルド時に、下記のエラーが発生。
DisplayProgressbar: Detecting Android SDK UnityException: Android SDK not found Unable to locate Android SDK.解決法
- システム環境変数に「ANDROID_SDK_ROOT」を追加。
- サービス「gitlab-runner」を再起動。
説明
Unity 2018.4.20f1 の Preferences -> External Tools で Android SDK の設定はしているが、GitLab Runner でコマンドラインビルドを実行すると、上記のエラーが発生。
サービス「gitlab-runner」は別のアカウントで Windows 10 にログインしているため、レジストリに保存されている Android SDK の設定は参照されていない模様。
- 投稿日:2020-04-04T01:41:29+09:00
【Unity】オンデマンドレンダリングで描画処理負荷を抑える
はじめに
Unity 2019.3からオンデマンドレンダリング(On-demand rendering)なるものが追加されました。1
レンダリングのパフォーマンスには苦労することの多いモバイルアプリ開発などで特に有用そうな機能でしたのでご紹介します。どういうもの?
ゲームループ(MonoBehaviour.Updateとか)のフレームレートは通常通りに、レンダリングを一定間隔でスキップできる機能です。
これの一番の使いどころは(特にモバイル端末での)「レンダリング処理負荷低減」でしょう。
例えばユーザー入力待機画面のような画面の動きが激しくない(=見た目のフレームレートを落としても影響が小さい)場面なら、レンダリングを適度にスキップすることでクオリティそのままに端末の発熱や消費電力を減らすことが期待できます。また、従来からあるフレームレート調節方法であるApplication.targetFrameRateを変える方法よりも、入力の応答性という点でより良い選択になると考えられます。2
例として、入力がない間はフレームレートを落としておき、入力があったタイミングでフレームレートを上げて応答することを考えた際に下の違いがあります。あとは、シミュレーションや機械学習といったシチュエーションでも望まれていた機能ではないかと思います。
それらは実際はレンダリングを必要としないことがほとんどなので、この機能を活用してレンダリングにリソースを割かないようにすればより早く結果を得られると考えられます。使用方法
制御はスクリプトから行います。
名前空間UnityEngine.RenderingのOnDemandRenderingというクラスに3つのStaticなAPIが用意されています。OnDemandRendering.renderFrameInterval
私たちが直接変更できる唯一のプロパティであり、これでレンダリングをおこなう間隔を設定します。
例えばこれに3を代入すれば、ゲームループの3フレーム中に1回レンダリングするようになります。(レンダリング更新頻度が1/3)タッチ入力があるまで20[fps]にしておき、タッチがあったらそこから60[fps]にする例はこんな感じです。
OnDemandRenderingTest.csusing UnityEngine; using UnityEngine.Rendering; public class OnDemandRenderingTest : MonoBehaviour { private void Start() { QualitySettings.vSyncCount = 0; Application.targetFrameRate = 60; // 20 (= 60 / 3) fps OnDemandRendering.renderFrameInterval = 3; } private void Update() { if (Input.GetMouseButtonDown(0)) { // 60 fps OnDemandRendering.renderFrameInterval = 1; } } }OnDemandRendering.effectiveFrameRate
現在の設定から想定されるレンダリングフレームレート値です。
例えばゲームループを60fpsで動かしている端末なら、通常はレンダリングも60fpsですが、renderFrameIntervalを3に設定しているときは20(=60 / 3)が返ってきます。OnDemandRendering.willCurrentFrameRender
現在のゲームループフレームがレンダリング対象かを返します。
これは何に使えるのか…ということですが、レンダリングにリソースを割かなければならないフレームかどうかが判断できるので、「見た目のフレームレートを安定させつつ、高負荷な処理を裏で回す」的なことに使えるっぽいです。
なかなか使う場面は限られそうですが、使い方のイメージとしてはこんな感じでしょうか。OnDemandRenderingTest2.csusing UnityEngine; using UnityEngine.Rendering; public class OnDemandRenderingTest2 : MonoBehaviour { private void Update() { if (OnDemandRendering.willCurrentFrameRender) { // レンダリングするので重い処理はしない } else { // レンダリングしてないので重い処理を実行 } } }おわりに
今回は特に検証などはしていないですが、上手に使えば高い効果が得られそうです。
モバイルアプリ開発なんかでは積極的に取り入れていきたい機能だと感じました。参考