NeisesMike / VehicleFramework

a new vehicle for Subnautica
GNU General Public License v3.0
4 stars 1 forks source link

Problem with creating an vehicle. #37

Open BlazeYTTT opened 2 months ago

BlazeYTTT commented 2 months ago

Hey! Can you help me with my error?

I tried to create vehicle on vehicleFramework, but after my hourly work i see this error in BeplnEx log

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
Radical.EnsureComponent[T] (UnityEngine.GameObject obj) (at <aafb86ac724b47ddb09cd2e6deee2370>:0)
vehicle.MainPatcher+<Register>d__2.MoveNext () (at <08a8715dc5824d04908e1cea0ae04c7a>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <bd0d47c27bd84106afaaecc2c74cdb94>:0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
UWE.CoroutineHost:StartCoroutine(IEnumerator)
vehicle.MainPatcher:Start()

I think problem with MainPatcher.cs, but i can't find it :/

My MainPatcher.cs

using HarmonyLib;
using BepInEx;
using System.IO;
using System.Reflection;
using System.Collections;
using VehicleFramework.VehicleTypes;
using VehicleFramework;

namespace vehicle
{
    [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
    [BepInDependency(VehicleFramework.PluginInfo.PLUGIN_GUID)]
    public class MainPatcher : BaseUnityPlugin
    {
        public void Awake()
        {
            vehicle.GetAssets();
        }
        public void Start()
        {
            var harmony = new Harmony(PluginInfo.PLUGIN_GUID);
            harmony.PatchAll();
            string modFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            UWE.CoroutineHost.StartCoroutine(Register());
        }

        public static IEnumerator Register()
        {
            Submersible nowcub = vehicle.model.EnsureComponent<vehicle>() as Submersible;
            yield return UWE.CoroutineHost.StartCoroutine(VehicleRegistrar.RegisterVehicle(nowcub));

        }
    }
}

My vehicle.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.U2D;
using VehicleFramework;
using VehicleFramework.VehicleParts;
using VehicleFramework.VehicleTypes;
using System.Reflection;

namespace vehicle
{
    public class vehicle : Submersible
    {
        public static GameObject model = null;
        public static void GetAssets()

        {

             string modPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
             var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(modPath, "vehicle"));
             if (myLoadedAssetBundle == null)
             {
              return;
             }

            System.Object[] arr = myLoadedAssetBundle.LoadAllAssets();
            foreach (System.Object obj in arr)
            {
                if (obj.ToString().Contains("MY_SPRITE_ATLAS_NAME"))
                {
                    model = (GameObject)obj;
                }
            }
         }

        public override VehiclePilotSeat PilotSeat
        {
            get
            {
                VehicleFramework.VehicleParts.VehiclePilotSeat v95 = new VehicleFramework.VehicleParts.VehiclePilotSeat();
                Transform mainSeat = transform.Find("PilotSeat");
                v95.Seat = mainSeat.gameObject;
                v95.SitLocation = mainSeat.gameObject;
                v95.LeftHandLocation = mainSeat;
                v95.RightHandLocation = mainSeat;
                return v95;
            }

        }

        public override List<VehicleHatchStruct> Hatches

        {
            get
            {
                var list = new List<VehicleFramework.VehicleParts.VehicleHatchStruct>();

                VehicleFramework.VehicleParts.VehicleHatchStruct v96 = new VehicleFramework.VehicleParts.VehicleHatchStruct();
                Transform mainDoor = transform.Find("Hatch");
                v96.Hatch = mainDoor.gameObject;
                v96.ExitLocation = mainDoor.Find("ExitLocation");
                v96.SurfaceExitLocation = mainDoor.Find("ExitLocation");
                list.Add(v96);
                return list;
            }

        }

        public override GameObject VehicleModel
        {
            get
            {
                return model;
            }

        }

        public override GameObject CollisionModel

        {
            get
            {
                return transform.Find("CollisionModel").gameObject;
            }

        }

        public override GameObject StorageRootObject
        {
            get
            {
                return transform.Find("StoragesRoot").gameObject;
            }

        }

        public override GameObject ModulesRootObject
        {
            get
            {
                return transform.Find("ModulesRoot").gameObject;
            }

        }

        public override List<VehicleStorage> InnateStorages => null;

        public override List<VehicleStorage> ModularStorages => null;

        public override List<VehicleUpgrades> Upgrades => null;

        public override List<VehicleBattery> Batteries
        {
            get
            {
                var list = new List<VehicleFramework.VehicleParts.VehicleBattery>();

                VehicleFramework.VehicleParts.VehicleBattery v61 = new VehicleFramework.VehicleParts.VehicleBattery();
                v61.BatterySlot = transform.Find("Battaries/Battary1").gameObject;
                list.Add(v61);

                VehicleFramework.VehicleParts.VehicleBattery v62 = new VehicleFramework.VehicleParts.VehicleBattery();
                v61.BatterySlot = transform.Find("Battaries/Battary2").gameObject;
                list.Add(v62);

                return list;
            }

        }

        public override List<VehicleFloodLight> HeadLights => null;

        public override List<GameObject> WaterClipProxies

        {
            get
            {
                var list = new List<GameObject>();
                foreach (Transform child in transform.Find("WaterClipProxies"))
                {
                    list.Add(child.gameObject);
                }
                return list;
            }

        }

        public override List<GameObject> CanopyWindows

        {
            get
            {
                var list = new List<GameObject>();
                list.Add(transform.Find("CanopyWindows").gameObject);
                return list;
            }

        }

        public override GameObject BoundingBox
        {
            get
            {
                return transform.Find("BoundingBox").gameObject;
            }

        }

        public override Dictionary<TechType, int> Recipe => null;

        public override Atlas.Sprite PingSprite => null;

        public override string Description => "Тестовая субмарина";

        public override string EncyclopediaEntry => "Тестовая субмарина";

        public override int BaseCrushDepth => 200;

        public override int MaxHealth => 500;

        public override int Mass => 5000;

        public override int NumModules => 4;

        public override bool HasArms => false;
    }
}

My PluginInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace vehicle
{
    public static class PluginInfo
    {
        public const string PLUGIN_GUID = "com.blazik.subnautica.vehicle.mod";
        public const string PLUGIN_NAME = "vehicle";
        public const string PLUGIN_VERSION = "0.0.1";
    }
}

My unity project:

https://drive.google.com/file/d/1CArYDcTt4cv6UYMN-aigg-5CiFRjF-3E/view?usp=sharing

P.S Sorry for my eng

NeisesMike commented 2 months ago

Hi, it looks to me like your GetAssets method might be the problem. I think it is not correctly retrieving your model prefab. For that reason, I think vehicle.model is null when Register is invoked

Submersible nowcub = vehicle.model.EnsureComponent<vehicle>() as Submersible;

causing the error in the log:

NullReferenceException: Object reference not set to an instance of an object Stack trace: Radical.EnsureComponent

I think the fix should be in here:

            System.Object[] arr = myLoadedAssetBundle.LoadAllAssets();
            foreach (System.Object obj in arr)
            {
                if (obj.ToString().Contains("MY_SPRITE_ATLAS_NAME"))
                {
                    model = (GameObject)obj;
                }
            }

Perhaps like this:

            System.Object[] arr = myLoadedAssetBundle.LoadAllAssets();
            foreach (System.Object obj in arr)
            {
                if (obj.ToString().Contains("MY_CORRECTED_PREFAB_NAME"))
                {
                    VehicleFramework.Logger.Log("Found the prefab!");
                    model = (GameObject)obj;
                }
            }
BlazeYTTT commented 2 months ago

Thank You! But i have another error (0-0)

[Error  :VehicleFramework] vehicle:  A null VehicleBattery.BatterySlot was provided. There would be no way to access this battery.
[Error  :VehicleFramework] Invalid Submersible Registration for the vehicle. Next.

But the battery slots are correctly setted up (probably) Class with battaries

        public override List<VehicleBattery> Batteries
        {
            get
            {
                var list = new List<VehicleFramework.VehicleParts.VehicleBattery>();

                VehicleFramework.VehicleParts.VehicleBattery v61 = new VehicleFramework.VehicleParts.VehicleBattery();
                v61.BatterySlot = transform.Find("Battaries/Battary1").gameObject;
                list.Add(v61);

                VehicleFramework.VehicleParts.VehicleBattery v62 = new VehicleFramework.VehicleParts.VehicleBattery();
                v61.BatterySlot = transform.Find("Battaries/Battary2").gameObject;
                list.Add(v62);

                return list;
            }

        }

Unity gameobject Screenshot:

(159)

Pls help me, im really dont know what happend.

NeisesMike commented 1 month ago

Hi, it looks like a simple fix. Sorry for the delayed reply. You sent this:

public override List<VehicleBattery> Batteries
{
    get
    {
        var list = new List<VehicleFramework.VehicleParts.VehicleBattery>();

        VehicleFramework.VehicleParts.VehicleBattery v61 = new VehicleFramework.VehicleParts.VehicleBattery();
        v61.BatterySlot = transform.Find("Battaries/Battary1").gameObject;
        list.Add(v61);

        VehicleFramework.VehicleParts.VehicleBattery v62 = new VehicleFramework.VehicleParts.VehicleBattery();
        v61.BatterySlot = transform.Find("Battaries/Battary2").gameObject; // error is here!
        list.Add(v62);

        return list;
    }
}

So I think you should change this to reference the right VehicleBattery (v62 instead of v61).

v61.BatterySlot = transform.Find("Battaries/Battary2").gameObject;

Make it look like this instead:

v62.BatterySlot = transform.Find("Battaries/Battary2").gameObject;

That's an easy mistake to make, and I've made it many times :-)

BlazeYTTT commented 1 month ago

Thank you (when i be in home i try this.)