Unity的物理系统是构建真实交互体验的核心模块,无论是让角色自然移动、物体碰撞反弹,还是实现风格化的物理效果(如卡通弹跳),都离不开物理引擎的支撑。本文将从基础概念出发,逐步深入逼真效果实现、碰撞优化技巧、物理材质高级应用,并结合鸿蒙5+的跨平台能力,提供代码示例与实战案例,助你快速上手。
刚体是物理引擎中唯一受力和运动影响的对象。所有需要物理交互的物体必须添加刚体组件。
// 添加刚体并设置基础参数(C#)
Rigidbody rb = gameObject.AddComponent();
rb.mass = 2f; // 质量(单位:千克)
rb.drag = 0.5f; // 空气阻力(线性减速)
rb.angularDrag = 0.05f;// 旋转阻力
rb.useGravity = true; // 是否受重力影响
新手提示:
drag
使其快速停止。碰撞器决定了物体如何与其他物体交互。Unity提供两种碰撞器:
优化技巧:动态切换碰撞器类型
// 运行时切换碰撞器(C#)
void OptimizeCollider(bool isHighDetail) {
MeshCollider meshCollider = GetComponent();
if (isHighDetail) {
meshCollider.enabled = true; // 高精度模式
} else {
SphereCollider sphereCollider = gameObject.AddComponent();
sphereCollider.radius = meshCollider.bounds.extents.x; // 用球体近似
meshCollider.enabled = false;
}
}
应用场景:远距离物体用简单碰撞体,近距离交互时切换为高精度。
物理材质通过以下参数定义交互行为:
// 创建并应用物理材质(C#)
PhysicMaterial iceMaterial = new PhysicMaterial();
iceMaterial.bounciness = 0.2f; // 弱弹性
iceMaterial.dynamicFriction = 0.1f; // 光滑表面低摩擦
iceMaterial.staticFriction = 0.15f;
gameObject.GetComponent().material = iceMaterial;
通过脚本实时调整物理材质,实现特殊效果(如冰面打滑):
// 根据速度动态调整摩擦力(C#)
void UpdateFriction(Rigidbody rb) {
PhysicMaterial material = GetComponent().material;
float speed = rb.velocity.magnitude;
material.dynamicFriction = Mathf.Lerp(0.6f, 0.1f, speed / 10f); // 速度越快,摩擦越小
}
通过Unity的层级系统减少不必要的检测:
Edit > Project Settings > Physics
。代码动态设置层级:
// 将物体标记为“Player”层(C#)
gameObject.layer = LayerMask.NameToLayer("Player");
代码示例:
// 触发器检测(金币收集)
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);
}
}
通过鸿蒙的陀螺仪、加速度计数据影响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("gyroData");
if (gyroData != Vector3.zero) {
// 施加旋转力
rb.AddTorque(gyroData * 10f, ForceMode.Acceleration);
}
}
}
在多设备场景中,同步物理状态(如多人协作游戏):
// 鸿蒙分布式数据同步(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(position);
transform.rotation = JsonUtility.FromJson(rotation);
}
}