Search code examples
c#unity-game-enginenavmesh

My player character on load saved position falls of box


You can see on youtube video, that my character falls down after load. And I want to know why? https://youtu.be/_CKNaYBxvhQ?t=1 When i save player position the loaded position is same. Fall happens after load position.

here is whole project thx for download and respond whole project

This problem occured in first map(the player was falling down the platform). So I reproduced simple map with one platform and I used minimum code to move player and Save with Load but the problem was reproduced. Falling down is only from platform where does not lead navmesh path down.

I tried add walls to stop player fall down the box, but player goes through this walls.

using UnityEngine;
using UnityEngine.AI;
using System.Collections;
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine.SceneManagement;

public class PlayerController : MonoBehaviour
{
    public Camera camera2;
    public NavMeshAgent agent;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            Ray ray = camera2.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if(Physics.Raycast(ray, out hit))
            {
                agent.SetDestination(hit.point);
            }
        }
    }
 public void Save()
 {
     BinaryFormatter bf = new BinaryFormatter();
     FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.dat");

     PlayerData data = new PlayerData();
     data.x = transform.position.x;
     data.y = transform.position.y;
     data.z = transform.position.z;

     bf.Serialize(file, data);
     file.Close();
 }

 public void Load()
 {
     //SceneManager.LoadScene("enfos");
     if (File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
     {
         BinaryFormatter bf = new BinaryFormatter();
         FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
         PlayerData data = (PlayerData)bf.Deserialize(file);
         file.Close();

         transform.position = new Vector3(data.x, data.y, data.z);
         //transform.position = tempPos;
     }
 }

 //public delegate void SerializeAction();
 //public static event SerializeAction OnLoaded; was never used can be deleted works same

 void OnEnable()
 {
     //        Debug.Log("PrintOnEnable: script was enabled");
     Load();
 }

[Serializable]
public class PlayerData
{
    public float x;
    public float y;
    public float z;
}

Player has Capsule Collider, Rigidbody, NavMesh Agent and Player Controller Script. PlayerProperties

On button Menu the position of player is saved and new scene with Canvas and button displayed. On that button previous scene displayed. OnEnable load the player position.

I need the player load properly and stay on saved position. Please try to help me its my dream to make games. If you dont understand ask.


Solution

  • Add agent.Warp(transform.position); after Load();

    Since you're reloading the scene, the NavMeshAgent has the scene's starting position for the player as where it thinks it should be.

    So, when you load the position of the agent (by the way, consider saving its rotation too), the NavMeshAgent sees that it should be somewhere different than it is and it tries its best to compromise, which results in the different placement than where it was loaded.

    So, in order to avoid this, you need to tell the NavMeshAgent to change its state of where it should be, and that can be done with the Warp(Vector3 position) method:

    void OnEnable()
    {
        Load();
        agent.Warp(transform.position);
    }