c# - 如何用两个相同的盒子碰撞器打开相同的动画?
问题描述
我在游戏中有一个关卡,当你进入一个盒子对撞机时,一个传送门会打开,当你离开它时,它会关闭。当我进入 box collider 1 时,两个门户都需要打开,而当我离开它时,两者都需要关闭。当我进入第二个门户的框碰撞器 2 时,这也需要发生。我有一个盒子对撞机 1 的脚本,并将它应用到盒子对撞机 2。它检查玩家是否在对撞机中。我有一个动画器 bool,它直接从盒子对撞机脚本中获取变量来检查范围。我使用那个布尔动画。但是,该 animator bool 不适用于 box collider 2。box collider 的变量有效,但 animator bool 无效。有没有办法连接第二个,或者我需要为那个盒子对撞机制作一个新脚本?
盒子对撞机代码:
public bool inRange;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
inRange = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
inRange = false;
}
}
}
门户脚本代码:
public class Portal : MonoBehaviour {
private Animator anim;
private bool inPortalRange;
public GameObject portalBorder;
void Start ()
{
anim = GetComponent<Animator>();
}
void Update ()
{
OpenPortal();
UpdateAnimation();
}
private void UpdateAnimation()
{
anim.SetBool("inPortalRange", inPortalRange);
}
private void OpenPortal()
{
PortalBorder poborder = portalBorder.GetComponent<PortalBorder>();
inPortalRange = poborder.inRange;
}
}
一张情况图:
解决方案
首先,您不应该使用
GetComponent
每一帧。要么像anim
你应该立即存储它。或者您可以简单地制作portalBorder
类型,PortalBorder
然后在通过 Inspector 引用它时自动设置相应的引用。那么是的,目前您只更新其中一个动画师。为了控制它们,你必须以某种方式连接它们。
我会做这样的事情
public class Portal : MonoBehaviour
{
private Animator anim;
private bool inPortalRange;
// Public read-only access
public bool InPortalRange => inPortalRange;
// Reference each other via the Inspector in both portals
public Portal OtherPortal;
// Give this directly the according type so you don't need GetComponent at all
public PortalBorder portalBorder;
// I would recommend to do things always as early as possible
// Awake is executed before Start
private void Awake()
{
anim = GetComponent<Animator>();
}
private void Update ()
{
OpenPortal();
UpdateAnimation();
}
private void UpdateAnimation()
{
// Here now use the range of either this or the other portal
anim.SetBool("inPortalRange", InPortalRange || OtherPortal.inPortalRange );
}
private void OpenPortal()
{
inPortalRange = portalBorder.inRange;
}
}
然而,与其将其作为轮询调用,Update
我实际上宁愿使用事件驱动的方法:
public class PortalBorder : MonoBehaviour
{
public UnityEvent OnEnteredPortalRange;
public UnityEvent OnLeftPortalRange;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
OnEnteredPortalRange.Invoke();
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
OnEnteredPortalRange.Invoke();
}
}
}
现在您的脚本必须UnityEvent
(就像onClick
按钮一样)您可以通过检查器或使用代码添加回调
public class Portal : MonoBehaviour
{
public Animator anim;
private bool inPortalRange;
// Public read-only access
public bool InPortalRange => inPortalRange;
// Reference each other via the Inspector in both portals
public Portal OtherPortal;
// Give this directly the according type so you don't need GetComponent at all
public PortalBorder portalBorder;
// I would recommend to do things always as early as possible
// Awake is executed before Start
private void Awake()
{
anim = GetComponent<Animator>();
// Instead of checking a bool in Update simply
// wait until the according events get invoked
portalBorder.OnEnteredPortalRange.AddListener(EnablePortal);
portalBorder.OnLeftPortalRange.AddListener(DisablePortal);
}
private void OnDestroy()
{
// always make sure to remove callbacks when not needed anymore
// in roder to avoid NullReferenceExceptions
portalBorder.OnEnteredPortalRange.RemoveListener(EnablePortal);
portalBorder.OnLeftPortalRange.RemoveListener(DisablePortal);
}
public void EnablePortal()
{
anim.SetBool("inPortalRange", true);
OtherPortal.anim.SetBool("inPortalRange", true);
}
public void DisablePortal()
{
anim.SetBool("inPortalRange", false);
OtherPortal.anim.SetBool("inPortalRange", false);
}
}
推荐阅读
- mysql - WHERE 顺序的差异输出不同的结果。为什么?
- apache-kafka - kafka + 查询所有Topics的详细配置
- reactjs - 如何在反应中处理组件之间的道具
- ruby-on-rails - 全局模拟调用外部 API 的方法
- php - 将 WhereHas 与可能具有或不具有链接关系的模型一起使用
- python - IndexError: 读取 LUNA16 时列表索引超出范围
- java - 在Java的主类中放置一个类可以吗?
- java - 我正在尝试使用 springboot 在三个实体中使用一对多映射
- python - 我可以在没有代理的情况下从 main.py 在 Peewee 上初始化多数据库吗
- sql - QUERY TYPE 的雪花计算成本