敵キャラから攻撃を受けたときにHPを減らします。
まずBlenderで敵キャラのモデルとアニメーションを作りました。
これにナビメッシュエージェントとAudioSourceとスクリプトのコンポーネントを追加します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.AI;
public class AgentAttackTest : MonoBehaviour
{
[SerializeField] Transform player;
NavMeshAgent agent;
Animator animator;
bool isAttacking = false;
bool judged = false;
[SerializeField] AudioClip[] audios;
AudioSource audioSource;
UnityStandardAssets.Characters.FirstPerson1.FirstPersonController1 sc_fps;
// Start is called before the first frame update
void Start()
{
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
audioSource = GetComponent<AudioSource>();
sc_fps = player.GetComponent<UnityStandardAssets.Characters.FirstPerson1.FirstPersonController1>();
}
// Update is called once per frame
void Update()
{
agent.destination = player.position; // プレイヤーを追う
// 攻撃しているとき
if (animator.GetCurrentAnimatorStateInfo(0).IsName("Armature|Attack"))
{
// 攻撃アニメーション60%
if (!judged && animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.6f)
{
judged = true;
// 攻撃があたった時
if (Vector3.Distance(player.position, transform.position) <= 3f && Vector3.Dot(player.position - transform.position, transform.forward) >= 0.7f)
{
sc_fps.SetHP(-0.1f);
audioSource.clip = audios[1];
audioSource.Play();
}
// 攻撃があたらなかった時
else
{
audioSource.clip = audios[0];
audioSource.Play();
}
}
// 攻撃アニメーションのおわり
if (isAttacking && animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.95f)
{
isAttacking = false;
StartCoroutine("Groan");
}
}
// 歩いているとき
if (animator.GetCurrentAnimatorStateInfo(0).IsName("Armature|Walk"))
{
// プレイヤーが目の前にいると
if (!isAttacking && Vector3.Distance(player.position, transform.position) <= 2f && Vector3.Dot(player.position - transform.position, transform.forward) >= 0.9f) //!agent.pathPending && agent.remainingDistance < 2f &&
{
isAttacking = true;
judged = false;
animator.SetTrigger("Attack");
StopCoroutine("Groan");
}
}
}
IEnumerator Groan()
{
yield return new WaitForSeconds(Random.Range(1f,5f));
audioSource.clip = audios[2];
audioSource.Play();
}
}
敵はプレイヤーの方へ歩いてきて、プレイヤーが目の前にいると攻撃アニメーションを始めます。攻撃アニメーションが60%まで進んだときに、プレイヤーがまだ目の前にいれば当たったと判断して、叩く音を出して、プレイヤーのHPを減らします。
プレイヤーが遠かったり、敵の前方へのベクトルと、敵からプレイヤーへのベクトルの角度が大きいと当たらなかったと判断して、腕が空を切るような音を出してHPを減らしません。
また、攻撃が終わった後にしばらくしたら敵が唸り声を上げるようにしてみました。それまでに再度攻撃が始まると唸り声を上げるのをやめます。
敵とプレイヤーが衝突できないと、プレイヤーが静止しているときに攻撃が当たらないので、敵キャラの背中のあたりのボーンにカプセルコライダーをつけています。
HPゲージを減らす
HPゲージは前の記事の方法で作りました。プレイヤーのHPを敵のスクリプトから減らせるようにして、それをHPバー用のImageのfillAmountの値に代入しています。
[SerializeField] Image HpGauge;
float HP = 1f;
public void SetHP(float f)
{
HP += f;
HP = Mathf.Clamp(HP,0f,1f);
HpGauge.fillAmount = HP;
}