我发现很难弄清楚为什么我的变换是错误的。谁能帮助我解决这个问题。我试图为我的敌人制造一个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;
}
答案 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;
}
}