I am making a game that runs up infinite stairs.
First, I coded prototype code that can run infinite hallway by manipulating the player's Z position and it works.
Then, I change that code to manipulate the player's Y position.
This is HallWayController
script
void FixedUpdate()
{
this.handleInfiniteHallway();
}
private void handleInfiniteHallway()
{
if (this.isPlayerOutOfBounds())
{
float posYmod = HALLWAY_HEIGHT;
if (this.player.position.y > MAX_Y_BOUND)
{
posYmod *= -1;
}
this.player.position = new Vector3(this.player.position.x, this.player.position.y posYmod, this.player.position.z);
Debug.Log("Player Y position: " this.player.position.y);
}
}
private bool isPlayerOutOfBounds()
{
return this.player.position.y > MAX_Y_BOUND || this.player.position.y < MIN_Y_BOUND;
}
With this code, the game malfunctions just like the player have two Y position simultaneously.
What I found:
- If I use
FixedUpdate()
, the player's position doesn't change on game play view, butdebug.Log
says player Y Position has changed. And if player ever reachedY_Bound
, code insideif(this.isPlayterOutOfBounds())
infinitely executes. - If I use
Update()
instead ofFixedUpdate()
, the player's position does change in game play view anddebug.Log
, but sometimes the player flashes back and forth between the original position and repositioned position. And if player ever reachedY_Bound
code insideif(this.isPlayterOutOfBounds())
infinitely executes.
This is Player Controller
script that linked to the player game object
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
[SerializeField] private float playerSpeed = 10.0f;
[SerializeField] private float jumpHeight = 1.0f;
[SerializeField] private float gravityValue = -9.81f;
private bool isFlashLightOn = true;
public GameObject lightSource;
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
private InputManager inputManager;
private Transform cameraTransform;
private void Start()
{
controller = gameObject.GetComponent<CharacterController>();
inputManager = InputManager.Instance;
cameraTransform = Camera.main.transform;
lightSource.gameObject.SetActive(true);
isFlashLightOn = true;
}
void FixedUpdate()
{
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
Vector2 movement = inputManager.GetPlayerMovement();
Vector3 move = new Vector3(movement.x, 0, movement.y);
move = cameraTransform.forward * move.z cameraTransform.right * move.x;
move.y = 0f;
controller.Move(move * Time.deltaTime * playerSpeed);
// Changes the height position of the player..
if (inputManager.PlayerJumped() && groundedPlayer)
{
playerVelocity.y = Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
playerVelocity.y = gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
void Update()
{
if (inputManager.PlayerFlashLightOn())
{
isFlashLightOn = !isFlashLightOn;
lightSource.gameObject.SetActive(isFlashLightOn);
}
}
}
CodePudding user response:
Hmm, I think I quess what is the problem here. See comments I added
// You may call this twice on each frame, depending on your frame rate
void FixedUpdate()
{
this.handleInfiniteHallway();
}
private void handleInfiniteHallway()
{
if (this.isPlayerOutOfBounds())
{
// Problem is probably here. When your object hits another limit, you move it all HALLWAY_HEIGHT, so it hits another limit
// If you move just half of the height, your character returns to the middle.
// Original float posYmod = HALLWAY_HEIGHT;
float posYmod = HALLWAY_HEIGHT / 2;
if (this.player.position.y > MAX_Y_BOUND)
{
posYmod *= -1;
}
this.player.position = new Vector3(this.player.position.x, this.player.position.y posYmod, this.player.position.z);
Debug.Log("Player Y position: " this.player.position.y);
}
}
private bool isPlayerOutOfBounds()
{
return this.player.position.y > MAX_Y_BOUND || this.player.position.y < MIN_Y_BOUND;
}
If you call FixedUpdate method, it is run twice a frame so position is moved back and forth during one frame. Update method would be called each frame player is jumping between borders.