// 移动的方法
public void MoveToTarget()
{
FilpDirection();
}
// 攻击玩家
public void AttackAction(){}
// 对炸弹进行技能攻击
public void SkillAction(){}
// 巡逻过程中需要左右翻转 他一定是在移动的过程中进行调用的
public void FilpDirection(){}
[Header("Movement")]
public float speed; // 移动速度
public Transform ponitA, pointB;
public Transform targetPonit; // 目标点
public List<Transform> attackList = new List<Transform>();
使用移动坐标的方法,只需要更改当前坐标把它缓慢移动到目标坐标。
transform.position
表示坐标的位移,让它得到一个2D向量,MoveTowards方法需要传入三个参数:前坐标,目标坐标,距离的Delta值,也就是速度
。速度需要乘以Time.deltaTime确保在不同的机型得到同样的效果。
transform.position = Vector2.MoveTowards(transform.position,
targetPonit.position,speed * Time.deltaTime);
进行一个简单的测试
在游戏的开始假设移动的目标点是PointA,void Start(){targetPonit = ponitA;}
在update进行MoveToTarget()方法的调用void Update(){ MoveToTarget();}
可以观察到如下图:
黄瓜怪已经移动到A的位置,但它没有办法完全符合A的值,会缓慢的移动至A的位置并尽可能的无限接近这个位置。
如果怪物在A与B之间,挑选移动的位置,如果距离某一个点较远,就移动到较远的那个方向。此外希望在移动的过程中,人物进行翻转。
设置黄瓜怪初始Scale=-1保持不变
所有的敌人在初始的状态下都是面向右侧的,只有黄瓜怪和鲸鱼怪是面向左侧,如果使用transform.localscale修改-1或1的方法进行翻转将会得到一个反向移动的方式,即人面向左向右移动。为了确保所有的敌人都面朝同一个方向,使用同一套代码,单独的调整scale,人物翻转使用rotation的y值修改为180度。
黄瓜怪的左右移动
1.首先获取A,B两个点的位置,然后得到当前怪物位置,判断它与两个点的距离,就是判断position.x之间的大小。由于向左是负数,向右是正数,所以这里需要取绝对值。当前坐标距离哪一个点远就把移动的目标点切换到这个点。
/// 判断当前坐标与PointA和B的位置,将移动的目标点设置为距离远的那一个
public void SwitchPoint()
{
if (Mathf.Abs(ponitA.position.x - transform.position.x)
> Mathf.Abs(pointB.position.x - transform.position.x))
targetPonit = ponitA;
else
targetPonit = pointB;
}
2.判断它是否无限接近目标点,然后移动到另一侧。只需要判断当前坐标 - 目标点坐标的绝对值 < 0.01f
说明无限趋近目标点。
void Update()
{
if (Mathf.Abs(transform.position.x - targetPonit.position.x) < 0.01f)
SwitchPoint();
MoveToTarget();
}
如下图实现了怪物在目标点之间的左右移动
将怪物的rotation的y值改为180度即可实现怪物的翻转,但是除了达到目标点的时候需要进行翻转,如果Player在Enemy的左右两侧的时候也需要进行翻转,比如人物和怪物相向移动,怪物就需要翻转去追她。
判断当前坐标的x与目标点x的关系,如果是小于就往右追,反之向左。
/// 巡逻过程中需要左右翻转 他一定是在移动的过程中进行调用的
public void FilpDirection()
{
// 在目标点的左侧,向右追不需要翻转
if (transform.position.x < targetPonit.position.x)
transform.rotation = Quaternion.Euler(0f, 0f, 0f);
else
transform.rotation = Quaternion.Euler(0f, 180f, 0f);
}
对比1.3中的图,Enemy实现了敌人的翻转。
敌人在移动过程中有一个检测范围,当人物进入这个检测范围的时候,就需要把它添加进敌人的攻击列表attackList中,走出检测范围就需要把它移除。
这里使用Unity自带的函数方法:
OnTriggerStay2D
停留在检测范围内一直不断的进行
OnTriggerExit2D
离开检测范围时触发
/// 物体进入检测范围就添加进攻击列表里
private void OnTriggerStay2D(Collider2D other)
{
// 如果攻击列表不包含,再添加进列表里 添加的是transform
if (!attackList.Contains(other.transform))
attackList.Add(other.transform);
}
/// 物体走出检测范围从攻击列表里移除
private void OnTriggerExit2D(Collider2D other)
{
attackList.Remove(other.transform);
}
游戏未开始前,attackList没有任何游戏物体。
下面是游戏运行时暂停的截图,敌人的检测范围检测到了炸弹和Player,attackList里添加了这两个物体:
Enemy可以适用在各种各样的敌人身上,但是有些部分是比如技能攻击每个敌人各有不同,这就需要使用到继承。
除此之外,允许子类在原有的基础上进行修改,需要设置技能攻击为虚函数。
public class Cucumber : Enemy