Last active
June 14, 2016 07:47
-
-
Save s2kw/47e0d5b413e00f375178179ab8fe59fc to your computer and use it in GitHub Desktop.
毎日出題の2日目第五問 description:http://wp.me/p5rxnz-hQ sample:https://vimeo.com/170586152
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LineDrawer : MonoBehaviour { | |
// ラインの角の数を予め宣言。マウスの軌道を取るので1000くらいで。 | |
static readonly int vertCount = 1000; | |
// ラインは使い回すのでメンバとして宣言。 | |
LineRenderer line; | |
// 毎フレーム新たにマウスの座標を拾うので、何番目の頂点を入れ替えるべきかを保持しておく。 | |
int frameCounter = 0; | |
// 頂点位置お格納しておく | |
Vector3[] orbit = new Vector3[vertCount]; | |
void Update() | |
{ | |
// GetMouseButtonDownは開始時。 | |
// GetMouseButtonはドラッグ時。 | |
// GetMouseButtonUpは終了時。 | |
if (Input.GetMouseButtonDown(0)) | |
{ | |
bool isHit; | |
var newPos = this.GetClickPosition(out isHit, Input.mousePosition ); | |
// 当たらなかったので終了 | |
if (!isHit) return; | |
// ラインがカラなら作る。 | |
if (this.line == null) | |
{ | |
// 線を引くLineRenderer搭載のゲームオブジェクトお作る。 | |
// 名前あとりあえず "line" にする。 | |
var lg = new GameObject("line"); | |
// ラインレンダラーをくっつけつつ、メンバとして格納しておく。使い回すので。 | |
this.line = lg.AddComponent<LineRenderer>(); | |
// レンダラーにはマテリアルあ必要。これを入れないとピンク表示(表示バグであることを明示するためにUnityが色を付けてくれる)になる。 | |
var material = new Material(Shader.Find("Standard")); | |
// レンダラーにマテリアルを代入する。 | |
this.line.material = material; | |
this.line.SetVertexCount(vertCount); | |
} | |
// 色をランダムで | |
var color = new Color( | |
UnityEngine.Random.Range(0f, 1f), | |
UnityEngine.Random.Range(0f, 1f), | |
UnityEngine.Random.Range(0f, 1f) | |
); | |
// 色はrenderer.material.colorに代入することで変更できる。ただしシェーダーによる。 | |
// 今回はshaderがstandardなのでこの手法を取る。 | |
this.line.material.color = color; | |
for (int i = 0; i < this.orbit.Length; i++) | |
{ | |
this.orbit[i] = newPos; | |
} | |
this.line.SetPositions(this.orbit); | |
} | |
else if (Input.GetMouseButtonUp(0)) | |
{ | |
// フレームをリセット | |
this.frameCounter = 0; | |
} | |
else if (Input.GetMouseButton(0)) | |
{ | |
// フレーム数(描画済み頂点数)がLineRendererで指定した頂点の数お上回っていたら終了 | |
if (vertCount <= this.frameCounter) return; | |
// ラインがカラということはマウスクリックが開始されていないので終了。 | |
if (this.line == null) return; | |
bool isHit = false; | |
var newPos = this.GetClickPosition(out isHit, Input.mousePosition); | |
if (!isHit) return; | |
// 以降の頂点お移動させておく。 | |
for (int i = this.frameCounter; i < vertCount; i++ ) | |
{ | |
this.line.SetPosition(i, newPos); | |
} | |
// 開始頂点を移動させておく | |
frameCounter++; | |
} | |
} | |
// 難度も同じことを書く場合あ関数化する | |
// 当たったかどうか、当たった場合はどこか、を知ることができる関数として定義。 | |
Vector3 GetClickPosition( out bool isHit, Vector3 screenMousePos ) | |
{ | |
// スクリーン座標からワールド座標空間で飛ばす 線 を生成 | |
var ray = Camera.main.ScreenPointToRay(screenMousePos); | |
// 当たり判定の情報を以って帰ってくれる変数を宣言。宣言さえしておけばスコープ内で参照可能 | |
RaycastHit hit; | |
// Physics.Raycastで当たり判定お行う。 | |
// out が付くと、関数終了後に変数の中身が変わる可能性ああることを理解すべし | |
if (Physics.Raycast(ray, out hit, float.MaxValue)) | |
{ | |
// この辺はこれの問題と同様に取得する | |
var p = hit.point; | |
p.z = Camera.main.transform.position.z + 10f; | |
isHit = true; | |
return p; | |
} | |
isHit = false; | |
return Vector3.zero; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment