Vector3クラスのメモ

Vector3クラスのメモ


Vector3.normalized


これを利用する事は結果的に「傾き」を得る事に等しい

直線y=0.5x
この場合の傾きは0.5であるが、これをベクターに直すと

new Vector2(Mathf.Cos (0.5f*Mathf.PI*2),Mathf.Sin (0.5f*Mathf.PI*2))

となる。これは理屈で考えると複素数を使って0.5で円周を半周回転した位置をベクトルであらわしている事になる
つまり開始位置がVector2(1, 0)、これを半周してVector2(-1, 0)の位置になっている

y=0x Vector2(1, 0)
y=0.25x Vector2(0, 1)
y=0.5x Vector2(-1, 0)
y=0.75x Vector2(0, -1)
...  

長さ=1のVector2は半径1の円と同じだと考えると良い

new Vector2(2,2).normalized

これの値はVector2(0.7071,0.7071)となる
これを 傾きの公式 m = Δy/Δx にあてはめると
0.7071/0.7071 = 1 で傾きは1となる
y=1x は vector2(0.7071,0.7071) = Vector2(2,2).normalized
y=0.5574x は Vector2(0.8734, 0.4869) = new Vector2(452,252).normalize になる

こうすればベクターの方向からスカラーを無視して角度だけ傾きに転写できる
そして、この傾きを利用する事でゲームのキャラクターを自在に動かす事が可能となる

Vector3.Project

