自分で考えといてアレですが ナンヤネンこのタイトルは…… てことで知恵熱回です |
いつものように 処理のドツボにハマった部分を力技で 解決するという世界のプログラマーさんゴメンなさい状態なのよね |
まー 勉強が大嫌いだった冬月だからなぁ 独学で今頃ヒーヒー言っているわけだ |
ということで その力技の実装方法をメモ程度に書いておこうかなと思います 続きを読むからどうぞ~ |
~キャラの回転運動~
言うは易し 行うは難しとのことでキャラを回転運動させようってことです アミノ式じゃないですよ |
/*
予め、
Vector3 tagetPos : 回転させる中心座標
float moveRot : 回転角度
float distance : 回転させる幅の半径
を取得する
*/
//回転運動のプログラム
Vector3 nextPos; //回転後の座標
//三角関数を使って計算する
nextPos.x = tagetPos.x + Mathf.Sin(moveRot) * distance;
nextPos.z = tagetPos.z + Mathf.Cos(moveRot) * distance;
以上が回転運動を表現するプログラムよ コレは応用も聞くし便利なので暗記してるわ 回転運動系はコレでほぼなんとか出来るわね |
しかし、コレで求められるのは 回転後の座標値なんだよな Unityは3軸の移動速度でオブジェクトの移動を表現するんだよな |
つまり 座標ではなくて移動速度(移動差分)を求めないといけないんですよね ほら、ややこしくなってきましたでしょ? |
そして冬月先生は出身高校が普通科高校&不良校だったため 数学の知識は人並み以下だったりします 数式出されても理解できません…… |
/*
予め、
Vector3 tagetPos : 回転させる中心座標
Vector3 prevPos : 前フレーム(前回)の座標
float moveRot : 回転角度
float distance : 回転させる幅の半径
を取得する
*/
//回転運動のプログラム
Vector3 nextPos; //回転後の座標
//三角関数を使って計算する
nextPos.x = tagetPos.x + Mathf.Sin(moveRot) * distance;
nextPos.z = tagetPos.z + Mathf.Cos(moveRot) * distance;
//過去の位置と現在の位置を比べて差分を算出(コレを速度としようとした
Vector3 newVelocity; //速度(差分
newVelocity.x = nextPos.x - prevPos.x;
newVelocity.z = nextPos.z - prevPos.z;
考え方は小学生でも出来るわね 回転前の数値と回転後の数値を比較して、その差分を速度とするのよ 結論から行くとうまく行かなかったわ |
なんでうまく行かなかったか? 前と後をつなぐ移動が曲線ではなく直線になってしまうから なんだな |
曲線を描くはずの移動が直線になると何が問題なのか?と言いますと 曲の部分を直線に進むため、半径(対象との距離)が近くなってしまう のですね |
移動結果は ナルトの渦巻きのように中心に近づきつつ回転運動をします 面白いですが失敗です |
/*
予め、
Vector3 tagetPos : 回転させる中心座標
Vector3 playerPos : 自分自身の座標
float verticalVelocity : 縦移動速度
float horizontalVelocity : 横移動速度
を取得する
*/
//中心(ターゲット先)との距離を求める
float Distance = Vector3.Distance(playerPos, tagetPos);//距離
float angle = Mathf.Atan2((playerPos.x - tagetPos.x), (playerPos.z - tagetPos.z));//角度
//===================================================================
/** 縦の動き(近づく遠ざかる) **/
//直進するための角度(さっき求めた角度を入れる
float newAngle = angle;
//後ろ(中心寄り遠ざかる)場合は180度回転させて逆にする
if (verticalVelocity < 0.0f)
{
//後ろ向き
newAngle = angle + Mathf.PI;
}
//縦移動の処理
Vector3 nextPos; //移動後の座標
//三角関数を使って前後の移動だけ計算する
//絶対値にするため速度をMathf.Abs()で処理する
nextPos.x = Mathf.Sin(newAngle) * Mathf.Abs(verticalVelocity);
nextPos.z = Mathf.Cos(newAngle) * Mathf.Abs(verticalVelocity);
//===================================================================
/** 横の動き(左右回転) **/
//どうしても出来なかったので、Unityの回転処理を使う(´・ω・`)
transform.RotateAround(tagetPos, Vector3.up, horizontalVelocity);
はい、ぱっと見ただけじゃわかりませんよね 冬月先生もコード読まないと理解してないから大丈夫 ってことで解説よろしく |
えっと、まず縦移動は回転運動の応用だな 相手と自分の相対向きを計算して、向きに合わせて直進(半径を変化させる)してるんだ おそらく3D系のキャラ移動はこんな感じで作られてると思う |
回転の処理が distance(距離)からverticalVelocity(移動速度)に変えただけです 言葉で説明すると簡単です |
で 一番問題なのが横移動ですね 得体のしれない関数1つしかありません |
//===================================================================
/** 横の動き(左右回転) **/
//どうしても出来なかったので、Unityの回転処理を使う(´・ω・`)
transform.RotateAround(tagetPos, Vector3.up, horizontalVelocity);
この transform.RotateAround()ってなんぞやと申すと Unityに備わっている回転運動をさせるための関数なのよ |
RotateAroundは 第一引数に「回転させる中心位置」第二引数に「回転させる軸指定」第三引数に「移動速度」 を入れるんだな |
第二引数に「回転させる軸指定」っていうのはXYZ軸のうち、どこを回転させるかという設定です Vector3.upっていうのは(0,1,0)って言う上向きベクトルの表現になるので 上方向=Y軸を動かすっていう意味になります |
そして、この移動結果はどうなるかというと 直接オブジェクトに伝わります 前の座標指定と仕組みが変わってません…… |
縦方向を計算したnextPosは あとで速度として値を反映させるとちゃんと縦横ともに動いたわ 動いているけど、システム的には不完全燃焼ね…… |
ということで、解決したが 全く役にたたなかったプログラム講座だったな 次回はフォントについてお話しようかと思ってるぞ |