Unity3d Roguelike 2D:如何扩展敌人"OnCantMove"攻击城墙的脚本
本文关键字:quot OnCantMove 攻击 脚本 城墙 敌人 2D Roguelike 何扩展 扩展 Unity3d | 更新日期: 2023-09-27 18:02:20
这是我第一次在StackOverflow上提问。
我已经完成了Unity 3D官方"Roguelike 2D"教程,并试图自己扩展它。当Player
试图撞墙时,他反而破坏了墙,最终突破了墙。
为了清晰,我删除了声音和动画命令。
protected override void OnCantMove<T> (T component)
{
Wall hitWall = component as Wall;
hitWall.DamageWall (wallDamage);
}
当Enemy
试图走进Player
时,它反而伤害了他,伤害了他。
protected override void OnCantMove <T> (T component)
{
Player hitPlayer = component as Player;
hitPlayer.LoseFood (playerDamage);
}
playerDamage
是由敌人脚本设置的,wallDamage
是由玩家脚本设置的(意味着两者都是由造成伤害的人设置的)。LoseFood
和DamageWall
是由Player和Wall脚本设置的(也就是说两者都是由受到伤害的一方设置的)
我希望Enemy
能够像Player
一样破坏墙壁。所以,我试着改变敌人脚本的OnCantMove
部分,像这样:
protected override void OnCantMove<T> (T component)
{
Wall hitWall = component as Wall;
hitWall.DamageWall (wallDamage);
Player hitPlayer = component as Player;
hitPlayer.LoseFood (playerDamage);
}
:
protected override void OnCantMove<T> (T component)
{
Wall hitWall = component as Wall;
Player hitPlayer = component as Player;
if (hitWall) {hitWall.DamageWall (wallDamage);}
else if (hitPlayer) {hitPlayer.LoseFood (playerDamage);}
}
都没有按我想要的方式工作。我甚至试图将Enemy
的OnCantMove
功能替换为与Player
撞墙时相同的功能,但这只删除了Enemy
必须撞击Player
的能力,而没有使其能够撞击墙壁。接下来我该怎么做,看看能不能解决这个问题?
如果我设法让这个工作,我希望我可以继续扩大这款游戏在其他方面,以及,但我是一个新手。谢谢你的帮助和建议。
问题出在敌人脚本的moveenemy -方法上。它调用AttemptMove<Player>
,所以它只会向oncantmove方法发送一个播放器对象。我不知道如何解决它,但你可能需要重建一点,以获得你想要的行为
谢谢!我也完成了这个教程,并决定扩展游戏来学习更多关于Unity的知识。由于这个挑战,我能够重构代码并使其按预期工作(见这里的结果)
事实上,正如jonathan Hedborg指出的那样,这个问题与AttempMove<Player>
有关。
由于MovingObject.cs
中AttemptMove <T> (int xDir, int yDir)
函数的泛型类型,我决定让它返回一个整数来告诉它是否击中了提到的组件,同样:
protected virtual int AttemptMove <T> (int xDir, int yDir)
where T : Component
{
RaycastHit2D hit;
bool canMove = Move(xDir, yDir, out hit);
if (hit.transform == null)
return MOVE_ATTEMPT_NO_HIT;
T hitComponent = hit.transform.GetComponent<T>();
if (!canMove && hitComponent != null)
{
OnCantMove(hitComponent);
return MOVE_ATTEMPT_HIT;
}
return MOVE_ATTEMPT_NO_HIT;
}
MOVE_ATTEMPT_HIT
和MOVE_ATTEMPT_NO_HIT
是在MovingObject.cs
中定义的整数常量:
public const int MOVE_ATTEMPT_NO_HIT = 0;
public const int MOVE_ATTEMPT_HIT = 1;
然后它只是一个简单的问题,从Enemy.cs
更改MoveEnemy()
来检查玩家是否被击中,如果没有,然后尝试将他移动到墙上,同样:
....
// Check if player was hit
int hitCode = AttemptMove<Player>(xDir, yDir);
// if player was hit, exit (don't forget to skip next move)
if (hitCode == MOVE_ATTEMPT_HIT)
{
skipMove = true;
return;
}
// else, check if a wall was hit
else if (hitCode == MOVE_ATTEMPT_NO_HIT)
AttemptMove<Wall>(xDir, yDir);
skipMove = true;
}
跳过一个移动,就像在教程的原始代码中一样,这很重要。否则,因为僵尸可以到达一个没有墙挡道的地方,玩家就会永远被困住!