法線に投影されたベクトルを返す
利用方法がちょっと分りにくい概念ではあるが、これは例えばベクトル反射の計算の途中で利用される(参考:物体との衝突

画像を表示

using UnityEngine;
using System.Collections;

public class ProjectionTest2 : MonoBehaviour {

  Vector3 vi,Ndush,P;

  void Start () {
       Ndush = new Vector3(1,2);
       vi = new Vector3(5,3);
       P = Vector3.Project(vi,Ndush);     //第二引数は渡す際ノーマライズしなくても良い
   }
   
   void Update () {
       Vector3 NdushVisivle = new Vector3(0.03f,0.03f,0.03f);
       
       Debug.DrawLine(Vector3.zero+NdushVisivle,Ndush+NdushVisivle,Color.green);
       Debug.DrawLine(Vector3.zero,vi);
       Debug.DrawLine(Vector3.zero,P,Color.red);
   }
}

Vector3.OrthoNormalize

正規化された値とそれに直交する値を返す。

  Vector3 basisA,basisB,basisC;
   
   void Start () {
       Vector3.OrthoNormalize(ref basisA,ref basisB,ref basisC);
       print(basisA+" / " +basisB+" / " +basisC);

      basisA = Vector3.left;
       Vector3.OrthoNormalize(ref basisA,ref basisB,ref basisC);
       print(basisA+" / " +basisB+" / " +basisC);

      basisA = Vector3.up;
       Vector3.OrthoNormalize(ref basisA,ref basisB,ref basisC);
       print(basisA+" / " +basisB+" / " +basisC);
   }

(1.0,0.0,0.0) / (0.0,1.0,0.0) / (0.0,0.0,1.0)
(-1.0,0.0,0.0) / (0.0,-1.0,0.0) / (0.0,0.0,1.0)
(0.0,1.0,0.0) / (-1.0,0.0,0.0) / (0.0,0.0,1.0)

左手の座標系を返す関数らしい

すべてのパラメーターがVector3.zeroだと
(1.0,0.0,0.0) / (0.0,1.0,0.0) / (0.0,0.0,1.0) を返す


Vector3.Distance


2点間の距離を返す。Vector3.magnitude では (a-b).magnitude で同じ値が得られる

  public GameObject player, enemy;
   float dist,dist2;
   
   void Start () {
       dist = Vector3.Distance(player.transform.position,enemy.transform.position);
       dist2 = (enemy.transform.position - player.transform.position).magnitude;

1.414214
1.414214

Vector3.Angle



2「点」間の角度を返す。というより、ふたつのベクトル(方向)の角度差を返すという意味で考えた方が良い(内積Dotに近い)
+-やベクトルの長さは無視される

  Vector3 vec1, vec2;
   float answer;
   
   void Start ()
   {
       vec1 = Vector3.forward;
       vec2 = Vector3.right;
       print (Vector3.Angle (vec1, vec2));

      vec1 = new Vector3 (0, 0, 1);
       vec2 = new Vector3 (0.866f, 0, 0.5f);
       print (Vector3.Angle (vec1, vec2));
       
       vec1 = new Vector3 (0, 0, 1 * 5f);
       vec2 = new Vector3 (-0.866f * 2f, 0, 0.5f * 2f);
       print (Vector3.Angle (vec1, vec2));
       
   }

90
59.9999
59.9999

Vector3.ClampMagnitude



Mathf.Clamp の Vector3版。下記の場合、ベクトルの大きさ(長さ)がradiusを越えるとクランプされる。オフセット位置を適用したい場合は少し工夫が必要か
見た感じ半径 radius の円の中を動けるような感じになる

  public Vector3 offset = new Vector3 (2, 0, 0);
   public float radius = 3.0f;
   Vector3 pos = Vector3.zero;
   
   void Update ()
   {
       pos += new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
       pos = offset + Vector3.ClampMagnitude (pos - offset, radius);
       transform.position = pos;
   }

Vector3.Lerp


2 点間の特定の位置を返す。 Lerp( 開始点 , 終了点 , 0~1の比率); みたいな感じ
Mathf.LerpのVector3版

例:
go.transform.position = Vector3.Lerp(pos1,pos2,Mathf.PingPong(timer,1));


Vector3.MoveTowards

2 点間の特定の位置を返す。MoveTowards(開始点,終了点,距離);
第3引数が距離である事が最大の特徴

自前で同じような関数を作ってみるテスト
using UnityEngine;
using System.Collections;

public class MoveTowardsTest : MonoBehaviour
{
  
   public GameObject testObjPref, pointA, pointB;
   GameObject go, go2;
   Vector3 pos1, pos2;
   float distance;
   
   void Start ()
   {
       pos1 = pointA.transform.position;
       pos2 = pointB.transform.position;
       
       go = Instantiate (testObjPref, pos1, Quaternion.identity) as GameObject;
       go2 = Instantiate (testObjPref, Vector3.forward + pos1, Quaternion.identity) as GameObject;
   }
   
   void FixedUpdate ()
   {
       distance += Time.deltaTime * 4;
       go.transform.position = Vector3.MoveTowards (pos1, pos2, distance);
       go2.transform.position = Vector3.forward + CustumMoveTowards (pos1, pos2, distance);
       
   }

  Vector3 CustumMoveTowards (Vector3 vec1, Vector3 vec2, float distance)
   {
       Vector3 ret;
       Vector3 vector = vec2 - vec1;
       Vector3 move = vector.normalized * distance;
       if (move.sqrMagnitude < vector.sqrMagnitude) {
           ret = vec1 + move;
       } else {
           ret = vec2;
       }
       
       return ret;
   }
}


Vector3.Max とVector3.Min


各成分の大きい方を成分にしてVector3を返す。Minはこの逆

  Vector3 vec1,vec2;
   Vector3 answer;
   
   void Start () {
       vec1 = new Vector3(4,2,4);
       vec2 = new Vector3(1,8,6);
       answer = Vector3.Max(vec1,vec2);
       print(answer);

      answer = Vector3.Min(vec1,vec2);
       print(answer);
   }

4,8,6
1,2,4

複数のオブジェクトを包み込むバウンディングボックスの作成等に使えそう?

  • 最終更新:2014-01-13 03:03:37

このWIKIを編集するにはパスワード入力が必要です

認証パスワード