前提・実現したいこと
「MEGA WORM」「DEATH WORM」のワームのような、多関節のプレイヤーキャラクターを作っています。2Dゲームです。
上図のように、数珠繋ぎになった数個の身体オブジェクトを、頭オブジェクトの軌跡に固定間隔で追従させたいのですが、
現在のやりかたではうまくいきません。改善点やその他の方法を、教えていただきたいのです。
発生している問題・エラーメッセージ
問題点ですが、
【1:固定間隔で数珠繋ぎができない】
頭オブジェクトの通った軌跡(transform.position)を、10フレームほどList<>にVector2で保存しておき、別のList<>で保持した身体オブジェクトのtransform.positionを毎フレームごとに更新しています。
しかし、落下時など、頭オブジェクトの移動速度が速くなると、頭オブジェクトと身体オブジェクトの距離が空いてしまい、
首が伸びたように見えてしまいます。
頭オブジェクトと各身体オブジェクトの間隔を固定しつつ、数珠つなぎのまま放物線運動をさせるにはどうすればいいでしょうか?
【2:身体オブジェクトの移動が不自然にみえる】
毎フレームごとに、transform.positionを更新しているのですが、身体というよりは残像のように見えてしまいます。
頭オブジェクトの動きと同じように、滑らかに移動させるにはどうすればいいでしょうか?
該当のソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BumperToBumper : MonoBehaviour
{
private List<Vector2> points; //頭オブジェクトの位置を記録します。 float appendDistance = 0.5f; //各身体間、頭の固定した距離です。 private float appendSqrDistance; int maxPointCount = 10; //奇跡の最大記録数です。 public GameObject _body; //身体オブジェクトのプレハブです。 public GameObject Head; //頭オブジェクトを参照します。 List<GameObject> _bodyList = new List<GameObject>(); //身体オブジェクトのListです。 private int _bodyNum = 10; //多関節の数です。身体オブジェクトの個数です。 void Start() { setVectors(); } void Awake() { appendSqrDistance = Mathf.Pow(appendDistance, 2); Head = GameObject.Find("Head"); //身体オブジェクトを生成しています。 //Listで管理しています。 for (int i = 0; i < _bodyNum; i++) { GameObject bodypref = Instantiate(_body) as GameObject; _bodyList.Add(bodypref); } } void OnValidate() { //appendDistanceの二乗 appendSqrDistance = Mathf.Pow(appendDistance, 2); } void Update() { setPoints(); } //頭オブジェクトのtransform.positionを記録します void setPoints() { Vector2 curPoint = new Vector2(Head.transform.position.x, Head.transform.position.y); if (points == null) { points = new List<Vector2>(); points.Add(curPoint); } // ポイントの追加. addPoint(curPoint); // 最大数を超えた場合、削除. while (points.Count > maxPointCount) { points.RemoveAt(0); } } void addPoint(Vector2 curPoint) { //頭の移動速度が速くなると、首が伸びたようになってしまうので、その対策のつもりなのですが… //頭に一番近い身体オブジェクトとの距離を、固定間隔に分割しているのですが… //なぜかのびてしまいます。 while (true) { var distance = (curPoint - points[points.Count - 1]); if (distance.sqrMagnitude < appendSqrDistance) break; distance *= appendDistance / distance.magnitude; points.Add(points[points.Count - 1] + distance); } //各身体オブジェクトのpositionを、更新しています。 //身体が残像のように見えてしまい、画面酔いします… for (int i = 0; i < _bodyNum; i++) { _bodyList[i].transform.position = new Vector3(points[_bodyNum-1 - i].x, points[_bodyNum-1 - i].y); } }
}
頭オブジェクトの移動は、別ファイルで制御しています。
地中にいる場合:
一定速度で移動、十字キーで移動方向を変更
地上に飛び出したとき:
斜方投射式の放物線運動します。プレーヤーの入力は受け付けません。
頭と身体それぞれに、RigidBody2DとCircleCollider2Dをアタッチし、Kinematicをオンにしています。物理演算は利用していません。
x = 前フレームのposition.x + 初速度 * Mathf.Cos(投射角度) * 刻み時間;
y = 前フレームのposition.y + 初速度 * Mathf.Sin(投射角度) + (重力 * 刻み時間 * 刻み時間) * 0.5f;
試したこと
HingeJoint2DとDistanceJoint2Dを試しましたが、うまくいきませんでした。
質問に不備などありましたら、申し訳ありません。よろしくおねがいします。
補足情報(FW/ツールのバージョンなど)
環境:
UNITY 2018.2.18f1 64bit
VisualStudio2017 for Unity
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/04 09:22