「Unity/3d/アニメーション/追跡」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→正面を向いて追跡) |
|||
| 行66: | 行66: | ||
NavMeshAgent同士の接触半径を狭める場合は、InspectorのNavMeshAgentのRadiusを0.5から小さくする | NavMeshAgent同士の接触半径を狭める場合は、InspectorのNavMeshAgentのRadiusを0.5から小さくする | ||
| + | ==逃げる== | ||
| + | <pre> | ||
| + | using UnityEngine.AI; | ||
| + | public class PlayerController : MonoBehaviour | ||
| + | { | ||
| + | NavMeshAgent agent; | ||
| + | float speed = 6f; | ||
| + | GameObject enemyObj; | ||
| + | GameObject targetPointGroupObj; | ||
| + | void Start() | ||
| + | { | ||
| + | enemyObj = GameObject.Find("Enemy"); | ||
| + | targetPointGroupObj = GameObject.Find("TargetPointGroup"); | ||
| + | NavStart(); | ||
| + | GetFarTargetPointObj(); | ||
| + | } | ||
| + | // 追跡ロジック開始 | ||
| + | void NavStart() | ||
| + | { | ||
| + | if (GetComponent<NavMeshAgent>() != null) | ||
| + | { | ||
| + | agent = GetComponent<NavMeshAgent>(); | ||
| + | agent.updateRotation = false; | ||
| + | agent.updatePosition = true; | ||
| + | } | ||
| + | } | ||
| + | void Update() | ||
| + | { | ||
| + | UpdateNav(); | ||
| + | UpdateLookAt(); | ||
| + | } | ||
| + | void UpdateLookAt() | ||
| + | { | ||
| + | transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(enemyObj.transform.position - transform.position), 0.3f); | ||
| + | } | ||
| + | // 追跡ロジック | ||
| + | void UpdateNav() | ||
| + | { | ||
| + | if (agent != null) | ||
| + | { | ||
| + | if (agent.pathStatus != NavMeshPathStatus.PathInvalid) | ||
| + | { | ||
| + | // agent.SetDestination(gameObject.transform.Find("Back").transform.position); | ||
| + | agent.SetDestination(GetFarTargetPointObj().transform.position); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | // 敵から一番遠いターゲットポイントのGameObjectを返す | ||
| + | GameObject GetFarTargetPointObj() | ||
| + | { | ||
| + | float maxDistance = 0; | ||
| + | GameObject maxDistanceObj = new GameObject(); | ||
| + | foreach (Transform transform in targetPointGroupObj.GetComponentInChildren<Transform>()) | ||
| + | { | ||
| + | var distance = Vector3.Distance(enemyObj.transform.position, transform.gameObject.transform.position); | ||
| + | if (maxDistance < distance) | ||
| + | { | ||
| + | maxDistance = distance; | ||
| + | maxDistanceObj = transform.gameObject; | ||
| + | } | ||
| + | } | ||
| + | Debug.Log("maxDistanceObj.name=" + maxDistanceObj.name); | ||
| + | return maxDistanceObj; | ||
| + | } | ||
| + | } | ||
| + | 参考:https://yubeshicat.hatenablog.com/entry/2018/09/07/150259 | ||
| + | <pre> | ||
==参考== | ==参考== | ||
https://unity.moon-bear.com/3d%E3%83%9B%E3%83%A9%E3%83%BC%E3%82%B2%E3%83%BC%E3%83%A0%E3%80%8C%E3%82%B9%E3%82%B1%E3%82%A2%E3%82%AF%E3%83%AD%E3%82%A6%EF%BC%9A%E5%BB%83%E6%9D%91%E3%81%AE%E6%81%90%E6%80%96%E3%80%8D/navmesh%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%80%8C%E8%BF%BD%E3%81%84%E3%81%8B%E3%81%91%E3%81%A6%E3%81%8F%E3%82%8B%E6%95%B5%E3%82%AD%E3%83%A3%E3%83%A9%E3%80%8D%E3%82%92%E4%BD%9C%E3%82%8B/ | https://unity.moon-bear.com/3d%E3%83%9B%E3%83%A9%E3%83%BC%E3%82%B2%E3%83%BC%E3%83%A0%E3%80%8C%E3%82%B9%E3%82%B1%E3%82%A2%E3%82%AF%E3%83%AD%E3%82%A6%EF%BC%9A%E5%BB%83%E6%9D%91%E3%81%AE%E6%81%90%E6%80%96%E3%80%8D/navmesh%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%80%8C%E8%BF%BD%E3%81%84%E3%81%8B%E3%81%91%E3%81%A6%E3%81%8F%E3%82%8B%E6%95%B5%E3%82%AD%E3%83%A3%E3%83%A9%E3%80%8D%E3%82%92%E4%BD%9C%E3%82%8B/ | ||
https://qiita.com/aimy-07/items/d1fea617ab9cbb3bd1ed | https://qiita.com/aimy-07/items/d1fea617ab9cbb3bd1ed | ||
2023年5月27日 (土) 04:19時点における版
追跡アクション追加
- 敵オブジェクトにAddComponentsでRigidbodyとCapsuleColliderを追加
- 床オブジェクトの(名前の横にある)staticにチェックをつける
- Unityメインメニュー/Window/AI/Navigationから床オブジェクトを選択し、Bakeタブを選択しBakeボタンを押す。
- 敵オブジェクトのAddComponentsからNavMeshAgentを追加
- 敵オブジェクトに以下csのようにNavMeshAgentを追加
- 障害物オブジェクトを設置してstaticにチェックを入れる。
- 障害物オブジェクトにもBakeを設定する。
using UnityEngine.AI;
public class EnemyController : MonoBehaviour
{
NavMeshAgent agent;
GameObject playerObj;
void Start()
{
playerObj = GameObject.Find("Player");
NavStart();
}
// 追跡ロジック開始
void NavStart()
{
if (GetComponent<NavMeshAgent>() != null)
{
agent = GetComponent<NavMeshAgent>();
agent.updateRotation = false;
agent.updatePosition = true;
}
}
void Update()
{
NavUpdate();
}
// 追跡ロジック
void NavUpdate()
{
if (playerObj != null && agent != null)
{
agent.SetDestination(playerObj.transform.position);
}
}
}
追跡されない時
- 対象オブジェクトのscaleを変えてみる。
- bakeを再度やってみる
正面を向いて追跡
GameObject playerObj;
float speed = 0.1f;
void Start () {
playerObj = GameObject.Find("Player");
}
void Update() {
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(playerObj.transform.position - transform.position), 0.3f);
transform.position += transform.forward * speed;
}
参考:https://qiita.com/ganbaru/items/d4fe649370ce4451db80
接触判定させる場合で、追いついて回転して、接触判定しないときはRigidbodyが足りないのかも・・
NavMeshAgent同士の接触半径を狭める場合は、InspectorのNavMeshAgentのRadiusを0.5から小さくする
逃げる
using UnityEngine.AI;
public class PlayerController : MonoBehaviour
{
NavMeshAgent agent;
float speed = 6f;
GameObject enemyObj;
GameObject targetPointGroupObj;
void Start()
{
enemyObj = GameObject.Find("Enemy");
targetPointGroupObj = GameObject.Find("TargetPointGroup");
NavStart();
GetFarTargetPointObj();
}
// 追跡ロジック開始
void NavStart()
{
if (GetComponent<NavMeshAgent>() != null)
{
agent = GetComponent<NavMeshAgent>();
agent.updateRotation = false;
agent.updatePosition = true;
}
}
void Update()
{
UpdateNav();
UpdateLookAt();
}
void UpdateLookAt()
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(enemyObj.transform.position - transform.position), 0.3f);
}
// 追跡ロジック
void UpdateNav()
{
if (agent != null)
{
if (agent.pathStatus != NavMeshPathStatus.PathInvalid)
{
// agent.SetDestination(gameObject.transform.Find("Back").transform.position);
agent.SetDestination(GetFarTargetPointObj().transform.position);
}
}
}
// 敵から一番遠いターゲットポイントのGameObjectを返す
GameObject GetFarTargetPointObj()
{
float maxDistance = 0;
GameObject maxDistanceObj = new GameObject();
foreach (Transform transform in targetPointGroupObj.GetComponentInChildren<Transform>())
{
var distance = Vector3.Distance(enemyObj.transform.position, transform.gameObject.transform.position);
if (maxDistance < distance)
{
maxDistance = distance;
maxDistanceObj = transform.gameObject;
}
}
Debug.Log("maxDistanceObj.name=" + maxDistanceObj.name);
return maxDistanceObj;
}
}
参考:https://yubeshicat.hatenablog.com/entry/2018/09/07/150259
<pre>
==参考==
https://unity.moon-bear.com/3d%E3%83%9B%E3%83%A9%E3%83%BC%E3%82%B2%E3%83%BC%E3%83%A0%E3%80%8C%E3%82%B9%E3%82%B1%E3%82%A2%E3%82%AF%E3%83%AD%E3%82%A6%EF%BC%9A%E5%BB%83%E6%9D%91%E3%81%AE%E6%81%90%E6%80%96%E3%80%8D/navmesh%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%80%8C%E8%BF%BD%E3%81%84%E3%81%8B%E3%81%91%E3%81%A6%E3%81%8F%E3%82%8B%E6%95%B5%E3%82%AD%E3%83%A3%E3%83%A9%E3%80%8D%E3%82%92%E4%BD%9C%E3%82%8B/
https://qiita.com/aimy-07/items/d1fea617ab9cbb3bd1ed
