//tips
//Culling Maskを使用したミニマップでのアイコン表示
先のミニマップではカメラに映るオブジェクトそのまま全てを反映していたが、Culling Maskを使用して表示をアイコン化する。
まず、MiniMapレイヤーをレイヤーに追加。メインカメラのCulling MaskはMiniMapレイヤーを外し、MiniMapカメラは、DefaultとMiniMap以外のチェックを外す。
こうするとMiniMapには背景しか映らなくなる。
最後にレイヤーをMiniMapにしたオブジェクトを各既存のオブジェクトの子要素に追加する。小ライダーはいらないので外し、Cast ShadowsとRecieve Shadowsも取り除いておく。
これでシーン画像とミニマップ画像の表示形態を変えることができた。
フィールドの特定の場所にオブジェクトを自動生成する方法を見つけたので、そちらを使えるようにしていく。
上空からRayを飛ばし、それが当たったコライダーを検知するRayCastによって、検知したコライダーの持ち主の持つタグにより、条件分岐を発生させる。
Position(0,10,0)にRayの発射元となるRayMachineオブジェクトを設置する。今回がRayが床とGreenCubeに当たった場合にprefab生成するようにする。バウンスボールをRenderer.bounds.sizeでfloorから取得したサイズから配置座標を割り出し(floorは原点に置かれているのでサイズを2で割れば中心から左右の座標がわかる)、そこにローラー作戦でRayを当てていく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaySpawn : MonoBehaviour
{
[SerializeField]
GameObject Prefab;
[SerializeField]
float placementInterval = 1.0f;//間隔を開けるかどうか
[SerializeField]
float PPositionY = 1.5f;
GameObject floorObj;
Vector3 floorSize;
Ray ray;
RaycastHit rayCastHit;
Vector3 rayPosition;
List<Vector3> positions = new List<Vector3>();
void Start()
{
floorObj = GameObject.FindGameObjectWithTag("Floor");
GetFloorSize();//planeのサイズ取得
SetSpawnPosition();//座標をローラー
CreateP();
}
void GetFloorSize()
{
Renderer floorRenderer = floorObj.GetComponent<Renderer>();
floorSize = new Vector3(floorRenderer.bounds.size.x, floorRenderer.bounds.size.y, floorRenderer.bounds.size.z);
}
//コイン生成位置を決定するメソッド
//このスクリプトをアタッチしたゲームオブジェクトと床が両方とも原点にあることが前提
void SetSpawnPosition()
{
//床の左上から決めていく
float x = -floorSize.x / 2; //原点0から左右に分かれているので
float z = -floorSize.z / 2;
//縦方向のループ
for (int i = 0; i < Mathf.RoundToInt(floorSize.z / placementInterval); i++)//Mathf.RoundToInt(数値),で数値を四捨五入しIntに合わせる
{
x = -floorSize.x / 2;
for (int j = 0; j < Mathf.RoundToInt(floorSize.x / placementInterval); j++)
{
ray = new Ray(new Vector3(x, transform.position.y, z), transform.TransformDirection(Vector3.down));
if (Physics.Raycast(ray, out rayCastHit, transform.position.y))
{
//Rayが当たったのが床かGreenbox上なら、生成座標として登録
if (rayCastHit.collider.tag == "Green" || rayCastHit.collider.tag == "Floor")
{
positions.Add(rayCastHit.point);
}
}
x += placementInterval;
}
z += placementInterval;
}
}
void CreateP()
{
foreach (Vector3 position in positions) //登録した各座標への生成
{
Instantiate(Prefab, new Vector3(position.x, position.y + PPositionY, position.z), Quaternion.Euler(0, 0, 0));
}
}
}
生成確率を加えて、EnemyAIのSpawnポイントにこの仕組みを用いたら良いかもしれない。
UIのドラッグを3Dプレイヤーの移動または操作に反映させる。まずは、距離が決まっている瞬間移動を行わせる。UIのドラッグの起点と終点から、角度を取得し、その方向へ移動させることにする。
UIのy軸をz軸の値に変換し、その方向にtransford.forwardで複数マス瞬間的に移動させられないか考える。
Drag&Dropで使用したEventtriggerをベースにして考えていく。今回はDrag/PointerUpで設定することにした。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReceiveEvent : MonoBehaviour
{
Vector3 originpos;
private void Start()
{
Transform transform = GetComponent<RectTransform>();
originpos = transform.position;
}
public void MyDragUI()//Drag
{
transform.position = Input.mousePosition;
}
public void MyDragExit()//pointerupへ
{
transform.position = originpos;
}
}
MyDragExit()の際に現在座標を取得し、その座標とオリジナルの座標を比較する処理を加えて向きを取得する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReceiveEvent : MonoBehaviour
{
Vector3 originpos;
Vector3 movepos;
Vector3 heading;
Vector3 direction;
private void Start()
{
Transform transform = GetComponent<RectTransform>();
originpos = transform.position;
}
public void MyDragUI()//Drag
{
transform.position = Input.mousePosition;
}
public void MyDragExit()//pointerupへ
{
movepos = transform.position;
Dragsimulate();
transform.position = originpos;
}
public void Dragsimulate()
{
heading = movepos - originpos;
var distance = heading.magnitude;
direction = heading / distance;
Debug.Log(direction);
}
}
次はこの取得した向きを別のオブジェクトの向きに対応させることを考える。新たにPlayerFlashスクリプトを作成し、球体につけ、UIの動きに合わせて、3dオブジェクトの移動に反映させるようにする。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFlash : MonoBehaviour
{
public float speed =3.0f; //プレイヤーの動くスピード
private Vector3 Player_pos; //プレイヤーのポジション
private Rigidbody rigd;
[SerializeField]
ReceiveEvent receiveEvent;
void Start()
{
Player_pos = GetComponent<Transform>().position; //最初の時点でのプレイヤーのポジションを取得
rigd = GetComponent<Rigidbody>(); //プレイヤーのRigidbodyを取得
}
void FixedUpdate()
{
if (receiveEvent.onflash)
{
transform.rotation = Quaternion.LookRotation(receiveEvent.directionfix);
rigd.velocity = transform.forward * speed;
receiveEvent.onflash = false;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReceiveEvent : MonoBehaviour
{
Vector3 originpos;
Vector3 movepos;
Vector3 heading;
Vector3 direction;
public Vector3 directionfix;
public bool onflash = false;
private void Start()
{
Transform transform = GetComponent<RectTransform>();
originpos = transform.position;
}
public void MyDragUI()//Drag
{
transform.position = Input.mousePosition;
}
public void MyDragExit()//pointerupへ
{
movepos = transform.position;
Dragsimulate();
transform.position = originpos;
}
public void Dragsimulate()
{
heading = movepos - originpos;
var distance = heading.magnitude;
direction = heading / distance;
Debug.Log(direction);
directionfix = new Vector3(direction.x,0,direction.y);//2dから3dへ変換
Debug.Log(directionfix);
onflash = true;
}
}
無事に反映できた。現時点ではゆっくり反映されているのでtransform.positionなど瞬間移動のような形で前方移動させられないか考えていく。