code VR

Unity×VR(65)

スポンサーリンク

//tips

//アイテムの使用

Inventoryのアイテムをクリックしたら任意の場所に該当アイテムを生成する方法を確認する。

今回はinventoryのアイテムをクリックしたらrodをプレイヤーの手元に出現させるスクリプトを考える。

Dropしているrodを取得するスクリプトは下記なのでこちらをベースに考えていく。最初から接触している状態で呼び出すのでflagは必要なくinstantiateする場所の指定を適切にすれば問題ない。 m_Colliderには子要素となるrodのColliderを入れてあげることで接触反応を管理する。

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

public class OnTriggerParent : MonoBehaviour
{

bool flag = false;
Animation anim;

[SerializeField] private Collider m_Collider;

private void Update()
{
if (flag)
{
if (Input.GetKeyDown(KeyCode.Space))
{
anim = this.GetComponent<Animation>();
anim.Play();

}

}
}

public void HitStart()
{
m_Collider.enabled = true;
}

public void HitEnd()
{
m_Collider.enabled = false;
}

void OnTriggerStay(Collider other)
{
//接触しているオブジェクトのタグが"Player"のとき
if (other.CompareTag("Player"))
{

this.transform.parent = other.transform;

Transform myTransform = this.transform;

// 座標を取得
transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

Debug.Log(myTransform.position);

flag = true;
m_Collider.enabled = false;
}
}
}

今回はprefabからプレイヤーの子要素として生成するのでその部分は考える必要がある。OnTriggerStay(Collider other)の中身をInstantiateで肩代わりして、flag = true;にするメソッドがあれば良い。

下記のスクリプトを記載してiconオブジェクトにアタッチした。

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

public class Rodcom : MonoBehaviour
{
[SerializeField] private Transform p_pos;
[SerializeField] private Collider m_Collider;

public GameObject prefabrod;

Transform rod_pos;

OnTriggerParent onTriggerParent;

public void GetPPos()
{
Instantiate(prefabrod);

prefabrod.transform.parent = p_pos;

prefabrod.transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

onTriggerParent.flag = true;
m_Collider.enabled = false;
}
}

発生したエラーは2つ。

Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption (GameObject: 'rodPivot').
UnityEngine.Transform:set_parent(Transform)
Rodcom:GetPPos() (at Assets/Rodcom.cs:31)
UnityEngine.EventSystems.EventSystem:Update()

NullReferenceException: Object reference not set to an instance of an object
Rodcom.GetPPos () (at Assets/Rodcom.cs:36)

これはprefabObjをそのまま子オブジェクトに設定しようとしているときに起こるエラーのようでinstantiateしたオブジェクトをきちんと変数に入れ、そのオブジェクトを扱うようにしなければならない。なので下記のように修正。

GameObject gameObj = Instantiate(prefabrod) as GameObject;

gameObj.transform.parent = p_pos;

gameObj.transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

これによりrodのポジションは適切な場所に表示されるようになった。

ただ、 onTriggerParent.flag = true;の部分でエラーが出ている。

NullReferenceException: Object reference not set to an instance of an object
Rodcom.GetPPos () (at Assets/Rodcom.cs:25)

onflag.FlagOn();などのようにOnTriggerParentスクリプトを修正したが、なぜかrodpivodのprefabにアタッチされているOnTriggerParentのスクリプトが読み込まれていない。Updateの部分にDebug.Log(flag);を記載しても反応なし。

これはDebug.Log(flag);が反応しなかったのはVisual studioでのコード変更がUnityに反映されていないだけだった。各スクリプトで再度saveしたら反映された。

public void GetPPos()
{
GameObject gameObj = Instantiate(prefabrod) as GameObject;

gameObj.transform.parent = p_pos;

gameObj.transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

OnTriggerParent onflag = onTriggerParent.GetComponent<OnTriggerParent>();

onflag.FlagOn();

m_Collider.enabled = false;

Debug.Log(onTriggerParent);
Debug.Log("flag確認");

}
}

よく考えたら生成されるgameObjにスクリプトはアタッチされているのでもっとシンプルにできた。

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

public class Rodcom : MonoBehaviour
{
[SerializeField] private Transform p_pos;
[SerializeField] private Collider m_Collider;

public GameObject prefabrod;

public void GetPPos()
{
GameObject gameObj = Instantiate(prefabrod) as GameObject;

gameObj.transform.parent = p_pos;

gameObj.transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

OnTriggerParent onflag = gameObj.GetComponent<OnTriggerParent>();

onflag.FlagOn();

m_Collider.enabled = false;

Debug.Log("flag確認");

}
}

こちらでプレイヤーの定位置にアイテムの生成はできた。

問題はspaceボタンを押すたびにUIが開閉し、それにより、ボタンが押されたことになり、GetPPos()が呼ばれてしまうよう。

一度生成されたら2度呼べなくするように設定するのがシンプルなのでスクリプトを変更。

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

public class Rodcom : MonoBehaviour
{
[SerializeField] private Transform p_pos;
[SerializeField] private Collider m_Collider;

public GameObject prefabrod;
bool isntgameobj = true;

public void GetPPos()
{
GameObject gameObj;

if (isntgameobj)
{
gameObj = Instantiate(prefabrod) as GameObject;

gameObj.transform.parent = p_pos;

gameObj.transform.localPosition = new Vector3(0.7f, 0.3f, 0.3f);

OnTriggerParent onflag = gameObj.GetComponent<OnTriggerParent>();

onflag.FlagOn();

m_Collider.enabled = false;

Debug.Log("flag確認");

isntgameobj = 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.