代码实现:
using UnityEngine;
public class Monster : MonoBehaviour
{
public Transform player;
public float patrolRange = 10f;
public float moveSpeed = 2f;
public float attackRange = 2f;
public float attackInterval = 2f;
public float jumpBackDistance = 3f;
public float healInterval = 5f;
public float healAmount = 10f;
public float healSpeed = 1f;
private Animator animator;
private Rigidbody rigidbody;
private bool isDead = false;
private bool isAttacking = false;
private bool isHealing = false;
private float currentHealth;
private float lastAttackTime = 0f;
private float lastHealTime = 0f;
private void Start()
{
animator = GetComponent<Animator>();
rigidbody = GetComponent<Rigidbody>();
currentHealth = 100f;
}
private void Update()
{
if (isDead)
{
return;
}
float distance = Vector3.Distance(transform.position, player.position);
if (distance <= attackRange)
{
if (Time.time - lastAttackTime >= attackInterval)
{
isAttacking = true;
animator.SetBool("isAttacking", true);
lastAttackTime = Time.time;
}
}
else if (distance <= patrolRange)
{
Vector3 direction = (player.position - transform.position).normalized;
transform.LookAt(player);
transform.position += direction * moveSpeed * Time.deltaTime;
if (!isAttacking)
{
animator.SetBool("isWalking", true);
}
}
else
{
if (!isAttacking)
{
animator.SetBool("isWalking", false);
}
}
if (currentHealth <= 30f && !isHealing)
{
isHealing = true;
animator.SetBool("isHealing", true);
lastHealTime = Time.time;
}
if (isHealing && Time.time - lastHealTime >= healInterval)
{
currentHealth += healAmount * Time.deltaTime * healSpeed;
if (currentHealth >= 100f)
{
currentHealth = 100f;
isHealing = false;
animator.SetBool("isHealing", false);
}
}
}
public void TakeDamage(float damage)
{
if (isDead)
{
return;
}
currentHealth -= damage;
if (currentHealth <= 0f)
{
isDead = true;
animator.SetBool("isDead", true);
rigidbody.isKinematic = true;
Destroy(gameObject, 3f);
}
else if (currentHealth <= 30f && !isHealing)
{
isHealing = true;
animator.SetBool("isHealing", true);
lastHealTime = Time.time;
}
}
public void Attack()
{
float distance = Vector3.Distance(transform.position, player.position);
if (distance <= attackRange)
{
Player playerScript = player.GetComponent<Player>();
if (playerScript != null)
{
playerScript.TakeDamage(10f);
}
}
}
public void JumpBack()
{
Vector3 direction = (transform.position - player.position).normalized;
transform.position += direction * jumpBackDistance;
}
}
使用方法:
在Unity中创建一个空对象,将该对象作为怪物的父对象,然后将怪物的模型作为子对象,并将脚本 Monster 添加到子对象中。
在Unity中创建一个玩家对象,并将脚本 Player 添加到该对象中。
在 Monster 脚本中,将父对象的 Transform 组件赋值给 player 变量。
在 Monster 脚本中,根据需要调整各个参数的值,例如 patrolRange、moveSpeed、attackRange、attackInterval、jumpBackDistance、healInterval、healAmount 和 healSpeed。
在 Monster 脚本中,实现 TakeDamage() 方法,该方法用于在怪物受到攻击时减少血量。
在 Player 脚本中,实现 TakeDamage() 方法,该方法用于在玩家受到攻击时减少血量。
在 Monster 脚本中,实现 Attack() 方法,该方法用于在怪物攻击时对玩家造成伤害。
在 Monster 脚本中,实现 JumpBack() 方法,该方法用于在怪物血量低于30%时向后跳3米。
在 Monster 的动画控制器中,创建 isWalking、isAttacking、isHealing 和 isDead 四个布尔型参数,并创建相应的状态机和过渡。
运行游戏,测试怪物的巡逻、跟踪、攻击和回血等功能。