Open1
Unityで線を引くコード
何がしたいのか
線が引きたくてですね。
素直にLineRendererを使えばいいんですが、
DrawMeshを利用している関係上少しやりづらい。
ということで、DrawMeshだけでなんとか線を引けるように検討する。
手順
- 頂点を定義
- UV座標を定義(頂点と同じ数)
- 三角形の構成を定義
- DrawMeshのAPIコール時に上記情報を指定(Meshクラスに格納されてる)
あとは点を中心に進行方向(次の点へのベクトル)と垂直に幅を取って2点を定義すれば
線が完成する。
ピクセル単位の線ではなく、あくまでテクスチャ付きポリライン扱い。
余談
テクスチャの位置が反転しているっぽいけど、これは三角形の定義順とかも絡んでくる。
コード
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class LineDraw : MonoBehaviour {
[SerializeField]
Material m_mat;
Mesh m_mesh;
public float buf_x=1.0f;
public float buf_y=1.0f;
public float offset_x=0.0f;
public float offset_y=0.0f;
private int bullet_num=1;
//
private Vector2[] uv_base;
private Vector2[] uv_result=new Vector2[8];
private float delta = 0.01666667f;
private float _time;
private float _pre_time;
public class status{
public float x;
public float y;
public float z;
public bool isAlive;
public int count;
public float dx;
public float dy;
public status(){
x=0.0f;
y=0.0f;
isAlive=false;
count=0;
dx=0.0f;
dy=0.0f;
}
};
private Vector2 offset;
public status[] bullet_status;
private MaterialPropertyBlock _materialPropertyBlock;
void Start () {
// 動的なMesh生成
m_mesh = new Mesh();
m_mesh.vertices = new Vector3[] {
new Vector3 (-1.0f+3.0f, -1.0f),
new Vector3 (1.0f+2.0f, -1.0f),
new Vector3 (1.0f, 0.0f),
new Vector3 (-1.0f, 0.0f),
new Vector3 (1.0f, 3.0f),
new Vector3 (-1.0f, 3.0f),
new Vector3 (1.0f-3.0f, 6.0f),
new Vector3 (-1.0f-2.0f, 6.0f),
};
uv_base = new Vector2[]
{
new Vector2(0,0),
new Vector2(0.25f,0),
new Vector2(0.25f,0.5f),
new Vector2(0, 0.5f),
new Vector2(0.25f,0.75f),
new Vector2(0, 0.75f),
new Vector2(0.25f,1.0f),
new Vector2(0, 1.0f),
};
m_mesh.triangles = new int[] {
0, 3, 2,
0, 2, 1,
3, 4, 2,
3, 5, 4,
5,7,6,
5,6,4,
};
m_mesh.RecalculateNormals();
m_mesh.RecalculateBounds();
bullet_status = new status[bullet_num];
for(int i=0;i<bullet_num; i++){
bullet_status[i] = new status();
bullet_status[i].dx = 0.0f;//Random.Range(-0.05f, 0.05f);
bullet_status[i].dy = 0.0f;//Random.Range(-0.05f, 0.05f);
bullet_status[i].isAlive = true;
bullet_status[i].count=i;
bullet_status[i].z = i*0.00001f;
}
//_materialPropertyBlock = new MaterialPropertyBlock();
_time=Time.deltaTime;
_pre_time=Time.deltaTime;
}
private void Update()
{
bool isMove = false;
_time += Time.deltaTime;
if( _time> delta){
isMove =true;
_time=0.0f;
//Debug.Log(_time);
}
selfUpdate(isMove);
}
public void selfUpdate(bool isMove){
//_materialPropertyBlock.Clear();
Material tmp = m_mat;
for(int i=0; i<bullet_num; i++ ){
//描画命令
if( bullet_status[i].isAlive==true){
//UV座標の更新
for( int j=0; j<8; j++){
{
uv_result[j].x = uv_base[j].x;// + (bullet_status[i].count%4*0.25f);
}
//Y座標は変化なし
uv_result[j].y= uv_base[j].y;
}
//UV座標をアニメさせる
m_mesh.uv = uv_result;
if( isMove== true){
bullet_status[i].x += bullet_status[i].dx;
bullet_status[i].y += bullet_status[i].dy;
}
tmp = m_mat;
/*
offset.x = bullet_status[i].count%4*0.25f;
offset.y = 0.0f;
*/
//_materialPropertyBlock.SetTextureOffset("_MainTex", offset);
//_materialPropertyBlock.SetVector("_MainTex_ST", new Vector4(1.0f, 1.0f, bullet_status[i].count%4*0.25f, 0.0f));
Graphics.DrawMesh(m_mesh, new Vector3(bullet_status[i].x,
bullet_status[i].y,
bullet_status[i].z),
Quaternion.identity,//Quaternion.AngleAxis(20*(float)(bullet_status[i].count%18), new Vector3(0,0,1)), //
tmp, 0
//,null, 0, _materialPropertyBlock, false, false
);
}
//カウント
if( isMove == true){
bullet_status[i].count++;
if( bullet_status[i].count>0)
bullet_status[i].isAlive=true;
}
}
}
}