【Unity】移動している的にボールをくっつける
的にボールが衝突したタイミングで、IsKinematicを有効にして物理的な作用を止め、くっついたイメージとしている場合、的を移動しているとその場にボールが止まるといった不自然な状態になります
動作の違い
動画でイメージを確認してみましょう
ボールがその場に止まっている
的とともにボールも移動
仕様の追加
的を左右に動かす仕様と、ボールが的に止まる状態となる仕様を追加します
移動のためにスクリプト
まず、的の移動が必要ですね
このスクリプトでは、オブジェクトはx軸方向にsin関数によって往復します。振幅(amplitude)と周波数(frequency)を調整することで、動きの特性を調整できます。このスクリプトをオブジェクトにアタッチし、振幅と周波数を調整して試してみてください
スクリプトは的に追加でアタッチします
using UnityEngine;
public class SinMovement : MonoBehaviour
{
[Tooltip("オブジェクトの振幅")]
public float amplitude = 1.0f;
[Tooltip("オブジェクトの周波数")]
public float frequency = 1.0f;
// オブジェクトの初期位置
private Vector3 initialPosition;
private void Start()
{
// オブジェクトの初期位置を保存
initialPosition = transform.position;
}
private void Update()
{
// sin関数を使ってオブジェクトを往復させる
float time = Time.time;
// x軸方向の変異を計算
float xOffset = amplitude * Mathf.Sin(frequency * time);
// 新しい位置を設定
transform.position = initialPosition + new Vector3(xOffset, 0, 0);
}
}
float xOffset = Mathf.PingPong(time, amplitude);
的とともに移動するボール
的にボールが当たると、そのタイミングで的の子オブジェクトにする方法を使ってみましょう
親オブジェクト(この場合、的)の子オブジェクト(この場合、ボール)にするには、次のコードを利用します
// 親を指定する
transform.parent = 親ゲームオブジェクトのTransformコンポーネント
.parent は、Transform コンポーネントの親オブジェクトを表します。親オブジェクトは、このゲームオブジェクトを包む親階層のオブジェクトです
具体的には次のようになります
transform.parent = GameObject.Find("target").transform;
ボールのコントローラに次のように1行追加します
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IgaguriController : MonoBehaviour
{
public void Shoot(Vector3 dir)
{
GetComponent<Rigidbody>().AddForce(dir);
}
void OnCollisionEnter(Collision collision)
{
GetComponent<Rigidbody>().isKinematic = true;
GetComponent<ParticleSystem>().Play();
// 的の子オブジェクトにする
transform.parent = GameObject.Find("target").transform;
}
void Start()
{
Application.targetFrameRate = 60;
// Shoot(new Vector3(0, 200, 2000));
}
}
複数の的に対応
的が1つの場合、これでもいいのですが、複数の的となると、衝突した的ごとに親を指定する必要があります
OnCollisionEnterの引数に衝突した相手の情報がありますので、それを使うといいでしょう
上記の追加行を次のように変更します
transform.parent = collision.gameObject.transform;
// または、参考に記しているように直接transformを取得することもできます
transform.parent = collision.transform;
参考
Collisionクラスで得られる情報
変数
「ArticulationBody」は、Unity 2020.1から利用できる新しい関節コンポーネントです。多くの関節を繋げても、正確で安定した動きを実現できるのが特徴になります。ロボットアームなど多関節ロボットの作成に適しています
articulationBody | GameObjectが衝突するコライダのArticulationBody(読み取り専用) |
body | コンポーネントが衝突するコライダのRigidbodyまたはArticulationBody(読み取り専用) |
collider | ヒットした Collider 情報を返します(読み取り専用) |
contactCount | この衝突のコンタクト数を取得する. |
contacts | 物理エンジンによって生成された接触点。これはメモリ・ガーベージを生成するため、使用を避けるべきである。代わりにGetContactまたはGetContactsを使用してください. |
gameObject | 衝突しているコライダーを持つGameObject。(読み取り専用) |
impulse | 衝突を解消するために互いの接触に適用される合計のインパルス |
relativeVelocity | 衝突した 2 つのオブジェクトの相対的な速度(読み取り専用) |
rigidbody | ヒットした Rigidbody (読み取り専用) ヒットしたオブジェクトに Rigidbody がアタッチされていない場合、null を返します。 |
transform | ヒットした Transform 情報を返します。(読み取り専用) |
Public 関数
GetContact | 指定したインデックスの接点を取得します |
GetContacts | この衝突のすべての接点を取得します |
マウスをホバーした時のヒント表示
ToolTipと呼ばれています
次のような効果があります
表示の見え方
コード
[Tooltip("オブジェクトの振幅")]
public float amplitude = 1.0f;
[Tooltip("オブジェクトの周波数")]
public float frequency = 1.0f;
インスペクターでの初期化の方法
コード中で初期値として代入された値とインスペクターの値が違う時、インスペクターの値が使われます
コード中の初期値の値は、最初にアタッチされた時と初期化した時に使われます
Sin波の説明リンク
往復運動の他の方法
PingPong関数を使った方法などがあります
ディスカッション
コメント一覧
まだ、コメントがありません