Unity3d Roguelike 2D: как расширить сценарий Enemy "OnCantMove" для атаки на стены?

Я впервые задаю вопрос здесь, в Stackru.

Я закончил официальный учебник 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 устанавливается сценарием Enemy, и wallDamage устанавливается скриптом Player (имеется в виду тот, кто наносит урон.) LoseFood а также DamageWall устанавливаются сценариями Player и Wall (т.е. оба устанавливаются тем, кто получает урон).

Я хочу Enemy чтобы быть в состоянии повредить стены, как Player является. Итак, я попытался изменить сценарий Enemy 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);}
}

Ни один из них не работал так, как я хотел. Я даже пытался заменить OnCantMove функция Enemy быть таким же, как когда Player ударяется о стены, но это только убрало способность Enemy должен был ударить Player, не позволяя ему поразить стены. Что мне следует попробовать дальше, чтобы посмотреть, смогу ли я решить эту проблему?

Если мне удастся заставить это работать, я надеюсь, что смогу продолжить расширять эту игру и другими способами, но я очень новичок в этом. Спасибо за любую помощь и совет.

2 ответа

Проблема заключается в MoveEnemy-методе вражеского скрипта. Это вызывает AttemptMove<Player>поэтому он будет отправлять только объект проигрывателя в метод OnCantMove. Не уверен, как бы я решил это, но вам, вероятно, нужно немного перестроить, чтобы получить желаемое поведение.

Спасибо! Я также закончил этот урок и решил расширить игру, чтобы узнать немного больше об Unity. Благодаря этой задаче я смог повторно кодировать код и заставить его работать как положено (см. Результат здесь)

Действительно, проблема была связана с AttempMove<Player> как указал Jonatan Hedborg.

Из-за общего типа в AttemptMove <T> (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;
}

MOVE_ATTEMPT_HIT а также MOVE_ATTEMPT_NO_HIT просто целочисленные константы, определенные в MovingObject.cs как:

public const int MOVE_ATTEMPT_NO_HIT  = 0;
public const int MOVE_ATTEMPT_HIT     = 1;

Тогда это было просто вопрос изменения MoveEnemy() от Enemy.cs чтобы проверить, был ли поражен игрок, а если нет, то пытается прижать его к стене, аналогично:

....
// 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;
}

Пропуск хода, как в оригинальном коде учебника, очень важен. В противном случае, поскольку зомби могут достичь точки, где у них нет стен, преграждающих путь, игрок действительно может застрять навсегда!

Другие вопросы по тегам