I’m using Unity with Edgar procedural level generator and First Person Shooter Engine (FPSEngine).
My player prefab hierarchy looks like this:
PlayerContainer (root prefab, untagged) -> PlayerSubContainer -> Player (tagged "Player", contains CharacterController, camera, and movement scripts)
Логика:
При запуске сцены генерируется уровень. Работает нормально. < /P>
Когда игрок достигает конца уровня, триггер начинает регенерацию уровня (без перезагрузки сцены). < /P>
Если игрок уже существует, я перемещаю Playercontainer в новую Spawnpoint. Локальное смещение с предыдущего уровня. < /p>
Несмотря на то, что я перемещаю PlayerContainer в правильную позицию, видимая камера и контроллер кажутся смещенными (смещенными), потому что игрок сохраняет свое локальное положение от предыдущего прогона. LocalPosition to (0, 0, 0) < /p>
Держите стабильный контроллер игрока < /p>
Предотвратить мгновенный характер или другие скрипты.public override void Run(DungeonGeneratorLevelGrid3D level)
{
Vector3 spawnPos = PlayerPosition(level); // позиция игрока при старте
Vector3 direction = PlayerRotation(level) - spawnPos; // направление куда игрок смотрит
direction.y = 0;
Quaternion rotation = Quaternion.LookRotation(direction); // ставим кватернион на направление
GameObject existingPlayer
= GameObject.FindGameObjectWithTag("PlayerContainer");
GameObject cameraObj;
if (existingPlayer == null)
{
Debug.Log("Instantiate Player");
Debug.Log(spawnPos);
Instantiate(player, spawnPos, Quaternion.identity);
}
else
{
Debug.Log("Change Player Position");
Debug.Log(spawnPos);
// GameObject playerSub = GameObject.FindGameObjectWithTag("Player");
// playerSub.transform.localPosition = new Vector3(0, 1, 0);
// playerSub.transform.position = new Vector3(0, 1, 0); - Doesn't Work
existingPlayer.transform.SetPositionAndRotation(spawnPos, Quaternion.identity);
existingPlayer.GetComponent().ChangePlayerSubPos();
}
}
< /code>
regenerate.cs:
private IEnumerator GenerateNewLevel()
{
GameObject playerContainer = GameObject.FindWithTag("PlayerContainer");
GameObject player = GameObject.FindWithTag("Player");
Rigidbody playerRb = player.GetComponent();
yield return null; // waiting 1 frame
player.transform.localPosition = new Vector3(0, 1, 0);
player.transform.position = new Vector3(0, 1, 0);
yield return null;
DungeonGeneratorGrid3D generator =
GameObject.FindWithTag("Level Generator")?.GetComponent();
yield return null;
if (generator != null)
generator.Generate();
yield return new WaitForSeconds(0.1f);
}
< /code>
Также я попробовал это: < /p>
private IEnumerator GenerateNewLevel()
{
GameObject playerContainer = GameObject.FindWithTag("PlayerContainer");
GameObject player = GameObject.FindWithTag("Player");
Rigidbody playerRb = player.GetComponent();
yield return null;
playerRb.isKinematic = true;
foreach (var component in player.GetComponents()) // Disable all components
{
if (component is Behaviour behaviour)
behaviour.enabled = false;
else if (component is Collider collider)
collider.enabled = false;
else if (component is Rigidbody rb)
rb.isKinematic = true; // отключать нельзя, но можно "заморозить"
}
foreach (var component in player.GetComponents()) // And all Behaviours as a precaution
{
component.enabled = false;
}
yield return new WaitForSeconds(0.01f);
player.transform.localPosition = new Vector3(0, 1, 0);
player.transform.position = new Vector3(0, 1, 0);
yield return new WaitForSeconds(0.01f);
DungeonGeneratorGrid3D generator =
GameObject.FindWithTag("Level Generator")?.GetComponent();
yield return new WaitForSeconds(0.01f);
playerRb.isKinematic = false;
foreach (var component in player.GetComponents())
{
if (component is Behaviour behaviour)
behaviour.enabled = true;
else if (component is Collider collider)
collider.enabled = true;
else if (component is Rigidbody rb)
rb.isKinematic = false; // отключать нельзя, но можно "заморозить"
}
foreach (var component in player.GetComponents())
{
component.enabled = true;
}
yield return new WaitForSeconds(0.01f);
if (generator != null)
generator.Generate();
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... -fpsengine