また、日記的なものを始めようと思い立つ。
ハードルを下げれるだけ下げて、人の役に立つとかは全く関係のない、自分の記録のためだけの日記。
なんのためにやるのか、と言われれば、多分、自分がどういうものが書けるのか見てみたいということになるだろうか。
今日は朝からUnityをやっている。途中、昨日見当たらなかったモバイル充電器が気になって、再度探したけれど、やはり見当たらなくてがっくりしている。多分、レンタカーの中にでも忘れてきたんだと思う。記憶がない。5000円ぐらいしたものだったので、がっかりしている。
それは、でも、人生においてどうでもいいことで、今日もUnityをやってみる。
今日はRaycastについて。
今つくってみているゲームで、キャラクターが急な坂でも立つことができてしまうので、一定以上の角度の坂は滑り落ちるようにしたいと思っている。
それを解決するために、キャラクターの立っている場所のmeshの角度を検知して、その角度によってキャラクターを移動する処理を書きたい。
キャラクターの幅を考慮に入れる必要があることがわかり、書いてみているけど、まだ、あまり綺麗な挙動にならない。
特定の角度以上の坂と接触しているキャラクターがジリジリ前後に動いてしまうのと、特定の角度以上の坂にいる間に方向キーを入れると方向キーによる速度に坂によるスライドの速度が合計された速度で動いてしまう。
今日は疲れたので、このあたりでおしまい。
private void Slide ()
{
if (!Grounded) {
return;
}
// フラットな場所に立っている場合にtransform.positionのy座標がその場所のコライダーより-0.01されてしまい、Rayがその場所にあたらないのでy座標だけ+1しておく
Vector3 posFront = transform.position + new Vector3(_controller.radius * 0.5f, 1, 0);
Ray rayFront = new Ray(posFront, Vector3.down);
RaycastHit hitFront;
Vector3 posBack = transform.position + new Vector3(-_controller.radius * 0.5f, 1, 0);
Ray rayBack = new Ray(posBack, Vector3.down);
RaycastHit hitBack;
if (Physics.Raycast(rayFront, out hitFront)) {
float angle = Vector2.Angle(new Vector2(0, 1), new Vector2(hitFront.normal.x, hitFront.normal.y));
float slideSpeed = hitFront.normal.x * 3;
slideSpeed = Mathf.Round(slideSpeed * 1000f) / 1000f;
if (angle > _controller.slopeLimit && angle < 90) {
Vector3 direction = new Vector3(1, 0, 0);
_controller.Move(direction * (slideSpeed * Time.deltaTime));
}
}
if (Physics.Raycast(rayBack, out hitBack)) {
float angle = Vector2.Angle(new Vector2(0, 1), new Vector2(hitBack.normal.x, hitBack.normal.y));
float slideSpeed = hitBack.normal.x * 3;
slideSpeed = Mathf.Round(slideSpeed * 1000f) / 1000f;
if (angle < -_controller.slopeLimit && angle > -90) {
Vector3 direction = new Vector3(-1, 0, 0);
_controller.Move(direction * (slideSpeed * Time.deltaTime));
}
}
}