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

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

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.