c# - 问题,OnCollisionStay 上的布尔冲突
问题描述
问题,当我按 E 来实例化 Hole 对象时,他们按 F 来实例化树,
即使玩家仍在与 Hole 碰撞,当我按 F 时,holeColliding 变为假。
公共类 CreateHole : MonoBehaviour {
public GameObject gameObject2;
public GameObject gameObject1;
public bool holeColliding;
public Transform playerPosition;
public bool facingRight1 = true;
public Vector3 holePosition;
public bool treeColliding;
void Update()
{
facingRight1 = GetComponent<PlayerMovement>().facingRight;
if (Input.GetKeyDown(KeyCode.E) && holeColliding == false && facingRight1 == true)
{
Instantiate(gameObject1, playerPosition.position + new Vector3(0.6f, -1f, 0f), Quaternion.identity);
}
else if (Input.GetKeyDown(KeyCode.E) && holeColliding == false && facingRight1 == false)
{
Instantiate(gameObject1, playerPosition.position + new Vector3(-0.6f, -1f, 0f), Quaternion.identity);
}
if (Input.GetKeyDown(KeyCode.F) && holeColliding == true && treeColliding == false)
{
Instantiate(gameObject2, holePosition + new Vector3(0f, 0.5f), Quaternion.identity);
}
}
void OnTriggerStay2D(Collider2D other)
{
if(other.tag == "Hole")
{
holePosition = other.transform.position;
holeColliding = true;
Debug.Log("true");
}
else
{
holeColliding = false;
Debug.Log("false");
}
if(other.tag == "Tree")
{
treeColliding = true;
}
else
{
treeColliding = false;
}
}
解决方案
gameObject2
似乎没有被标记为“洞”,所以你else
的OnTriggerStay
套装holeColliding = false
......
由于OnTriggerStay2D
每帧都执行,但一次只针对一个 Collider,所以你的bool
s 总是一团糟!
(不幸的是,API 并不清楚它是只为一个其他对象调用还是为每个对象调用,我假设/期待后者 - 但在这里并不重要)
我宁愿不使用重复OnTriggerStay2D
,而是将其拆分为OnTriggerEnter2D
and OnTriggerExit2D
。无论如何这是有道理的,否则你可以进入一个洞,离开它但holeColliding
会true
永远留下!
void OnTriggerEnter2D (Collider2D other)
{
if(other.CompareTag("Hole"))
{
holePosition = other.transform.position;
holeColliding = true;
Debug.Log("true");
}
else if(other.CompareTag("Tree"))
{
treeColliding = true;
}
}
void OnTriggerExit2D(Collider2D other)
{
if(other.CompareTag("Hole"))
{
holeColliding = false;
}
else if(other.CompareTag("Tree"))
{
treeColliding = false;
}
}
请注意,在上面的代码中,我建议宁愿使用CompareTag
而不是直接将字符串与==
. CompareTag
如果提供的标签拼写错误或根本不存在,则抛出异常。一个“错误”会通过==
简单地返回而默默地隐藏起来,这会false
花费你的开发时间和精力;)
一般还有两点:
- 永远不要使用或重复使用 - 这是一个非常昂贵的电话
GetComponent
。Update
而是存储一次引用并重用它! - 您检查了
E
两次输入,这也是多余的并且针头昂贵。因为在两个代码块中你做的几乎一样,你甚至可以使用?
运算符来缩短它(这基本上是if - else
当只以不同方式分配一个变量时的简写)
我会将您的代码修改为
// Best would be you already reference this via the Inspector
// Then you can skip the GetComponent completely
[SerializeField] private PlayerMovement playerMovement;
private void Awake ()
{
// Otherwise get it at runtime and store it for later
if(! playerMovement) playerMovement = GetComponent<PlayerMovement>();
}
void Update()
{
// Now reuse the already stored reference
facingRight1 = playerMovement.facingRight;
if (Input.GetKeyDown(KeyCode.E) && !holeColliding)
{
// Since in both code blocks you do exactly the same
// .. the only changing is a `-` you can shorten your code a lot
var x = 0.6f * (facingRight1 ? 1 : -1);
Instantiate(gameObject1, playerPosition.position + new Vector3(x, -1f, 0f), Quaternion.identity);
}
if (Input.GetKeyDown(KeyCode.F) && holeColliding && !treeColliding)
{
Instantiate(gameObject2, holePosition + Vector3.up * 0.5f, Quaternion.identity);
}
}
推荐阅读
- node.js - Firebase Cloud Functions - 在 Firestore 中移动数据
- c# - 如果没有从 DbContext 类派生的上下文类,则无法使用启用迁移创建默认数据库
- php - 两次跨域
- python - E1120: 构造函数调用中的参数没有值
- oracle - 如何在 Oracle 中使用 dbms_output.put_line
- java - Spring 显示用户刚刚上传的图片,无需重启服务器
- javascript - CSS 颜色样式取决于返回的 Ajax 响应
- javascript - 有没有一种简单的方法来克隆现有的选择框?
- android -
- java - 调整 JFrame 大小时缩放 JPanel