您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
171 行
5.7 KiB
171 行
5.7 KiB
using System;
|
|
using Unity.Collections;
|
|
using Unity.Entities;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
using Unity.Physics;
|
|
using UnityEngine;
|
|
using Unity.NetCode;
|
|
using static CharacterControllerUtilities;
|
|
using static Unity.Physics.PhysicsStep;
|
|
|
|
[Serializable]
|
|
public struct CharacterControllerComponentData : IComponentData
|
|
{
|
|
public float3 GroundProbeVector;
|
|
public float MaxSlope; // radians
|
|
public int MaxIterations;
|
|
public float CharacterMass;
|
|
public float SkinWidth;
|
|
public float ContactTolerance;
|
|
public int AffectsPhysicsBodies;
|
|
public float MaxMovementSpeed;
|
|
}
|
|
|
|
public struct CharacterControllerGroundSupportData : IComponentData
|
|
{
|
|
[GhostDefaultField(0)]
|
|
public float3 SurfaceNormal;
|
|
[GhostDefaultField(0)]
|
|
public float3 SurfaceVelocity;
|
|
[GhostDefaultField]
|
|
public CharacterSupportState SupportedState;
|
|
}
|
|
|
|
public struct CharacterControllerMoveQuery : IComponentData
|
|
{
|
|
public float3 StartPosition;
|
|
public bool FollowGround;
|
|
public bool CheckSupport;
|
|
}
|
|
|
|
public struct CharacterControllerMoveResult : IComponentData
|
|
{
|
|
[GhostDefaultField(0)]
|
|
public float3 MoveResult;
|
|
}
|
|
|
|
public struct CharacterControllerVelocity : IComponentData
|
|
{
|
|
[GhostDefaultField(0)]
|
|
public float3 Velocity;
|
|
}
|
|
|
|
public struct CharacterControllerInitializationData : IComponentData
|
|
{
|
|
public float3 CapsuleCenter;
|
|
public float CapsuleRadius;
|
|
public float CapsuleHeight;
|
|
}
|
|
|
|
struct CharacterControllerCollider : ISystemStateComponentData
|
|
{
|
|
public BlobAssetReference<Unity.Physics.Collider> Collider;
|
|
}
|
|
|
|
[Serializable]
|
|
public class CharacterControllerAuthoring : MonoBehaviour, IConvertGameObjectToEntity
|
|
{
|
|
// Gravity force applied to the character controller body
|
|
public float3 Gravity = Default.Gravity;
|
|
|
|
// Maximum slope angle character can overcome (in degrees)
|
|
public float MaxSlope = 60.0f;
|
|
|
|
// Maximum number of character controller solver iterations
|
|
public int MaxIterations = 10;
|
|
|
|
// Mass of the character (used for affecting other rigid bodies)
|
|
public float CharacterMass = 1.0f;
|
|
|
|
// Keep the character at this distance to planes (used for numerical stability)
|
|
public float SkinWidth = 0.02f;
|
|
|
|
// Anything in this distance to the character will be considered a potential contact
|
|
// when checking support
|
|
public float ContactTolerance = 0.1f;
|
|
|
|
// Whether to affect other rigid bodies
|
|
public int AffectsPhysicsBodies = 1;
|
|
|
|
// Maximum speed of movement at any given time
|
|
public float MaxMovementSpeed = 10.0f;
|
|
|
|
public float3 GroundProbeVector = new float3(0.0f, -0.1f, 0.0f);
|
|
|
|
public float3 CapsuleCenter = new float3(0.0f, 1.0f, 0.0f);
|
|
public float CapsuleRadius = 0.5f;
|
|
public float CapsuleHeight = 2.0f;
|
|
|
|
void IConvertGameObjectToEntity.Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
|
|
{
|
|
if (enabled)
|
|
{
|
|
dstManager.AddComponentData(entity, new CharacterControllerComponentData
|
|
{
|
|
GroundProbeVector = GroundProbeVector,
|
|
MaxSlope = math.radians(MaxSlope),
|
|
MaxIterations = MaxIterations,
|
|
CharacterMass = CharacterMass,
|
|
SkinWidth = SkinWidth,
|
|
ContactTolerance = ContactTolerance,
|
|
AffectsPhysicsBodies = AffectsPhysicsBodies,
|
|
MaxMovementSpeed = MaxMovementSpeed
|
|
});
|
|
|
|
dstManager.AddComponentData(entity, new CharacterControllerInitializationData
|
|
{
|
|
CapsuleCenter = CapsuleCenter,
|
|
CapsuleHeight = CapsuleHeight,
|
|
CapsuleRadius = CapsuleRadius
|
|
});
|
|
|
|
dstManager.AddComponent(entity, typeof(CharacterControllerVelocity));
|
|
dstManager.AddComponent(entity, typeof(CharacterControllerMoveQuery));
|
|
dstManager.AddComponent(entity, typeof(CharacterControllerMoveResult));
|
|
dstManager.AddComponent(entity, typeof(CharacterControllerGroundSupportData));
|
|
}
|
|
}
|
|
}
|
|
|
|
[DisableAutoCreation]
|
|
[AlwaysSynchronizeSystem]
|
|
[AlwaysUpdateSystem]
|
|
[UpdateInGroup(typeof(AbilityUpdateSystemGroup))]
|
|
[UpdateAfter(typeof(MovementUpdatePhase))]
|
|
[UpdateBefore(typeof(CharacterControllerStepSystem))]
|
|
public class CharacterControllerInitAndCleanupSystem : JobComponentSystem
|
|
{
|
|
protected override JobHandle OnUpdate(JobHandle inputDeps)
|
|
{
|
|
var ecb = new EntityCommandBuffer(Allocator.TempJob);
|
|
|
|
Entities
|
|
.WithNone<CharacterControllerCollider>()
|
|
.ForEach((Entity e, ref CharacterControllerInitializationData initData) =>
|
|
{
|
|
var capsule = new CapsuleGeometry
|
|
{
|
|
Vertex0 = initData.CapsuleCenter + new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
|
|
Vertex1 = initData.CapsuleCenter - new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
|
|
Radius = initData.CapsuleRadius
|
|
};
|
|
var filter = new CollisionFilter { BelongsTo = 1, CollidesWith = 1, GroupIndex = 0 };
|
|
var collider = Unity.Physics.CapsuleCollider.Create(capsule, filter, new Unity.Physics.Material { Flags = new Unity.Physics.Material.MaterialFlags() });
|
|
ecb.AddComponent(e, new CharacterControllerCollider { Collider = collider });
|
|
}).Run();
|
|
|
|
Entities
|
|
.WithNone<CharacterControllerComponentData>()
|
|
.ForEach((Entity e, ref CharacterControllerCollider collider) =>
|
|
{
|
|
collider.Collider.Dispose();
|
|
ecb.RemoveComponent<CharacterControllerCollider>(e);
|
|
}).Run();
|
|
|
|
ecb.Playback(EntityManager);
|
|
ecb.Dispose();
|
|
|
|
return inputDeps;
|
|
}
|
|
}
|