引言
Unity的物理系统是构建真实交互体验的核心模块,无论是让角色自然移动、物体碰撞反弹,还是实现风格化的物理效果(如卡通弹跳),都离不开物理引擎的支撑。本文将从基础概念出发,逐步深入逼真效果实现、碰撞优化技巧、物理材质高级应用,并结合鸿蒙5+的跨平台能力,提供代码示例与实战案例,助你快速上手。
一、物理系统核心:刚体与碰撞器
1. 刚体(Rigidbody):物理模拟的起点
刚体是物理引擎中唯一受力和运动影响的对象。所有需要物理交互的物体必须添加刚体组件。
// 添加刚体并设置基础参数(C#)
Rigidbody rb = gameObject.AddComponent<Rigidbody>();
rb.mass = 2f; // 质量(单位:千克)
rb.drag = 0.5f; // 空气阻力(线性减速)
rb.angularDrag = 0.05f;// 旋转阻力
rb.useGravity = true; // 是否受重力影响
新手提示:
- 质量与比例:真实世界中,铁球质量应远大于乒乓球。
- 阻力调节:高速运动的子弹需增大
drag使其快速停止。
2. 碰撞器(Collider):定义物体形状
碰撞器决定了物体如何与其他物体交互。Unity提供两种碰撞器:
- 简单碰撞体(Primitive Colliders):如Box、Sphere,性能最优。
- 网格碰撞体(Mesh Collider):基于模型网格,精度高但计算开销大。
优化技巧:动态切换碰撞器类型
// 运行时切换碰撞器(C#)
void OptimizeCollider(bool isHighDetail) {
MeshCollider meshCollider = GetComponent<MeshCollider>();
if (isHighDetail) {
meshCollider.enabled = true; // 高精度模式
} else {
SphereCollider sphereCollider = gameObject.AddComponent<SphereCollider>();
sphereCollider.radius = meshCollider.bounds.extents.x; // 用球体近似
meshCollider.enabled = false;
}
}
应用场景:远距离物体用简单碰撞体,近距离交互时切换为高精度。
二、物理材质(Physic Material):从冰面到橡胶
1. 基础参数:摩擦力与弹性
物理材质通过以下参数定义交互行为:
- Dynamic Friction(动摩擦):物体滑动时的阻力。
- Static Friction(静摩擦):物体静止时的阻力。
- Bounciness(弹性):碰撞后的能量保留比例。
// 创建并应用物理材质(C#)
PhysicMaterial iceMaterial = new PhysicMaterial();
iceMaterial.bounciness = 0.2f; // 弱弹性
iceMaterial.dynamicFriction = 0.1f; // 光滑表面低摩擦
iceMaterial.staticFriction = 0.15f;
gameObject.GetComponent<Collider>().material = iceMaterial;
2. 高级技巧:动态修改材质属性
通过脚本实时调整物理材质,实现特殊效果(如冰面打滑):
// 根据速度动态调整摩擦力(C#)
void UpdateFriction(Rigidbody rb) {
PhysicMaterial material = GetComponent<Collider>().material;
float speed = rb.velocity.magnitude;
material.dynamicFriction = Mathf.Lerp(0.6f, 0.1f, speed / 10f); // 速度越快,摩擦越小
}
三、碰撞检测优化:性能与精度平衡
1. 层级碰撞矩阵(Layer Collision Matrix)
通过Unity的层级系统减少不必要的检测:
- 进入
Edit > Project Settings > Physics。 - 取消勾选无关层级的碰撞(如“Player”与“NPC”无需检测)。
代码动态设置层级:
// 将物体标记为“Player”层(C#)
gameObject.layer = LayerMask.NameToLayer("Player");
2. 触发器(Trigger)与碰撞事件分离
- 触发器:仅触发逻辑(如拾取物品),无物理反馈。
- 碰撞事件:触发物理反应(如反弹)。
代码示例:
// 触发器检测(金币收集)
private void OnTriggerEnter(Collider other) {
if (other.CompareTag("Player")) {
Destroy(gameObject); // 销毁金币
GameManager.instance.AddScore(100);
}
}
// 碰撞事件处理(反弹)
private void OnCollisionEnter(Collision collision) {
if (collision.gameObject.CompareTag("Wall")) {
rb.AddForce(-collision.contacts[0].normal * 10f, ForceMode.Impulse);
}
}
四、鸿蒙5+跨平台整合:传感器驱动物理
1. 鸿蒙传感器数据接入
通过鸿蒙的陀螺仪、加速度计数据影响Unity物理行为:
// 鸿蒙端传感器监听(ArkTS)
import sensor from '@ohos.sensors';
export default {
onInit() {
sensor.on('gyroscope', (data) => {
// 将数据传递给Unity
this.context.sendMessageToUnity('gyroData', {
x: data.x,
y: data.y,
z: data.z
});
});
}
}
// Unity端接收数据并施加旋转(C#)
using Huawei.HarmonyOS;
public class GyroController : MonoBehaviour {
void Update() {
// 从鸿蒙接收陀螺仪数据
Vector3 gyroData = HarmonyOS.GetSensorData<Vector3>("gyroData");
if (gyroData != Vector3.zero) {
// 施加旋转力
rb.AddTorque(gyroData * 10f, ForceMode.Acceleration);
}
}
}
2. 分布式物理同步
在多设备场景中,同步物理状态(如多人协作游戏):
// 鸿蒙分布式数据同步(ArkTS)
import distributedData from '@ohos.distributedData';
export default {
async SyncPhysicsState(Vector3 position, Quaternion rotation) {
const dataObject = await distributedData.createDataObject("PhysicsState");
dataObject.writeVector3("position", position);
dataObject.writeQuaternion("rotation", rotation);
await dataObject.flush(); // 同步到其他设备
}
}
// Unity端更新物体位置(C#)
public class DistributedSync : MonoBehaviour {
void Start() {
string position = HarmonyOS.CallHarmonyMethod("getPosition");
string rotation = HarmonyOS.CallHarmonyMethod("getRotation");
transform.position = JsonUtility.FromJson<Vector3>(position);
transform.rotation = JsonUtility.FromJson<Quaternion>(rotation);
}
}
2486

被折叠的 条评论
为什么被折叠?



