如何让 Physics2D.IgnoreLayerCollision 只忽略物理硬碰撞而不触发碰撞?
How do I make Physics2D.IgnoreLayerCollision only ignore physical hard collisions and not trigger collisions?
我刚刚发现了如何忽略碰撞,这真的很有帮助。我想要它是因为我希望我的游戏中有一些宝藏,既有物理硬碰撞器,又有玩家触摸它时的触发器。我不希望我的玩家与宝物发生物理碰撞,但我确实希望我的宝物在地面上发生物理碰撞而不是掉落。
不幸的是,当我使用 Physics2D.IgnoreLayerCollision
时,它也忽略了当我的玩家走过宝藏捡起它时我使用的触发对撞机。我希望启用触发碰撞器,禁用物理硬碰撞器。
这是我的代码:
public class colliderTreasureScript : MonoBehaviour
{
public Rigidbody2D rb;
public float jumpforce;
public float speed;
public LayerMask playerlayer; // 8
public LayerMask treasurelayer; // 9
// Start is called before the first frame update
void Start()
{
Physics2D.IgnoreLayerCollision(8, 9, true);
Physics2D.IgnoreLayerCollision(9, 8, true);
Physics2D.IgnoreLayerCollision(9, 9,true);
rb = GetComponent<Rigidbody2D>();
rb.AddForce(Vector2.up * jumpforce * Time.deltaTime, ForceMode2D.Impulse);
}
这是另一个捡宝的脚本
public class GenericTreasureScript : MonoBehaviour
{
public float rotatespeed;
private Player playerscript;
public int treasurevalue;
public Transform movetowardsposition;
public float speed;
public bool touched;
// public CircleCollider2D heavycollider;
// Start is called before the first frame update
void Start()
{
movetowardsposition = GameObject.Find("ScorePositionUpdated").transform;
touched = false;
playerscript = FindObjectOfType<Player>();
//rotatespeed = Random.Range(140, 155.3f);
speed = Random.Range(18, 22);
}
// Update is called once per frame
void Update()
{
if (touched == true)
{
transform.position = Vector2.MoveTowards(transform.position, movetowardsposition.position, speed * Time.deltaTime);
}
if (Vector2.Distance(transform.position, movetowardsposition.position) < .2f)
{
destroy();
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
playerscript.score += treasurevalue;
touched = true;
StartCoroutine("destroyBackup");
}
}
I dont want my player to collide physically with the treasure, but I
do want my treasure to collide physically on the ground and not fall
through
如果你想分离物理碰撞器和触发碰撞器以在玩家接触时仍然触发但不引起碰撞。
您可以:
- 删除
RigidBody2D
completely, the object that gets triggered does not need a RigidBody2D
只有玩家会在你的情况下删除物理碰撞器
- 保持
RigidBody2D
but set the gravityScale
为0并移除物理碰撞器
- 添加另一个额外层并将物理碰撞器移动到具有该层的另一个父游戏对象上,例如
"treasurephysicallayer"
,然后仅禁用该层与玩家之间的碰撞,而不是禁用两个碰撞器所在的层
示例编号 3:
public LayerMask playerlayer; // 8
public LayerMask treasurelayer; // 9
public LayerMask treasurephysicallayer; // 10
// Start is called before the first frame update
void Start() {
Physics2D.IgnoreLayerCollision(8, 8, true);
Physics2D.IgnoreLayerCollision(8, 10, true);
Physics2D.IgnoreLayerCollision(10, 8, true);
Physics2D.IgnoreLayerCollision(9, 9, true);
Physics2D.IgnoreLayerCollision(9, 10, true);
Physics2D.IgnoreLayerCollision(10, 9, true);
Physics2D.IgnoreLayerCollision(10, 10, true);
}
另外通过设置图层。代码是可能的,但在 Physics2D PlayerSettings
中设置它们要容易得多。
您可以在您当前通过代码设置的相应碰撞上勾选或勾选。
我刚刚发现了如何忽略碰撞,这真的很有帮助。我想要它是因为我希望我的游戏中有一些宝藏,既有物理硬碰撞器,又有玩家触摸它时的触发器。我不希望我的玩家与宝物发生物理碰撞,但我确实希望我的宝物在地面上发生物理碰撞而不是掉落。
不幸的是,当我使用 Physics2D.IgnoreLayerCollision
时,它也忽略了当我的玩家走过宝藏捡起它时我使用的触发对撞机。我希望启用触发碰撞器,禁用物理硬碰撞器。
这是我的代码:
public class colliderTreasureScript : MonoBehaviour
{
public Rigidbody2D rb;
public float jumpforce;
public float speed;
public LayerMask playerlayer; // 8
public LayerMask treasurelayer; // 9
// Start is called before the first frame update
void Start()
{
Physics2D.IgnoreLayerCollision(8, 9, true);
Physics2D.IgnoreLayerCollision(9, 8, true);
Physics2D.IgnoreLayerCollision(9, 9,true);
rb = GetComponent<Rigidbody2D>();
rb.AddForce(Vector2.up * jumpforce * Time.deltaTime, ForceMode2D.Impulse);
}
这是另一个捡宝的脚本
public class GenericTreasureScript : MonoBehaviour
{
public float rotatespeed;
private Player playerscript;
public int treasurevalue;
public Transform movetowardsposition;
public float speed;
public bool touched;
// public CircleCollider2D heavycollider;
// Start is called before the first frame update
void Start()
{
movetowardsposition = GameObject.Find("ScorePositionUpdated").transform;
touched = false;
playerscript = FindObjectOfType<Player>();
//rotatespeed = Random.Range(140, 155.3f);
speed = Random.Range(18, 22);
}
// Update is called once per frame
void Update()
{
if (touched == true)
{
transform.position = Vector2.MoveTowards(transform.position, movetowardsposition.position, speed * Time.deltaTime);
}
if (Vector2.Distance(transform.position, movetowardsposition.position) < .2f)
{
destroy();
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
playerscript.score += treasurevalue;
touched = true;
StartCoroutine("destroyBackup");
}
}
I dont want my player to collide physically with the treasure, but I do want my treasure to collide physically on the ground and not fall through
如果你想分离物理碰撞器和触发碰撞器以在玩家接触时仍然触发但不引起碰撞。
您可以:
- 删除
RigidBody2D
completely, the object that gets triggered does not need aRigidBody2D
只有玩家会在你的情况下删除物理碰撞器 - 保持
RigidBody2D
but set thegravityScale
为0并移除物理碰撞器 - 添加另一个额外层并将物理碰撞器移动到具有该层的另一个父游戏对象上,例如
"treasurephysicallayer"
,然后仅禁用该层与玩家之间的碰撞,而不是禁用两个碰撞器所在的层
示例编号 3:
public LayerMask playerlayer; // 8
public LayerMask treasurelayer; // 9
public LayerMask treasurephysicallayer; // 10
// Start is called before the first frame update
void Start() {
Physics2D.IgnoreLayerCollision(8, 8, true);
Physics2D.IgnoreLayerCollision(8, 10, true);
Physics2D.IgnoreLayerCollision(10, 8, true);
Physics2D.IgnoreLayerCollision(9, 9, true);
Physics2D.IgnoreLayerCollision(9, 10, true);
Physics2D.IgnoreLayerCollision(10, 9, true);
Physics2D.IgnoreLayerCollision(10, 10, true);
}
另外通过设置图层。代码是可能的,但在 Physics2D PlayerSettings
中设置它们要容易得多。
您可以在您当前通过代码设置的相应碰撞上勾选或勾选。