//tips
//3Dプレイヤー接触での3Dアイテム取得
シーンにプレイヤーを追加し、クリックでのアイテム取得ではなく、プレイヤーとの重なりでアイテム取得するようにする。
衝突の場合はOnCollisionEnterを使用するが、重なった際に処理を実行する場合はOnTriggerEnterを実行することになる。
CubeインスペクターのisTriggerのチェックするのを忘れない。
カプセルのプレイヤーを動かすためのスクリプトをアタッチする。
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
void FixedUpdate()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Rigidbody rigidbody = GetComponent<Rigidbody>();
rigidbody.AddForce(x * 10, 0, z * 10);
}
}
void Updateで記述すると、処理を毎フレーム更新時に呼び出すので、物理演算でキャラクターが動く度に呼ばれる処理を設定する事ができるFixedUpdateにする。
アイテムのdestroyを呼ぶCubeDスクリプトにOnTriggerEnter関数の組み込みを考える
//OnTriggerEnter関数
//接触したオブジェクトが引数otherとして渡される
void OnTriggerEnter(Collider other)
{
//接触したオブジェクトのタグが"Player"のとき
if (other.CompareTag("Player"))
{
}
}
そのため先にカプセルにプレイヤータグを設置し、先にアタッチしていたクリックしてイベントを発生させるeventtriggerコンポーネントを外す。
アイテムにアタッチした編集スクリプトは下記となる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeD : MonoBehaviour
{
public Item item;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Destroy(this.gameObject);
Debug.Log("aaa");
//アイテム取得
Inventory.instance.Add(item);
}
}
}
次は、photonのルーム内での活動として実行できるようにしていく。
ロビーからの移行先として設定しているSampleシーンを再度整えていく。
コードから抜いていたPhotonNetwork.ConnectUsingSettings();をSampleSceneスクリプトに設定。planeを追加して設定を変更していたらそもそものplayer自体が現れなくなってしまったので再度設定し直す。時計の設定は不要なので取り除いておく。
新たしいシーンで作成すると問題なくplayerが生成されたので、そちらで進めていく。GameplayerのprefabにGravityとPlayerMoveスクリプトを追加。tagもplayerに変更しておく。
さらにcanvasを追加し、prefab化したinventoryをアタッチし、UIManagerのインスペクターにも反映させる。projectilemanagerとgameplayermanagerにもタグづけするのを忘れない。
自動生成したものでもきちんとインベントリに格納できることが確認できた。
GamePlayerのスクリプトの中にプレイヤーの移動操作も記述されているのでPlayerMoveスクリプトは削除。
インベントリはプレイヤーごとに分けたいので、個別にインベントリを持てる方法を考える。
ネットワークオブジェクトのインスタンスが、自身側で生成したものか他プレイヤー側で生成したものかはPhotonView.IsMineによって判別することができるのでGamePlayerスクリプトでのプレイヤー操作にはif (photonView.IsMine) が含まれている。
今回のアイテムの取得操作で考えると、
・同期シーン上のアイテムをdestroyすること
・自身のインベントリにアイテムをAddすること
が必要で、CubeDスクリプトが持つ、Destroy(this.gameObject);によってシーン上のアイテムを消すことはできている。
座標を同期するためのPhotonTransformViewというコンポーネントをGamePlayerにアタッチして、PhotonViewの監視対象に設定しているので、類似の方法でGamePLayerUIの中身も監視させたい。
色の変更時に使用した、IPunObservableを実装したスクリプトをPhotonViewの監視対象に設定すると、定期的にデータを送受信するためのメソッドIPunObservable.OnPhotonSerializeView()が呼ばれるようになるので、下記の仕組みをうまくいかせないか考えてみる。
// データを送受信するメソッド
void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
if (stream.IsWriting) {
// 自身側が生成したオブジェクトの場合は
// 色相値と移動中フラグのデータを送信する
stream.SendNext(hue);
stream.SendNext(isMoving);
} else {
// 他プレイヤー側が生成したオブジェクトの場合は
// 受信したデータから色相値と移動中フラグを更新する
hue = (float)stream.ReceiveNext();
isMoving = (bool)stream.ReceiveNext();
ChangeBodyColor();
}
if (photonView.IsMine)でオブジェクトを破壊した場合のみに自身のインベトリにアイテム追加のコードを送信するようにしようかと考えたが、現在のdestroyメソッドは破壊されるアイテム自身につけられているので、photonView.IsMineは使いづらく、どちらかというとInventory.instance.Add(item);にother.などを加える方がシンプルになるように思われる。
区別可能なプレイヤーとともに生成されるインベントリの作成方法を考える。