AI会在横版地图上向左向右移动,移动一段距离后会原地停止移动,等待一段时间后,会随机向左或向右移动,以此循环,其中AI移动速度,移动时间、停留时间均可以自行调控,当人物进入怪物攻击范围后 会自动面向人物进行攻击,攻击时不会移动,直至人物离开攻击范围,怪物受到攻击后会闪红,有血量:
脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChameleonController : MonoBehaviour
{
public static ChameleonController chameleonController;
private void Awake()
{
chameleonController = this;
}
Animator animator;
Rigidbody2D rg;
public float MoveSpeed = 0;
float changeTime = 0;
float time = 0;
//随机时间
public float minTime = 0;
public float maxTime = 0;
int direction = 1;
float distance_ = 0;
bool isChange = false;
bool canHit = false;
Transform PlayerTransform;
public float Distance = 0;
float Dwell_gap = 0; //停留时间
float Dwell_Cumulative = 0; //停留时间累积
public float DwellMinTime = 0;
public float DwellMaxTime = 0;
float moveTime = 0; //行走时间
//行走的最大时间和最短时间设定
public float moveMinTime = 0;
public float moveMaxTime = 0;
float moveTimeCumulative = 0;
bool isDwell = false;
bool isDwellRange = false;
bool CanMove = false;
bool CanCount = false;
bool CanTimeCumulative = false;
bool isAttacking = false;
bool isAttacked = false;
public bool TrackPlayer = false;
public float TrackSpeed = 0;
public float CurrentPlayer = 0;
public float Life_value = 0;
public float hitTime = 0;
bool isHit = false;
float time1 = 0;
GameObject gm;
bool isinvincible = false;
void Start()
{
animator = GetComponent<Animator>();
rg = GetComponent<Rigidbody2D>();
CanMove = false;
CanCount = true;
}
void Update()
{
PlayerTransform = GameObject.Find("Player").transform;
//得到与玩家的距离
distance_ = Mathf.Sqrt(Mathf.Abs(PlayerTransform.transform.position.x - transform.position.x) * Mathf.Abs(PlayerTransform.transform.position.x - transform.position.x) +
Mathf.Abs(PlayerTransform.transform.position.y - transform.position.y) * Mathf.Abs(PlayerTransform.transform.position.y - transform.position.y));
time = time + Time.deltaTime;
if(isChange==false)
{
changeTime = Random.Range(minTime, maxTime);
isChange = true;
}
transform.localScale = new Vector3(-direction, 1, 1);
if (time > changeTime)
{
direction = -direction;
transform.localScale = new Vector3(-direction, 1, 1);
time = 0;
isChange = false;
}
//判断是否在攻击距离之内
if(distance_<Distance)
{
canHit = true;
}
else
{
canHit = false;
}
if(canHit)
{
//判断玩家在怪物的哪边
if (PlayerTransform.transform.position.x < transform.position.x)
{
direction = 1;
animator.SetBool("attack", true);
GMF_PlayerController._PlayeController.inJured(CurrentPlayer);
transform.localScale = new Vector3(direction, 1, 1);
}
else
{
direction = -1;
animator.SetBool("attack", true);
transform.localScale = new Vector3(direction, 1, 1);
GMF_PlayerController._PlayeController.inJured(CurrentPlayer);
}
}else
{
animator.SetBool("attack", false);
}
//随机暂停时间 开始暂停 播放停留动画 人物停止移动 生成暂停时间
if(CanCount)
{
isDwellRange = true;
CanTimeCumulative = true;
CanCount = false;
}
if(isDwellRange) //设置停留动画 设置暂停时间
{
Dwell_gap = Random.Range(DwellMinTime, DwellMaxTime);
animator.SetBool("idem", true);
animator.SetBool("run", false);
CanMove = false;
isDwellRange = false;
}
if (CanTimeCumulative)
{
Dwell_Cumulative = Dwell_Cumulative + Time.deltaTime;
}
if (Dwell_Cumulative > Dwell_gap) //超过暂停时间 停留结束 结束停留动画 生成行走时间 开始行走动画
{
animator.SetBool("idem", false);
animator.SetBool("run", true);
moveTime = Random.Range(moveMinTime, moveMaxTime);
CanMove = true;
Dwell_Cumulative = 0;
CanTimeCumulative = false;
}
//行走时间结束
if(CanMove)
{
moveTimeCumulative = moveTimeCumulative + Time.deltaTime;
if(moveTimeCumulative>moveTime)
{
CanMove = false;
moveTimeCumulative = 0;
CanCount = true;
}
}
if(Life_value<=0)
{
Destroy(this.gameObject);
}
if (isHit)
{
// animator.SetBool("current", true);
time1 = time1 + Time.deltaTime;
if (time1 > hitTime)
{
animator.SetBool("current", false);
isinvincible = false;
isHit = false;
time1 = 0;
}
}
}
private void FixedUpdate()
{
//没有停留就可以移动
if(CanMove)
{
MoveMent();
}
}
void MoveMent()
{
if(TrackPlayer==false)
{
rg.velocity = new Vector2(1 * direction * MoveSpeed, 0);
}
else
{
if (distance_ < Distance)
{
if(PlayerTransform.transform.position.x < transform.position.x)
{
rg.velocity = new Vector2(-1 * TrackSpeed, 0);
}else
{
rg.velocity = new Vector2( 1 * TrackSpeed, 0);
}
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if(collision.tag=="Player")
{
CanMove = true;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Player")
{
CanMove = false;
}
if (collision.tag == "bullte")
{
if(isinvincible==false)
{
animator.SetBool("current", true);
isinvincible = true;
isHit = true;
}
}
}
public void Current(float value)
{
Life_value = Life_value - value;
}
}
AI动画设置,注意动画的命名要一样,不然需要修改代码:
需要注意的是,每个动画没有过度,直接切换,不然会有一些卡顿
人物标签需要设置为Player
怪物标签需要设置为Chameleon
如果想让怪物之间不能够相互碰撞,让怪物和玩家间可以相互碰撞,可以给怪物AI和玩家分别设置一个碰撞层级,方法如下:
首先我们需要为人物和怪物设置分别设置一个层级,一个是人物层级,一个是怪物层级,点击Layer下拉菜单:
添加一个层级:
接下来:
在编辑下拉菜单下找到Project Setting,将不想发生碰撞的两个层级较差的对勾取消掉
子弹攻击,AI掉血摧毁设置:
bullte为子弹,需要有boxCollider2D,勾选Is Trigger