Beispiel #1
0
    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);
        }
    }
Beispiel #2
0
    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();
        }
    }
Beispiel #3
0
    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());
        }
    }
Beispiel #5
0
    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;
    }
Beispiel #6
0
    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;
        }
    }
Beispiel #7
0
    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);
    }
Beispiel #8
0
    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();
            }
        }
    }
Beispiel #9
0
    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;
            }
        }
    }
Beispiel #11
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);
            }
        }
    }
Beispiel #12
0
    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;
        });
    }
Beispiel #13
0
    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;
        }
    }