Как сбросить локальную позицию для детей после перемещения Parent Prefab? (Установка FPSengine)C#

Место общения программистов C#
Ответить
Anonymous
 Как сбросить локальную позицию для детей после перемещения Parent Prefab? (Установка FPSengine)

Сообщение Anonymous »

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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»