游戏开发Unity 3D中的界面



对不起,我知道这是一个愚蠢的问题,但我的大脑需要一些强大的方法来帮助它度过难关。我在youtube上发现了一段关于Interface=>这里显示了情况和代码。我的问题是:

private void Update()
{
var nearestGameObject = GetNearestGameObject();
if (nearestGameObject == null) return;
if (Input.GetButtonDown("Fire1"))
{
var interactable = nearestGameObject.GetComponent<IInteractable>();
interactable?.Interact();
}
}

在更新功能中=>这一行代码=>var interactable = nearestGameObject.GetComponent<IInteractable>();
GetComponent<IInteractable>(),它实际上得到了什么?获取接口????或者获取游戏对象,我以前从未在检查器中看到过连接到Gobj的界面。

我发现这到底有什么好处仍然存在一些困惑。

因此,我决定用一个实际的例子来扩展这个答案和我的评论。

假设您有给定的interface,例如

public interface IInteractable
{
void Interact();
}

现在,您可以拥有任意多个不同的实现。interface只是一种类型的模板,并且告诉实现类型它需要提供某些成员。它告诉这样一个接口的用户(比如在您的情况下,您共享的代码(,无论返回什么实际类型,我们都可以确保有特定的成员可以使用。

例如,一旦你与交互,可能会有一个简单的自毁装置

public class DestroyInteractable : MonoBehaviour, IInteractable
{
public void Interact()
{
Destroy(gameObject);
}
}

或者为什么不移动,例如触发平台

public class MoveInteractable : Monobehaviour, IInteractable
{
[SerializeField] Rigidbody _rigidbody;
[SerializeField] float moveDuration = 1f;
[SerializeField] Vector3 targetPosition;
public void Interact()
{
StartCoroutine(Move());
}
IEnumerator Move()
{
yield return new WaitForFixedUpdate();
var startPosoition = _rigidbody.position;
for(var timePassed = 0f; timePassed < moveDuration; timePassed += Time.deltaTime)
{
_rigidbody.MovePosition(Vector3.Lerp(startPosition, targetPosition, timePassed / moveDuration));
yield return new WaitForFixedUpdate();
}
}
}

等等。。。你可以在你的可交互对象中做任何你想触发的事情。


现在我们来谈谈您的共享代码。

在这一点上,请允许我进行一次小而重要的短途旅行。

有一个巨大的缺陷:永远不要在UnityEngine.Object上使用?.运算符(请参阅为什么C#null条件运算符不适用于Unity可序列化变量?(

一般来说,它应该是

if(nearestGameObject.TryGetComponent<IInteractable>(out var interactable))
{
interactable.Interact();
}

这是怎么回事?

它在实现IInteractable接口的给定GameObject上搜索任何组件类型。如果它找到一个,它将返回对找到的(意味着已经存在的(组件的引用作为IInteractable。如果不存在,则返回null

您的代码根本不关心实际的类类型是什么,因为它不需要知道。为了让它自己工作,它只需要知道它可以调用一个名为Interact()的方法。这次通话后发生的一切都不关我们的事,目前对我们来说也无关紧要。

现在你明白了为什么它如此强大了:通过玩家对象上的一个控制器,你现在可以与所有不同类型的IInteractble对象进行交互,每个对象都可以定义对你的交互的不同反应——你根本不必在意。

我希望这不仅能让我们进一步了解它的作用,还能让我们了解它为什么有用。

接口无法实例化。相反,它将获得可交互对象,该对象是实现IInteractable的类的实例。

最新更新