前回の記事でプレイヤーを追いかけてくるキャラクターを実装しました。これに機能を追加して相手を踏んで倒せるようにします。
具体的にはジャンプして上から敵に触れた場合は、敵を消滅させます。逆に横から触れた場合はプレイヤーキャラクターが消滅するようにします。
前回の記事は以下のURLになります。
https://qiita.com/yanagiiiiiii_t/items/accd63204791ff102705
実装
2つあるキャラクターのオブジェクトのうち、敵とする方、つまり操作しない方において、InspectorビューのTagの名前をEnemyに設定します。
次に操作キャラクターにアタッチされているスクリプトPlayerController.csを以下のように修正します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
public float speed; //移動速度
public float jumpPower; //ジャンプ力
private bool isJumping = false; //ジャンプ判定
Rigidbody rigidbody;
void Start()
{
rigidbody = GetComponent<Rigidbody>(); //Rigidbodyを取得
rigidbody.constraints = RigidbodyConstraints.FreezeRotation; //オブジェクトの回転を防ぐ
}
void Update()
{
if (Input.GetKey(KeyCode.UpArrow)) //上矢印を押すと奥へ移動
{
transform.position += speed * transform.forward * Time.deltaTime;
}
if (Input.GetKey(KeyCode.DownArrow)) //下矢印を押すと手前へ移動
{
transform.position -= speed * transform.forward * Time.deltaTime;
}
if (Input.GetKey(KeyCode.RightArrow)) //右矢印を押すと右へ移動
{
transform.position += speed * transform.right * Time.deltaTime;
}
if (Input.GetKey(KeyCode.LeftArrow)) //左矢印を押すと左へ移動
{
transform.position -= speed * transform.right * Time.deltaTime;
}
if (Input.GetKeyDown(KeyCode.Space) && isJumping == false)
{
rigidbody.AddForce(Vector3.up * jumpPower); //ジャンプしていない時にスペースキー入力でジャンプする
isJumping = true;
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Floor"))
{
isJumping = false; //床に着地したらジャンプ判定をfalseにする
}
if (collision.gameObject.CompareTag("Enemy")) //Enemyに衝突した時の処理
{
if (transform.position.y > collision.gameObject.transform.position.y)
{
Destroy(GameObject.Find("Slime_Green")); //敵より高い位置から触れた場合は敵を消滅させる
}
else
{
Destroy(this.gameObject); //プレイヤーが消滅する
}
}
}
}
前回からの変更点はOnCollisionEnter関数の中にEnemyと衝突した時の処理が追加されたことです。
if (transform.position.y > collision.gameObject.transform.position.y)
このIf文によってプレイヤーのY座標が敵のY座標より大きい、すなわち敵を上から踏んでいるかを判定します。踏んだと判定したらDestroyで敵オブジェクトを消します。そうでない場合は横から接触したと判定し、プレイヤーのオブジェクトが消えます。
プレイヤーが消滅すると敵は追いかける対象がなくなってしまいエラーが発生してしまうので、敵オブジェクトにアタッチされているEnemyMove.csの方も少し修正します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(NavMeshAgent))]
public class EnemyMove : MonoBehaviour
{
private Transform target;
private NavMeshAgent agent;
Rigidbody rigidbody;
void Start()
{
target = GameObject.Find("Rabbit_Yellow").transform; //追いかける対象のオブジェクトのtransformを取得
rigidbody = GetComponent<Rigidbody>(); //Rigidbodyを取得
rigidbody.constraints = RigidbodyConstraints.FreezeRotation; //オブジェクトの回転を防ぐ
agent = GetComponent<NavMeshAgent>(); //NavMeshAgentを取得
}
void Update()
{
if (GameObject.Find("Rabbit_Yellow") != null)
{
agent.SetDestination(target.position); //追いかける対象を目的地に設定する
}
}
}
Update関数の中のSetDestinationをIf文の中に入れました。これによってGameObject.Find("プレイヤーオブジェクト名称")がnullではない、すなわちプレイヤーが負けておらず存在しているかどうかを判定します。プレイヤーが存在している時だけプレイヤーの座標を目的地に設定しているため、プレイヤーが負けて消えてもエラーが出なくなります。
以上を実行して敵を上から踏んで倒せることと、横から敵に触れたらプレイヤーが消滅することを確認出来たら成功です。
参考
https://tech.pjin.jp/blog/2021/01/12/unity_csharp_destroy/
https://mogi0506.com/unity-destroy/