質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

4776閲覧

【Unity】LineRendererが思うように扱えない時の対処方法

pip

総合スコア19

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2018/09/30 23:16

編集2018/09/30 23:19

抽象的なタイトルで申し訳ありません。

Unityのルートの軌跡を描くようなプログラムを作っているのですが、実行結果に違和感のようなものがあります。
軌跡の描画にはLineRendererを使っているのですが、線が掠れてしまったり、始点の切り替えが出来なかったりします。

上記方法を解決するには、
LineRendelerの使い方に誤りがあるのか、
そもそも別のコンポーネントや方法を取るべきなのか判断できません。

ざっくりした内容で申し訳ございませんが、何か良い方法があればご教示頂きたいです。

当初の仕様仕様

プレイヤー(添付した動画の緑カプセル)の移動に合わせて、LineRendererで軌跡を描きます。
チェックポイント(添付した動画の黄色玉)まで移動すると、LineRendererの始点がチェックポイントに代わります。
イメージとしては一本線で描きます。

イメージ説明

プレイヤーは手動操作ではなく、あらかじめ決めたルートを自動で移動します。

実際に実行した時の挙動。

実際に動かしたときの挙動をキャプチャしたものをyoutubeにアップしました。
実際の挙動をキャプチャしたもの

問題点

最終的には、正しい線になるのですが、途中の表示が想定とは違う挙動をします。
添付したyoutubeの動画をご覧いただけると幸いですが、下記の問題が生じます。

  • 一番最初の点からのプレイヤーまで常に繋がった状態になってしまう。
  • チェックポイントを通過すると、始点が変わってしまう。
  • 途中で線が消えかけてしまう

結果画面

イメージ説明

実際のソース

質問用に一部調整していますが、ほぼ、同じような構成です。

後述しますが、キーやボタン等でdoMovenmentを実行することで動きます。
チェックポイント間の移動はDOTweenというアセットを使って制御しています。

USERクラス

チェックポイント

cs

1class point { 2 public int Index; 3 public Vector3 Postion; 4 5 public point ( 6 int index; 7 Vector3 position; 8 ){ 9 Index = index; 10 Postion = position; 11 } 12}

実行するスクリプト

プレイヤーのオブジェクトに追加します。

cs

1class routeing { 2 public GameObject Walker; // プレイヤー自体にオブジェクト 3 4 public Point[] Points = new Points[]{ 5 new Point(1, new Vector3(座標情報)), 6 new Point(2, new Vector3(座標情報)), 7 new Point(3, new Vector3(座標情報)), 8 ... 9 new Point(9, new Vector3(座標情報)), 10 } 11 12 public LineRenderer _LineRenderer // 13 public int LineNumber = 0; // LineRenderer.SetPositionで指定するindex 14 15 public void doMovenment() 16 { 17 18 // 初期設定 19 _LineRenderer.positionCount = Points.Length + 1; 20 _LineRenderer.SetPosition(LineNumber, Points[0].transform.position); 21 LineNumber++; 22 23 // 自動的に実行する処理 24 Sequence sequence = DOTween.Sequence(); 25 26 for (int i = 1; i < Points.Length; i++) 27 { 28 sequence.SetDelay(Delay); 29 30 sequence.Append( 31 DOTween.To( 32 () => Walker.transform.position, 33 v => 34 { 35 Walker.transform.position = v; 36 _LineRenderer.SetPosition( 37 LineNumber, Walker.transform.position); 38 }, 39 Points[i].TeacherObject.transform.position, 40 Verocity 41 ) 42 ).AppendCallback(() => 43 { 44 LineNumber++; 45 }); 46 } 47 48 // 最後までルートを通り終わったら開始地点に戻る 49 sequence.SetDelay(Delay); 50 sequence.Append( 51 DOTween.To( 52 () => Walker.transform.position, 53 v => 54 { 55 Walker.transform.position = v; 56 }, 57 Points[0].TeacherObject.transform.position, 58 Verocity 59 ) 60 ); 61 } 62} 63

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

■最初の点からの線が常に繋がってしまう問題
_LineRenderer.positionCount = Points.Length + 1;

最初にポイントを作ってしまっているため、LineRendererのPositionsを見ると、
0,0,0の点が入っていると思います。こうなると、0,0,0に向かって線を引くので、
最初の点とつながっているようになります。

解決策としては、次の点に移動するたびに、_LineRenderer.positionCountを足していきます。

■Delay
sequence.SetDelay(Delay);
では、シーケンス自体の遅延になってしまうため、
sequence.AppendInterval(Delay); が良いかと思います。

■開始地点に戻る処理
var PointList = Points.ToList();
PointList.Add(Points[0]);

とやって、開始地点を足した一時リストを作ると、
後のTweenが不要になり見やすくなります。

■線が消える問題

線が重なってしまった場合はちらつきます。これは3Dなので仕方ありません。
重ねないようにするのが簡単かと思います。描画順を弄る、という方法もありますが難しいと思います。

あとはLineRendererは急に角度が変わったときなどに、ねじれます。
3Dで、薄い板の線なので、角度が変わってねじれる、ということです。
これはちょっと解決が難しいです。

例えば
毎フレーム、_LineRenderer.positionCountを増やして、点を打っていけば、
ねじれは目立ちません。ただかなり重いと思います。
カーブの直前、直後だけ点を増やせるとよさそうですがすぐにはできませんでした。

あとは線1本につき1つのLineRendererを使う方法があるので、
恐らくこちらが良いかと思います。

using System.Linq; class routeing { public GameObject Walker; // プレイヤー自体にオブジェクト public Point[] Points = new Points[]{ new Point(1, new Vector3(座標情報)), new Point(2, new Vector3(座標情報)), new Point(3, new Vector3(座標情報)), ... new Point(9, new Vector3(座標情報)), } public LineRenderer _LineRenderer // public int LineNumber = 0; // LineRenderer.SetPositionで指定するindex public void doMovenment() { // 初期設定 _LineRenderer.SetPosition(LineNumber, Points[0].transform.position); LineNumber++; // 自動的に実行する処理 Sequence sequence = DOTween.Sequence(); var PointList = Points.ToList(); PointList.Add(Points[0]); for (int i = 1; i < PointList.Count; i++) { sequence.Append( DOTween.To( () => Walker.transform.position, v => { Walker.transform.position = v; _LineRenderer.SetPosition(LineNumber, Walker.transform.position); }, PointList[i].TeacherObject.transform.position, Verocity ) ).AppendCallback(() => { LineNumber++; _LineRenderer.positionCount _LineRenderer.SetPosition(LineNumber, Walker.transform.position); });       sequence.AppendInterval(Delay); } } }

投稿2018/10/01 03:57

編集2018/10/01 03:59
ganta7188

総合スコア436

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pip

2018/10/01 11:35

ありがとうございます! ご連絡が遅れてしまい申し訳ありません。 確認させていただきます。
pip

2018/10/01 15:32

ありがとうございます。解決出来ました。 ソースのご共有もありがとうございます。 LineRendererがねじれる件も承知しました。 個人的には、カメラに対して正面を向かせるという方法を思いつきましたが、実装は大変だろうなという気がします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問