private Vector3 PickAPointInFront(IMoverComponent mover, float distanceAhead, float radius, float angle) { var centerPoint = mover.CurrentPosition + (mover.LastDirectionFacing.normalized * distanceAhead); var destination = GetPointWithinACircle(centerPoint, radius, angle); return(destination); }
private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover, CollidableComponent collider) { foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) { if (entity == transform.Owner) { continue; // Don't try to push off of yourself! } if (!entity.TryGetComponent <CollidableComponent>(out var otherCollider)) { continue; } // TODO: Item check. var touching = ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision true; // !entity.HasComponent<ItemComponent>(); // This can't be an item if (touching) { return(true); } } return(false); }
protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent physics, ICollidableComponent?collider = null) { physics.EnsureController <MoverController>(); var weightless = !transform.Owner.HasComponent <MovementIgnoreGravityComponent>() && _physicsManager.IsWeightless(transform.GridPosition); if (weightless && collider != null) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(transform, mover, collider); if (!touching) { return; } } // TODO: movement check. var(walkDir, sprintDir) = mover.VelocityDir; var combined = walkDir + sprintDir; if (combined.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless) { if (physics.TryGetController(out MoverController controller)) { controller.StopMoving(); } } else { //Console.WriteLine($"{IoCManager.Resolve<IGameTiming>().TickStamp}: {combined}"); if (weightless) { if (physics.TryGetController(out MoverController controller)) { controller.Push(combined, mover.CurrentPushSpeed); } transform.LocalRotation = walkDir.GetDir().ToAngle(); return; } var total = walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed; //Console.WriteLine($"{walkDir} ({mover.CurrentWalkSpeed}) + {sprintDir} ({mover.CurrentSprintSpeed}): {total}"); { if (physics.TryGetController(out MoverController controller)) { controller.Move(total, 1); } } transform.LocalRotation = total.GetDir().ToAngle(); HandleFootsteps(mover); } }
public static Vector3 Flee(Vector3 targetPosition, Vector3 currentVelocity, IMoverComponent mover) { var desired = (targetPosition - mover.CurrentPosition) * -1; //var desired = mover.CurrentPosition - targetPosition; desired = desired.normalized * mover.MaxSpeed; return(Steer(desired, currentVelocity, mover.MaxSteering)); }
protected void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent physics) { physics.EnsureController <MoverController>(); var weightless = transform.Owner.IsWeightless(); if (weightless) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(transform, mover, physics); if (!touching) { transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle(); return; } } // TODO: movement check. var(walkDir, sprintDir) = mover.VelocityDir; var combined = walkDir + sprintDir; if (combined.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless) { if (physics.TryGetController(out MoverController controller)) { controller.StopMoving(); } } else { if (weightless) { if (physics.TryGetController(out MoverController controller)) { controller.Push(combined, mover.CurrentPushSpeed); } transform.LocalRotation = physics.LinearVelocity.GetDir().ToAngle(); return; } var total = walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed; { if (physics.TryGetController(out MoverController controller)) { controller.Move(total, 1); } } transform.LocalRotation = total.GetDir().ToAngle(); HandleFootsteps(mover); } }
public static Vector3 Seek(Vector3 targetPosition, Vector3 currentVelocity, IMoverComponent mover) { var desired = targetPosition - mover.CurrentPosition; //var desired = targetPosition - currentVelocity; desired = desired.normalized * mover.MaxSpeed; return(Steer(desired, mover.CurrentVelocity, mover.MaxSteering)); //return Steer(desired, currentVelocity, mover.MaxSteering); }
/// <summary> /// Movement while considering actionblockers, weightlessness, etc. /// </summary> /// <param name="mover"></param> /// <param name="physicsComponent"></param> /// <param name="mobMover"></param> protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover) { // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _mapManager)) { return; } var transform = mover.Owner.Transform; var(walkDir, sprintDir) = mover.VelocityDir; var weightless = transform.Owner.IsWeightless(physicsComponent, mapManager: _mapManager); // Handle wall-pushes. if (weightless) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent); if (!touching) { transform.WorldRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); return; } } // Regular movement. // Target velocity. // This is relative to the map / grid we're on. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); var worldTotal = _relativeMovement ? new Angle(transform.Parent !.WorldRotation.Theta).RotateVec(total) : total; DebugTools.Assert(MathHelper.CloseTo(total.Length, worldTotal.Length)); if (weightless) { worldTotal *= mobMover.WeightlessStrength; } if (worldTotal != Vector2.Zero) { // This should have its event run during island solver soooo transform.DeferUpdates = true; transform.WorldRotation = worldTotal.GetDir().ToAngle(); transform.DeferUpdates = false; HandleFootsteps(mover, mobMover); } physicsComponent.LinearVelocity = worldTotal; }
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics) { if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner)) { if (physics.LinearVelocity != Vector2.Zero) { physics.LinearVelocity = Vector2.Zero; } } else { physics.LinearVelocity = mover.VelocityDir * (mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GridID)) { // Can happen when teleporting between grids. var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition); mover.StepSoundDistance += distance; } mover.LastPosition = transform.GridPosition; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.GridPosition); } } }
protected override void HandleFootsteps(IMoverComponent mover) { var transform = mover.Owner.Transform; // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GetGridId(EntityManager))) { // Can happen when teleporting between grids. if (!transform.Coordinates.TryDistance(_entityManager, mover.LastPosition, out var distance)) { mover.LastPosition = transform.Coordinates; return; } mover.StepSoundDistance += distance; } mover.LastPosition = transform.Coordinates; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.Coordinates); } }
/// <summary> /// A generic kinematic mover for entities. /// </summary> protected void HandleKinematicMovement(IMoverComponent mover, PhysicsComponent physicsComponent) { var(walkDir, sprintDir) = mover.VelocityDir; // Regular movement. // Target velocity. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); if (total != Vector2.Zero) { mover.Owner.Transform.LocalRotation = total.GetDir().ToAngle(); } physicsComponent.LinearVelocity = total; }
protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover) { // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _physicsManager)) { return; } var transform = mover.Owner.Transform; var(walkDir, sprintDir) = mover.VelocityDir; var weightless = transform.Owner.IsWeightless(_physicsManager); // Handle wall-pushes. if (weightless) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent); if (!touching) { transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle(); return; } } // Regular movement. // Target velocity. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); if (weightless) { total *= mobMover.WeightlessStrength; } if (total != Vector2.Zero) { // This should have its event run during island solver soooo transform.DeferUpdates = true; transform.LocalRotation = total.GetDir().ToAngle(); transform.DeferUpdates = false; HandleFootsteps(mover, mobMover); } physicsComponent.LinearVelocity = total; }
/// <summary> /// A generic kinematic mover for entities. /// </summary> protected void HandleKinematicMovement(IMoverComponent mover, PhysicsComponent physicsComponent) { var(walkDir, sprintDir) = mover.VelocityDir; // Regular movement. // Target velocity. var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed); var worldTotal = _relativeMovement ? new Angle(mover.Owner.Transform.Parent !.WorldRotation.Theta).RotateVec(total) : total; if (worldTotal != Vector2.Zero) { mover.Owner.Transform.WorldRotation = worldTotal.GetDir().ToAngle(); } physicsComponent.LinearVelocity = worldTotal; }
public static Vector3 Arriving(IMoverComponent mover, Vector3 direction, Vector3 target, float distanceFromTarget = 0, float threshold = 0) { if (threshold < 0 || distanceFromTarget < 0) { throw new ArgumentOutOfRangeException("Threshold or distanceFromTarget must have a value of >= 0"); } float arrivingDistanceToTarget = Vector3.Distance(mover.CurrentPosition, target); var distance = Vector3.Distance(target, mover.CurrentPosition) - distanceFromTarget; if (distance < threshold) { distance = 0; } float multiplier = (distance < arrivingDistanceToTarget) ? distance / arrivingDistanceToTarget : 1; return(Vector3.ClampMagnitude(direction, mover.MaxSpeed * multiplier)); }
private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover, IPhysicsComponent collider) { foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) { if (entity == transform.Owner) { continue; // Don't try to push off of yourself! } if (!entity.TryGetComponent<IPhysicsComponent>(out var otherCollider) || !otherCollider.CanCollide || (collider.CollisionMask & otherCollider.CollisionLayer) == 0) { continue; } // Don't count pulled entities if (otherCollider.HasController<PullController>()) { continue; } // TODO: Item check. var touching = ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) // Ensure collision && !entity.HasComponent<IItemComponent>(); // This can't be an item if (touching) { return true; } } return false; }
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null) { bool weightless = false; var tile = _mapManager.GetGrid(transform.GridID).GetTileRef(transform.GridPosition).Tile; if ((!_mapManager.GetGrid(transform.GridID).HasGravity || tile.IsEmpty) && collider != null) { weightless = true; // No gravity: is our entity touching anything? var touching = false; foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) { if (entity.TryGetComponent <CollidableComponent>(out var otherCollider)) { if (otherCollider.Owner == transform.Owner) { continue; // Don't try to push off of yourself! } touching |= ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision !entity.HasComponent <ItemComponent>(); // This can't be an item } } if (!touching) { return; } } if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner)) { if (physics.LinearVelocity != Vector2.Zero) { physics.LinearVelocity = Vector2.Zero; } } else { if (weightless) { physics.LinearVelocity = mover.VelocityDir * mover.CurrentPushSpeed; transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); return; } physics.LinearVelocity = mover.VelocityDir * (mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GridID)) { // Can happen when teleporting between grids. var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition); mover.StepSoundDistance += distance; } mover.LastPosition = transform.GridPosition; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.GridPosition); } } }
protected virtual void HandleFootsteps(IMoverComponent mover) { }
private void OnMoverStartup(EntityUid uid, IMoverComponent component, ComponentStartup args) { UpdateCanMove(uid, component); }
private void Awake() { _mover = GetComponent <IMoverComponent>(); }
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null) { if (physics.Controller == null) { // Set up controller physics.SetController <MoverController>(); } var weightless = !transform.Owner.HasComponent <MovementIgnoreGravityComponent>() && _physicsManager.IsWeightless(transform.GridPosition); if (weightless && collider != null) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(transform, mover, collider); if (!touching) { return; } } if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless) { (physics.Controller as MoverController)?.StopMoving(); } else { if (weightless) { (physics.Controller as MoverController)?.Push(mover.VelocityDir, mover.CurrentPushSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); return; } (physics.Controller as MoverController)?.Move(mover.VelocityDir, mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GridID)) { // Can happen when teleporting between grids. var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition); mover.StepSoundDistance += distance; } mover.LastPosition = transform.GridPosition; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.GridPosition); } } }