public void Collided(object[] args) { if (active) { KinematicCollision collision = (KinematicCollision)args[0]; if (target != null && collision.Collider.Equals(target)) { if (state == BreedState.GoingForBreed) { SetState(BreedState.Breeding); } else if (state == BreedState.Breeding) { if (breedingTimer > breedingThreshold) { if (component.Sex == AnimalBehaviourComponent.AnimalSex.Female) { Node spawnNode = component.parent.GetNode(Game.ANIMAL_SPAWNER_PATH); int nextSex = BaseComponent.random.Next(0, 2); spawnNode.Call("SpawnAnimal", component.PresetName, (AnimalBehaviourComponent.AnimalSex)nextSex, component.Body.GetTranslation() + new Vector3(0.0f, 2.0f, 0.0f)); component.Satiated -= component.BirthDrop; //quick and dirty balance fix - frogs not reproducing enough if (component.PresetName == "frog") { spawnNode.Call("SpawnAnimal", component.PresetName, (AnimalBehaviourComponent.AnimalSex)nextSex, component.Body.GetTranslation() + new Vector3(0.5f, 2.0f, 0.0f)); } } active = false; } } } } }
public void Move(Vector3 movement, float moveDelta = 1f) { movement *= moveDelta; Transform current = GetTransform(); Transform destination = current; destination.Translated(movement); Vector3 delta = destination.origin - current.origin; KinematicCollision collision = MoveAndCollide(delta); if (collision != null && collision.Collider != null) { ICollide collider = collision.Collider as ICollide; if (collider != null) { Node colliderNode = collider as Node; collider.OnCollide(this as object); } } if (!grounded && collision != null && collision.Position.y < GetTranslation().y) { if (gravityVelocity < 0) { grounded = true; gravityVelocity = 0f; } } }
public void ProcessCollision(KinematicCollision collision) { if (((Node)collision.Collider).GetGroups().Contains("WaterWell")) { _currentWaterCapacity = MaxWaterCapacity; } }
public void CheckCollision() { int slideCount = GetSlideCount(); if (slideCount == 0) { return; } speed *= speedMultiplier; KinematicCollision collisionInfo = GetSlideCollision(slideCount - 1); Pad pad = collisionInfo.Collider as Pad; if (pad != null) { hitAmount++; if (hitAmount % 4 == 0) { BallSpawner.singleton.SpawnBall(); } pad.shooter.ResetBullets(); } Vector3 collisionNormal = collisionInfo.Normal; collisionNormal.y = 0; Vector3 reflectedDirection = (direction - 2 * (direction * collisionNormal) * collisionNormal).Normalized(); direction = reflectedDirection; }
protected AbstractState CheckIfFalling(KinematicCollision kc) { if (kc == null) { return(new FallingState(sharedState)); } sharedState.otherForces.y = -5; //Keep player grounded - This is kinda hacky return(this); }
public override void Move(Vector3 direction) { Transform current = Transform; Transform destination = current; destination.Translated(direction); Vector3 delta = destination.origin - current.origin; KinematicCollision collision = MoveAndCollide(delta); }
public static Vector3 CastBoxFromPlayer(float distance) { //Goto Player Singleton.PlacementPreview.GlobalTransform = Player.Singleton.ScanRay.GlobalTransform; Vector3 rel = -(Singleton.PlacementPreview.GlobalTransform.basis.z * distance); KinematicCollision collision = Singleton.PlacementPreview.MoveAndCollide(rel, testOnly: true); return((collision == null) ? Singleton.PlacementPreview.Translation + rel : Singleton.PlacementPreview.Translation + collision.Travel); }
// Physics substeps void ResetGrounded() { KinematicCollision groundCollision = new KinematicCollision { normal = Vector3.up, slope = 0.0f }; ground = groundCollision; wasGrounded = isGrounded; isGrounded = false; }
public void Collided(object[] args) { if (active) { KinematicCollision collision = (KinematicCollision)args[0]; if (target != null && collision.Collider.Equals(target)) { eat(collision.Collider); } } }
public override void _PhysicsProcess(float delta) { if (_processMovement) { ProcessMovement(delta); KinematicCollision collision = MoveAndCollide(_velocity * delta); if (collision != null) { CollisionHandler(collision); } } }
private void Fall() { KinematicCollision collision = null; for (uint i = 0; i < 10; i++) { collision = Move(Vector3.Down); if (collision != null) { break; } } }
private void HandleCollision(KinematicCollision collision) { Node collider = (Node)collision.Collider; if (collider.Name == "Water") { thirst = 100f; hunger -= 1f; direction = Direction.IDLE; state = State.SEARCHING_WATER; timer = maxTime; } }
// ****************** FUNCION PRINCIPAL DESPLAZAMIENTO ******* public override void _PhysicsProcess(float delta) { try { if (golpeado > 0) { Transform trans = this.GlobalTransform; // Vector3 directionlocal = trans.basis.Xform(direcciongolpeado); Vector3 directionlocal = direcciongolpeado; KinematicCollision choque = MoveAndCollide(directionlocal * VELOCIDADGOLPEADO * delta); } } catch (Exception ex) { } }
public override void Move(Vector3 direction) { Transform current = Transform; Transform destination = current; destination.Translated(direction); Vector3 delta = destination.origin - current.origin; KinematicCollision collision = MoveAndCollide(delta); if (collision != null && collision.Position.y < this.Transform.origin.y) { jumpReady = true; } }
public override AbstractState PhysicsProcess(float dt) { base.PhysicsProcess(dt); sharedState.ConsciousMovement(CalculateMovementVector(dt)); //If the player is colliding with anything, change to stationary state KinematicCollision kc = sharedState.UnconsciousMovement(sharedState.otherForces * dt); if (kc != null) { sharedState.otherForces.y = -5; //Keep grounded - Super hacky? return(new StandingState(sharedState)); } return(this); }
// acciones a realizar cuando choca contra algo mientras atacaba private void choca(KinematicCollision choque, Vector3 directionlocal) { // if (tipomovimiento==TIPOSMOVIMIENTOS.ATAQUEPREPARANDO || tipomovimiento==TIPOSMOVIMIENTOS.ATAQUEDESACELERANDO) // timerusogeneral.Stop(); Godot.Object golpeado = choque.Collider; ulong idcollider = choque.ColliderId; ulong idjugador = globales.NODOJUGADOR.GetInstanceId(); if (idjugador == idcollider) { globales.NODOJUGADOR.golpeadoCaja(directionlocal); } cambiaTipoMovimiento(TIPOSMOVIMIENTOS.PARADACHOQUE, 0); }
public override void _PhysicsProcess(float delta) { _activeTime += delta; StageTwoPhysicsProcess(delta); // let grenade "drop" for a frame if (_explodeNextTick) { this.PrimeTimeFinished(); } // after 3 seconds, explode if (_activeTime > _maxPrimedTime) { if (_thrown) { this.PrimeTimeFinished(); } else { this.Transform = this._playerOwner.GetGlobalTransform(); _explodeNextTick = true; } } if ((_thrown || _explodeNextTick) && _stageOne) { _velocity = _direction * _currentSpeed; Vector3 motion = _velocity * delta; KinematicCollision c = this.MoveAndCollide(motion); if (c != null) { // bounce _direction = motion.Bounce(c.Normal); _currentSpeed *= .95f; } else { // apply gravity _direction.y -= _gravity * delta; } } }
void NormalPhysicsProcess(float delta) { HandleRaycast(); if (floors > 0 && !wants_to_move) { linear_velocity = new Vector3(linear_velocity.x, 0, linear_velocity.z); } if (floors > 0 && GetSlideCount() > 0) { KinematicCollision col = GetSlideCollision(0); old_normal = col.Normal; } linear_velocity = MoveAndSlide(linear_velocity, floorNormal: Vector3.Up, floorMaxAngle: Mathf.Pi * 2); if (floors > 0 && GetSlideCount() < 1) { //MoveAndCollide(-1 * old_normal); } }
// logic functions public void drop_path(KinematicCollision hit_data = null) { target_point = Translation; target_path = new List <Vector3>(); var hit_obj = hit_data.Collider as Spatial; step_back_normal = (hit_obj.GlobalTransform.origin - GlobalTransform.origin).Normalized(); step_back_mode = mode; mode = 3; debug.Clear(); GD.Print("impact while moving"); if (hit_data != null) { GD.Print("data: " + hit_data.ToString()); } }
void ProbeGround() { KinematicCollision groundCollision; CalculateOwnCapsuleParameters(out Vector3 capsuleTop, out Vector3 capsuleBottom, out float radius); // Move capsule bottom up just a bit to make sure we raycast against anything that's already touching capsuleBottom += Vector3.up * collisionResolutionDistance; // Check for ground by casting our capsule down if (Physics.CapsuleCast(capsuleTop, capsuleBottom, radius, -Vector3.up, out RaycastHit capsuleHit, groundSnapDistance)) { groundCollision.point = capsuleHit.point; groundCollision.normal = capsuleHit.normal; groundCollision.slope = Vector3.Angle(groundCollision.normal, Vector3.up); // Try to find surface normal if possible, using raycast if (Physics.Raycast(capsuleBottom, -capsuleHit.normal, out RaycastHit rayHit, (groundSnapDistance + radius))) { groundCollision.normal = rayHit.normal; groundCollision.slope = Vector3.Angle(groundCollision.normal, Vector3.up); } if (groundCollision.slope <= slopeAngleLimit) { // Update ground properties isGrounded = true; ground = groundCollision; // Snap to ground position += Vector3.up * -(capsuleHit.distance - collisionResolutionDistance); if (!wasGrounded) { HandleOnGrounded(); } } else if (groundCollision.slope <= 90.0f && wasGrounded) { HandleOnTakeoff(groundCollision); } }
private void CollisionHandler(KinematicCollision collision) { // stop updating movement _processMovement = false; // need to rotate weapon so +y axis is parallel to velocity and move it into body to be "stuck in" GlobalTransform = Util.Normal2Basis(GlobalTransform, _velocity.Normalized()); Vector3 localDelta = ToLocal(collision.Position) - ToLocal(GetNode <Position3D>("PenetrationPoint").GlobalTransform.origin); TranslateObjectLocal(localDelta); // turn on pickup hitbox _pickupHitbox.Monitoring = true; _pickupHitbox.Monitorable = true; // visualize teleport location (leave for later to update teleport location further) // MeshInstance debugTeleportLocation = GetNode<MeshInstance>("DebugTeleportLocation"); // debugTeleportLocation.Visible = true; // Transform placeholder = debugTeleportLocation.GlobalTransform; // placeholder.origin = GetTeleportLocation(); // debugTeleportLocation.GlobalTransform = placeholder; }
public override void _PhysicsProcess(float delta) { Vector3 vel = _direction * _speed; Vector3 motion = vel * delta; KinematicCollision c = this.MoveAndCollide(motion); if (c != null) { Random ran = new Random(); float damage = _damage + ran.Next(0, 20); // if c collider is kinematic body (direct hit) if (c.Collider is Player pl) { pl.TakeDamage(this.Transform, _weaponOwnerString, _weaponOwnerInflictLength, _playerOwner, damage); this.Explode(pl, damage); } else { this.Explode(null, damage); } } }
public override void Move(Vector3 direction) { Transform current = Transform; Transform destination = current; destination.Translated(direction); Vector3 delta = destination.origin - current.origin; KinematicCollision collision = MoveAndCollide(delta); if (collision != null && collision.Position.y < this.Transform.origin.y) { jumpReady = true; } Node colliderNode = collision?.Collider as Node; if (colliderNode != null && colliderNode.IsInGroup(Constants.HazardGroup)) { Main.Game.GameOver(); } }
public override void _PhysicsProcess(float delta) { _time += delta; _velocity = _direction * _currentSpeed; Vector3 motion = _velocity * delta; KinematicCollision c = this.MoveAndCollide(motion); if (c != null) { // if c collider is kinematic body (direct hit) if (c.Collider is Player pl) { if (pl != this._playerOwner) { pl.TakeDamage(this.Transform, this.WeaponOwner.GetType().ToString().ToLower(), this.WeaponOwner.InflictLength, _playerOwner, _damage); this.Explode(pl, _damage); } } else { // bounce _direction = motion.Bounce(c.Normal); _currentSpeed *= .95f; } } else { // apply gravity _direction.y -= _gravity * delta; } // after 2.5 seconds, explode if (_time > _lifeTime) { this.Explode(null, _damage); } }
private void Walk(float delta) { //Since IsOnFloor() doesn't properly update on concave collision shapes, count the number of bodies that _JumpArea is colliding with //Get the rotation of the head Basis aim = Head.GlobalTransform.basis; //Get slope of floor and if ground hit, set head velocity Vector3 normal; bool playerFeetOverlapsFloor = PlayerFeet.Singleton.Bodies > 0; if (playerFeetOverlapsFloor) { normal = GroundRay.GetCollisionNormal(); } else { normal = Vector3.Up; } //Calculate ground angle float groundAngle = Mathf.Acos(normal.Dot(Vector3.Up)); //Determine if slipping and set initial direction bool slipping = false; bool noWalkSlipping = false; if (groundAngle > MaxSlopeSlip) { slipping = true; if (groundAngle > MaxSlopeNoWalk) { noWalkSlipping = true; } Direction = Vector3.Up.Slide(normal); } else { Direction = Vector3.Zero; } //Get crouch bool crouchPressed = CrouchToggle && !CrouchJumped?Input.IsActionJustPressed("crouch") : (Input.IsActionPressed("crouch") != Crouched); //Determine if landing PlayerArms.Singleton.Land = false; if (IsOnFloor()) { if (WasInAir) { //GD.Print("Landed"); //Reset number of jumps JumpsLeft = JumpCount; //Play land animations PlayerArms.Singleton.Fall = false; PlayerArms.Singleton.Land = true; if (!slipping && ImpactVelocity >= HeadDipThreshold) { PlayerAnimationTree.Singleton.LandBlend = Mathf.Min(1f, Mathf.Abs((ImpactVelocity - HeadDipThreshold) / (-Gravity - HeadDipThreshold))); PlayerAnimationTree.Singleton.Land(); } //Play Land Sounds if Velocity is significant PlayerFeet.Singleton.LandPlayer.Play(); //GD.Print(ImpactVelocity); //Deal fall damage if (ImpactVelocity >= FatalFallVelocity) { PlayerHealthManager.Singleton.Kill("A Fatal Fall"); } else if (ImpactVelocity >= MajorInjuryFallVelocity) { PlayerHealthManager.Singleton.TakeDamage("A Major Spill", 50); } else if (ImpactVelocity >= MinorInjuryFallVelocity) { PlayerHealthManager.Singleton.TakeDamage("A Minor Spill", 10); } //Determine if player had crouch jumped if (CrouchJumped) { CrouchJumped = false; WantsToUncrouch = crouchPressed; } WasInAir = false; } } else if (Mathf.Abs(Velocity.y) > 4f) { //GD.Print(Velocity.y); WasInAir = true; PlayerArms.Singleton.Fall = true; ImpactVelocity = -Velocity.y; } //Get input and set direction bool userMoving = (Vinput != 0 || Hinput != 0); Direction += aim.z * (slipping ? -1f : 1f) * Vinput; Direction += aim.x * (slipping ? -1f : 1f) * Hinput; if (Direction.Length() > 1f) { Direction = Direction.Normalized(); } Vector3 velocityNoGravity = new Vector3(Velocity.x, 0, Velocity.z); //Get sprint if (SprintToggle) { if (Input.IsActionJustPressed("sprint")) { Sprint = !Sprint; } } else { Sprint = (Input.IsActionPressed("sprint") != SprintToWalk); } //Get speed and acceleration dependant variables bool accelerate = Direction.Dot(velocityNoGravity) > 0; //Set target speed Vector3 targetVelocity; if (slipping) { targetVelocity = Direction * Gravity * (1f - Vector3.Up.Dot(normal)); } else { targetVelocity = Direction * (Sprint ? (IsOnFloor() ? FullSpeedSprint : Mathf.Max(Velocity.Length(), FullSpeedWalk)) : FullSpeedWalk); } //Apply gravity Velocity.y += Gravity * delta; //Calculate velocity float acceleration = IsOnFloor() || (IsOnWall() && noWalkSlipping) ? AccelerationWalk: AccelerationAir; float deacceleration = IsOnFloor() ? DeaccelerationWalk : DeaccelerationAir; velocityNoGravity = velocityNoGravity.LinearInterpolate(targetVelocity, (accelerate ? acceleration : deacceleration) * delta); Velocity.x = velocityNoGravity.x; Velocity.z = velocityNoGravity.z; //Set walking animation blend float bob1D = PlayerArms.Singleton.Walk; if (userMoving && IsOnFloor()) { bob1D = Mathf.Min(1f, bob1D + ((Sprint ? BobIncrementSprint : BobIncrementWalk) * delta)); } else { bob1D = Mathf.Max(0.01f, bob1D - ((IsOnFloor() ? BobDecrementFloor : BobDecrementAir) * delta)); } if (HeadBobbing) { PlayerAnimationTree.Singleton.HeadBobBlend = bob1D; } PlayerArms.Singleton.Walk = bob1D; PlayerAnimationTree.Singleton.HeadBobScale = Sprint ? 1.5f : 1f; //Set arm swing blend SwingTarget = SwingTarget.LinearInterpolate(Vector2.Zero, 0.05f); PlayerArms.Singleton.Swing = SwingTarget; //Set step timer if (bob1D > 0.1f) { if (PlayerFeet.Singleton.StepTimer.Paused == true) { //GD.Print("Not Paused"); PlayerFeet.Singleton.StepTimer.Paused = false; } } else { if (PlayerFeet.Singleton.StepTimer.Paused == false) { //GD.Print("Paused"); PlayerFeet.Singleton.StepTimer.Paused = true; } } PlayerFeet.Singleton.StepTimer.WaitTime = Sprint ? 0.25f : 0.5f; //Get jump PlayerArms.Singleton.Jump = false; if ((BunnyHopping ? Input.IsActionPressed("jump") : Input.IsActionJustPressed("jump")) && (playerFeetOverlapsFloor) || Input.IsActionJustPressed("jump") && JumpsLeft > 0) { PlayerArms.Singleton.Jump = true; if (!PlayerFeet.Singleton.JumpPlayer.Playing) { PlayerFeet.Singleton.JumpPlayer.Play(); } Velocity.y = 0f; //Velocity += normal * JumpHeight; //Velocity.y *= (noWalkSlipping ? 0.1f : 1f); if (!slipping && Direction.Dot(velocityNoGravity) < 0f) { //GD.Print("Reset Velocity"); Velocity.x = 0f; Velocity.z = 0f; } Velocity += (noWalkSlipping ? normal : Vector3.Up) * JumpHeight; PlayerFeet.Singleton.CanBunnyHop = false; _SnapArea.Snap = false; if (!playerFeetOverlapsFloor) { //Update number of jumps JumpsLeft -= 1; } } if (crouchPressed || (Crouched && WantsToUncrouch)) { if (IsOnFloor()) { //Check if uncrouch is possible if ((Crouched && StandArea.GetOverlappingBodies().Count == 0) || (!Crouched)) { //Invert crouch (animation, collision, etc. handled in get set) Crouched = !Crouched; WantsToUncrouch = false; } else if (crouchPressed) { //Invert WantToUncrouch. Player will uncrouch at latest opportunity. WantsToUncrouch = !WantsToUncrouch; } } else if (CanCrouchJump && !Crouched && !CrouchJumped) { CrouchJumped = true; Crouched = true; PlayerAnimationTree.Singleton.StateMachineCrouch.Start("CrouchJump"); Translate(Vector3.Up * 1.1f); //GD.Print("Crouch jump."); } } //Get Climb if (Input.IsActionPressed("climb")) { WantsToClimb = true; ClimbTimer.Start(ClimbTimeout); } //Calculate ledge point Vector3 closestLedgePoint = Vector3.Inf; bool canClimb = false; bool withCrouch = false; ClimbLabel.Visible = false; if (!Crouched) { foreach (RayCast LedgeRay in LedgeRays) { if (LedgeRay.IsColliding()) { if (LedgeRay.GetCollisionPoint().DistanceTo(Translation) < closestLedgePoint.DistanceTo(Translation)) { closestLedgePoint = LedgeRay.GetCollisionPoint(); canClimb = true; } } } closestLedgePoint = closestLedgePoint + (Vector3.Up * (StandHeight + 0.075f)); if (canClimb) { //Disable all other colliders bool[] shapeDisabledState = new bool[OtherCollision.Count]; for (int i = 0; i < OtherCollision.Count; ++i) { //GD.Print("Disabling collision ", OtherCollision[i].Name); shapeDisabledState[i] = OtherCollision[i].Disabled; OtherCollision[i].Disabled = true; } //Test to see if player has space to climb canClimb = !TestMove(new Transform(Quat.Identity, closestLedgePoint), Vector3.Zero); if (!canClimb) { _CollisionStand.Disabled = true; _CollisionCrouch.Disabled = false; canClimb = !TestMove(new Transform(Quat.Identity, closestLedgePoint), Vector3.Zero); withCrouch = canClimb; _CollisionStand.Disabled = false; _CollisionCrouch.Disabled = true; } //Reset colliders for (int i = 0; i < OtherCollision.Count; ++i) { //GD.Print("Reseting other collision", OtherCollision[i], " ", shapeDisabledState[i]); OtherCollision[i].Disabled = shapeDisabledState[i]; } } ClimbLabel.Visible = canClimb; if (canClimb && WantsToClimb) { if (withCrouch) { Crouched = true; } //Set climb point and enter climb state ClimbPoint = closestLedgePoint; ClimbStep = (ClimbPoint - Translation).Normalized() * ClimbSpeed; ClimbDistance = (ClimbPoint - Translation).Length(); PlayerAnimationTree.Singleton.Climb(); PlayerAnimationTree.Singleton.HeadBobScale = 0f; Climbing = true; //Reset ImpactVelocity and zero y Velocity to avoid confusing animations ImpactVelocity = Velocity.y = 0f; } } //Move Player and calculate distance Vector3 o = Translation; Vector3 vo = velocityNoGravity; if (userMoving || slipping) { Velocity = MoveAndSlideWithSnap(Velocity, _SnapArea.Snap ? Vector3.Down : Vector3.Zero, Vector3.Up, true, 4, MaxSlopeNoWalk); } else { //Velocity = MoveAndSlideWithSnap(Velocity, _SnapArea.Snap ? Vector3.Down : Vector3.Zero, Vector3.Up, true, 4, MaxSlopeNoWalk); Velocity = MoveAndSlide(Velocity, Vector3.Up, true, 4, MaxSlopeNoWalk); if (GetSlideCount() > 0) { KinematicCollision slide = GetSlideCollision(0); if (Vector3.Up.AngleTo(slide.Normal) < MaxSlopeSlip) { //Player is sliding on a slope they shouldn't be sliding on. Velocity = vo; } } } Vector3 d = Translation; Vector3 distance = (d - o); //Calculate Acceleration and force MovementVelocity = distance / delta; MovementAcceleration = 2f * distance / Mathf.Pow(delta, 2f); MovementForce = Mass * MovementAcceleration; }
private void HandleCollision(KinematicCollision collision) { if (collision.Collider == Parent) { return; } heading = Vector3.Zero; if (collision.Collider.HasMethod("Hit")) { Node b = new Node(); // Set hit particle based on living or inanimate object if (collision.Collider is Player) { b = humanHitParticle.Instance(); } else if (collision.Collider is Enemy) { if (((Global)GetNode("/root/Global")).HumanEnemies) { b = humanHitParticle.Instance(); } else { b = waspHitParticle.Instance(); } } else { b = hitParticle.Instance(); } // Set particle variables ((CPUParticles)b.GetNode("CPUParticles")).Emitting = true; Vector3 offset = Vector3.Zero; if (collision.Collider.Get("Translation") == null) { } else { offset = (Vector3)collision.Collider.Get("Translation"); } ((CPUParticles)b.GetNode("CPUParticles")).SetTranslation(collision.Position - offset); if (collision.Collider is RigidBody && !(collision.Collider is Player) && !(collision.Collider is Enemy)) { // Apply impulse to rigidbodies ((RigidBody)collision.Collider).ApplyCentralImpulse(-collision.Normal * 5f); } // Add particle ((Node)collision.Collider).AddChild(b); collision.Collider.Call("Hit"); RemoveBullet(); } else { Node b = hitParticle.Instance(); ((CPUParticles)b.GetNode("CPUParticles")).Emitting = true; Vector3 offset = Vector3.Zero; if (collision.Collider.Get("Translation") == null) { } else { offset = (Vector3)collision.Collider.Get("Translation"); } ((CPUParticles)b.GetNode("CPUParticles")).SetTranslation(collision.Position - offset); ((Node)collision.Collider).AddChild(b); RemoveBullet(); } }
public virtual void OnPlayerCollide(KinematicCollision Collision) { }
//provides grid based movement and handles collision information public KinematicCollision Move(Vector3 relVec) { if (!_collisionLoaded) { return(null); } relVec *= SPEED; KinematicCollision collision = MoveAndCollide(relVec, testOnly: true); //don't move if it would cause a collision and return that collision if (collision != null) { //handle the collision Node collider = (Node)collision.Collider; string name = NameGetter.FromCollision(collider); switch (name) { case "bambooPlatformStatic": Spatial staticBody = (StaticBody)collider; if (staticBody.Translation.y != 0) { staticBody.Translation = Vector3.Zero; relVec += new Vector3(0, SPEED, 0); collision = null; } break; case "pot": moveWrapper colliderMove = (moveWrapper)collider; if (colliderMove.Move(relVec / SPEED) == null) { collision = null; } break; case "GridMap": case "flowerPlatform": break; default: GD.Print("Unhandled collision against " + name); break; } } //move if it wouldn't cause a collision if (collision == null) { Translation += relVec; if (planted) { var plant = (Spatial)plantRaycast.GetCollider(); if (plant != null) { plant.Translation += relVec; } else { planted = false; } } } return(collision); }
public Vector3 Move(Vector3 Momentum, float Delta, int MaxSlideCount, float MaxAngle, float Snap) { Vector3 Movement = Momentum * Delta; if (Momentum.y <= 0) { Vector3 OriginalTranslation = Translation; var SnapVec = new Vector3(0, -Snap, 0); KinematicCollision SnapCollision = MoveAndCollide(SnapVec); if (SnapCollision != null && Acos(SnapCollision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle)) { OnFloor = true; float TargetHLength = Movement.Flattened().Length(); Movement = Movement.Slide(SnapCollision.Normal); float NewHLength = Movement.Flattened().Length(); if (TargetHLength != 0 && NewHLength != 0) //Protect against division by zero { Movement *= TargetHLength / Movement.Flattened().Length(); } Translation = OriginalTranslation; Momentum.y = 0; //On floor so "zero" out vertical momentum } else { Translation = OriginalTranslation; OnFloor = false; } } else { OnFloor = false; } int SlideCount = 0; float Traveled = 0f; while (SlideCount <= MaxSlideCount) { Movement = Movement.Normalized() * (Movement.Length() - Traveled); KinematicCollision Collision = MoveAndCollide(Movement); if (Collision == null) { break; //No collision, reached destination } Traveled += Collision.Travel.Length(); if (Traveled >= Movement.Length()) { break; //Reached destination } SlideCount += 1; //Dirty hack to prevent horizontal nudging when landing bool SlideByNormal = true; float NormalAverageHorizontal = (Abs(Collision.Normal.x) + Abs(Collision.Normal.z)) / 2f; if (Collision.Normal.y >= NormalAverageHorizontal) { SlideByNormal = false; } if (SlideByNormal && Acos(Collision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle)) { Movement = Movement.Slide(Collision.Normal); } if (Acos(Collision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle)) { OnFloor = true; } else if (SlideByNormal) { Momentum = Momentum.Slide(Collision.Normal); } } if (OnFloor) { Momentum.y = 0f; //On floor so "zero" out vertical momentum } MoveAndSlide(new Vector3()); return(Momentum); }
public override void _PhysicsProcess(float delta) { try { // ****** No se mueve if (tipomovimiento == TIPOSMOVIMIENTOS.NINGUNO) { /* * if (direccion != new Vector3()) * { * * * // ascender/descender * * * Vector3 direcciontrans = new Vector3(direccion.x, 0,direccion.z); * * Transform trans = this.GlobalTransform; * Vector3 directionlocal = trans.basis.Xform(direcciontrans); * // Vector3 directionlocal = direccion; * KinematicCollision choque = MoveAndCollide(directionlocal * VELOCIDAD * delta); * * * // actuamos si chocamos * } */ return; } // se mueve al azar por el escenario if (tipomovimiento == TIPOSMOVIMIENTOS.MOVIENDOSE) { // el movimiento normal es siempre hacia el frente, si está mirando hacia arriba o abajo // hacemos que mire al frente Vector3 giroactual = Rotation; if (giroactual.x != 0) { if (Math.Abs(giroactual.x) < VELOCIDADGIRO) { giroactual.x = 0; } else if (giroactual.x > VELOCIDADGIRO) { giroactual.x -= VELOCIDADGIRO; } else { giroactual.x += VELOCIDADGIRO; } this.Rotation = giroactual; } // comprobamos si hay que rotar Vector3 posicionyo = this.Translation; Vector2 diferencia2d = new Vector2(posicionobjetivoactual.x, posicionobjetivoactual.z) - new Vector2(posicionyo.x, posicionyo.z); Vector3 zfact = -this.GlobalTransform.basis.z; Vector2 zfact2d = new Vector2(zfact.x, zfact.z); Vector2 diferencia2dnorm = diferencia2d.Normalized(); Vector2 zfact2dnorm = zfact2d.Normalized(); float anguloangle = zfact2dnorm.AngleTo(diferencia2dnorm); if (anguloangle > (float)VELOCIDADGIRO) { this.RotateY(-VELOCIDADGIRO); } else if (anguloangle < (float)VELOCIDADGIRO) { this.RotateY(VELOCIDADGIRO); } // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { Vector3 vectordistancia = posicionobjetivoactual - posicionyo; float distanciafloat = vectordistancia.Length(); float lay = 0; // ascender/descender if (vectordistancia.y > 0) { lay = (float)0.02; } if (vectordistancia.y < 0) { lay = (float)-0.02; } Vector3 direcciontrans = new Vector3(direccion.x, lay, direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; KinematicCollision choque = MoveAndCollide(directionlocal * VELOCIDAD * delta); // actuamos si chocamos if (choque != null || distanciafloat < 10) { cambiaObjetivoAzar(); } if (decideAtacarJugador()) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.ATAQUEPREPARANDO, 0); } } } // se desplaza como siempre, pero buscando como objetivo al jugador if (tipomovimiento == TIPOSMOVIMIENTOS.BUSCANDOJUGADOR) { // funciona igual que el movimiento normal, pero el objetivo es siempre el jugador posicionobjetivoactual = globales.NODOJUGADOR.Translation; // comprobamos si hay que rotar Vector3 posicionyo = this.Translation; Vector2 diferencia2d = new Vector2(posicionobjetivoactual.x, posicionobjetivoactual.z) - new Vector2(posicionyo.x, posicionyo.z); Vector3 zfact = -this.GlobalTransform.basis.z; Vector2 zfact2d = new Vector2(zfact.x, zfact.z); Vector2 diferencia2dnorm = diferencia2d.Normalized(); Vector2 zfact2dnorm = zfact2d.Normalized(); float anguloangle = zfact2dnorm.AngleTo(diferencia2dnorm); if (anguloangle > (float)VELOCIDADGIRO) { this.RotateY(-VELOCIDADGIRO); } else if (anguloangle < (float)VELOCIDADGIRO) { this.RotateY(VELOCIDADGIRO); } // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { Vector3 vectordistancia = posicionobjetivoactual - posicionyo; float distanciafloat = vectordistancia.Length(); float lay = 0; // ascender/descender if (vectordistancia.y > 0) { lay = (float)0.02; } if (vectordistancia.y < 0) { lay = (float)-0.02; } Vector3 direcciontrans = new Vector3(direccion.x, lay, direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; KinematicCollision choque = MoveAndCollide(directionlocal * VELOCIDAD * delta); // actuamos si chocamos if (choque != null) { cambiaObjetivoAzar(); } if (decideAtacarJugador()) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.ATAQUEPREPARANDO, 0); } } } // deja de moverse y gira para encarar al jugador antes de atacar if (tipomovimiento == TIPOSMOVIMIENTOS.ATAQUEPREPARANDO) { Vector3 giroactual = Rotation; Vector3 girodestino = vectorgirapreparaataque; if (giroactual.y < girodestino.y && (girodestino.y - giroactual.y) > (VELOCIDADGIRO * 1.5)) { // RotateY(CANTIDADGIROAT); giroactual.y += VELOCIDADGIRO * (float)1.5; } if (giroactual.y > girodestino.y && (giroactual.y - girodestino.y) > (VELOCIDADGIRO * 1.5)) { // RotateY(-CANTIDADGIROAT); giroactual.y -= VELOCIDADGIRO * (float)1.5; } if (giroactual.x < girodestino.x && (girodestino.x - giroactual.x) > (VELOCIDADGIRO * 1.5)) { // RotateY(CANTIDADGIROAT); giroactual.x += VELOCIDADGIRO * (float)1.5; } if (giroactual.x > girodestino.x && (giroactual.x - girodestino.x) > (VELOCIDADGIRO * 1.5)) { // RotateY(-CANTIDADGIROAT); giroactual.x -= VELOCIDADGIRO * (float)1.5; } this.Rotation = giroactual; // si alcanza el giro destino, se lanza al ataque despues de 1 segundo if ((girodestino.y - giroactual.y) < (VELOCIDADGIRO * 2) && (giroactual.x - girodestino.x) < (VELOCIDADGIRO * 1.5)) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.ATAQUEAPUNTOLANZAR, 0); } } // deja de moverse y gira para encarar al jugador antes de atacar if (tipomovimiento == TIPOSMOVIMIENTOS.ATAQUEAPUNTOLANZAR) { contadordeltaataque -= delta; this.Rotation = vectorgirapreparaataque; this.RotateZ(objrand.RandfRange(-(float)0.2, (float)0.2)); if (contadordeltaataque <= 0) { lanzaAtaque(); } } // avanza en linea recta acelerando hasta alcanzar una velocidad maxima if (tipomovimiento == TIPOSMOVIMIENTOS.ATAQUEACELERANDO) { // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { Vector3 direcciontrans = new Vector3(direccion.x, 0, direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; contadordeltaataque -= delta; KinematicCollision choque = MoveAndCollide(directionlocal * velocidadatacando * delta); if (choque != null) { choca(choque, directionlocal); } else if (contadordeltaataque <= 0) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.ATAQUECONSTANTE, 0); } // actuamos si chocamos } } if (tipomovimiento == TIPOSMOVIMIENTOS.ATAQUECONSTANTE) { // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { Vector3 direcciontrans = new Vector3(direccion.x, 0, direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; contadordeltaataque -= delta; KinematicCollision choque = MoveAndCollide(directionlocal * velocidadatacando * delta); if (choque != null) { choca(choque, directionlocal); } else if (contadordeltaataque <= 0) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.ATAQUEDESACELERANDO, 0); } // actuamos si chocamos } } if (tipomovimiento == TIPOSMOVIMIENTOS.ATAQUEDESACELERANDO) { // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { Vector3 direcciontrans = new Vector3(direccion.x, 0, direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; contadordeltaataque -= delta; KinematicCollision choque = MoveAndCollide(directionlocal * velocidadatacando * delta); if (choque != null) { choca(choque, directionlocal); } else if (contadordeltaataque <= 0) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.MOVIENDOSE, 0); } // actuamos si chocamos } } // se mueve un poco hacia atras al chocar despues de un ataque if (tipomovimiento == TIPOSMOVIMIENTOS.PARADACHOQUE) { // avanzamos Vector3 posicionactual = Translation; if (direccion != new Vector3()) { // hacemos que se vaya poniendo derecho Vector3 giroactual = Rotation; if (giroactual.x != 0) { if (Math.Abs(giroactual.x) < VELOCIDADGIRO) { giroactual.x = 0; } else if (giroactual.x > VELOCIDADGIRO) { giroactual.x -= VELOCIDADGIRO; } else { giroactual.x += VELOCIDADGIRO; } this.Rotation = giroactual; } Vector3 direcciontrans = new Vector3(direccion.x, 0, -direccion.z); Transform trans = this.GlobalTransform; Vector3 directionlocal = trans.basis.Xform(direcciontrans); // Vector3 directionlocal = direccion; contadordeltaataque -= delta; KinematicCollision choque = MoveAndCollide(directionlocal * VELOCIDAD * 2 * delta); if (contadordeltaataque <= 0) { cambiaTipoMovimiento(TIPOSMOVIMIENTOS.MOVIENDOSE, 0); } // actuamos si chocamos } } } catch (Exception ex) { } }