Unity Physics 学习笔记第三章:刚体的运动状态
本文介绍获取与修改刚体速度的方法
并实现控制立方体每隔一段时间朝随机方向运动,具有匀速运动与施加冲量两种方式
添加组件控制方向
我们新建一个用于控制运动方向的组件
MoveDirection.cs
[Serializable]
public struct MoveDirection : IComponentData {
public Unity.Mathematics.Random random;
public float timeToChangeDirection;
public float2 direction;
}
解释:这里把 random
放进去是为了保证随机数生成的均匀性。
然后写一个 Authoring 用来把这个组件添加到 Entity 上
RandomMoveCubeAuthoring.cs
public class RandomMoveCubeAuthoring : MonoBehaviour, IConvertGameObjectToEntity {
public void Convert (Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
var moveRandomCmpt = new MoveDirection {
random = new Unity.Mathematics.Random ((uint) System.DateTime.Now.Ticks),
timeToChangeDirection = new Unity.Mathematics.Random ((uint) System.DateTime.Now.Ticks).NextFloat (),
direction = Unity.Mathematics.float2.zero
};
dstManager.AddComponentData (entity, moveRandomCmpt);
}
}
配置 Entity
新建一个立方体 GameObject,移除 Box Collider
,添加 Convert To Entity
、Physics Shape
、Physics Body
以及我们写的 RandomMoveCubeAuthoring
脚本
在 Physics Body
中把重力系数设为 0,线性阻尼设为 0.5。其他的用默认值就行
这样这个 GameObject 在启动后会被自动转化为 Entity 并具有物理相关的组件以及 MoveDirection
组件
控制运动状态
显然,写一个 System 生成随机方向,然后修改这个立方体的速度就行了
下面有匀速运动和添加冲量两个版本,区别在于匀速运动每一帧都把速度修改为指定值,而添加冲量只需要在方向改变的那一帧修改速度
这个是匀速版本的
public class RandomMoveSystem : JobComponentSystem {
[BurstCompile]
struct RandomMoveJob : IJobForEach<MoveDirection, PhysicsVelocity> {
public float deltaTime;
public void Execute (ref MoveDirection moveDirection, ref PhysicsVelocity velocity) {
var dir = moveDirection;
dir.timeToChangeDirection -= deltaTime;
if (dir.timeToChangeDirection < 0) {
dir.timeToChangeDirection += 1;
dir.direction = 0.5f * math.normalize (dir.random.NextFloat2 () - new float2 (0.5f, 0.5f));
}
moveDirection = dir;
var v = velocity.Linear;
v = new float3 (dir.direction, 0);
velocity = new PhysicsVelocity { Linear = v };
}
}
protected override JobHandle OnUpdate (JobHandle inputDeps) {
return new RandomMoveJob { deltaTime = Time.DeltaTime }.Schedule (this, inputDeps);
}
}
这个是冲量版本的,发现立方体会受到线性阻尼的影响,如果不明显可以把线性阻尼再改大一点
public class RandomMoveSystem : JobComponentSystem {
[BurstCompile]
struct RandomMoveJob : IJobForEach<MoveDirection, PhysicsVelocity> {
public float deltaTime;
public void Execute (ref MoveDirection moveDirection, ref PhysicsVelocity velocity) {
var dir = moveDirection;
dir.timeToChangeDirection -= deltaTime;
if (dir.timeToChangeDirection < 0) {
dir.timeToChangeDirection += 1;
dir.direction = 0.5f * math.normalize (dir.random.NextFloat2 () - new float2 (0.5f, 0.5f));
var v = velocity.Linear;
v += new float3 (dir.direction, 0);
velocity = new PhysicsVelocity { Linear = v };
}
moveDirection = dir;
}
}
protected override JobHandle OnUpdate (JobHandle inputDeps) {
return new RandomMoveJob { deltaTime = Time.DeltaTime }.Schedule (this, inputDeps);
}
}
Thanks for reading! Read other posts?