#A problem confusing me for a long time

1 messages · Page 1 of 1 (latest)

ebon trench
#

I made a demo in Unity where I placed an empty GameObject near a door, added a Box Collider to it, and set it as a trigger so that I can detect OnTriggerEnter. When the player moves into this collider, I use SceneManager to load a target scene and move the player to a predefined spawn point in that scene (the spawn point is an empty GameObject in the target scene, and the player is positioned at that object’s transform).

In the Unity Editor and in the built executable on my own computer, scene transitions work correctly. However, after I sent the built .exe to my friends, they reported that when the player approaches the door, the player does not appear at the correct spawn point. Instead, the player sometimes appears in a location without a floor and falls downward.

I have three questions and would appreciate any help:

Why does the player sometimes fail to land exactly at the spawn point?
This seems to be a probabilistic issue and happens very randomly. Sometimes the player spawns correctly, and sometimes an error occurs. (The exact behavior can be seen in the video.)

Why does everything work perfectly in the Unity Editor and in the built executable on my own computer, even after entering and exiting the room 20 times, but consistently fails on my friends’ computers?

Why does the player appear to be floating and not tightly attached to the ground, even though I apply gravity in my code?

#

The following script is attached to the empty GameObject near the door. As soon as the player enters this trigger, it loads the target scene using SceneManager. In the Unity Editor, the debug logs show that other.transform.position and spawnPoint.transform.position are identical:```using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

public class DoorTrigger : MonoBehaviour
{
public string targetSceneName;
public string spawnPointName;

public PlayerMovement playerMovement;

public bool debugLog = true;

void Update()
{
    if (playerMovement == null)
    {
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if (player != null)
        {
            playerMovement = player.GetComponent<PlayerMovement>();
        }
    }
}

private void OnTriggerEnter(Collider other)
{
    if (!other.CompareTag("Player")) return;

    playerMovement.canMove = false;

    GameObject player = other.gameObject;

    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(targetSceneName);
    asyncLoad.completed += (operation) =>
    {
        GameObject spawnPoint = GameObject.Find(spawnPointName);
        if (spawnPoint == null)
        {
            return;
        }

        playerMovement.canMove = true;

        player.transform.position = spawnPoint.transform.position;
        player.transform.rotation = spawnPoint.transform.rotation;

        Debug.Log("player.position: " + other.transform.position);
        Debug.Log("spawnPoint.position: " + spawnPoint.transform.position);
    };
}

}

#

On the player GameObject, I have:

An Animator to control animations

A CharacterController, where I adjusted the collider shape and center

The Step Offset value is relatively large because the scale of my player model and environment models is not consistent. I need a larger step offset for the player to climb stairs smoothly.

The PlayerMovement script, which controls movement and gravity, with speed values configured in the Inspector

On the empty GameObject near the door, I only attached:

A BoxCollider (set as Trigger)

The DoorTrigger script

In DoorTrigger, I specify the target scene name and the spawn point name that the player should appear at after the scene loads.

Any insights into what might be causing this behavior would be greatly appreciated.

#

Below is the script that controls player movement. I am using a CharacterController to move the player:

silk flame
#

Find is non-deterministic if there's more than one object that it could find, that would be the only obvious cause. Using Find is not recommended in general

simple nacelle
#

you have to change many things

#
  void Update()
    {
        if (playerMovement == null)
        {
            GameObject player = GameObject.FindGameObjectWithTag("Player");
            if (player != null)
            {
                playerMovement = player.GetComponent<PlayerMovement>();
            }
        }
    }

you can delete everything here and assign the Player / PlayerMovement via inspector
a SerializeField is enough for this

[SerializeField] PlayerMovement playermovement; // assig the script from the inspector
#

then for the player spawning you can make things much easier. Just have the player on the right spot you want, when you lead the new scene the player will already be present

#

this should fix the problem with the spawn position

ebon trench
#

Root Cause:
The player movement script contained a function that applies gravity to the player. During the scene switching process via SceneManager, this gravity function was not disabled. As a result, the player continued to be affected by gravity while transitioning between scenes, causing them to fall prematurely before reaching the intended spawn point in the target scene.

ebon trench