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

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

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

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

Q&A

解決済

1回答

1322閲覧

ランタイム生成したメッシュがずれた位置に描画される

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2017/10/24 03:47

現在Unity5.6.0 にてランタイムでメッシュを生成し、ロープ状のオブジェクトを作成しようとしています。
メッシュの定義及び描画まではできているのですが座標が( 0, 0, 0 )の時以外だとメッシュの描画位置がずれてしまいます。
詳細は↓画像にて
イメージ説明
画像左の黒い点が座標( 0, 0, 0 ) 真ん中の点が ( 1, 0, 0 )です、オブジェクト自体の座標は ( 1, 0, 0 )の位置にセットしています。
中央のギズモの点群がMeshに設定した頂点群です。
これを見る限り頂点座標は問題なさそうなのですが生成したメッシュの方に何か原因があるのでしょうか?

ランタイムでのメッシュ生成は初めてですので至らないところがありますがソースコードは以下の通りです。
よろしくお願いします。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5 6 7//============================================================================== 8//------------------------------------------------------------------------------ 9// チューブ描画レンダラー. 10// http://wiki.unity3d.com/index.php/3D_Physics_Based_Rope 11// ↑のページのソースを参考に. 12public class TubeRenderer : MonoBehaviour { 13 14 15 //============================================================================== 16 //------------------------------------------------------------------------------ 17 public class TubeVertex { 18 public Vector3 point = Vector3.zero; 19 public float radius = 1f; 20 public Color color = Color.white; 21 22 23 //------------------------------------------------------------------------------ 24 // コンストラクタ. 25 public TubeVertex( 26 Vector3 _pt, 27 float _r, 28 Color _color ) { 29 30 point = _pt; 31 radius = _r; 32 color = _color; 33 } 34 } 35 36 37 [SerializeField] private TubeVertex[] vertices; 38 public TubeVertex[] Vertices { get { return vertices; } set { vertices = value; } } 39 40 [SerializeField] private bool useMeshCollision = false; 41 public bool UseMeshCollision { get { return useMeshCollision; } set { useMeshCollision = value; } } 42 43 [SerializeField] private int crossSegments = 3; 44 public int CrossSegments { get { return crossSegments; } set { crossSegments = value; } } 45 46 [SerializeField] private Material material; 47 public Material Mat { get { return material; } set { material = value; } } 48 49 [SerializeField] private float floatAtDistance = -1f; 50 [SerializeField] private int movePixelsForRebuild = 6; 51 [SerializeField] private float maxRebuildTime = 0.1f; 52 [SerializeField] private Vector3 lastCamearPosition1; 53 [SerializeField] private Vector3 lastCameraPosition2; 54 [SerializeField] private Vector3[] crossPoints; 55 [SerializeField] private bool isDrawGizmo = false; 56 [SerializeField] private bool colliderExists = false; 57 [SerializeField] private bool usingBumpmap = false; 58 59 private Mesh mesh; 60 private float lastRebuildTime = 0f; 61 private int lastCrossSegments; 62 63 64 //------------------------------------------------------------------------------ 65 void Start () { 66 this.reset(); 67 mesh = new Mesh(); 68 var _meshRenderer = gameObject.GetComponent<MeshRenderer>(); 69 _meshRenderer.material = material; 70 if ( material ) { 71 if ( material.GetTexture( "_BumpMap" ) ) 72 usingBumpmap = true; 73 } 74 } 75 76 77 //------------------------------------------------------------------------------ 78 void LateUpdate() { 79 80 if ( vertices == null || vertices.Length <= 1 ) return; 81 82 83 if ( crossSegments != lastCrossSegments ) { 84 crossPoints = new Vector3[ crossSegments ]; 85 float _theta = 2f * Mathf.PI / crossSegments; 86 for ( int i = 0; i < crossSegments; ++i ) { 87 crossPoints[i] = new Vector3( Mathf.Cos( _theta * i ), Mathf.Sin( _theta * i ), 0 ); 88 } 89 lastCrossSegments = crossSegments; 90 } 91 92 93 Vector3[] _meshVertices = new Vector3[ vertices.Length * crossSegments ]; 94 mesh.vertices = new Vector3[ vertices.Length * crossSegments ]; 95 Vector2[] _uvs = new Vector2[ vertices.Length * crossSegments ]; 96 Color[] _colors = new Color[ vertices.Length * crossSegments ]; 97 int[] _lastVertices = new int[ crossSegments ]; 98 int[] _theseVertices = new int[ crossSegments ]; 99 Quaternion _rotation = transform.rotation; 100 101 // 頂点作成. 102 for ( int i = 0; i < vertices.Length; ++i ) { 103 104 if ( i < vertices.Length - 1 ) 105 _rotation = Quaternion.FromToRotation( Vector3.forward, vertices[i].point - vertices[ i + 1 ].point ); 106 107 for ( int j = 0; j < crossSegments; ++j ) { 108 int _vertexIndex = i * crossSegments + j; 109 _meshVertices [ _vertexIndex ] = vertices[i].point + ( _rotation * crossPoints[j] ) * vertices[i].radius; 110 111 _uvs[ _vertexIndex ] = new Vector2( ( 0f + j ) / crossSegments, ( 0f + i ) / vertices.Length ); 112 _colors[ _vertexIndex ] = vertices[i].color; 113 114 _lastVertices[j] = _theseVertices[j]; 115 _theseVertices[j] = i * crossSegments; 116 } 117 } 118 119 // TriangleListを作成. 120 // 手前蓋閉め,チューブインデックス追加,先端蓋閉め. 121 List<int> _tempList = new List<int>(); 122 for ( int i = 0; i < crossSegments - 2; ++i ) { 123 if ( i < 1 ) { 124 _tempList.Add( 0 ); 125 _tempList.Add( 1 ); 126 _tempList.Add( 2 ); 127 } else { 128 int _num = i + 1; 129 _tempList.Add( _num ); 130 _tempList.Add( _num + 1 ); 131 _tempList.Add( 0 ); 132 } 133 } 134 135 for ( int i = 0; i < vertices.Length - 1; ++i ) { 136 for ( int j = 0; j < crossSegments; ++j ) { 137 int _a = i * crossSegments + j; 138 int _b = ( i + 1 ) * crossSegments + j; 139 140 if ( j < crossSegments - 1 ) { 141 _tempList.Add( _a ); 142 _tempList.Add( _a + crossSegments ); 143 _tempList.Add( _a + 1 ); 144 145 _tempList.Add( _a + crossSegments ); 146 _tempList.Add( _a + crossSegments + 1 ); 147 _tempList.Add( _a + 1 ); 148 } else { 149 _tempList.Add( _a ); 150 _tempList.Add( _a + crossSegments ); 151 _tempList.Add( i * crossSegments ); 152 153 _tempList.Add( _a + crossSegments ); 154 _tempList.Add( i * crossSegments + crossSegments ); 155 _tempList.Add( i * crossSegments ); 156 } 157 } 158 } 159 160 for ( int i = _meshVertices.Length; ( _meshVertices.Length - crossSegments ) + 2 < i; --i ) { 161 if ( _meshVertices.Length <= i ) { 162 _tempList.Add( _meshVertices.Length - 1 ); 163 _tempList.Add( _meshVertices.Length - 2 ); 164 _tempList.Add( _meshVertices.Length - 3 ); 165 } else { 166 int _num = i - 2; 167 _tempList.Add( _meshVertices.Length - 1 ); 168 _tempList.Add( _num ); 169 _tempList.Add( _num - 1); 170 } 171 } 172 mesh.Clear(); 173 mesh.vertices = _meshVertices; 174 mesh.triangles = _tempList.ToArray(); 175 mesh.RecalculateNormals(); 176 177 178 if ( usingBumpmap ) 179 mesh.tangents = calculateTangents( mesh.vertices ); 180 mesh.uv = _uvs; 181 182 if ( useMeshCollision ) { 183 if ( colliderExists ) { 184 gameObject.GetComponent<MeshCollider>().sharedMesh = mesh; 185 } else { 186 gameObject.AddComponent<MeshCollider>(); 187 colliderExists = true; 188 } 189 } 190 gameObject.GetComponent<MeshFilter>().mesh = mesh; 191 192 } 193 194 195 //------------------------------------------------------------------------------ 196 // ギズモ描画. 197 void OnDrawGizmos() { 198 199 if ( !isDrawGizmo ) return; 200 if ( vertices != null && 0 < vertices.Length) { 201 202 for ( int i = 0; i < mesh.vertices.Length; ++i ) { 203 Gizmos.color = Color.white; 204 Gizmos.DrawWireSphere( mesh.vertices[i], 0.02f ); 205 } 206 207 for ( int i = 0; i < mesh.triangles.Length; ++i ) { 208 switch ( mesh.triangles[i] % 3 ) { 209 case 0: Gizmos.color = Color.red; break; 210 case 1: Gizmos.color = Color.blue; break; 211 case 2: Gizmos.color = Color.green; break; 212 } 213 Gizmos.DrawSphere( mesh.vertices[ mesh.triangles[i] ], 0.01f ); 214 } 215 } 216 217 } 218 219 220 221 222 //------------------------------------------------------------------------------ 223 // 正接を求める. 224 public Vector4[] calculateTangents( 225 Vector3[] _verts ) { 226 227 Vector4[] _tangents = new Vector4[ _verts.Length ]; 228 for ( int i = 0; i < _tangents.Length; ++i ) { 229 Vector3 _vertex1 = ( 0 < i ) ? _verts[ i - 1 ] : _verts[i]; 230 Vector3 _vertex2 = ( i < _tangents.Length -1 ) ? _verts[ i + 1 ] : _verts[i]; 231 Vector3 _tan = ( _vertex1 - _vertex2 ).normalized; 232 _tangents[i] = new Vector4( _tan.x, _tan.y, _tan.z, 1f ); 233 } 234 return _tangents; 235 } 236 237 238 //------------------------------------------------------------------------------ 239 // 座標をセット. 240 public void setPoints( 241 Vector3[] _points, 242 float _radius, 243 Color _color ) { 244 245 if ( _points.Length < 2 ) return; 246 vertices = new TubeVertex[ _points.Length ]; 247 for ( int i = 0; i < _points.Length; ++i ) { 248 vertices[ i ] = new TubeVertex( _points[i], _radius, _color ); 249 } 250 } 251 252 253 //------------------------------------------------------------------------------ 254 public void reset() { 255 vertices = new TubeVertex[]{ new TubeVertex( Vector3.zero, 1f, Color.white ), new TubeVertex( new Vector3( 1, 0, 0 ), 1f, Color.white ) }; 256 } 257} 258

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

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

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

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

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

guest

回答1

0

ベストアンサー

自己解決解決しました

先ほど張り付けたスクリプトはロープの描画のみを行うクラスだったのですが原因はそのスクリプトに座標を指定するクラスにありました...

構成としては以下の画像の通りです
イメージ説明
イメージ説明

RopeLinePFオブジェクトに
RopeLine.cs : ロープのジョイント作成等の処理及びジョイント座標更新処理
TubeRenderer.cs : ロープのメッシュ描画処理
↑コンポーネントをアタッチしている構成で、各ジョイントはRopeLinePFオブジェクトの子要素にしています。
この時の座標更新処理ですがRopeLine.cs側での座標更新処理にて以下の画像の通りに変更したら解決しました。
イメージ説明
コメントアウトされているのが問題があったバージョンのソース.

投稿2017/10/24 05:17

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問