Unity 2d游戏玩家和敌人没有移动

问题描述 投票:0回答:1

我一直在关注有关统一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);

}

}

我不确定哪个玩家还是敌人都遇到了基本脚本问题。谁能帮忙。

c# unity3d 2d
1个回答
0
投票

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()中,最后,此代码不应位于else中,而应位于else之后:

AttemptMove<Player>(xDir,yDir); 
© www.soinside.com 2019 - 2024. All rights reserved.