所以我目前正在尝试将我的播放器对象及其脚本添加到为相机对象编写的相机脚本中。
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
private Vector3 offset;
private float damping = 0.2f;
public bool canMove = true;
public PlayerMovement player;
private void Start()
{
player = gameObject.GetComponent<PlayerMovement>();
}
void FixedUpdate()
{
if (player.faceRight)
{
offset = new Vector3(1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
else if (!player.faceRight)
{
offset = new Vector3(-1f, 0.5f, -10f);
transform.position = Vector3.Lerp(transform.position, target.position, damping) + offset;
}
}
}
我的问题是我不能写CCD_;这些是不同类型的元件";但如果我写CCD_ 2并且它有效,我可以拖动我的播放器对象。问题是我想学习如何在不拖动对象的情况下使用它。
首先,可以通过Inspector使用属性[SerializeField]
来公开和分配private
(和protected
(字段,而不必像那样强制使其成为public
[SerializeField] private PlayerMovement player;
private void Awake()
{
// if it's not referenced via the Inspector
// get it from this object on runtime as fallback
if(!player) player = GetComponent<PlayerMovement>();
}
然后,字段player
的类型是PlayerMovement
,而Find
返回player = gameObject.Find("Player");
0→不是同一类型。
现在,如果你想从这个脚本附加到的同一个对象中获取该组件。。那你为什么要用昂贵的Find
呢?!你已经知道这个物体了!仅使用GetComponent
将组件附加到与此脚本相同的对象(就像上面的代码中一样(。
如果您真的想使用Find
,那么您想在结果上使用GetComponent
,而不是在gameObject
上,后者是拥有GameObject
的脚本的引用。你宁愿做
[SerializeField] private PlayerMovement player;
private void Awake()
{
if(!player) player = GameObject.Find("player").GetComponent<PlayerMovement>();
}
或者,如果你的场景中只有一个这种类型的实例,你也可以简单地使用FindObjectOfType
[SerializeField] private PlayerMovement player;
private void Awake()
{
if(!player) player = FindObjectOfType<PlayerMovement>();
}
一般来说:如果你可以通过Inspector引用某个东西,那么这样做总是更好的。它更高效,因为引用将被序列化到你的场景或预制资产中,所以当它被加载时,你已经"了;知道";目标引用。使用Find
是非常昂贵的,尽管它在后来的版本中进行了大量优化,但GetComponent
也是您可以避免的工作;(