winstxnhdw / lc-hax

A powerful, feature-rich and highly performant internal cheat for the co-op indie horror video game, Lethal Company.
77 stars 25 forks source link

[Bug]: Possession Jump #373

Closed D1GQ closed 4 months ago

D1GQ commented 4 months ago

It seems there's a bug right now for possession where sometimes you just don't jump when you click spacebar, it has something to do how the velocity is handled. This seems to fix it.

Code:

using UnityEngine;
using GameNetcodeStuff;
using UnityEngine.InputSystem;
using Hax;

internal class CharacterMovement : MonoBehaviour {
    // Movement constants
    const float BaseSpeed = 5.0f;
    const float SprintSpeedMultiplier = 2.8f; // Multiplier for sprinting speed
    const float WalkingSpeed = 0.5f; // Walking speed when left control is held
    const float SprintDuration = 0.0f; // Duration sprint key must be held for sprinting (adjust as needed)
    const float JumpForce = 9.2f;
    const float Gravity = 18.0f;
    const float MaxVelocityMagnitude = 15.0f; // Adjust as needed

    // used to sync with the enemy to make sure it plays the correct animation when it is moving
    public bool IsMoving { get; private set; } = false;
    public bool IsSprinting { get; private set; } = false;

    // Components and state variables
    CharacterController CharacterController { get; set; }
    float VelocityY { get; set; } = 0.0f;
    bool IsSprintHeld { get; set; } = false;
    float SprintTimer { get; set; } = 0.0f;
    Keyboard Keyboard { get; set; } = Keyboard.current;

    // Adjust collision box in Awake
    const float AdjustedWidth = 0.0f; // Adjust as needed
    const float AdjustedHeight = 0.0f; // Adjust as needed
    const float AdjustedDepth = 0.0f; // Adjust as needed

    Vector3 velocity;

    internal CharacterMovement() => this.CharacterController = this.GetComponent<CharacterController>();

    // Initialize method
    internal void Init() {
        if (Helper.LocalPlayer is not PlayerControllerB localPlayer) return;
        this.gameObject.layer = localPlayer.gameObject.layer;
    }

    void Awake() {
        this.Keyboard = Keyboard.current;
        this.CharacterController = this.gameObject.AddComponent<CharacterController>();
        this.CharacterController.height = 0.0f; // Adjust as needed
        this.CharacterController.center = new Vector3(0f, 0.3f, 0.5f); // Adjust as needed

        this.transform.localScale = new Vector3(
            CharacterMovement.AdjustedWidth,
            this.transform.localScale.y,
            CharacterMovement.AdjustedDepth
        );
    }

    // Update is called once per frame
    void Update() {
        // Read movement input from keyboard
        Vector2 moveInput = new Vector2(
            this.Keyboard.dKey.ReadValue() - this.Keyboard.aKey.ReadValue(),
            this.Keyboard.wKey.ReadValue() - this.Keyboard.sKey.ReadValue()
        ).normalized;

        this.IsMoving = moveInput.magnitude > 0.0f;

        // Apply speed modifier based on left control key
        float speedModifier = 1.0f;

        if (this.Keyboard.leftCtrlKey.isPressed) {
            speedModifier = WalkingSpeed;
        }

        // Calculate movement direction relative to character's forward direction
        Vector3 forward = Vector3.ProjectOnPlane(this.transform.forward, Vector3.up);
        Vector3 right = Vector3.ProjectOnPlane(this.transform.right, Vector3.up);
        Vector3 moveDirection = (forward * moveInput.y) + (right * moveInput.x);

        // Apply speed and sprint modifiers
        moveDirection *= speedModifier * (
            this.IsSprinting
                ? CharacterMovement.BaseSpeed * CharacterMovement.SprintSpeedMultiplier
                : CharacterMovement.BaseSpeed
            );

        // Apply gravity
        this.ApplyGravity();

        // Attempt to move
        _ = this.CharacterController.Move(moveDirection * Time.deltaTime);

        // Jump if jump key is pressed
        if (this.Keyboard.spaceKey.wasPressedThisFrame) {
            this.Jump();
        }

        // Sprinting mechanic: Hold to sprint
        if (this.Keyboard.leftShiftKey.isPressed) {
            if (!this.IsSprintHeld) {
                this.SprintTimer = 0f;
                this.IsSprintHeld = true;
            }

            if (!this.IsSprinting && this.SprintTimer >= CharacterMovement.SprintDuration) {
                this.IsSprinting = true;
            }

            this.SprintTimer += Time.deltaTime;
        }

        else {
            this.IsSprintHeld = false;

            if (this.IsSprinting) {
                this.IsSprinting = false;
            }
        }
    }

