C# Unity3d无赖2D:如何在敌人身上扩张;OnCantMove“;攻击墙壁的脚本?

C# Unity3d无赖2D:如何在敌人身上扩张;OnCantMove“;攻击墙壁的脚本?,c#,unity3d,unity3d-2dtools,roguelike,C#,Unity3d,Unity3d 2dtools,Roguelike,这是我第一次在StackOverflow问问题 我已经完成了Unity 3D官方的“Roguelike 2D”教程,并尝试自己对其进行扩展。当玩家试图走进一堵墙时,他反而破坏了它,最终冲破了墙 为了清晰起见,我删除了声音和动画命令 protected override void OnCantMove<T> (T component) { Wall hitWall = component as Wall; hitWall.DamageWall (wallDamage);

这是我第一次在StackOverflow问问题

我已经完成了Unity 3D官方的“Roguelike 2D”教程,并尝试自己对其进行扩展。当
玩家试图走进一堵墙时,他反而破坏了它,最终冲破了墙

为了清晰起见,我删除了声音和动画命令

protected override void OnCantMove<T> (T component)
{
    Wall hitWall = component as Wall;
    hitWall.DamageWall (wallDamage);
}
playerDamage
由敌方脚本设置,
walldmage
由玩家脚本设置(意思是两者都是由造成伤害的人设置的)。
LoseFood
DamageWall
由玩家和墙脚本设置(意思是两者都是由受到伤害的人设置的)

我希望
敌人
能够像
玩家
那样破坏城墙。因此,我尝试将敌方脚本的
OnCantMove
部分更改为如下内容:

protected override void OnCantMove<T> (T component)
{
    Wall hitWall = component as Wall;
    hitWall.DamageWall (wallDamage);
    Player hitPlayer = component as Player;
    hitPlayer.LoseFood (playerDamage);
}
受保护的覆盖无效OnCantMove(T组件)
{
墙hitWall=作为墙的构件;
hitWall.DamageWall(墙损坏);
玩家hitPlayer=作为玩家的组件;
hitPlayer.LoseFood(玩家伤害);
}
这是:

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);}
}
受保护的覆盖无效OnCantMove(T组件)
{
墙hitWall=作为墙的构件;
玩家hitPlayer=作为玩家的组件;
if(hitWall){hitWall.DamageWall(wallDamage);}
如果(击球员){hitPlayer.LoseFood(playerDamage);}
}
这两种方法都没有达到我想要的效果。我甚至尝试将
敌方
OnCantMove
功能替换为与
玩家
击中墙壁时相同的功能,但这只移除了
敌方
必须击中
玩家
的能力,而无法使其击中墙壁。下一步我应该做什么,看看我是否能解决这个问题


如果我能做到这一点,我希望我能在其他方面继续扩展这个游戏,但我在这方面非常新。感谢您的帮助和建议。

问题在于敌方脚本的move敌军方法。它调用
AttemptMove
,因此它将只向OnCantMove方法发送播放器对象。我不知道该如何解决,但您可能需要重新构建一点,以获得您想要的行为。

谢谢!我也已经完成了这个教程,并决定扩展游戏来学习更多关于Unity的知识。多亏了这个挑战,我能够重新考虑代码并使其按预期工作(参见结果)

事实上,正如所指出的,这个问题与
尝试移动相关

由于
AttemptMove(int-xDir,int-yDir)
函数中的泛型类型在
MovingObject.cs
中,我决定让它返回一个整数,以判断它是否命中所提到的组件,同样:

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;
}
....
// 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;
}
然后,只需将
移动敌人()
敌方.cs
更改为检查玩家是否被击中,如果没有,则尝试将其靠墙移动,同样:

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;
}
....
// 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;
}
。。。。
//检查玩家是否被击中
int hitCode=AttemptMove(xDir,yDir);
//如果玩家被击中,退出(别忘了跳过下一步)
如果(hitCode==移动\尝试\命中)
{
skipMove=true;
返回;
}
//否则,检查墙壁是否被击中
else if(hitCode==移动\尝试\未命中)
尝试移动(xDir、yDir);
skipMove=true;
}

在教程的原始代码中,跳过移动是很重要的。否则,由于僵尸可以到达一个点,他们没有墙壁阻挡的方式,玩家真的可以永远卡住

这个问题更适合我