Игра Unity 2d Игрок и враг не двигаются - PullRequest
0 голосов
/ 27 апреля 2020

Я следую учебному пособию по игре Unity 2D. Игрок и враг наследуют от базового класса, известного как MovingObject. Все в игре работает отлично, за исключением того, что игрок и враг не могут двигаться. Вот сценарии. Движение происходит в виде сетки в виде сетки.

Это оригинальная серия уроков. Попробуйте просмотреть движущийся объект, игрока и учебники противника. https://www.youtube.com/playlist?list=PLX2vGYjWbI0SKsNH5Rkpxvxr1dPE0Lw8F

Базовый класс MovingObject:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class MovingObject : MonoBehaviour {


public float moveTime = 0.1f;
public LayerMask blockinglayer;

private BoxCollider2D boxCollider;
private Rigidbody2D rb2D;
private float inverseMoveTime;
// Use this for initialization
protected virtual void Start () {
    boxCollider = GetComponent<BoxCollider2D>();
    rb2D = GetComponent<Rigidbody2D>();
    inverseMoveTime = 1f / moveTime;
}

protected bool Move(int xDir, int yDir, out RaycastHit2D hit)
{
    Vector2 start = transform.position;
    Vector2 end = start + new Vector2(xDir, yDir);
    boxCollider.enabled = false;
    hit = Physics2D.Linecast(start, end, blockinglayer);
    boxCollider.enabled = true;

    if (hit.transform == null)
    {
        StartCoroutine(SmoothMovement(end));
        return true;
    }
    return false;
}



protected IEnumerator SmoothMovement(Vector3 end)
{
    float sqrRemainingDistance = (transform.position - end).sqrMagnitude;

    while (sqrRemainingDistance > float.Epsilon)
    {
        Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
        rb2D.MovePosition(newPosition);
        sqrRemainingDistance = (transform.position - end).sqrMagnitude;
        yield return null;

    }
}

protected virtual void AttemptMove<T>(int xDir, int yDir)
    where T : Component
{
    RaycastHit2D hit;
    bool canMove= Move(xDir, yDir, out hit);

    if (hit.transform == null)
    {
        return;
    }

    T hitComponent = hit.transform.GetComponent<T>();

    if(!canMove && hitComponent != null)
    {
        OnCantMove(hitComponent);
    }

}

protected abstract void OnCantMove<T>(T component)

    where T : Component;


// Update is called once per frame

}

Сценарий игрока:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MovingObject {

public int wallDamage = 1;
public int pointsPerFood = 10;
public int pointsPerSoda = 20;
public float restartLevelDelay = 1f;

private Animator animator;
private int food;
// Use this for initialization
protected override void Start () {
    animator = GetComponent<Animator>();
    food = GameManager.instance.playerFoodPoints;
    base.Start();

}
private void OnDisable()
{
    GameManager.instance.playerFoodPoints = food;
}
// Update is called once per frame
void Update () {

    if (GameManager.instance.playersTurn)
    {
        return;


    }
    int horizontal = 0;
    int vertical = 0;

    horizontal = (int)Input.GetAxisRaw("Horizontal");
    vertical = (int)Input.GetAxisRaw("Vertical");
    if (horizontal != 0)
    {
        vertical = 0;
    }

    if(horizontal!=0 || vertical != 0)
    {
        AttemptMove<Wall>(horizontal, vertical);
    }

}

protected override void OnCantMove<T>(T component)
{
    Wall hitwall = component as Wall;
    hitwall.damageWall(wallDamage);
    animator.SetTrigger("playerChop");
}
protected override void AttemptMove<T>(int xDir, int yDir)
{
    food--;
    base.AttemptMove<T>(xDir, yDir);
    RaycastHit2D hit;
    CheckIfGameOver();
    GameManager.instance.playersTurn = false;
}

public void LoseFood(int loss)
{
    animator.SetTrigger("playerHit");
    food -= loss;
    CheckIfGameOver();
}

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "Exit")
    {
        Invoke("Restart", restartLevelDelay);
        enabled = false;
    }   
    else if (other.tag == "Food")
    {
        food += pointsPerFood;
        other.gameObject.SetActive(false);

    }
    else if (other.tag == "Soda")
    {
        food += pointsPerSoda;
        other.gameObject.SetActive(false);
    }
}

private void Restart()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); 
}

private void CheckIfGameOver()
{
    if (food <= 0)
    {
        GameManager.instance.GameOver();
    }
}
}

Сценарий врага:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MovingObject {
public int playerDamage;

private Animator animator;
private Transform target;
private bool skipmove;


// Use this for initialization
protected override void Start () {

    GameManager.instance.AddEnemyToList(this);
    animator = GetComponent<Animator>();
    target = GameObject.FindGameObjectWithTag("Player").transform;
    base.Start();


}

protected override void AttemptMove<T>(int xDir, int yDir)
{
    if (skipmove)
    {
        skipmove = false;
        return;
    }
    base.AttemptMove<T>(xDir, yDir);
}
public void MoveEnemy()
{
    int xDir = 0;
    int yDir = 0;

    if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
    {
        yDir = target.position.y > transform.position.y ? 1 : -1;

    }
    else
    {
        xDir = target.position.x > transform.position.x ? 1 : -1;
        AttemptMove<Player>(xDir,yDir);
    }
}

protected override void OnCantMove<T>(T component)
{
    Player hitplayer = component as Player;
    animator.SetTrigger("enemyAttack");
    hitplayer.LoseFood(playerDamage);

}

}

Я не уверен, есть ли у игрока или противника проблема с базовым сценарием. Может ли кто-нибудь помочь.

1 Ответ

0 голосов
/ 27 апреля 2020

Несколько замечаний (надеюсь, это поможет):

MovingObject.cs - Внутри Update (), не должно ли это быть?

if (!GameManager.instance.playersTurn)

Обратите внимание, я добавил "!" до GameManager

Player.cs - в AttemptMove () вам нужно вызвать Move () ... вот так

Move (xDir, yDir, out hit); 

Enemy.cs

1) В конце AttemptMove () должно быть:

skipMove = true;

2) В конце MoveEnemy () этот код НЕ должен находиться в остальное, но после остального:

AttemptMove<Player>(xDir,yDir); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...