Unity……マジむずヵしぃ……お熱でて我ハ覚醒ス(今回はプログラムも書きました

クロ 自分で考えといてアレですが
ナンヤネンこのタイトルは……
てことで知恵熱回です
いつものように
処理のドツボにハマった部分を力技で
解決するという世界のプログラマーさんゴメンなさい状態なのよね
霊夢
魔理沙 まー
勉強が大嫌いだった冬月だからなぁ
独学で今頃ヒーヒー言っているわけだ
ということで
その力技の実装方法をメモ程度に書いておこうかなと思います
続きを読むからどうぞ~
妖夢

~キャラの回転運動~

クロ 言うは易し
行うは難しとのことでキャラを回転運動させようってことです
アミノ式じゃないですよ

/*
予め、
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は
あとで速度として値を反映させるとちゃんと縦横ともに動いたわ
動いているけど、システム的には不完全燃焼ね……
霊夢
魔理沙 ということで、解決したが
全く役にたたなかったプログラム講座だったな
次回はフォントについてお話しようかと思ってるぞ

気軽にコメントをどうぞ!

この記事に関すること冬月に聞きたいこと等、小さいことでもコメントしていただける嬉しいです。
冬月に直接連絡したい方は下のお問合せフォームをお使いください。(メール送信されます)

内容に問題なければ、下記の「コメントを送信する」ボタンを押してください。
※メールアドレスは公開されることは有りません。


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

ゲーム製作の関連記事