防止物体通过对撞机
Prevent object from passing through collider
我正在建造一个由玩家移动的 3D 迷宫。我采用 "labyrinth" 方法,当玩家移动迷宫时,让一个小球在迷宫中移动。当玩家沿球的方向移动球当前停靠的墙时,就会出现问题。球穿过墙壁停在下一堵可用的墙上。
迷宫使用的是网格对撞机和刚体,小球是球体对撞机
我已经大幅提高了物理帧速率,但无济于事。考虑到迷宫的复杂性和潜在的大量迷宫组合,我真的不想在每一面墙上都安装简单的碰撞器。任何提示、技巧、建议、评论等,我们将不胜感激。
连续旋转的球脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballGravity : MonoBehaviour {
public Rigidbody m_Rigidbody;
public Vector3 m_EulerAngleVelocity;
// Use this for initialization
void Start () {
m_EulerAngleVelocity = new Vector3 (0, 100, 0);
m_Rigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
Quaternion deltaRotation = Quaternion.Euler (m_EulerAngleVelocity * Time.deltaTime);
m_Rigidbody.MoveRotation (m_Rigidbody.rotation * deltaRotation);
}
}
迷宫旋转脚本:
using UnityEngine;
using System.Collections;
public class rotObj : MonoBehaviour
{
private float baseAngle = 0.0f;
float rotSpeed = 10;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
//float rotY = Input.GetAxis("Vertical")*rotSpeed*Mathf.Deg2Rad;
//gm.transform.Rotate(Vector3.right, rotY);
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
}
要获得一致的物理状态,最好在 FixedUpdate 中移动碰撞器 - 如果您在管道的 OnMouseXX 阶段移动碰撞器(考虑咨询 https://docs.unity3d.com/Manual/ExecutionOrder.html),您可能会在下次 FixedUpdate 时错过更改叫做。 IE。你的球会根据你旋转迷宫之前的状态在你的场景中移动,并且有一些不幸的时间可能会错过碰撞。
如果您已经尝试使用更紧凑的时间步长,请考虑对 OnMouseDrag 更改进行排队,例如将生成的旋转存储在变量中,并将其应用到 FixedUpdate 中,以便在下一次物理计算时应用它。
您还可以考虑在旋转迷宫的同时移动您的球,快速移动网格对撞机以对抗一个小得多的刚体肯定是麻烦的来源。你可以移动相机吗?
我正在建造一个由玩家移动的 3D 迷宫。我采用 "labyrinth" 方法,当玩家移动迷宫时,让一个小球在迷宫中移动。当玩家沿球的方向移动球当前停靠的墙时,就会出现问题。球穿过墙壁停在下一堵可用的墙上。
迷宫使用的是网格对撞机和刚体,小球是球体对撞机
我已经大幅提高了物理帧速率,但无济于事。考虑到迷宫的复杂性和潜在的大量迷宫组合,我真的不想在每一面墙上都安装简单的碰撞器。任何提示、技巧、建议、评论等,我们将不胜感激。
连续旋转的球脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballGravity : MonoBehaviour {
public Rigidbody m_Rigidbody;
public Vector3 m_EulerAngleVelocity;
// Use this for initialization
void Start () {
m_EulerAngleVelocity = new Vector3 (0, 100, 0);
m_Rigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
Quaternion deltaRotation = Quaternion.Euler (m_EulerAngleVelocity * Time.deltaTime);
m_Rigidbody.MoveRotation (m_Rigidbody.rotation * deltaRotation);
}
}
迷宫旋转脚本:
using UnityEngine;
using System.Collections;
public class rotObj : MonoBehaviour
{
private float baseAngle = 0.0f;
float rotSpeed = 10;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
//float rotY = Input.GetAxis("Vertical")*rotSpeed*Mathf.Deg2Rad;
//gm.transform.Rotate(Vector3.right, rotY);
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
}
要获得一致的物理状态,最好在 FixedUpdate 中移动碰撞器 - 如果您在管道的 OnMouseXX 阶段移动碰撞器(考虑咨询 https://docs.unity3d.com/Manual/ExecutionOrder.html),您可能会在下次 FixedUpdate 时错过更改叫做。 IE。你的球会根据你旋转迷宫之前的状态在你的场景中移动,并且有一些不幸的时间可能会错过碰撞。 如果您已经尝试使用更紧凑的时间步长,请考虑对 OnMouseDrag 更改进行排队,例如将生成的旋转存储在变量中,并将其应用到 FixedUpdate 中,以便在下一次物理计算时应用它。
您还可以考虑在旋转迷宫的同时移动您的球,快速移动网格对撞机以对抗一个小得多的刚体肯定是麻烦的来源。你可以移动相机吗?