Home > Blockchain >  How to fix this glitch where the player snaps right back to the previous position
How to fix this glitch where the player snaps right back to the previous position

Time:07-25

I am making a game in unity, I want it so that when the user switched modes (can be done by pressing b), that the player in the game goes to the startposition.

There are two important scripts in this problem: PlayerMotor, which controls the movement of the player. There is also the SwitchModes script, which switches the modes. There are two modes, exploring and building. When switching to the exploring mode I want the player to go to the startPosition. When going back to the building mode, the player should go back to the position where he originally was.

Unfortunately, there was a problem when going to the startPosition, as you can see in the code down below, the player should go to the startPosition when switching to exploring mode. But this is what happens when I run this code:

https://streamable.com/0coe34

As you can see the player switches to the right position for like 1 frame. I don't know why this happens, so can anyone explain to me why this doesn't work?

Here is the code:

https://paste.myst.rs/vgdupxih

Here is it in a raw version:

PlayerMotor

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMotor : MonoBehaviour
{
    private CharacterController controller;
    public Vector3 playerVelocity;
    public float speed = 5f;
    public bool isGrounded;
    public float gravity = -9.8f;
    public float jumpHeight = 1.5f;

    private bool lerpCrouch;
    private bool crouching;
    //private bool sprinting;
    private float crouchTimer;
    // Start is called before the first frame update
    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        isGrounded = controller.isGrounded;
        if (lerpCrouch)
        {
            crouchTimer  = Time.deltaTime;
            float p = crouchTimer / 1;
            p *= p;
            if (crouching)
                controller.height = Mathf.Lerp(controller.height, 1, p);
            else
                controller.height = Mathf.Lerp(controller.height, 2, p);

            if (p > 1)
            {
                lerpCrouch = false;
                crouchTimer = 0f;
            }
        }
    }
    public void Crouch()
    {
        crouching = !crouching;
        crouchTimer = 0;
        lerpCrouch = true;
    }
    //public void Sprint()
    //{
    //    sprinting = !sprinting;
    //    if (sprinting)
    //        speed = 15;
    //    else
    //        speed = 5;
    //}
    public void ProcessMove(Vector2 input)
    {
        Vector3 moveDirection = Vector3.zero;
        moveDirection.x = input.x;
        moveDirection.z = input.y;
        controller.Move(transform.TransformDirection(moveDirection) * speed * Time.deltaTime);
        playerVelocity.y  = gravity * Time.deltaTime;
        if (isGrounded && playerVelocity.y < 0)
            playerVelocity.y = -2f;
        controller.Move(playerVelocity * Time.deltaTime);

    }
    public void Jump()
    {
        if (isGrounded)
        {
            playerVelocity.y = Mathf.Sqrt(jumpHeight * -3.0f * gravity);
        }
    }
}

SwitchModes

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwitchModes : MonoBehaviour
{
    private string mode;
    private InputManager inputManager;

    [Header("Exploring")]
    public GameObject exploringUI;

    [Header("Building")]
    public GameObject buildingUI;

    private Vector3 buildingPosition;

    private string activemode;

    void Start()
    {
        inputManager = GetComponent<InputManager>();
        activemode = "building";
    }

    void Update()
    {
        if (inputManager.onFoot.SwitchModes.triggered)
        {
            SwitchMode();
        }

        if (activemode == "exploring")
        {
            Exploring();
        }
        else if (activemode == "building")
        {
            Building();
        }
        else
        {
            Debug.Log("the code is completely fucked up, give up");
        }
    }

    public void SwitchMode()
    {
        if (activemode == "building")
        {
            buildingPosition = transform.position;
            Vector3 startPosition = GetComponent<PlaceEntriesAndExits>().placedStartPosition;
            transform.position = new Vector3(startPosition.x, transform.position.y, startPosition.z);
            activemode = "exploring";


        }
        else if (activemode == "exploring")
        {
            //transform.position = buildingTransform.position;
            //transform.rotation = buildingTransform.rotation;
            //transform.localScale = buildingTransform.localScale;

            activemode = "building";
        }
    }

    public void Exploring()
    {
        exploringUI.SetActive(true);
        buildingUI.SetActive(false);

        GetComponent<Building>().buildModelList[GetComponent<Building>().currentSelectedBuild].SetActive(false);
        GetComponent<Exploring>().enabled = true;
        GetComponent<Building>().enabled = false;
    }
    public void Building()
    {
        exploringUI.SetActive(false);
        buildingUI.SetActive(true);

        GetComponent<Exploring>().enabled = false;
        if (GetComponent<PlaceEntriesAndExits>().endPlaced)
        {
            GetComponent<Building>().enabled = true;
            GetComponent<PlaceEntriesAndExits>().enabled = false;
        }
        else
        {
            GetComponent<PlaceEntriesAndExits>().enabled = true;

            GetComponent<Building>().enabled = false;
        }
    }
}

CodePudding user response:

Disable the character controller the frame you're switching mode, and enable it the next frame.

  • Related