void CalculateMoveToFloor(float delta) { if (IsOnFloor()) { hasFloorContact = true; forcedWalk = false; alowJumpInput = true; Vector3 floorNormal = floorChecker.GetCollisionNormal(); float floorAngle = Mathf.Rad2Deg(Mathf.Acos(floorNormal.Dot(Vector3.Up))); if (floorAngle > maxSlopeAngle) { forcedWalk = true; airJumpsLeft = 0; Fall(delta); } } else { if (!floorChecker.IsColliding()) { hasFloorContact = false; Fall(delta); } } if (hasFloorContact && !IsOnFloor()) { MoveAndCollide(Vector3.Down); } }
public void GroundMove(float delta, PlayerCmd pCmd) { Vector3 wishDir = new Vector3(); float scale = CmdScale(pCmd); wishDir += pCmd.aim.x * pCmd.move_right; wishDir -= pCmd.aim.z * pCmd.move_forward; wishDir = wishDir.Normalized(); _moveDirectionNorm = wishDir; float wishSpeed = wishDir.Length(); wishSpeed *= MoveSpeed; Accelerate(wishDir, wishSpeed, _runAcceleration, delta); if (_climbLadder) { if (pCmd.move_forward != 0f) { _playerVelocity.y = _moveSpeed * (pCmd.cam_angle / 90) * pCmd.move_forward; } else { _playerVelocity.y = 0; } if (pCmd.move_right == 0f) { _playerVelocity.x = 0; _playerVelocity.z = 0; } } // walk up stairs if (wishSpeed > 0 && _stairCatcher.IsColliding()) { Vector3 col = _stairCatcher.GetCollisionNormal(); float ang = Mathf.Rad2Deg(Mathf.Acos(col.Dot(_game.World.Up))); if (ang < _maxStairAngle) { _playerVelocity.y = _stairJumpHeight; } } if (_wishJump && IsOnFloor()) { // FIXME - if we add jump speed velocity we enable trimping right? _playerVelocity.y = _jumpSpeed; _jumpSound.Play(); } }
public override void _PhysicsProcess(float delta) { Vector3 direction = GetAxisDirection() * speed; groundingRay.ForceRaycastUpdate(); if (groundingRay.IsColliding() && groundingRay.GetCollisionNormal().AngleTo(Vector3.Up) < steepAngle) // check the ngle is not too steep { Transform t = GlobalTransform; t.origin.y = groundingRay.GetCollisionPoint().y; GlobalTransform = t; Vector3 normal = groundingRay.GetCollisionNormal(); Vector3 cross = GlobalTransform.basis.y.Cross(normal); if (cross.Length() > 0.0001f) // If the current player angle is not already at the slope angle { Rotate(cross.Normalized(), GlobalTransform.basis.y.AngleTo(normal)); } direction = direction.Rotated(Vector3.Up.Cross(normal).Normalized(), Vector3.Up.AngleTo(normal)); // Also rotate the direction } else { MoveAndSlide(new Vector3(0, downwardsVelocity, 0)); // If player is falling, align him Vector3 normal = Vector3.Up; Vector3 cross = GlobalTransform.basis.y.Cross(normal); if (cross.Length() > 0.0001f) // If the current player angle is not already at the slope angle { Rotate(cross.Normalized(), GlobalTransform.basis.y.AngleTo(normal)); } } MoveAndSlide(direction); if (direction.Length() > 0) { LookAt(GlobalTransform.origin - direction, GlobalTransform.basis.y); } }
public void Update(RayCast ray) { // update manually instead only once per frame in process ray.ForceRaycastUpdate(); var isColliding = ray.IsColliding(); Visible = isColliding; if (isColliding) { Vector3 collisionPoint = ray.GetCollisionPoint(); Vector3 collisionNormal = ray.GetCollisionNormal(); var transform = this.GlobalTransform; transform.origin = collisionPoint + collisionNormal * 0.01f; GlobalTransform = transform; LookAt(collisionPoint - collisionNormal, GlobalTransform.basis.y.Normalized()); } }
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 GroundMove(float delta) { Vector3 wishDir = new Vector3(); Basis aim = camera.GetGlobalTransform().basis; // Do not apply friction if the player is queueing up the next jump if (!wishJump) { ApplyFriction(1.0f, delta); } else { ApplyFriction(0, delta); } float scale = CmdScale(); wishDir += aim.x * _playerController.move_right; wishDir -= aim.z * _playerController.move_forward; wishDir = wishDir.Normalized(); moveDirectionNorm = wishDir; float wishSpeed = wishDir.Length(); wishSpeed *= _tranquilised ? moveSpeed / 2 : moveSpeed; Accelerate(wishDir, wishSpeed, runAcceleration, delta); if (climbLadder) { if (_playerController.move_forward != 0f) { playerVelocity.y = moveSpeed * (cameraAngle / 90) * _playerController.move_forward; } else { playerVelocity.y = 0; } if (_playerController.move_right == 0f) { playerVelocity.x = 0; playerVelocity.z = 0; } } else { playerVelocity.y = 0; } // walk up stairs if (wishSpeed > 0 && stairCatcher.IsColliding()) { Vector3 col = stairCatcher.GetCollisionNormal(); float ang = Mathf.Rad2Deg(Mathf.Acos(col.Dot(new Vector3(0, 1, 0)))); if (ang < maxStairAngle) { playerVelocity.y = stairJumpHeight; } } if (wishJump) { playerVelocity.y = jumpSpeed; wishJump = false; } }
public override void _PhysicsProcess(float delta) { if (ray.IsColliding()) { picker.Pick(ray.GetCollisionPoint(), ray.GetCollisionNormal()); ray.Enabled = false; } chunks.Text = "Chunks: " + Foreman.chunksPlaced; vertices.Text = "Vertices: " + Performance.GetMonitor(Performance.Monitor.RenderVerticesInFrame); fps.Text = "FPS: " + Performance.GetMonitor(Performance.Monitor.TimeFps); position.Text = "X: " + GlobalTransform.origin.x + "Y: " + GlobalTransform.origin.y + "Z:" + GlobalTransform.origin.z; memory.Text = "Memory: " + GC.GetTotalMemory(false) / (1048576) + "MB"; Vector3 velocity = new Vector3(); if (Input.IsActionPressed("walk_left")) { motion.x = 1; } else if (Input.IsActionPressed("walk_right")) { motion.x = -1; } else { motion.x = 0; } if (Input.IsActionPressed("walk_forward")) { motion.z = -1; } else if (Input.IsActionPressed("walk_backward")) { motion.z = 1; } else { motion.z = 0; } if (Input.IsActionPressed("move_up")) { motion.y = 1; } else if (Input.IsActionPressed("move_down")) { motion.y = -1; } else { motion.y = 0; } motion = motion.Normalized(); if (Input.IsActionPressed("move_speed")) { motion *= 2; } motion = motion.Rotated(new Vector3(0, 1, 0), Rotation.y - initialRotation.y) .Rotated(new Vector3(1, 0, 0), (float)Math.Cos(Rotation.y) * Rotation.x) .Rotated(new Vector3(0, 0, 1), -(float)Math.Sin(Rotation.y) * Rotation.x); velocity = motion * MOVE_SPEED; speed.Text = "Movement Speed: " + velocity.Length() + "m/s"; Vector3 translation = new Vector3(Translation.x + velocity.x, Translation.y + velocity.y, Translation.z + velocity.z); Translation = translation; TerraVector3 origin = Converter.ConvertVector(translation); marker.MoveTo(origin); }
public void shoot(float delta, bool isPuppet) { if (reloadWeapon) { return; } if (!isPuppet) { return; } // Get bullet ray. RayCast bulletRay = (RayCast)camera.GetNode("bullet_ray"); if (bullets > 0) { bullets -= 1; // Notify bullet update GameState.instance.EmitSignal(nameof(GameState.updateWeapon), weaponName, bullets, ammo); if (camera != null) { // Recoil camera.Rotation = new Vector3( Mathf.Lerp(camera.Rotation.x, (float)GD.RandRange(1, 2), delta), Mathf.Lerp(camera.Rotation.y, (float)GD.RandRange(-1, 1), delta), camera.Rotation.z ); // Shake camera.Set("shakeForce", 0.002); camera.Set("shakeTime", 0.2); } // Audio AudioStreamPlayer3D shoot = ((AudioStreamPlayer3D)audioNode.GetNode("shoot")); shoot.PitchScale = (float)GD.RandRange(0.9, 1.1); shoot.Play(); // Update crosshair crosshair.RectScale = crosshair.RectScale.LinearInterpolate(new Vector2(4, 4), 10 * delta); if (bulletRay.IsColliding()) { // Object collision CollisionObject collisionObject = (CollisionObject)bulletRay.GetCollider(); // Add spark to props. if (collisionObject.IsInGroup("props")) { // Add Spark Particles spark = (Particles)sparkScene.Instance(); ((Node)bulletRay.GetCollider()).AddChild(spark); spark.GlobalTransform = new Transform(spark.GlobalTransform.basis, bulletRay.GetCollisionPoint()); spark.Emitting = true; } // Add Muzzle Particles muzzle = (Particles)muzzleScene.Instance(); barrelNode.AddChild(muzzle); muzzle.Emitting = true; if (collisionObject is KinematicBody) { // Add Blood splatter Particles splatter = (Particles)splatterScene.Instance(); ((Node)bulletRay.GetCollider()).AddChild(splatter); splatter.GlobalTransform = new Transform(splatter.GlobalTransform.basis, bulletRay.GetCollisionPoint()); splatter.Emitting = true; int localDamage = 0; if (collisionObject.IsInGroup("head")) { localDamage = (int)GD.RandRange(damage / 2, damage); } else { localDamage = (int)GD.RandRange(damage / 3, damage / 2); } int colliderId = Convert.ToInt32(collisionObject.Name); // Send damage report. GameState.instance.EmitSignal(nameof(GameState.takeDamage), colliderId, localDamage); return; } else if (collisionObject.IsInGroup("props") || collisionObject.IsInGroup("walls")) { // Apply force to rigid body other than hitbox if (bulletRay.GetCollider() is RigidBody) { int localDamage = (int)GD.RandRange(damage / 1.5f, damage); ((RigidBody)bulletRay.GetCollider()).ApplyCentralImpulse(-bulletRay.GetCollisionNormal() * (localDamage * 0.3f)); } // Apply decal Spatial decal = (Spatial)decalScene.Instance(); ((Node)bulletRay.GetCollider()).AddChild(decal); decal.GlobalTransform = new Transform( decal.GlobalTransform.basis, bulletRay.GetCollisionPoint() ); decal.LookAt(bulletRay.GetCollisionPoint() + bulletRay.GetCollisionNormal(), new Vector3(1, 1, 0)); return; } } } else { AudioStreamPlayer3D empty = ((AudioStreamPlayer3D)audioNode.GetNode("empty")); if (!empty.Playing) { empty.PitchScale = (float)GD.RandRange(0.9, 1.1); empty.Play(); } } }
private void walk(float delta) { direction = Vector3.Zero; // Direction player is looking aim = head.GetGlobalTransform().basis; // Get input if (Input.IsActionPressed("Forward")) { direction.z -= 1; } if (Input.IsActionPressed("Backward")) { direction.z += 1; } if (Input.IsActionPressed("Left")) { direction.x -= 1; } if (Input.IsActionPressed("Right")) { direction.x += 1; } // Rotate direction direction = direction.Rotated(Vector3.Up, head.Rotation.y); direction.Normalized(); // Determine if player is on the ground and do some gravity stuff if (IsOnFloor()) { onGround = true; var normal = onGroundRaycast.GetCollisionNormal(); var floorAngle = Math.PI * (Math.Acos(normal.Dot(Vector3.Up))); if (floorAngle > maxSlopAngle) { velocity.y += gravity * delta; } } else { if (!onGroundRaycast.IsColliding()) { onGround = false; } velocity.y += gravity; } // Jump if (Input.IsActionPressed("Jump") && onGround) { velocity.y += jumpHeight; onGround = false; } Vector3 horizVelocity = velocity; horizVelocity.y = 0; // Speed to move at float speed = maxWalkSpeed; // Check if also running if (Input.IsActionPressed("Run")) { speed = maxSprintSpeed; } // Position player would move to at max speed var target = direction * speed; // Decide if accel or deaccel float acceleration; if (direction.Dot(horizVelocity) > 0) { acceleration = accel; } else { acceleration = deAccel; } // Calculate amount to move based on acceleration. horizVelocity = horizVelocity.LinearInterpolate(target, accel * delta); velocity.x = horizVelocity.x; velocity.z = horizVelocity.z; // Move only when movement is not extremely small. Workaround for some godot bug if (velocity.Length() > 0.1f) { // TODO: Velocity is not supposed to be multiplied by delta but it is above. Removing delta messes up velocity though so this needs experimenting. velocity = MoveAndSlide(velocity, Vector3.Up, false, 4, 0.784398f, false); } // Apply impulse to rigidbodies player is colliding with for (int i = 0; i < GetSlideCount(); i++) { var collision = GetSlideCollision(i); // TODO: Replace this with something more proper than try catch try { ((RigidBody)collision.Collider).ApplyCentralImpulse(-collision.Normal + -collision.Normal * Velocity.Length()); } catch {} } }
//Processes movement public void ProcessMovement(float delta) { //Sets the normal in a variable to calculate the dot product later if (GetFloorNormal() != Vector3.Zero) { Normal_vect = GetFloorNormal(); } else if (Floor_cast.GetCollisionNormal() != Vector3.Zero) { Normal_vect = Floor_cast.GetCollisionNormal(); } //Sets a redundant check to secure that the character isn't on the ground (and sets a fake normal that is perpendicular to the up vector) if (!Floor_cast.IsColliding()) { Normal_vect = Vector3.Forward; Floor_dect = false; } //Reset the redundant check to true if it detects it touched the floor (and sets a -10 gravity value) if (IsOnFloor()) { Floor_dect = true; Grav.y = -10; } //Sets the velocity of gravity if the check is negative if (!Floor_dect) { Grav.y -= 30.0f * delta; } //Sets the velocity vector (acceleration coming in the future) Velocity_vect = Direction_vect * 20; //If the dot product of the normalized normal and the Vector 3 that points downwards is -0.5 < or 0.5 > and the player presed jump (aka space) set a variable to jump and change the gravity if ((new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5 || new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5) && Input.IsActionPressed("Player_jump")) { Jumping = true; Grav.y = 10; } //If you were not jumping and you fell from a platform it resets the gravity to 0 for 1 frame if (Floor_dect_PFPS && !Floor_dect && !Jumping) { Grav.y = 0; } //If you were jumping and you touched the floor it reset jumping to false if (!Floor_dect_PFPS && Floor_dect && Jumping) { Jumping = false; } //If the dot product of the normalized normal and the Vector 3 that points downwards is not -0.5 < and not 0.5 > or the Vector_velocity isn't 0 or is jumping, it aplies the movement WITH gravity if (((!(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5) && !(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5)) || Velocity_vect != Vector3.Zero) || Jumping) { MoveAndSlide((Velocity_vect) + Grav, Vector3.Up, true); } Floor_dect_PFPS = Floor_dect; //If you touch the ceiling with a positive y value on gravity and you keep pressing jump you get ""grabed"" on the ceiling, else you bonk if (IsOnCeiling() && Grav.y > 0) { if (Input.IsActionPressed("Player_jump")) { Grav.y = 2; } else { Grav.y = 0; } } }
public override void _Process(float delta) { // Mouse movement. _mouse_motion.y = Clamp(_mouse_motion.y, -1550, 1550); Transform t = GlobalTransform; t.basis = new Basis(new Vector3(0, _mouse_motion.x * -0.001f, 0)); GlobalTransform = t; var htr = head.GlobalTransform; htr.basis = new Basis(new Vector3(_mouse_motion.y * -0.001f, 0, 0)); head.GlobalTransform = htr; // Block selection. var position = raycast.GetCollisionPoint(); var normal = raycast.GetCollisionNormal(); if (Input.IsActionJustPressed("pick_block")) { // Block picking. var block_global_position = (position - normal / 2).Floor(); _selected_block = voxel_world.get_block_global_position(block_global_position); } else { // Block prev/next keys. if (Input.IsActionJustPressed("prev_block")) { _selected_block -= 1; } if (Input.IsActionJustPressed("next_block")) { _selected_block += 1; } _selected_block = Wrap(_selected_block, 1, 30); } // # Set the appropriate texture. var uv = Chunk.calculate_block_uvs(_selected_block); Texture texture = selected_block_texture.Texture; if (texture is AtlasTexture atlasTexture) { atlasTexture.Region = new Rect2(uv[0] * 512, Vector2.One * 64); } // Block breaking/placing. if (crosshair.Visible && raycast.IsColliding()) { var breaking = Input.IsActionJustPressed("break"); var placing = Input.IsActionJustPressed("place"); // Either both buttons were pressed or neither are, so stop. if (breaking == placing) { return; } if (breaking) { var block_global_position = (position - normal / 2).Floor(); voxel_world.set_block_global_position(block_global_position, 0); } else if (placing) { var block_global_position = (position + normal / 2).Floor(); voxel_world.set_block_global_position(block_global_position, _selected_block); } } }
public override void AReady() { PlayerSprite = GetNodeOrNull(new NodePath("PlayerSprite")) as AnimatedSprite3D; ActorDetectorArea = GetNodeOrNull(new NodePath("ActorDetector")) as Area; FloorRayCast = GetNodeOrNull(new NodePath("FloorRayCast")) as RayCast; if (PlayerSprite == null || ActorDetectorArea == null || FloorRayCast == null) { GD.PrintErr("One or multiple required child nodes could not be found! Some features won't work!"); } InputManager = new InputManager(PlayerNumber); StandState = new ActorState(() => { //Enter State SnapToGround = true; }, (float delta) => { //Process State if (Mathf.Abs(Velocity.x) > 0.5f) { PlayerSprite.SetAnimation(PlayerAnimation.WALK); PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 5); } else { PlayerSprite.SetAnimation(PlayerAnimation.IDLE); } }, (float delta) => { //State Physics Processing if (InputManager.DirectionalInput.x != 0) { ChangeState(WalkState); } CanFall(); CanJump(); CanCrouch(); }, () => { //Exit State }); WalkState = new ActorState(() => { //Enter State SetSpeedLimit(WalkSpeed); SnapToGround = true; }, (float delta) => { //Process State if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0) { PlayerSprite.SetAnimation(PlayerAnimation.WALK); PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 5); } else { PlayerSprite.SetAnimation(PlayerAnimation.TURN); } }, (float delta) => { //State Physics Processing if (InputManager.DirectionalInput.x == 0) { ChangeState(StandState); } if (InputManager.RunPressed || InputManager.AltRunPressed) { ChangeState(RunState); } CanFall(); CanJump(); CanCrouch(); float force = InputManager.DirectionalInput.x * WalkAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State }); RunState = new ActorState(() => { //Enter State SetSpeedLimit(RunSpeed); SnapToGround = true; }, (float delta) => { //Process State if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0) { PlayerSprite.SetAnimation(PlayerAnimation.WALK); PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.WALK, (Mathf.Abs(Velocity.x)) + 7); } else { PlayerSprite.SetAnimation(PlayerAnimation.TURN); } }, (float delta) => { //State Physics Processing if (InputManager.DirectionalInput.x == 0) { ChangeState(StandState); } if (!InputManager.RunPressed && !InputManager.AltRunPressed) { ChangeState(WalkState); } if (GetElapsedTimeInState() > LongRunTime) { ChangeState(LongRunState); } CanFall(); CanJump(); CanCrouch(); float force = InputManager.DirectionalInput.x * RunAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State }); LongRunState = new ActorState(() => { //Enter State PlayerSprite.SetAnimation(PlayerAnimation.LONG_RUN); SetSpeedLimit(LongRunSpeed); SnapToGround = true; }, (float delta) => { //Process State if (Mathf.Sign(Velocity.x) == Mathf.Sign(InputManager.DirectionalInput.x) || Velocity.x == 0) { PlayerSprite.SetAnimation(PlayerAnimation.LONG_RUN); PlayerSprite.Frames.SetAnimationSpeed(PlayerAnimation.LONG_RUN, (Mathf.Abs(Velocity.x)) + 10); } else { PlayerSprite.SetAnimation(PlayerAnimation.TURN); } }, (float delta) => { //State Physics Processing if (InputManager.DirectionalInput.x == 0) { ChangeState(StandState); } if (!InputManager.RunPressed && !InputManager.AltRunPressed || Mathf.Sign(Velocity.x) != Mathf.Sign(InputManager.DirectionalInput.x)) { ChangeState(WalkState); } CanFall(); CanJump(); CanCrouch(); float force = InputManager.DirectionalInput.x * LongRunAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State }); JumpState = new ActorState(() => { //Enter State SnapToGround = false; float speed = Mathf.Abs(Velocity.x); if (speed > RunSpeed) { ApplyForce2D(new Vector2(0, LongRunJumpForce)); PlayerSprite.SetAnimation(PlayerAnimation.HIGH_JUMP); } else if (speed > 0.5f) { ApplyForce2D(new Vector2(0, WalkJumpForce)); PlayerSprite.SetAnimation(PlayerAnimation.JUMP); } else if (PreviousState == CrouchState) { ApplyForce2D(new Vector2(0, IdleJumpForce)); PlayerSprite.SetAnimation(PlayerAnimation.CROUCH); SetPlayerCollisionShape(PlayerCollisionShape.SMALL); } else { ApplyForce2D(new Vector2(0, IdleJumpForce)); PlayerSprite.SetAnimation(PlayerAnimation.JUMP); } }, (float delta) => { //Process State //DebugText.Display("P" + PlayerNumber + "_JumpSusTime", "P" + PlayerNumber + " Jump Sustain Time: " + (MaxJumpSustainTime - GetElapsedTimeInState()).ToString()); }, (float delta) => { //State Physics Processing if (IsOnFloor()) { ChangeState(StandState); } if ((!InputManager.JumpPressed && !InputManager.AltJumpPressed) || GetElapsedTimeInState() > MaxJumpSustainTime) { ChangeState(FallState); } if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed)) { SetSpeedLimit(LongRunSpeed); } else if (InputManager.RunPressed || InputManager.AltRunPressed) { SetSpeedLimit(RunSpeed); } else { SetSpeedLimit(WalkSpeed); } //Add some force for extra air time if the jump button is held ApplyForce2D(Vector2.Up, Gravity.y * (1 - JumpSustainGravityMultiplier)); float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State //DebugText.Remove("P" + PlayerNumber + "_JumpSusTime"); SetPlayerCollisionShape(GetDefaultCollisionShape()); }); SpinJumpState = new ActorState(() => { //Enter State SnapToGround = false; PlayerSprite.SetAnimation(PlayerAnimation.SPIN_JUMP); float speed = Mathf.Abs(Velocity.x); if (speed > RunSpeed) { ApplyForce2D(new Vector2(0, LongRunJumpForce)); } else if (speed > 0.5f) { ApplyForce2D(new Vector2(0, WalkJumpForce)); } else if (PreviousState == CrouchState) { ApplyForce2D(new Vector2(0, IdleJumpForce)); } else { ApplyForce2D(new Vector2(0, IdleJumpForce)); } }, (float delta) => { //Process State //DebugText.Display("P" + PlayerNumber + "_JumpSusTime", "P" + PlayerNumber + " Jump Sustain Time: " + (MaxJumpSustainTime - GetElapsedTimeInState()).ToString()); }, (float delta) => { //State Physics Processing if (IsOnFloor()) { ChangeState(StandState); } if ((!InputManager.JumpPressed && !InputManager.AltJumpPressed) || GetElapsedTimeInState() > MaxJumpSustainTime) { ChangeState(FallState); } if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed)) { SetSpeedLimit(LongRunSpeed); } else if (InputManager.RunPressed || InputManager.AltRunPressed) { SetSpeedLimit(RunSpeed); } else { SetSpeedLimit(WalkSpeed); } //Add some force for extra air time if the jump button is held ApplyForce2D(Vector2.Up, Gravity.y * (1 - JumpSustainGravityMultiplier)); float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State //DebugText.Remove("P" + PlayerNumber + "_JumpSusTime"); }); FallState = new ActorState(() => { //Enter State if (InputManager.DirectionalInput.y < CrouchInputThreshold) { PlayerSprite.SetAnimation(PlayerAnimation.CROUCH); SetPlayerCollisionShape(PlayerCollisionShape.SMALL); } else if (PreviousState == SpinJumpState) { PlayerSprite.SetAnimation(PlayerAnimation.SPIN_JUMP); } else { PlayerSprite.SetAnimation(PlayerAnimation.FALL); } SnapToGround = false; }, (float delta) => { //Process State }, (float delta) => { //State Physics Processing if (IsOnFloor()) { if (InputManager.DirectionalInput.y < CrouchInputThreshold) { ChangeState(CrouchState); } else { ChangeState(StandState); } } if (SpeedLimit >= LongRunSpeed && (InputManager.RunPressed || InputManager.AltRunPressed)) { SetSpeedLimit(LongRunSpeed); } else if (InputManager.RunPressed || InputManager.AltRunPressed) { SetSpeedLimit(RunSpeed); } else { SetSpeedLimit(WalkSpeed); } float force = InputManager.DirectionalInput.x * AirHorizontalAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State SetPlayerCollisionShape(GetDefaultCollisionShape()); }); CrouchState = new ActorState(() => { //Enter State SnapToGround = true; var angle = Mathf.Rad2Deg(Mathf.Acos(FloorRayCast.GetCollisionNormal().Dot(FloorNormal))); if (angle >= SlideMinAngle) { ChangeState(SlideState); return; } PlayerSprite.SetAnimation(PlayerAnimation.CROUCH); SetPlayerCollisionShape(PlayerCollisionShape.SMALL); }, (float delta) => { //Process State }, (float delta) => { //State Physics Processing Transform slightlyRight; slightlyRight.origin = Transform.origin; slightlyRight.basis = Transform.basis; slightlyRight.origin.x += 0.4f; Transform slightlyLeft; slightlyLeft.origin = Transform.origin; slightlyLeft.basis = Transform.basis; slightlyLeft.origin.x -= 0.4f; if (!TestMove(Transform, new Vector3(0, 0.5f, 0))) { if (InputManager.DirectionalInput.y >= CrouchInputThreshold) { ChangeState(StandState); } CanJump(); CanFall(); } else if (!TestMove(slightlyRight, new Vector3(0, 0.5f, 0))) { ApplyForce2D(new Vector2(0.4f, 0)); } else if (!TestMove(slightlyLeft, new Vector3(0, 0.5f, 0))) { ApplyForce2D(new Vector2(-0.4f, 0)); } else { if (InputManager.JumpJustPressed || InputManager.AltJumpJustPressed) { ApplyForce2D(new Vector2(CrouchBoostForce.x * InputManager.DirectionalInput.x, CrouchBoostForce.y)); } } }, () => { //Exit State SetPlayerCollisionShape(GetDefaultCollisionShape()); }); SlideState = new ActorState(() => { //Enter State SetSpeedLimit(SlideSpeed); SnapToGround = true; PlayerSprite.SetAnimation(PlayerAnimation.SLIDE); autoPlayerFacing = false; }, (float delta) => { //Process State //Manually flip the sprite according to the movement direction if (Velocity.x > 0) { PlayerSprite.SetFlipH(false); } else if (Velocity.x < 0) { PlayerSprite.SetFlipH(true); } }, (float delta) => { //State Physics Processing Vector3 normal = FloorRayCast.GetCollisionNormal(); float angle = Mathf.Rad2Deg(Mathf.Acos(normal.Dot(FloorNormal))); if (angle < SlideMinAngle) { ChangeState(InputManager.DirectionalInput.y < CrouchInputThreshold ? CrouchState : StandState); } CanFall(); CanJump(); float force = Mathf.Sign(normal.x) * SlideAcceleration; ApplyForce2D(new Vector2(force, 0)); }, () => { //Exit State autoPlayerFacing = true; }); }
public void GroundMove(float delta) { Vector3 wishDir = new Vector3(); if (!_wishJump) { ApplyFriction(1.0f, delta); } else { ApplyFriction(0, delta); } float scale = CmdScale(); wishDir += _pCmd.aim.x * _pCmd.move_right; wishDir -= _pCmd.aim.z * _pCmd.move_forward; wishDir = wishDir.Normalized(); _moveDirectionNorm = wishDir; float wishSpeed = wishDir.Length(); wishSpeed *= _moveSpeed; Accelerate(wishDir, wishSpeed, _runAcceleration, delta); if (_climbLadder) { if (_pCmd.move_forward != 0f) { _playerVelocity.y = _moveSpeed * (_pCmd.cam_angle / 90) * _pCmd.move_forward; } else { _playerVelocity.y = 0; } if (_pCmd.move_right == 0f) { _playerVelocity.x = 0; _playerVelocity.z = 0; } } /*else * { * _playerVelocity.y = 0; * }*/ // walk up stairs if (wishSpeed > 0 && _stairCatcher.IsColliding()) { Vector3 col = _stairCatcher.GetCollisionNormal(); float ang = Mathf.Rad2Deg(Mathf.Acos(col.Dot(_world.Up))); if (ang < _maxStairAngle) { _playerVelocity.y = _stairJumpHeight; } } if (_wishJump && IsOnFloor()) { _playerVelocity.y = _jumpSpeed; _wishJump = false; } }