/// <summary> /// Move the character with the Srt (CPMA based) algorithm. /// </summary> /// <param name="initialVelocity">The initial velocity to use</param> /// <param name="direction">The movement direction</param> /// <param name="settings">The movement settings</param> /// <param name="dt">Delta time</param> /// <returns>Return the new position</returns> private static float3 SrtMove(float3 initialVelocity, float2 initialDirection, float3 direction, DefStGroundRunSettings settings, CharacterControllerState state, float dt) { // Fix NaN errors direction = SrtFixNaN(direction); // Set Y axe to zero initialVelocity.y = 0; var previousSpeed = math.length(initialVelocity); var friction = SrtGetFrictionPower ( previousSpeed, settings.FrictionSpeedMin, settings.FrictionSpeedMax, settings.FrictionMin, settings.FrictionMax ); var angleInvertedDir = 1 - state.AngleDir.y; if (math.abs(angleInvertedDir) > 0.4f) { friction *= math.clamp(math.abs(angleInvertedDir), 0.4f, 1f); } var velocity = SrtApplyFriction(initialVelocity, direction, friction, settings.SurfaceFriction, settings.Acceleration, settings.Deacceleration, dt); var wishSpeed = math.length(direction) * settings.BaseSpeed; if (float.IsNaN(wishSpeed)) { wishSpeed = 0; } var strafeAngleNormalized = SrtGetStrafeAngleNormalized(direction, math.normalize(initialVelocity)); if (wishSpeed > settings.BaseSpeed && wishSpeed < previousSpeed) { wishSpeed = math.lerp(previousSpeed, wishSpeed, math.max(math.distance(wishSpeed, previousSpeed), 0) * dt); } if (initialDirection.y > 0.5f) { if (previousSpeed >= settings.BaseSpeed - 0.25f) { wishSpeed = settings.SprintSpeed; settings.Acceleration = 6f; } } if (state.AngleDir.y >= 0) { wishSpeed *= math.clamp(state.AngleDir.y + 0.1f, 0.1f, 1f); } velocity = SrtAccelerate(velocity, direction, wishSpeed, settings.Acceleration, math.min(strafeAngleNormalized, 0.25f), dt); var nextSpeed = math.length(math.float3(velocity.x, 0, velocity.z)); if (previousSpeed > nextSpeed && nextSpeed < settings.BaseSpeed && strafeAngleNormalized > 0.1f && strafeAngleNormalized < 0.9f) { velocity.y = 0; velocity = Vector3.Normalize(velocity) * math.lerp(nextSpeed, previousSpeed, math.max(1 - strafeAngleNormalized, 0.8f)); } return(velocity); }
public override void Create(Entity entity) { Debug.Assert(GameObject != null, "GameObject != null"); Debug.Assert(GameObjectEntity.Entity == entity, "GameObjectEntity.Entity == entity"); var characterController = GameObject.GetComponent <CharacterController>(); characterController.center = Vector3.up * 0.9f; characterController.radius = 0.4f; characterController.stepOffset = 0.4f; characterController.height = 2f * 0.9f; characterController.slopeLimit = 75; characterController.detectCollisions = false; AddDefaultComponents(entity); if (Player.IsCreated) { EntityManager.AddComponentData(entity, new CharacterPlayerOwner { Target = Player.WorldPointer }); } EntityManager.AddComponentData(entity, new CharacterControllerState(false, false, false, Vector3.up)); EntityManager.AddComponentData(entity, StormiumCharacterMvData.NewBase()); EntityManager.AddComponentData(entity, new StormiumCharacterMvProcessData()); ShareManager.SetShareOption(entity, typeof(CharacterPlayerOwner), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(CharacterControllerState), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(StormiumCharacterMvData), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(StormiumCharacterMvProcessData), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); /*// Add switcher * { * var actionEntity = EntityManager.CreateEntity * ( * typeof(StActionTag), * typeof(StActionOwner), * typeof(StActionSlot), * typeof(StActionDualSwitch) * ); * * var actionType = typeof(StActionDualSwitch); * * EntityManager.SetComponentData(actionEntity, new StActionTag(TypeManager.GetTypeIndex(actionType))); * EntityManager.SetComponentData(actionEntity, new StActionOwner(entity)); * EntityManager.SetComponentData(actionEntity, new StActionSlot(0)); * EntityManager.SetComponentData(actionEntity, new StActionDualSwitch(rocketEntity, rocketEntity)); * * EntityManager.GetBuffer<StActionContainer>(entity).Add(new StActionContainer(actionEntity)); * } * // Add grenade * { * var actionEntity = EntityManager.CreateEntity * ( * typeof(StActionTag), * typeof(StActionOwner), * typeof(StActionSlot), * typeof(StActionAmmo), * typeof(StActionAmmoCooldown), * typeof(StDefActionThrowGrenade) * ); * * var actionType = typeof(StDefActionThrowGrenade); * * EntityManager.SetComponentData(actionEntity, new StActionTag(TypeManager.GetTypeIndex(actionType))); * EntityManager.SetComponentData(actionEntity, new StActionOwner(entity)); * EntityManager.SetComponentData(actionEntity, new StActionSlot(1)); * EntityManager.SetComponentData(actionEntity, new StActionAmmo(0, 1, 0)); * EntityManager.SetComponentData(actionEntity, new StActionAmmoCooldown(-1, 8)); * EntityManager.SetComponentData(actionEntity, new StDefActionThrowGrenade(28f, 25, 2)); * * EntityManager.GetBuffer<StActionContainer>(entity).Add(new StActionContainer(actionEntity)); * }*/ // Add transforms component EntityManager.AddComponentData(entity, new Position()); EntityManager.AddComponentData(entity, new Rotation()); EntityManager.AddComponentData(entity, new StVelocity()); ShareManager.SetShareOption(entity, typeof(Position), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(Rotation), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(StVelocity), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); // Add settings EntityManager.AddComponentData(entity, new EntityPhysicLayer(30)); EntityManager.AddComponentData(entity, new StStamina(4, 0.75f, 0)); EntityManager.AddComponentData(entity, DefStGroundRunSettings.NewBase()); EntityManager.AddComponentData(entity, DefStAerialRunSettings.NewBase()); EntityManager.AddComponentData(entity, DefStJumpSettings.NewBase()); EntityManager.AddComponentData(entity, DefStDodgeOnGroundSettings.NewBase()); EntityManager.AddComponentData(entity, new DefStJumpStaminaUsageData() { Usage = EStaminaUsage.RemoveStamina, RemoveBySpeedFactor01 = 0.01f, BaseRemove = 0.1f }); EntityManager.AddComponentData(entity, new DefStDodgeStaminaUsageData() { Usage = EStaminaUsage.BlockAction, Needed = 1f, BaseRemove = 1f }); ShareManager.SetShareOption(entity, typeof(EntityPhysicLayer), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(StStamina), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStGroundRunSettings), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStAerialRunSettings), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStJumpSettings), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStDodgeOnGroundSettings), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStJumpStaminaUsageData), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStDodgeStaminaUsageData), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); // Add simple client inputs EntityManager.AddComponentData(entity, new DefStRunClientInput()); EntityManager.AddComponentData(entity, new DefStJumpClientInput()); EntityManager.AddComponentData(entity, new DefStDodgeClientInput()); EntityManager.AddComponentData(entity, new DefStEntityAimClientInput()); ShareManager.SetShareOption(entity, typeof(DefStRunClientInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStJumpClientInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStDodgeClientInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStEntityAimClientInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); // Add global inputs EntityManager.AddComponentData(entity, new DefStRunInput()); EntityManager.AddComponentData(entity, new DefStJumpInput()); EntityManager.AddComponentData(entity, new DefStDodgeInput()); EntityManager.AddComponentData(entity, new DefStEntityAimInput()); ShareManager.SetShareOption(entity, typeof(DefStRunInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStJumpInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStDodgeInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStEntityAimInput), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); // Add processable data EntityManager.AddComponentData(entity, new DefStJumpProcessData()); EntityManager.AddComponentData(entity, new DefStDodgeOnGroundProcessData()); EntityManager.AddComponentData(entity, new DefStWallJumpProcessData()); EntityManager.AddComponentData(entity, new DefStWallDodgeProcessData()); ShareManager.SetShareOption(entity, typeof(DefStJumpProcessData), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStDodgeOnGroundProcessData), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(DefStWallDodgeProcessData), ComponentShareOption.Manual, DeliveryMethod.ReliableOrdered); // Make the clients able to change the input data EntityManager.AddComponentData(entity, new ClientDriveData <DefStRunInput>(Player)); EntityManager.AddComponentData(entity, new ClientDriveData <DefStJumpInput>(Player)); EntityManager.AddComponentData(entity, new ClientDriveData <DefStDodgeInput>(Player)); EntityManager.AddComponentData(entity, new ClientDriveData <DefStEntityAimInput>(Player)); ShareManager.SetShareOption(entity, typeof(ClientDriveData <DefStRunInput>), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(ClientDriveData <DefStJumpInput>), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(ClientDriveData <DefStDodgeInput>), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); ShareManager.SetShareOption(entity, typeof(ClientDriveData <DefStEntityAimInput>), ComponentShareOption.Automatic, DeliveryMethod.ReliableOrdered); }