    // Apply gravity to the character controller
    void ApplyGravity() {
        if (!CharacterController.isGrounded) {
            velocity.y -= Gravity * Time.deltaTime;
        }
        else if (velocity.y < 0) {
            velocity.y = 0f;
        }
        Vector3 motion = velocity * Time.deltaTime;
        _ = CharacterController.Move(motion);
    }

    // Jumping action
    void Jump() {
        velocity.y = JumpForce;
    }
}
winstxnhdw commented 4 months ago

I can't actually tell which part is changed.

D1GQ commented 4 months ago

I can't actually tell which part is changed.

    Vector3 velocity;

    // Apply gravity to the character controller
    void ApplyGravity() {
        if (!CharacterController.isGrounded) {
            velocity.y -= Gravity * Time.deltaTime;
        }
        else if (velocity.y < 0) {
            velocity.y = 0f;
        }
        Vector3 motion = velocity * Time.deltaTime;
        _ = CharacterController.Move(motion);
    }

    // Jumping action
    void Jump() {
        velocity.y = JumpForce;
    }
}
D1GQ commented 4 months ago

There's also an issue where if you look up or down you clip through the map because of the Collision box decrease.

winstxnhdw commented 4 months ago

Hmm, maybe setting it to 0.01f will help?

D1GQ commented 4 months ago

Nope, A possible fix is to make it where when you first possess your Collision box is zero then it increases it after a second

winstxnhdw commented 4 months ago

Aha.

winstxnhdw commented 4 months ago

There doesn't seem to be a logical difference between your changed code and mine and I can't replicate the issue where jumps are not working.

winstxnhdw commented 4 months ago

Seems fine now.

winstxnhdw commented 4 months ago

If there are no issues, I'll close this tomorrow.

D1GQ commented 4 months ago

I think the possession mod is getting close to be perfect, the only issue I know of now is the issue when you possess another enemy there's a chance that you teleport from the previous enemies location.

winstxnhdw commented 4 months ago

I haven't gotten that issue yet either, but I'll look into it.

D1GQ commented 4 months ago

I haven't gotten that issue yet either.

It seems that it happens more when you switch to another enemy while you're possessing one

winstxnhdw commented 4 months ago

I tried that a few times between a giant and bee, and I am still not getting it.

D1GQ commented 4 months ago

I tried that a few times between a giant and bee, and I am still not getting it.

here https://streamable.com/amod9a

winstxnhdw commented 4 months ago

Is it not possible that Lethal Menu is causing this problem instead?

D1GQ commented 4 months ago

Okay, I am finally getting the problem too.

And I think I know what might be the problem, when I implemented a Teleport system for myself to teleport to the previous spot sometimes it wouldn't work until a couple tries, so it seems that the game is for some reason not letting the player location change for a sec.

D1GQ commented 4 months ago

Hey this is completely off topic but I'm curious do you think there is a way to override control company with possession? Like I remember being able to do it back then but it was very buggy because of the host despawned the enemy it would break everything, but now you just can't take control I'm curious if that is because of a change that we made or a change that was made in control company.

winstxnhdw commented 4 months ago

I am not sure about you, but I am still able to take control of enemies that are being controlled by Control Company. The enemy position is de-synced but I am able to attack players.

D1GQ commented 4 months ago

I am not sure about you, but I am still able to take control of enemies that are being controlled by Control Company. The enemy position is de-synced but I am able to attack players.

Mmm ok, If I get another opportunity I'll try again.

winstxnhdw commented 4 months ago

I’ll be closing it. The teleport bug is fixed in latest by @LTYGUY. It seems most of the issues came from using CharacterController :/ Maybe sticking with RigidbodyController would’ve been a better choice.