Unity3D效果实现:怪物的控制和怪物刷新点
前言:
在制作游戏的过程中我们会需要不同的敌人或者说是怪物,每个怪物都有自己的状态,在一些RPG游戏中还会有固定的刷怪点,本文就来描述如何用脚本实现怪物的控制和怪物的刷新
效果:
- 玩家靠近时怪物会开始攻击玩家,到达一定距离之后攻击玩家,如果玩家不在范围内则会在出生点徘徊
- 刷新点会一次产生三个怪
实现方法:
1.敌人刷新点
- 我们需要建立一个空物体来作为刷新点,随后将脚本组件添加给它
- 将敌人预制体放入该脚本中即可
- 脚本代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyPoint : MonoBehaviour
{
public GameObject EnemyPre;
// Start is called before the first frame update
public int Num = 3;
private float timer;
// Update is called once per frame
void Update()
{
//计时器时间增加
timer += Time.deltaTime;
//2s检测一次
if(timer>2)
{
//重置计时器
timer = 0;
//查看有几个敌人
int n = transform.childCount;
if (n < Num)
{
Vector3 v = transform.position;
v.x += Random.Range(-5, 5);
v.z += Random.Range(-5, 5);
//随机确定一个旋转
Quaternion q = Quaternion.Euler(0, Random.Range(0, 360), 0);
//创建一个敌人
GameObject enemy = GameObject.Instantiate(EnemyPre, v, q);
//设置父子关系
enemy.transform.SetParent(transform);
}
}
}
}
2.敌人
- 敌人需要判断和玩家之间的距离,随后开始跟踪玩家,如果超出范围则回到刷新点,当和玩家小于一定距离时开始攻击,如果玩家死亡则停止攻击
- 敌人死亡后掉落物品,
- 脚本代码添加给敌人,并给他的tag设置为“enemy”
- 脚本代码如下
using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyControl : MonoBehaviour { public int ID = 101; //主角 private PlayerControl player; public int Hp = 100; //攻击力 public int Attack = 20; //出身点位置 private Vector3 position; //动画器组件 private Animator animator; //攻击计时器 private float timer = 1; //当前是否攻击 private bool isAttack = false; //血瓶预制件 public GameObject PotionPre; // Start is called before the first frame update void Start() { player = GameObject.FindWithTag("Player").GetComponent<PlayerControl>(); //获得出生点位置 position = transform.position; //获取动画器组件 animator = GetComponent<Animator>(); } // Update is called once per frame void Update() { if(player.hp<=0||Hp<=0) { animator.SetBool("Run", false); animator.SetBool("Attack", false); return; } //获得与主角的距离 float distance = Vector3.Distance(player.transform.position, transform.position); Debug.Log(distance); //如果7m没发现主角 if(distance>7f) { if (Vector3.Distance(transform.position, position) > 1f) //转向出生点 { transform.LookAt(new Vector3(position.x, transform.position.y, position.z)); //向前移动 transform.Translate(Vector3.forward * 2 * Time.deltaTime); animator.SetBool("Run", true); } else { //停止播放移动画面 animator.SetBool("Run", false); } } else if(distance>3f) { //如果与主角的距离在3到7m之间,则朝主角移动 //转向玩家 transform.LookAt(new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z)); //向前移动,这里我们直接移动,也可用导航 transform.Translate(Vector3.forward * 2 * Time.deltaTime); animator.SetBool("Run", true); //保证当前不在攻击状态 isAttack = false; } else { //3m内停止移动,开始攻击 animator.SetBool("Run", false); //转向玩家 transform.LookAt(new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z)); animator.SetBool("Attack", true); if(isAttack==false) { isAttack = true; timer = 1; } } timer += Time.deltaTime; if(timer>=2) { timer = 0; player.GetDamage(Attack); } } public void GetDamage(int damage) { if(Hp>0) { GetComponentInChildren<HpManager>().ShowText("-" + damage); Hp -= damage; } if(Hp<=0) { Instantiate(PotionPre, transform.position, transform.rotation); animator.SetTrigger("Die"); //给任务系统报告,击杀了一个ID为101的敌人 QuestManager.Instance.AddEnemy(ID); Destroy(gameObject, 20); } } }