code VR

Unity×VR(76)

スポンサーリンク

//tips

//UIでのオブジェクト操作

UIのドラッグ機能をスティックがわりに使い、プレイヤーの移動地点指定するオブジェクトを操作し、ドラッグを話した最終地点で、プレイヤーとオブジェクトが入れ替わる機能を実装する。

現状ではUI操作がうまくGhost側に反映されず、オブジェクトが動いていない。Debug.Log(directionfix)はきちんと座標を表示させているので、directionfixの受け取りがうまくいっていないことがわかる。スクリプトを見直すとReceiveEventGhost receiveEventGhostがうまく貼り付けられていなかったので修正。子要素にしたカプセルもきちんと動くようになった。

きちんと稼働しているが、playerghostのrigidbody周りでエラー表示が出ているので、改善していく。

playerghostにrigidbodyをつけず、transform.positionのみで動かすコードに変えてみる。こちらでもうまくいったので、プレイヤーに施していたコライダーのisTriggerを切り替えるGhostmode.isTriggerの記述を削除する。

また、UIのドラッグで距離が生じている場合のみghostの移動処理を行うためif(receiveEventGhost.distance != 0 )でドラッグ状態と認識されているが距離が生じていない状態は除外するようにした。

これで全てのエラー要因はなくせた。

