ステルスゲージを作ってみました。敵とゲージをまとめて管理するで敵のいる方向にゲージを表示したのでこれを回転させます。
まず敵のスクリプトのUpdateメソッドで、ゲージのスクリプトにある位置と回転を変えるメソッドを呼びます。
public class TestAgent : MonoBehaviour
{
NavMeshAgent agent;
// ゲージ
public Gauge Gauge{ get; private set; }
// ...
// Update is called once per frame
void Update()
{
if (!agent.pathPending && agent.remainingDistance < 0.5f)
{
GoNextPoint();
}
// ゲージの位置と回転を変える
if(Gauge!= null) Gauge.ChangePosRot(transform);
}
// ...
}
そのメソッドでは、ゲージの位置を、敵の位置とプレイヤーの向きによって変えます。また、Canvas上のゲージの位置によってゲージの向きを変えて常に中心に同じ側を見せるようにします。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.FirstPerson;
public class Gauge : MonoBehaviour
{
RectTransform rt;
private void Awake()
{
rt = GetComponent<RectTransform>();
}
// Start is called before the first frame update
void Start()
{
}
// 表示位置をセット
public void SetPosition(float x, float y)
{
Vector2 pos = rt.anchoredPosition;
pos.x = x;
pos.y = y;
rt.anchoredPosition = pos;
}
void SetRotation()
{
// Imageが表示されている角度(ラジアン)
float rad = Mathf.Atan2(rt.anchoredPosition.x, rt.anchoredPosition.y);
//float rad = Mathf.Atan2(rt.anchoredPosition.y, rt.anchoredPosition.x);
Vector3 angle = rt.rotation.eulerAngles;
// 度数法になおして、Imageの角度のZに入れる
angle.z = -rad * Mathf.Rad2Deg;
//angle.z = rad * Mathf.Rad2Deg;
rt.rotation = Quaternion.Euler(angle);
}
// 色を変える
public void ChangeColor(Color color)
{
Image image = GetComponent<Image>();
image.color = color;
}
// 敵のUpdateで呼ばれる
public void ChangePosRot(Transform agentTransform)
{
// 敵の位置
Vector3 dir = agentTransform.position;
// プレイヤーと敵の高さを合わせる
dir.y = FirstPersonController.GetInstance().transform.position.y;
// 敵からプレイヤーへの方向
dir -= FirstPersonController.GetInstance().transform.position;
//dir = FirstPersonController.GetInstance().transform.position - dir;
// 方向ベクトルをプレイヤーに合わせて回転
dir = Quaternion.Inverse(FirstPersonController.GetInstance().transform.rotation) * dir;
//dir = FirstPersonController.GetInstance().transform.rotation * dir;
// 長さを一定にする
dir = Vector3.Normalize(dir);
// ゲージの位置をセット
SetPosition(dir.x * 150f, dir.z * 150f);
// ゲージを回転
SetRotation();
}
}
位置を計算するときに、常に中心から同じ距離に表示するようにしています。
回転値の計算では、まずCanvasの中心から上方向と、中心からゲージへの方向との角度をMathf.Atan2で求めます。ゲージを画面と平行に回転させるには、rotationのZ軸の値を増減させるので、Z軸にこの値を入れます。
先に求めた角度はラジアンなので、度数法に治しています。それだけだと逆に回転したのでマイナスを付けました。これでステルスゲージのようになりました。
Mathf.Atan2の引数の渡す値を逆にしてマイナスを付けないと、ゲージの短い辺が中心を向きました。
敵がゲージを持っていて、敵と同時にゲージも追加/削除できます。