コード例 #1
0
            private void HandleUserInput(CharacterMoveSetting ccComponentData, UserCommand command, float3 up,
                                         float3 surfaceVelocity, ref CharacterMovePredictedState ccPredictedState, out float3 linearVelocity,
                                         ref MoveInternalState moveInternalState)
            {
                // Reset jumping state and unsupported velocity
                if (moveInternalState.SupportedState == CharacterSupportState.Supported)
                {
                    moveInternalState.IsJumping          = false;
                    ccPredictedState.UnsupportedVelocity = float3.zero;
                }

                var shouldJump = command.Buttons.IsSet(UserCommand.Button.Jump) &&
                                 moveInternalState.SupportedState == CharacterSupportState.Supported;

                if (shouldJump)
                {
                    // Add jump speed to surface velocity and make character unsupported
                    moveInternalState.IsJumping          = true;
                    moveInternalState.SupportedState     = CharacterSupportState.Unsupported;
                    ccPredictedState.UnsupportedVelocity = surfaceVelocity + ccComponentData.JumpUpwardsVelocity * up;
                }
                else if (moveInternalState.SupportedState != CharacterSupportState.Supported)
                {
                    // Apply gravity
                    ccPredictedState.UnsupportedVelocity += ccComponentData.Gravity * DeltaTime;
                }

                // If unsupported then keep jump and surface momentum
                linearVelocity = (float3)command.TargetDir * ccComponentData.Velocity +
                                 (moveInternalState.SupportedState != CharacterSupportState.Supported
                                     ? ccPredictedState.UnsupportedVelocity
                                     : float3.zero);
            }
コード例 #2
0
            public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var up = math.up();

                var chunkEntityData          = chunk.GetNativeArray(EntityType);
                var chunkMoveSettingData     = chunk.GetNativeArray(CharacterMoveType);
                var chunkTransformData       = chunk.GetNativeArray(TransformType);
                var chunkVelocityData        = chunk.GetNativeArray(VelocityType);
                var chunkUserCommand         = chunk.GetNativeArray(UserCommandComponentType);
                var chunkMovePredictedData   = chunk.GetNativeArray(CharacterMovePredictedType);
                var chunkPhysicsColliderData = chunk.GetNativeArray(PhysicsColliderType);

                DeferredImpulseWriter.BeginForEachIndex(chunkIndex);

                for (var i = 0; i < chunk.Count; i++)
                {
                    var entity            = chunkEntityData[i];
                    var moveSetting       = chunkMoveSettingData[i];
                    var userCommand       = chunkUserCommand[i];
                    var movePredictedData = chunkMovePredictedData[i];
                    var collider          = chunkPhysicsColliderData[i];
                    var transformData     = chunkTransformData[i];
                    var velocityData      = chunkVelocityData[i];

                    // Collision filter must be valid
                    if (!collider.IsValid || collider.Value.Value.Filter.IsEmpty)
                    {
                        continue;
                    }

                    // Character step input
                    var stepInput = new CharacterControllerStepInput
                    {
                        World            = PhysicsWorld,
                        DeltaTime        = DeltaTime,
                        Up               = math.up(),
                        Gravity          = moveSetting.Gravity,
                        MaxIterations    = moveSetting.MaxIterations,
                        Tau              = KDefaultTau,
                        Damping          = KDefaultDamping,
                        SkinWidth        = moveSetting.SkinWidth,
                        ContactTolerance = moveSetting.ContactTolerance,
                        MaxSlope         = moveSetting.MaxSlope,
                        RigidBodyIndex   = PhysicsWorld.GetRigidBodyIndex(entity),
                        CurrentVelocity  = velocityData.Linear,
                        MaxMovementSpeed = moveSetting.MaxVelocity
                    };

                    // Character transform
                    var transform = new RigidTransform
                    {
                        pos = transformData.Position,
                        rot = transformData.Rotation
                    };

                    var moveInternalState = new MoveInternalState
                    {
                        SupportedState = CharacterSupportState.Unsupported,
                        IsJumping      = false
                    };

                    // Check support
                    CheckSupport(ref PhysicsWorld, ref collider, stepInput, transform, moveSetting.MaxSlope,
                                 out moveInternalState.SupportedState, out var surfaceNormal, out var surfaceVelocity);

                    // User input
                    HandleUserInput(moveSetting, userCommand, stepInput.Up, surfaceVelocity,
                                    ref movePredictedData, out var desiredVelocity, ref moveInternalState);

                    //add InitVelocity , clear InitVelocity
                    desiredVelocity += movePredictedData.ImpulseVelocity;
                    if (movePredictedData.ImpulseDuration > 0)
                    {
                        movePredictedData.ImpulseDuration--;
                    }
                    else
                    {
                        movePredictedData.ImpulseVelocity = float3.zero;
                    }

                    //    FSLog.Info($"stepInput.CurrentVelocity:{stepInput.CurrentVelocity},desiredVelocity:{desiredVelocity}");
                    // Calculate actual velocity with respect to surface
                    if (moveInternalState.SupportedState == CharacterSupportState.Supported)
                    {
                        CalculateMovement(transformData.Rotation, stepInput.Up, moveInternalState.IsJumping,
                                          stepInput.CurrentVelocity, desiredVelocity, surfaceNormal, surfaceVelocity,
                                          out velocityData.Linear);
                    }
                    // if(math.distancesq(velocityData.Linear, float3.zero) > 0.0001f)
                    // FSLog.Info($"Entity:{entity},velocityData.Linear:{velocityData.Linear}," +
                    //     $"stepInput.CurrentVelocity:{stepInput.CurrentVelocity}");
                    else
                    {
                        velocityData.Linear = desiredVelocity;
                    }

                    // World collision + integrate
                    CollideAndIntegrate(stepInput, moveSetting.CharacterMass, moveSetting.AffectsPhysicsBodies > 0,
                                        collider.ColliderPtr, ref transform, ref velocityData.Linear, ref DeferredImpulseWriter);

                    //  if(math.distancesq(velocityData.Linear, float3.zero) > 0.0001f)
                    //  FSLog.Info($"end  velocityData.Linear:{ velocityData.Linear}");
                    // Write back and orientation integration
                    transformData.Position = transform.pos;

                    // character rotate
                    if (math.distancesq(userCommand.TargetDir, float3.zero) > 0.0001f)
                    {
                        // var dir = Vector3.SqrMagnitude(velocityData.Linear) < 0.001f
                        // ? Vector3.zero :(Vector3) math.normalize(velocityData.Linear);

                        var fromRotation = transformData.Rotation;
                        var toRotation   = quaternion.LookRotationSafe(userCommand.TargetDir, up);
                        var angle        = Quaternion.Angle(fromRotation, toRotation);
                        transformData.Rotation = Quaternion.RotateTowards(fromRotation, toRotation,
                                                                          math.abs(angle - 180.0f) < float.Epsilon
                                ? -moveSetting.RotationVelocity
                                : moveSetting.RotationVelocity);
                    }

                    // Write back to chunk data
                    {
                        chunkMovePredictedData[i] = movePredictedData;
                        chunkTransformData[i]     = transformData;
                        chunkVelocityData[i]      = velocityData;
                    }
                }

                DeferredImpulseWriter.EndForEachIndex();
            }