碰撞检测和 isGrounded 检查
Collision Detection and isGrounded checks
我目前正在使用 Unity 开发一个项目,由于我对 C# 和一般编程还很陌生,所以我遇到了一些问题。第一个问题是我的播放器的碰撞检测——我有一个带有重力的建模刚体和一个(非凸面)附加的网格对撞机。对于我的墙,它们是导入的模型,并附有盒式碰撞器。
如果我将我的盒子碰撞器保持为模型的默认大小(大约是玩家厚度的两倍),那么玩家有时会出现故障并飞出另一边。为了解决这个问题,我只是让墙壁/环境的对撞机更大,但如果我希望玩家能够四处走动或在墙壁的两侧,这并不理想。目前玩家 "climbs" 在撞墙的一侧,这不应该发生?我想知道我是否配置有误,或者完全通过脚本管理播放器的碰撞是否会更好?我在下面有我的角色和播放器组件的屏幕截图:
墙 - http://i.imgur.com/YRdTgSh.png?
玩家 - http://i.imgur.com/DVKOdG1.png?
我的第二个问题是当我尝试检查我的播放器是否接地以便让它们跳跃时。下面的代码是我当前用于管理玩家移动和跳跃的整个移动脚本。目前,玩家可以跳得无限高,但是如果我从高 space 生成玩家,他们只会跳一次,直到他们达到一定的高度,然后他们会重复跳到 space放手了
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
// Update is called once per frame
void FixedUpdate() {
// Creating floats to hold the speed of the plater
float playerSpeedHorizontal = 4f * Input.GetAxis ("Horizontal");
float playerSpeedVertical = 4f * Input.GetAxis ("Vertical");
// Transform statements to move the player by the playerSpeed amount.
transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);
// Calling the playerJump function when the jump key is pressed
if (Input.GetButton("Jump"))
{
playerJump();
Debug.Log ("Can jump");
}
}
/// Here we handle anything to do with the jump, including the raycast, any animations, and the force setting it's self.
void playerJump() {
const float JumpForce = 1.0f;
Debug.Log ("Should Jump");
if(Physics.Raycast(rigidbody.position, Vector3.up, collider.bounds.extents.y + 0.1f)) {
// Debug.Log ("Can jump");
rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
}
}
}
如果有人能提供帮助,我将不胜感激,因为我对此感到很困惑
移动物理体时,使用刚体的AddForce函数。您已经将它与您的跳跃代码一起使用,这很好,但您还必须将它与所有其他移动代码一起使用。
transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);
应该是
rigidBody.AddForce(transform.forward * playerSpeedVertical);
rigidBody.AddForce(transform.right * playerSpeedHorizontal);
这将使物理引擎能够在物理模拟过程中正确解析刚体的运动。我省略了 ForceMode 参数,但您可以随意使用它。
通过使用 transform.Translate,您实质上是将刚体传送到您的碰撞几何体中,因为 transform.Translate 对物理模拟一无所知。
另请注意,不要在 FixedUpdate 函数中使用 Time.deltaTime,而是使用 Time.fixedDeltaTime。但是,由于物理模拟始终以固定速率计算,因此在施加力时实际上不需要使用 fixedDeltaTime。
至于跳跃,你是向上投射光线。你要射线投下来。
Vector3 rayOrigin = transform.position;
rayOrigin.y += collider.bounds.extents.y; //move the ray origin up into the collider, so there's no chance your ray cast will begin inside the ground
float rayDistance = collider.bounds.extents.y + 0.1f;
Ray ray = new Ray();
ray.origin = rayOrigin;
ray.direction = Vector3.down;
if(Physics.Raycast(ray, rayDistance, 1 << 8)) {
rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
}
请注意光线投射的第三个参数,它是1 << 8。这是光线的layerMask。它只会针对这一层中的对象进行投射(因此 排除 你的播放器,这就是为什么我认为你之前得到的光线投射结果不正确)
为了知道这应该是什么参数,首先您需要创建一个新层(在 Unity 中:编辑 -> 项目设置 -> 标签和层)
创建一个图层,将其命名为地面或地形。注意层数。 (即用户第 8 层意味着您的光线投射的第三个参数将是 1 << 8,但是如果您要创建 ground/terrain 层作为第 10 层,您将使用 1 << 10)
现在最后一步是将此层分配给您的 ground/terrain 对撞机。
现在你的玩家应该向下投射光线,从他的中段开始,一直到他脚下一点。此射线将忽略他的碰撞器,仅在射线与地面分层对象发生碰撞时告诉您。
我目前正在使用 Unity 开发一个项目,由于我对 C# 和一般编程还很陌生,所以我遇到了一些问题。第一个问题是我的播放器的碰撞检测——我有一个带有重力的建模刚体和一个(非凸面)附加的网格对撞机。对于我的墙,它们是导入的模型,并附有盒式碰撞器。
如果我将我的盒子碰撞器保持为模型的默认大小(大约是玩家厚度的两倍),那么玩家有时会出现故障并飞出另一边。为了解决这个问题,我只是让墙壁/环境的对撞机更大,但如果我希望玩家能够四处走动或在墙壁的两侧,这并不理想。目前玩家 "climbs" 在撞墙的一侧,这不应该发生?我想知道我是否配置有误,或者完全通过脚本管理播放器的碰撞是否会更好?我在下面有我的角色和播放器组件的屏幕截图: 墙 - http://i.imgur.com/YRdTgSh.png? 玩家 - http://i.imgur.com/DVKOdG1.png?
我的第二个问题是当我尝试检查我的播放器是否接地以便让它们跳跃时。下面的代码是我当前用于管理玩家移动和跳跃的整个移动脚本。目前,玩家可以跳得无限高,但是如果我从高 space 生成玩家,他们只会跳一次,直到他们达到一定的高度,然后他们会重复跳到 space放手了
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
// Update is called once per frame
void FixedUpdate() {
// Creating floats to hold the speed of the plater
float playerSpeedHorizontal = 4f * Input.GetAxis ("Horizontal");
float playerSpeedVertical = 4f * Input.GetAxis ("Vertical");
// Transform statements to move the player by the playerSpeed amount.
transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);
// Calling the playerJump function when the jump key is pressed
if (Input.GetButton("Jump"))
{
playerJump();
Debug.Log ("Can jump");
}
}
/// Here we handle anything to do with the jump, including the raycast, any animations, and the force setting it's self.
void playerJump() {
const float JumpForce = 1.0f;
Debug.Log ("Should Jump");
if(Physics.Raycast(rigidbody.position, Vector3.up, collider.bounds.extents.y + 0.1f)) {
// Debug.Log ("Can jump");
rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
}
}
}
如果有人能提供帮助,我将不胜感激,因为我对此感到很困惑
移动物理体时,使用刚体的AddForce函数。您已经将它与您的跳跃代码一起使用,这很好,但您还必须将它与所有其他移动代码一起使用。
transform.Translate (Vector3.forward * playerSpeedVertical * Time.deltaTime);
transform.Translate (Vector3.right * playerSpeedHorizontal * Time.deltaTime);
应该是
rigidBody.AddForce(transform.forward * playerSpeedVertical);
rigidBody.AddForce(transform.right * playerSpeedHorizontal);
这将使物理引擎能够在物理模拟过程中正确解析刚体的运动。我省略了 ForceMode 参数,但您可以随意使用它。
通过使用 transform.Translate,您实质上是将刚体传送到您的碰撞几何体中,因为 transform.Translate 对物理模拟一无所知。
另请注意,不要在 FixedUpdate 函数中使用 Time.deltaTime,而是使用 Time.fixedDeltaTime。但是,由于物理模拟始终以固定速率计算,因此在施加力时实际上不需要使用 fixedDeltaTime。
至于跳跃,你是向上投射光线。你要射线投下来。
Vector3 rayOrigin = transform.position;
rayOrigin.y += collider.bounds.extents.y; //move the ray origin up into the collider, so there's no chance your ray cast will begin inside the ground
float rayDistance = collider.bounds.extents.y + 0.1f;
Ray ray = new Ray();
ray.origin = rayOrigin;
ray.direction = Vector3.down;
if(Physics.Raycast(ray, rayDistance, 1 << 8)) {
rigidbody.AddForce (Vector3.up * JumpForce, ForceMode.VelocityChange);
}
请注意光线投射的第三个参数,它是1 << 8。这是光线的layerMask。它只会针对这一层中的对象进行投射(因此 排除 你的播放器,这就是为什么我认为你之前得到的光线投射结果不正确)
为了知道这应该是什么参数,首先您需要创建一个新层(在 Unity 中:编辑 -> 项目设置 -> 标签和层)
创建一个图层,将其命名为地面或地形。注意层数。 (即用户第 8 层意味着您的光线投射的第三个参数将是 1 << 8,但是如果您要创建 ground/terrain 层作为第 10 层,您将使用 1 << 10)
现在最后一步是将此层分配给您的 ground/terrain 对撞机。
现在你的玩家应该向下投射光线,从他的中段开始,一直到他脚下一点。此射线将忽略他的碰撞器,仅在射线与地面分层对象发生碰撞时告诉您。