【发布时间】:2019-11-14 10:56:59
【问题描述】:
我有一个 2d 角色,他可以使用下面的脚本发射一个带有rigidbody2d 的hookshot 射弹。当射弹与某个层(在 Physics2D 项目设置中选择)上的 tilemapcollider2d 碰撞时,它应该立即停止。但是,OnTriggerEnter2D 并不总是发生得足够快,导致弹丸在停止之前就被夹入瓷砖中。使用此设置的脚本基本上可以正常工作,而不是剪辑。
我知道 onCollisionEnter2D 和使用速度而不是 MoveTowards 可能是这里的解决方案,以在弹丸与该层的瓷砖碰撞时停止弹丸。不幸的是,我无法让它工作,我不确定为什么。我在 tilemapcollider2d 和弹丸刚体2d 上都取消选中“是触发器”,它直接通过,onCollisionEnter2D 事件从未被注册。
public class Hookshot : MonoBehaviour
{
private GameObject player;
private Vector2 playerPos;
private BoxCollider2D col;
private Rigidbody2D rbody;
public GameObject DustParticle;
private readonly float hookshotCastTime = 0.2f;
private readonly float hookshotReturnSpeed = 200f;
private readonly float hookshotDistanceBuffer = 0.2f;
private void Awake()
{
col = GetComponent<BoxCollider2D>();
rbody = GetComponent<Rigidbody2D>();
}
public IEnumerator CastHookshot(float castDistance, Vector2 aimDir, GameObject playerInstance)
{
player = playerInstance;
playerPos = gameObject.transform.position;
Vector2 target = playerPos + (castDistance * aimDir);
float speed = castDistance / hookshotCastTime * Time.deltaTime;
while (Vector2.Distance(transform.position, target) > hookshotDistanceBuffer)
{
//transform.position = Vector2.MoveTowards(transform.position, target, speed);
rbody.velocity = speed * 10 * aimDir;
yield return new WaitForFixedUpdate();
}
transform.position = target;
StartCoroutine(ReturnHookshot());
}
public IEnumerator ReturnHookshot()
{
col.enabled = false;
playerPos = player.transform.position;
while (Vector2.Distance(transform.position, playerPos) > hookshotDistanceBuffer)
{
playerPos = player.transform.position;
transform.position = Vector2.MoveTowards(transform.position, playerPos, hookshotReturnSpeed * Time.deltaTime);
yield return new WaitForEndOfFrame();
}
Destroy(gameObject);
}
//private void OnTriggerEnter2D(Collider2D collision)
//{
// StopAllCoroutines();
// Player playerInstance = player.GetComponent<Player>();
// playerInstance.hookshotAttached = true;
// if (GameManager.instance != null)
// {
// GameManager.instance.Emit(DustParticle, 5, transform.position, Vector2.one * 3f);
// }
//}
private void OnCollisionEnter2D(Collision2D collision)
{
StopAllCoroutines();
rbody.velocity = Vector2.zero;
Player playerInstance = player.GetComponent<Player>();
playerInstance.hookshotAttached = true;
if (GameManager.instance != null)
{
GameManager.instance.Emit(DustParticle, 5, transform.position, Vector2.one * 3f);
}
}
}
【问题讨论】:
-
这几乎可以肯定是因为物理在
FixedUpdate上,而你的协程在(有效地)Update上。请改用WaitForFixedUpdate()。 -
我刚刚尝试了 WaitForFixedUpdate() 并没有改变任何东西