我在网上查找如何创建一个没有rigidbody的角色控制器。 我想学习碰撞和移动的基础知识。 我在github上找到了一段代码,但我不能理解为什么使用vector2.dot,因为我们已经修改了距离了,而且为什么有两个Move()函数在fixedUpdate中。 如果只有一个Move()函数,系统就会崩溃。 我读了注释,但我不能完全理解它。 为什么会这样发生呢?
使用 System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D), typeof(BoxCollider2D))]
public class PhysicsObject : MonoBehaviour
{
public float m_GravityModifier = 1f; // 我们可以设置重力值
public LayerMask m_Mask; // 障碍物遮罩
protected BoxCollider2D m_BoxCollider2D; // 必须用于boxcasting,需要知道其大小
protected Rigidbody2D m_Rigidbody2D; // 我们使用rigidbody.position来移动对象
protected Vector2 m_Velocity; // 速度向量
protected RaycastHit2D[] m_HitInfos = new RaycastHit2D[16]; // 物理盒子投射返回的信息
protected bool m_Grounded; // 如果地面正常为1,表示我们在地面上
protected const float m_ShellDistance = 0.01f; // 这个值使得碰撞器不会进入其他碰撞器
// Start是调用在第一帧更新之前
void Awake()
{
m_BoxCollider2D = GetComponent
m_Rigidbody2D = GetComponent
}
}
private void FixedUpdate()
{
m_Grounded = false;
// 物理定律:最后速度 = 初速度 + 加速度 * 时间差
// delta表示两个帧之间的时间差
m_Velocity += m_GravityModifier * Physics2D.gravity * Time.fixedDeltaTime;
// 位置变化 = 速度 * 时间差
Vector2 deltaPosition = m_Velocity * Time.fixedDeltaTime;
// 现在我们到了最痛苦的位置。 为什么有两个Move函数。 因为如果角色试图水平移动
// rigidbody.position会试图进入地面。 我们必须单独计算。
Vector2 moveHorizontal = Vector2.right * deltaPosition.x; // 水平移动向量
Move(moveHorizontal);
// 垂直移动向量
Vector2 moveVertical = deltaPosition.y * Vector2.up;
Move(moveVertical);
// 如果你删除两个Move函数并写一个Move(deltaPosition)你会看到什么意思。
}
void Move(Vector2 move)
{
float distance = move.magnitude;
// 移动起点
Vector2 origin = m_Rigidbody2D.position + m_BoxCollider2D.offset;
// 检测碰撞
int count = Physics2D.BoxCastNonAlloc(origin, m_BoxCollider2D.size, 0f, move, m_HitInfos, distance + m_ShellDistance, m_Mask);
// 检测碰撞后处理
for (int i = 0; i < count; i++)
{
Vector2 currentNormal = m_HitInfos[i].normal;
// 如果当前正常为1,表示我们在地面上
if (currentNormal.y == 1)
{
m_Grounded = true;
}
// 如果速度向量和当前正常向量的点积小于0,表示速度向量在当前正常向量的反方向
float project = Vector2.Dot(currentNormal, m_Velocity);
if (project < 0)
{
m_Velocity -= project * currentNormal;
}
// 修改距离
float modifiedDistance = m_HitInfos[i].distance - m_ShellDistance;
distance = modifiedDistance < distance ? modifiedDistance : distance;
}
// 移动角色
m_Rigidbody2D.position += move.normalized * distance;
}
}
评论 (0)