转换不会在当前上下文中退出

时间:2018-11-18 17:13:05

标签: c# unity3d

我发现很难弄清楚为什么我的变换是错误的。谁能帮助我解决这个问题。我试图为我的敌人制造一个FSM,所以它既可以用于玩家,也可以用于食物。但是,当我尝试对其进行测试时,会出现编译器错误。

using UnityEngine;
using System.Collections;

public class Enemy : MovingObject 
{
    public int playerDamage;

    private Animator animator;
    private Transform target;
    private bool skipMove;
    private Transform Player;
    public AudioClip enemyAttack1;
    public AudioClip enemyAttack2;

    protected override void Start () 
    {
        GameManager.instance.AddEnemeyToList(this);
        animator = GetComponent<Animator> ();
        target = GameObject.FindGameObjectWithTag ("Food").transform;
        base.Start ();

        AIEnemy();
        Player = GameObject.FindWithTag("Player").transform;
    }

    protected override void AttemptMove<T> (int xDir, int yDir) 
    {
        if (skipMove) 
        {
            skipMove = false;
            return;
        }

        base.AttemptMove <T> (xDir, yDir);

        skipMove = true;
    }

    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;
        hitPlayer.LoseFood (playerDamage);
        animator.SetTrigger("enemyAttack");
        SoundManager.instance.RandomizeSfx (enemyAttack1, enemyAttack2);
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Food")
        {
            other.gameObject.SetActive(false);
        }
        else if (other.tag == "Soda")
        {
            other.gameObject.SetActive(false);
        }
    }

    void AIEnemy()
    {
        int State = 0;

        if (State == 0)
        {
            transform.LookAt(Player);
            State++;
        }

        if (State == 1)
            transform.LookAt(target);

        Debug.Log("State 1");
        State++;

        if (State == 2)
        {
            Debug.Log("State 2");
        }

    }

}

public Transform FindClosetFood()
{
    float minDistance = float.PositiveInfinity;
    Transform closetFood = null;
    GameObject[] foods = GameObject.FindGameObjectsWithTag("Food");
    for(int i = 0; i<foods.Length; i++)
    {
        float distance = Vector2.Distance(transform.position, foods[i].transform.position);
        if (distance < minDistance)
        {
            minDistance = distance;
            closetFood = foods[i].transform;
        }
    }
    return closetFood;
 }

}

我添加了一个私人的Transform Player。所以我的敌人知道要看什么,但我仍然无法在控制台中得到任何东西。我尝试在一开始就调用它。但是现在我最终遇到了此编译器错误。

此行出现错误

float distance = Vector2.Distance("transform".position, foods[i].transform.position);

MovingObject脚本:

using UnityEngine;
using System.Collections;

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

1 个答案:

答案 0 :(得分:3)

找不到transform.position,因为transform是在Component下未声明的变量。 MonoBehaviour来自Behaviour的驱动器,而Behaviour来自Component的驱动器。要访问transform变量,您的脚本必须从其中之一派生。尽管MonoBehaviour是脚本应源自的内容。

在代码中,您的Enemy脚本已经从MovingObject派生的MonoBehaviour脚本派生出来,因此应该可以访问transform变量,但是存在问题。 您的敌人脚本中}函数末尾有一个额外的AIEnemy() }函数末尾有一个额外的AIEnemy()关闭或标记Enemy脚本的结尾,因此使transform变量对您不可用。在}函数末尾删除多余的AIEnemy(),您的问题应该得到解决。

如果找不到它,请使用下面的新Enemy脚本:

public class Enemy : MovingObject
{

    public int playerDamage;

    private Animator animator;
    private Transform target;
    private bool skipMove;
    private Transform Player;
    public AudioClip enemyAttack1;
    public AudioClip enemyAttack2;

    protected override void Start()
    {
        GameManager.instance.AddEnemeyToList(this);
        animator = GetComponent<Animator>();
        target = GameObject.FindGameObjectWithTag("Food").transform;
        base.Start();

        AIEnemy();
        Player = GameObject.FindWithTag("Player").transform;


    }

    protected override void AttemptMove<T>(int xDir, int yDir)
    {
        if (skipMove)
        {
            skipMove = false;
            return;
        }

        base.AttemptMove<T>(xDir, yDir);

        skipMove = true;
    }

    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;
        hitPlayer.LoseFood(playerDamage);
        animator.SetTrigger("enemyAttack");
        SoundManager.instance.RandomizeSfx(enemyAttack1, enemyAttack2);
    }

    private void OnTriggerEnter2D(Collider2D other)
    {

        if (other.tag == "Food")
        {

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

            other.gameObject.SetActive(false);
        }


    }

    void AIEnemy()
    {
        int State = 0;

        if (State == 0)
        {
            transform.LookAt(Player);
            State++;
        }
        if (State == 1)

            transform.LookAt(target);
        Debug.Log("State 1");
        State++;
        if (State == 2)
        {
            Debug.Log("State 2");
        }

    }


    public Transform FindClosetFood()
    {
        float minDistance = float.PositiveInfinity;
        Transform closetFood = null;
        GameObject[] foods = GameObject.FindGameObjectsWithTag("Food");
        for (int i = 0; i < foods.Length; i++)
        {
            float distance = Vector2.Distance(transform.position, foods[i].transform.position);
            if (distance < minDistance)
            {
                minDistance = distance;
                closetFood = foods[i].transform;
            }
        }
        return closetFood;
    }
}