何事もマイペースが信条でっすw
(;^o^) \(ToT )あんたほんとにそれでいいの
外は天気がいいのに、どこにも行けない。
自粛要請はいつまで続くのやらヽ(´~`;)ウーン
コロナの無い所にテレポートしたいですね~
そんな事で、無理やりお題に結びつけてみました。
今回はテレポーターを作ってみたので記事にしてみます。
まず、オブジェクトをテレポートさせるには、
transformに移動先を指定すれば、瞬間移動してくれます。
実際に簡単な物を作ってみます。
赤い円がテレポーターです。
ボール青が上昇して行き、テレポーターに当たると
Canvasの最下段にテレポートして、上昇を続けます。
黄色のストッパーに当たると停止するみたいな感じです。
Test_Ball
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test_Ball : MonoBehaviour
{
public float speed; //ボールのスピード
private Transform balltran; //ボールのtransform
private bool moving=true; //移動フラグ
void Start()
{
//ボールのtransform取得
balltran = GetComponent<Transform>();
}
void Update()
{
//フラグ判定falseなら停止
if (moving)
{
MovingBall();
}
}
//ボールの移動処理
void MovingBall()
{
float y = balltran.localPosition.y;
y += Time.deltaTime * speed;
Vector3 pos = new Vector3(balltran.localPosition.x, y, 0f);
balltran.localPosition = pos;
}
//接触判定
private void OnTriggerEnter2D(Collider2D collision)
{
//黄色なら停止
if (collision.gameObject.tag == "TelY")
{
moving = false;
}
//赤ならテレポート
if (collision.gameObject.tag == "TelR")
{
balltran.localPosition = new Vector2(0, -590);
}
}
}
このスクリプトをボールにアタッチします。
ボールのスピードは、public変数にしてあるのでコンポーネント上で設定します。
今回は300くらいにしておきます。
続いて、各オブジェクトに必要なコンポーネントをアタッチして行きます。
ボールには、Rigidbody2DとCircleCollider2Dをアタッチします。
Rigidbodyをtransformで動かす場合、必ずモードをキネマティックにして、
完全なキネマティックコンタクトにチェックを入れます。
これは、物理演算の計算が重複すると処理が重くなる為で、
物理演算が必要な処理の場合、Rigidbody.Positionで移動させる必要があります。
今回は、物理演算が必要ないのでキネマティックにしています。
次はテレポーターです。
接触判定を使うので、CircleCollider2Dをアタッチします。
接触時の判定用にタグを設定します。
Colliderは接触センサーになるので、トリガーにチェックを入れます。
最後はストッパーです。
接触判定のタグを設定して、トリガーにチェックします。
これで、テレポーターの完成です。
再生できない場合、ダウンロードは🎥こちら
動画がショボイですが、一応動いてるのが分かると思います。
簡単な物は作れたのですが、本来テレポーターって対になっていて、
どちらからでもアクセスできるようになっていると思います。
対になるテレポーターを設置すればいいだけと言いたいのですが、
どちらもトリガーになるので、一度乗せると転送が繰り返されて、
無限ループが起こってしまいます。
なので、転送先で再転送が起こらない処理を考えてみます。
また、テレポーターが二つになるので、お互いの座標を
読み取れるように改良してみます。
まず、テレポーターの座標取得から新規Scriptを立ち上げて
スクリプト名をTest_Telとしておきます。
Test_Tel
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test_Tel : MonoBehaviour
{
public GameObject target; //テレポーターの相方
public Vector3 targettvector; //相方の座標
void Awake()
{
targettvector = target.GetComponent<Transform>().localPosition;
}
}
このスクリプトをテレポーターにアタッチします。
注意点なのですが、このtransformの取得はstartで行うとエラーが出るので、
Awakeで行っています。
良くは分からないのですが、コンポーネントの取得だけならStartでも問題ないようですが、
positionまで取得しているので、取得が間に合わないのかもしれません。
続いて、テレポーターの複製を作ります。
テレポーターにTest_Telスクリプトをアタッチして、
target変数にお互いのテレポーターをアタッチします。
これで、お互いの座標が取得できたので、
テレポートの処理を改良してみます。
Test_Ball
private bool transfer; //転送中のフラグ
private void OnTriggerEnter2D(Collider2D collision)
{
//赤ならテレポート
if (collision.gameObject.tag == "TelR")
{
//転送判定
if (transfer)
{
transfer = false;
}
else
{
//接触時に転送座標を取得する
balltran.localPosition = collision.GetComponent<Test_Tel>().targetvector;
transfer = true;
}
}
}
テレポーターに接触したら、ターゲット座標を取得して相方に転送します。
転送中が判断できるようにtransferフラグをtrueにします。
転送先でフラグcheckを行って、trueなら転送されてきたと判断して、
何もしない処理にしています。
これで無事、転送ループから出れるようになります。
最後に動きを修正して、できたのがこちら。
再生できない場合、ダウンロードは🎥こちら
ボールを上下に動くようにして様子をみましたが、
お互いの座標に無事、転送が行えています。
難点は、接触したテレポーターの上に移動する前に転送されてしまう所でしょうか。
この辺りは、コルーチンなどを使う必要があるかと思います。
テレポーター上で、パーティクルなどの処理を行ってから移動させると
綺麗な転送ができるかと思います。
何か良い処理が思いついたら、また記事にしてみたいと思います。
それでは、今回はこのへんで
( ^ 0 ^ )/~~~~see you again
この記事へのコメント