unity3d - Unity 飞行相机在加速时穿过地面和物体
问题描述
我正在使用统一的extendedflycam.cs。我添加了一个球体对撞机和一个刚体。目的是避免相机穿过地面和建筑物。这仅在相机以正常速度飞行时实现,但当相机使用 shift 键加速时,如脚本所预期的那样,它会穿过地面和建筑物。这是通过脚本本身的速度倍增器来实现的。如何避免这种情况?即使在加速时,相机怎么会发生碰撞?
我有没有重力的刚体,质量、阻力和角度阻力为 1000。这是 ExtendedFlycam.cs:
using UnityEngine;
{
public class ExtendedFlycam : MonoBehaviour
{
public float CameraSensitivity = 90;
public float ClimbSpeed = 4;
public float NormalMoveSpeed = 10;
public float SlowMoveFactor = 0.25f;
public float FastMoveFactor = 3;
private float _rotationX;
private float _rotationY;
// ReSharper disable once UnusedMember.Local
private void Start()
{
_rotationX = transform.eulerAngles.y;
}
// ReSharper disable once UnusedMember.Local
private void Update()
{
if (Input.GetMouseButton(1))
{
_rotationX += Input.GetAxis("Mouse X") * CameraSensitivity * Time.deltaTime;
_rotationY += Input.GetAxis("Mouse Y") * CameraSensitivity * Time.deltaTime;
_rotationY = Mathf.Clamp(_rotationY, -90, 90);
}
Quaternion targetRotation = Quaternion.AngleAxis(_rotationX, Vector3.up);
targetRotation *= Quaternion.AngleAxis(_rotationY, Vector3.left);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 4f);
float speedFactor = 1f;
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) speedFactor = FastMoveFactor;
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) speedFactor = SlowMoveFactor;
transform.position += transform.forward * NormalMoveSpeed * speedFactor * Input.GetAxis("Vertical") *
Time.deltaTime;
transform.position += transform.right * NormalMoveSpeed * speedFactor * Input.GetAxis("Horizontal") *
Time.deltaTime;
float upAxis = 0;
if (Input.GetKey(KeyCode.Q)) upAxis = -0.5f;
if (Input.GetKey(KeyCode.E)) upAxis = 0.5f;
transform.position += transform.up * NormalMoveSpeed * speedFactor * upAxis * Time.deltaTime;
}
}
}
解决方案
改用Rigidbody.AddForce
:
您显然是在使用Transform.Translate
移动相机。如果您希望您的相机在完全碰撞的情况下移动,那么您不能使用平移(因为在下一次碰撞检测之前,平移可能会使您的相机完全穿过一个对象)。
如果你想拥有碰撞的全部容量,那么你必须使用Rigidbody.AddForce
.
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
您必须特别注意物体的重力、运动特性等。但是,您应该能够以与翻译类似的方式控制对象。例如:
rb.AddForce(transform.forward * thrust);
rb.AddForce(transform.forward * -thrust);
rb.AddForce(transform.right* thrust);
rb.AddForce(transform.right* -thrust);
向前转变,向前迈进。向后移动的负推力。您还可以在正确的方向和负的正确方向上施加推力。我仍然会使用翻译进行旋转,只是因为这对你来说可能更容易。
您可能希望在对象上设置高摩擦力,以便它像使用平移时一样快速停止。
扩展示例:
public float thrust = 5f;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
// Movement code.
if (Input.GetKey(KeyCode.UpArrow))
{
rb.AddForce(transform.forward * thrust);
}
if (Input.GetKey(KeyCode.DownArrow))
{
rb.AddForce(transform.forward * -thrust);
}
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(transform.right* thrust);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(transform.right* -thrust);
}
// Your rotation code
if (Input.GetMouseButton(1))
{
_rotationX += Input.GetAxis("Mouse X") * CameraSensitivity * Time.deltaTime;
_rotationY += Input.GetAxis("Mouse Y") * CameraSensitivity * Time.deltaTime;
_rotationY = Mathf.Clamp(_rotationY, -90, 90);
}
Quaternion targetRotation = Quaternion.AngleAxis(_rotationX, Vector3.up);
targetRotation *= Quaternion.AngleAxis(_rotationY, Vector3.left);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 4f);
}
推荐阅读
- html - 为什么背景颜色在内联网格中不起作用
- android - 前台服务在 didExitRegion 上重新启动
- .htaccess - 在 Xenforo 中排除文件夹
- wpf - IsEnabled = false 使 WPF 按钮在使用 caliburn micro 时消失
- json - 使用 newman 批处理命令从 jenkins 运行的邮递员 json 集合。在詹金斯屏幕中填充二进制文件,请指导我解决此问题
- python - 如何使用特定日期时间查找文档?
- git - 将 VSTS 与 Github 集成
- r - 比较两个数据框的列联表
- android - GoogleMap moveCamera/animateCamera 不工作
- asp.net-core - 路由以允许来自查询字符串和默认 {id} 模板的参数