PlayerWarpとReceiveEventGhostのスクリプトは下記でプレイヤーはrigidbodyあり、ghostはなしでコライダーにisTriggerをつけている。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerWarp : MonoBehaviour
{
public float speed = 3.0f; //プレイヤーの動くスピード

//private Vector3 Player_pos; //プレイヤーのポジション
private Rigidbody rigd;

[SerializeField]
ReceiveEventGhost receiveEventGhost;

[SerializeField]
GameObject playerghost;

//Collider Ghostmode;

void Start()
{
//Player_pos = GetComponent<Transform>().position; //最初の時点でのプレイヤーのポジションを取得
//rigd = playerghost.GetComponent<Rigidbody>(); //プレイヤーのRigidbodyを取得
//Ghostmode = GetComponent<Collider>();
}

public void GhostActive()
{
//Ghostmode.isTrigger = true;
playerghost.SetActive(true);
}

public void GhostDeactive()
{
transform.position = playerghost.transform.position;
playerghost.SetActive(false);
//Ghostmode.isTrigger = false;
}

void Update()
{
if (receiveEventGhost.onDrag)
{
if (receiveEventGhost.distance != 0)
{
playerghost.transform.rotation = Quaternion.LookRotation(receiveEventGhost.directionfix);

//rigd.position = transform.position + receiveEventGhost.directionfix * 3.0f;
playerghost.transform.position = transform.position + receiveEventGhost.directionfix * 3.0f;
}
}

/*
if (receiveEvent.onghost)//ボタンの移動計算が終了してからの動作にしたいので
{
transform.rotation = Quaternion.LookRotation(receiveEvent.directionfix);

//rigd.velocity = transform.forward * speed;
rigd.position = transform.position + transform.forward * 3.0f;

receiveEvent.onflash = false;
}
*/
}
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ReceiveEventGhost : MonoBehaviour
{
Vector3 originpos;
Vector3 movepos;
Vector3 beforemovepos;
public Vector3 heading;
Vector3 direction;
public Vector3 directionfix;
public float distance;

PlayerWarp playerWarp;

//public bool onflash = false;
//bool cooldown = false;
//float countTime = 0;
//[SerializeField]
//int maxtime = 3;

public bool onDrag = false;

private void Start()
{
Transform transform = GetComponent<RectTransform>();
originpos = transform.position;
beforemovepos = originpos;
}

void Update()
{
if (onDrag)
{
movepos = transform.position;
Dragsimulate();
Debug.Log("計算開始");
}

/*
if (cooldown)
{
countTime += Time.deltaTime; //スタートしてからの秒数を格納
GetComponent<Image>().fillAmount = countTime / maxtime;

if (countTime >= 3.0f)
{
cooldown = false;
countTime = 0;
}
}
*/
}

public void MyDragIn()//pointerdown
{
playerWarp = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerWarp>();
playerWarp.GhostActive();
onDrag = true;
}

public void MyDragUI()//Drag
{
transform.position = Input.mousePosition;
/*
movepos = transform.position;
Dragsimulate();
transform.position = originpos;
*/

/*
if (cooldown != true)
{
transform.position = Input.mousePosition;
}
*/
}

public void MyDragExit()//pointerupへ
{
//cooldown = true;
transform.position = originpos;
playerWarp.GhostDeactive();
onDrag = false;
}

public void Dragsimulate()
{
heading = movepos - beforemovepos;

distance = heading.magnitude;
direction = heading / distance;
Debug.Log(direction);

directionfix = new Vector3(direction.x, 0, direction.y);//2dから3dへ変換
Debug.Log(directionfix);

beforemovepos = movepos;
}
}

UIのghostへの動作反映が歪なので、修正していく。歪というのは少しの手ぶれがオブジェクトに大きな影響を与えること、フレームの始まりと終わりの値の決まり方次第で方向が真逆に変わってしまうことなどがある。

playerghost.transform.position = transform.position + receiveEventGhost.directionfix * 3.0f;の動作にうまく動きの補完を入れることで滑らかに移動させていけないか考える。

現在はUIのupdateメソッドの読み出しタイミングでDragsimulateが読み込まれ、directionfixというベクトルを算出し、そのベクトルをreceiveEventGhost.directionfixという形でplayerghost.transform.positionに加算している。

void Update()
{
if (onDrag)
{
movepos = transform.position;
Dragsimulate();
Debug.Log("計算開始");
}

public void Dragsimulate()
{
heading = movepos - beforemovepos;

distance = heading.magnitude;
direction = heading / distance;
Debug.Log(direction);

directionfix = new Vector3(direction.x, 0, direction.y);//2dから3dへ変換
Debug.Log(directionfix);

beforemovepos = movepos;
}

下記のupdate,fixedupdateの違い、補間移動のサイトを参照し、変更を加える。

https://gametukurikata.com/basic/smoothmove

上記を参考にし補完移動を導入する。また、移動後にプレイヤーとghostで位置ズレする場合も見られたのでplayerghost.transform.position = transform.position;をif (receiveEventGhost.onDrag)がオフの際に追加。

前半の通常の動作と後半のVector3.Lerp動作を見比べる。

今回はVector3.Lerpがなくても大丈夫そう。修正したスクリプトは下記に記載する。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerWarp : MonoBehaviour
{
public float speed = 3.0f; //プレイヤーの動くスピード

//private Vector3 Player_pos; //プレイヤーのポジション
private Rigidbody rigd;

[SerializeField]
ReceiveEventGhost receiveEventGhost;

[SerializeField]
GameObject playerghost;

//Collider Ghostmode;

void Start()
{
//Player_pos = GetComponent<Transform>().position; //最初の時点でのプレイヤーのポジションを取得
//rigd = playerghost.GetComponent<Rigidbody>(); //プレイヤーのRigidbodyを取得
//Ghostmode = GetComponent<Collider>();
}

public void GhostActive()
{
//Ghostmode.isTrigger = true;
playerghost.SetActive(true);
}

public void GhostDeactive()
{
transform.position = playerghost.transform.position;
playerghost.SetActive(false);
//Ghostmode.isTrigger = false;
}

void Update()
{
if (receiveEventGhost.onDrag)
{
if (receiveEventGhost.distance != 0)
{
playerghost.transform.rotation = Quaternion.LookRotation(receiveEventGhost.directionfix);

//rigd.position = transform.position + receiveEventGhost.directionfix * 3.0f;

playerghost.transform.position = playerghost.transform.position + receiveEventGhost.directionfix * 0.1f;

//Vector3 targetposition = playerghost.transform.position + receiveEventGhost.directionfix * 3.0f;
//playerghost.transform.position = Vector3.Lerp(playerghost.transform.position, targetposition,Time.deltaTime);

//Debug.Log("playerghost.transform.position" + playerghost.transform.position);
}
}
else
{
playerghost.transform.position = transform.position;

}

/*
if (receiveEvent.onghost)//ボタンの移動計算が終了してからの動作にしたいので
{
transform.rotation = Quaternion.LookRotation(receiveEvent.directionfix);

//rigd.velocity = transform.forward * speed;
rigd.position = transform.position + transform.forward * 3.0f;

receiveEvent.onflash = false;
}
*/
}
}

人気の記事

1

皆さん、ついに、エアラインでも、サブスクリプションが始まったのはご存じですか? まだ実験段階ですが、ANAが、定額全国住み放題サービスを提供する「ADDress」と組んで、国内線を4回まで定額利用可能 ...

2

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

3

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

4

ついに、noteの月間アクティブユーザー数が4400万人(2020年3月時点)に到達しました。 そもそも、「note」とは、クリエイターが、文章やマンガ、写真、音声を投稿することができ、ユーザーはその ...

5

ボードゲームカフェが1日2回転で儲かるという記事をみつけたので興味を持ち、調べてみました。 まずは、需要がどれくらいあるのか、市場のようすからみていきましょう。 世界最大のボードゲーム市場はドイツで、 ...

-code, VR
-,

Copyright© BUSINESS HUNTER , 2023 All Rights Reserved Powered by AFFINGER5.