问题描述
所以我目前正在尝试将我的播放器对象及其脚本添加到我为相机对象编写的相机脚本中。
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,damping) + offset;
}
}
}
我的问题是我不能写 player = gameObject.Find("Player");
,因为 unity 说的是“那些是不同类型的元素”,但是如果我写 public PlayerMovement player;
并且它可以工作,我可以拖动我的播放器对象。问题是我想学习如何在不拖动对象的情况下使用它。
解决方法
首先,您可以使用属性{{3}通过检查器公开和分配private
(和protected
)字段} 而不必强迫它们 public
像 eg
[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
而 [SerializeField]
返回 GameObject
→ 类型不同。
现在,如果你想从这个脚本附加到的同一个对象中获取那个组件..那么你为什么要使用昂贵的 Find
呢?!你已经知道对象了!仅使用 GetComponent
将组件附加到与此脚本相同的对象(就像上面的代码一样)。
如果您真的想使用 Find
,那么您想在结果上使用 GetComponent
,而不是在 Find
上使用,gameObject
是对该脚本的引用 own 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
也是您可以避免的工作 ;)
我添加了 GameObject 和 PlayerMovement 属性。首先编写游戏对象,称为“播放器”。然后通过使用我的 GameObject,我与名为 PlayerMovement 的脚本进行了交互。
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
private Vector3 offset;
private float damping = 0.2f;
public bool canMove = true;
private GameObject playerObject;
private PlayerMovement playerMovementScript;
private void Start()
{
player = GameObject.Find("Player");
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,damping) + offset;
}
}
}
我在这里写这个问题时解决了这个问题。所以我有点为自己感到自豪,但我也想分享我的解决方案,所以如果有人遇到这样的问题,他们可以解决他们的问题。如果有人有更好的解决方案,请分享。