code VR

Unity×VR(68)

スポンサーリンク

//tips

//年末儀式多めの日
//EnemyAi作成

プレイヤーががEnemyに近づいたら主人を追跡する仕組みを作る。

Enemyのon triggerの範囲を大きくとり、索敵フィールドを作る。プレイヤーがその中に侵入したら、Enemyの移動目的地を親友したプレイヤー座標に設定する。

まずはEnemyオブジェクトの子要素に空オブジェクトを作成、sphere Colliderを選択し、Is Triggerにチェックを入れて、索敵エリアを作成する。

さらに、索敵オブジェクトにSearchCharacterスクリプトを追加。

接触したコライダのタグがPlayerの時にEnemyが主人公を追いかけるようにすれ良いので、下記のスクリプトを編集していき、そのif (col.tag == "Player”)の後を意図したもので埋めていけば良いことになる。

using UnityEngine;
using System.Collections;

public class SearchCharacter : MonoBehaviour {

private MoveEnemy moveEnemy;

void Start() {
moveEnemy = GetComponentInParent<MoveEnemy>();
}

void OnTriggerStay(Collider col) {
// プレイヤーキャラクターを発見
if (col.tag == "Player") {

}
}
}

moveEnemy = GetComponentInParent<MoveEnemy>();を入れているのは、Enemyの状態にバリエーションを作り、それに対応するアクションをMoveEnemyに行わせたいからである。

Walkで始まり、Wait、ChaseとTriggerの状態によりEnemyの状態を切り替える方法を行う。

public enum EnemyState {
Walk,
Wait,
Chase
};

をMoveEnemyスクリプトに組み込み、EnemyState.Walk、EnemyState.Chaseなどで状態を分岐させていく。

EnemyState.Walkの際は、setPosition.CreateRandomPosition();で目的地はランダムに設定し、AIに自動探索させる。

EnemyState.Chaseの際は、playerTransform = targetObj;で侵入したプレイヤーの座標を追わせる。

EnemyState.Waitの際は、AIが目的地到着した場合で、立ち止まらせる。

下記の形にMoveEnemyとSearchCharacterスクリプトを修正した。

using UnityEngine;
using System.Collections;

public class MoveEnemy : MonoBehaviour
{
// 目的地
private Vector3 destination;
// 歩くスピード
[SerializeField]
private float walkSpeed = 1.0f;
// 速度
private Vector3 velocity;
// 移動方向
private Vector3 direction;

private Rigidbody rigd;

private bool arrived;

private SetPosition setPosition;

// 待ち時間
[SerializeField]
private float waitTime = 1f;
// 経過時間
private float elapsedTime;

// 敵の状態
private EnemyState state;
// 追いかけるキャラクター
private Transform playerTransform;

public enum EnemyState
{
Walk,
Wait,
Chase
};

void Start()
{
rigd = GetComponent<Rigidbody>(); //プレイヤーのRigidbodyを取得

//destination = new Vector3(4, 0f, 4f);

setPosition = GetComponent<SetPosition>();
setPosition.CreateRandomPosition(); //目的地設定

velocity = Vector3.zero;
arrived = false;
elapsedTime = 0f;
SetState(EnemyState.Walk);
}

// Update is called once per frame
void Update()
{
// 見回りまたはキャラクターを追いかける状態
if (state == EnemyState.Walk || state == EnemyState.Chase)
{
// キャラクターを追いかける状態であればキャラクターの目的地を再設定
if (state == EnemyState.Chase)
{
setPosition.SetDestination(playerTransform.position);
}

velocity = Vector3.zero;
direction = (setPosition.GetDestination() - transform.position).normalized;
transform.LookAt(new Vector3(setPosition.GetDestination().x, transform.position.y, setPosition.GetDestination().z));
velocity = direction * walkSpeed;

// 目的地に到着したかどうかの判定
if (Vector3.Distance(transform.position, setPosition.GetDestination()) < 0.5f)
{
SetState(EnemyState.Wait);
}
}
else if (state == EnemyState.Wait)
{
elapsedTime += Time.deltaTime;

// 待ち時間を越えたら次の目的地を設定
if (elapsedTime > waitTime)
{
SetState(EnemyState.Walk);
}
}
velocity.y += Physics.gravity.y * Time.deltaTime;
rigd.velocity = velocity;
}
/*
void Update()
{
if (!arrived)
{
velocity = Vector3.zero;

direction = (destination - transform.position).normalized;
transform.LookAt(new Vector3(destination.x, transform.position.y, destination.z));

velocity = direction * walkSpeed;
Debug.Log(destination);

//velocity.y += Physics.gravity.y * Time.deltaTime;
rigd.velocity = velocity;

if (Vector3.Distance(transform.position, destination) < 0.5f)
{
arrived = true;
}
}
else
{
elapsedTime += Time.deltaTime;

// 待ち時間を越えたら次の目的地を設定
if (elapsedTime > waitTime)
{
setPosition.CreateRandomPosition();
destination = setPosition.GetDestination();
arrived = false;
elapsedTime = 0f;
}
Debug.Log(elapsedTime);
}

}
*/
// 敵キャラクターの状態変更メソッド
public void SetState(EnemyState tempState, Transform targetObj = null)
{
if (tempState == EnemyState.Walk)
{
arrived = false;
elapsedTime = 0f;
state = tempState;
setPosition.CreateRandomPosition();
}
else if (tempState == EnemyState.Chase)
{
state = tempState;
// 待機状態から追いかける場合もあるのでOff
arrived = false;
// 追いかける対象をセット
playerTransform = targetObj;
}
else if (tempState == EnemyState.Wait)
{
elapsedTime = 0f;
state = tempState;
arrived = true;
velocity = Vector3.zero;
}
}
// 敵キャラクターの状態取得メソッド
public EnemyState GetState()
{
return state;
}
}

using UnityEngine;
using System.Collections;

public class SearchCharacter : MonoBehaviour
{
private MoveEnemy moveEnemy;

void Start()
{
moveEnemy = GetComponentInParent<MoveEnemy>();
}

void OnTriggerStay(Collider col)
{
// プレイヤーキャラクターを発見
if (col.tag == "Player")
{
// 敵キャラクターの状態を取得
MoveEnemy.EnemyState state = moveEnemy.GetState();
// 敵キャラクターが追いかける状態でなければ追いかける設定に変更
if (state != MoveEnemy.EnemyState.Chase)
{
Debug.Log("プレイヤー発見");
moveEnemy.SetState(MoveEnemy.EnemyState.Chase, col.transform);
}
}
}
}

このように最初は自動探索で始まり、範囲内に入るとプレイヤーを追尾するようになる。

人気の記事

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.