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

コロナによる需要変化 コロナパンデミックの影響で、人々は外に出られなくなり、自宅で過ごす時間が増えました。 この自粛ムードの中、下記のようなビジネスの需要変化が引き起こされています。 【利用者減少】 ...

2

米国レストランの決済時に毎日お世話になっていた「Square」のビジネスモデルについて本日はふれていきたいと思います。 「Square」とは、ネットにつながったモバイル端末と専用のカードリーダーを用意 ...

3

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

4

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

5

ナイキのSNKRSが、なぜこれほどまでに人気なのか?調べてみました。 きっかけは米国での友達との会話。彼は自分のシューズをみせて、「これ20万円もしたんだぜ。」と語ってくれました。 あまり靴に興味がな ...

-code, VR
-,

Copyright© BUSINESS HACKER , 2021 All Rights Reserved Powered by AFFINGER5.