C# 在Unity中与游戏对象交互
我想在Unity中与游戏对象交互。这些对象可能是钥匙、门、箱子 假设桌子上有一把钥匙。当玩家靠近它时,它应该被一个着色器勾勒出来,一个文本显示为“拾取键” 我为可交互的游戏对象创建了一个界面C# 在Unity中与游戏对象交互,c#,unity3d,C#,Unity3d,我想在Unity中与游戏对象交互。这些对象可能是钥匙、门、箱子 假设桌子上有一把钥匙。当玩家靠近它时,它应该被一个着色器勾勒出来,一个文本显示为“拾取键” 我为可交互的游戏对象创建了一个界面 public interface IInteractable { string InteractabilityInfo { get; } void ShowInteractability(); void Interact(); } 通过这样做,我可以将接口组件添加到我的Key脚
public interface IInteractable
{
string InteractabilityInfo { get; }
void ShowInteractability();
void Interact();
}
通过这样做,我可以将接口组件添加到我的Key
脚本中
public class Key : MonoBehaviour, IInteractable
{
public string InteractabilityInfo { get { return "some text here"; } }
public void ShowInteractability()
{
// Outline Shader maybe?
}
public void Interact()
{
// Do something with the key
}
}
当涉及到一个脚本来检查某些东西是否可交互时,我创建了一个脚本来创建一个光线投射来检查可交互。(我将此脚本附加到我的FPS相机)
公共类可交互性检查:单行为
{
私有常量int范围=3;
私有void更新()
{
雷卡斯特击中;
if(物理光线投射(变换.位置,变换.向前,命中率,射程))
{
IIINTERACTABLE interactable=hit.collider.GetComponent();
if(可交互!=null)
{
可交互。显示可交互();
if(Input.GetKeyDown(KeyCode.E))
{
可交互的;
}
}
}
}
}
此脚本尝试获取接口组件,如果该组件不为null,则从中调用方法
这段代码工作得很好,但我不喜欢的是光线投射每帧触发一次。有没有其他方法实现可交互性?是的,光线投射是“昂贵的”,称它为每一帧都不酷,有很多方法可以避免这种情况。在您的情况下,您可以这样简单地重新构造代码:
private void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, RANGE))
{
IInteractable interactable = hit.collider.GetComponent<IInteractable>();
if (interactable != null)
{
interactable.ShowInteractability();
interactable.Interact();
}
}
}
}
另一种方法是在可交互对象上放置球形触发器,然后可以通过球形触发器的
半径
控制范围。
这类似于我刚才回答的另一个问题,所以我刚刚修改了代码
using UnityEngine;
[RequireComponent(typeof(SphereCollider))]
internal abstract class CollisionTrigger : MonoBehaviour
{
private bool _isPlayerInsideTrigger = false;
private void Awake()
{
if(!GetComponent<SphereCollider>().isTrigger)
{
Debug.LogError("Please set the sphere collider to a trigger.");
enabled = false;
return;
}
}
private void Update()
{
if(_isPlayerInsideTrigger)
{
FakeOnTriggerStay();
}
}
private void OnTriggerEnter(Collider collider)
{
if(!collider.CompareTag("Player")) return;
_isPlayerInsideTrigger = true;
}
public abstract void FakeOnTriggerStay();
private void OnTriggerExit(Collider collider)
{
if(!collider.CompareTag("Player")) return;
_isPlayerInsideTrigger = false;
}
}
很抱歉,我必须撤消接受,因为此解决方案无效。我必须调用
interactiable.showInteractibility()代码>当某些东西被光线投射击中时,而不仅仅是按键
public void interactWithYourObject()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, RANGE))
{
IInteractable interactable = hit.collider.GetComponent<IInteractable>();
if (interactable != null)
{
interactable.ShowInteractability();
interactable.Interact();
}
}
}
private void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, RANGE))
{
interactWithYourObject()
}
}
using UnityEngine;
[RequireComponent(typeof(SphereCollider))]
internal abstract class CollisionTrigger : MonoBehaviour
{
private bool _isPlayerInsideTrigger = false;
private void Awake()
{
if(!GetComponent<SphereCollider>().isTrigger)
{
Debug.LogError("Please set the sphere collider to a trigger.");
enabled = false;
return;
}
}
private void Update()
{
if(_isPlayerInsideTrigger)
{
FakeOnTriggerStay();
}
}
private void OnTriggerEnter(Collider collider)
{
if(!collider.CompareTag("Player")) return;
_isPlayerInsideTrigger = true;
}
public abstract void FakeOnTriggerStay();
private void OnTriggerExit(Collider collider)
{
if(!collider.CompareTag("Player")) return;
_isPlayerInsideTrigger = false;
}
}
internal class Key : CollisionTrigger
{
public override void FakeOnTriggerStay()
{
// Show the user they can now interact with it.
// Outline Shader maybe?
if(Input.GetKeyDown(KeyCode.E))
{
// Do something with the key.
}
}
}