我目前正在统一制作我的第一个“更大”的 2D 游戏,我使用
Tilemap
来创建教程级别。
敌人向玩家方向移动,如果他们之间的距离小于
m_attackRange
,敌人会发起近战攻击。
通常敌人会停止移动,发动攻击,稍作休息,如果它仍在攻击范围内,则再次攻击,否则会尝试再次向玩家移动。
问题是敌人在持续攻击的同时开始滑动并推开玩家,但这只有在敌人达到一定速度时才会发生。
这是我的敌人脚本
Update()
方法中的移动和攻击部分。
// Move towards the target if it is within range
if (m_target != null && Vector2.Distance(transform.position, m_target.transform.position) <= m_targetRange && !m_isAttacking)
{
transform.position = Vector2.MoveTowards(transform.position, m_target.transform.position, m_speed * Time.deltaTime);
}
// Check if the target is within range and if enough time has passed since the last attack
if (m_target != null && Vector2.Distance(transform.position, m_target.transform.position) <= m_attackRange && m_timeSinceLastAttack >= m_attackRate && !m_isAttacking)
{
m_isAttacking = true;
m_timeSinceLastAttack = 0;
}
if (m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime > 1)
{
m_isAttacking = false;
}
m_timeSinceLastAttack += Time.deltaTime;
我尝试在攻击前将敌方物体的速度归零,但没有成功,它一直在移动。
我通过摩擦将材料放在
Tilemap Collider 2D
组件上。
唯一的“解决方法”是,如果我在攻击后跳到攻击上方以减慢敌人的速度,但是一旦我逃跑并且敌人获得一些速度,它就会再次开始滑动和推动。
我将非常感谢有关如何解决此问题的任何建议,如果需要,我会尽快提供更多信息。
我将变换命令(又名移动部分)的条件更改为仅在玩家处于目标范围内且不在攻击范围内时激活。此外,我必须在稍后将“isAttacking”标志设置为 false 以正确匹配攻击动画和攻击时间
所以我的敌人没有“滑动”,因为变换命令在不应该激活的时候激活,这也是速度归零不起作用的原因,因为它始终为零
我已经更改了您的脚本以避免重复,因此在每帧运行
Update()
方法的所有计算之后获得更多性能。
您检查了两次
m_target
和 m_isAttacking
似乎没有必要。你在哪里也计算距离两次。
正如机器人在评论中提到的那样,您自己的回答不清楚,希望您确实设法理解了您的问题并修复了您的脚本但是使用下面这个版本的脚本,我通过重新排列您的顺序来解决滑动问题逻辑。
//Check if there is a target
if (m_target != null)
{
//Check is attacking
if (!m_isAttacking)
{
//Calculate distance
var distance = Vector2.Distance(transform.position, m_target.transform.position);
// Check if target is within range
if (distance <= m_targetRange)
{
//Check if target is within attack range
if(distance <= m_attackRange && m_timeSinceLastAttack >= m_attackRate)
{
//Attack
m_isAttacking = true;
m_timeSinceLastAttack = 0;
}
else
{
//Move
transform.position = Vector2.MoveTowards(transform.position, m_target.transform.position, m_speed * Time.deltaTime);
}
}
}
else
{
//If its attacking wait for animation to end
if (m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime > 1)
{
m_isAttacking = false;
}
}
//Accumulate time since last attack
m_timeSinceLastAttack += Time.deltaTime;
}
考虑将此逻辑包装在方法中,例如,
if(m_target != null)
中的整个逻辑都可以包装在一个方法中。