/// <summary>
        /// Gets the prefab game object
        /// </summary>
        public sealed override GameObject GetGameObject()
        {
            V2.Logger.Debug($"[FishFramework] Initializing fish: {this.ClassID}");
            GameObject mainObj = modelPrefab;

            Renderer[] renderers = mainObj.GetComponentsInChildren <Renderer>();
            foreach (Renderer rend in renderers)
            {
                rend.material.shader = Shader.Find("MarmosetUBER");
            }

            Rigidbody rb = mainObj.EnsureComponent <Rigidbody>();

            rb.useGravity  = false;
            rb.angularDrag = 1f;

            WorldForces forces = mainObj.EnsureComponent <WorldForces>();

            forces.useRigidbody      = rb;
            forces.aboveWaterDrag    = 0f;
            forces.aboveWaterGravity = 9.81f;
            forces.handleDrag        = true;
            forces.handleGravity     = true;
            forces.underwaterDrag    = 1f;
            forces.underwaterGravity = 0;
#if BELOWZERO || SUBNAUTICA_EXP
            forces.waterDepth = Ocean.GetOceanLevel();
#else
            forces.waterDepth = Ocean.main.GetOceanLevel();
#endif
            forces.enabled = false;
            forces.enabled = true;

            mainObj.EnsureComponent <EntityTag>().slotType         = EntitySlot.Type.Creature;
            mainObj.EnsureComponent <PrefabIdentifier>().ClassId   = this.ClassID;
            mainObj.EnsureComponent <TechTag>().type               = this.TechType;
            mainObj.EnsureComponent <SkyApplier>().renderers       = renderers;
            mainObj.EnsureComponent <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.Near;
            mainObj.EnsureComponent <LiveMixin>().health           = 10f;

            Creature creature = mainObj.EnsureComponent <Creature>();
            creature.initialCuriosity    = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);
            creature.initialFriendliness = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);
            creature.initialHunger       = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);

            SwimBehaviour behaviour = null;
            if (isWaterCreature)
            {
                behaviour = mainObj.EnsureComponent <SwimBehaviour>();
                SwimRandom swim = mainObj.EnsureComponent <SwimRandom>();
                swim.swimVelocity = swimSpeed;
                swim.swimRadius   = swimRadius;
                swim.swimInterval = swimInterval;
            }
            else
            {
                behaviour = mainObj.EnsureComponent <WalkBehaviour>();
                WalkOnGround      walk = mainObj.EnsureComponent <WalkOnGround>();
                OnSurfaceMovement move = mainObj.EnsureComponent <OnSurfaceMovement>();
                move.onSurfaceTracker = mainObj.EnsureComponent <OnSurfaceTracker>();
            }

            Locomotion loco = mainObj.EnsureComponent <Locomotion>();
            loco.useRigidbody = rb;

            mainObj.EnsureComponent <EcoTarget>().type = EcoTargetType.Peeper;
            mainObj.EnsureComponent <CreatureUtils>();
            mainObj.EnsureComponent <VFXSchoolFishRepulsor>();

            SplineFollowing spline = mainObj.EnsureComponent <SplineFollowing>();
            spline.locomotion    = loco;
            spline.levelOfDetail = mainObj.EnsureComponent <BehaviourLOD>();
            spline.GoTo(mainObj.transform.position + mainObj.transform.forward, mainObj.transform.forward, 5f);

            behaviour.splineFollowing = spline;

            if (pickupable)
            {
                mainObj.EnsureComponent <Pickupable>();
            }

            creature.ScanCreatureActions();

            return(mainObj);
        }
        public override GameObject GetGameObject()
        {
            Console.WriteLine("[FishFramework] Getting object from asset bundle");
            GameObject mainObj = bundle.LoadAsset <GameObject>(PrefabFileName);

            mainObj.AddComponent <ScaleFixer>().scale = scale;

            Console.WriteLine("[FishFramework] Setting correct shaders on renderers");
            Renderer[] renderers = mainObj.GetComponentsInChildren <Renderer>();
            foreach (Renderer rend in renderers)
            {
                rend.material.shader = Shader.Find("MarmosetUBER");
            }

            Console.WriteLine("[FishFramework] Adding essential components to object");

            Rigidbody rb = mainObj.AddOrGet <Rigidbody>();

            rb.useGravity  = false;
            rb.angularDrag = 1f;

            WorldForces forces = mainObj.AddOrGet <WorldForces>();

            forces.useRigidbody      = rb;
            forces.aboveWaterDrag    = 0f;
            forces.aboveWaterGravity = 9.81f;
            forces.handleDrag        = true;
            forces.handleGravity     = true;
            forces.underwaterDrag    = 1f;
            forces.underwaterGravity = 0;
            forces.waterDepth        = Ocean.main.GetOceanLevel();
            forces.enabled           = false;
            forces.enabled           = true;

            mainObj.AddOrGet <EntityTag>().slotType       = EntitySlot.Type.Creature;
            mainObj.AddOrGet <PrefabIdentifier>().ClassId = ClassID;
            mainObj.AddOrGet <TechTag>().type             = TechType;

            mainObj.AddOrGet <SkyApplier>().renderers       = renderers;
            mainObj.AddOrGet <LargeWorldEntity>().cellLevel = LargeWorldEntity.CellLevel.Near;
            mainObj.AddOrGet <LiveMixin>().health           = 10f;

            Creature creature = mainObj.AddOrGet <Creature>();

            creature.initialCuriosity    = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);
            creature.initialFriendliness = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);
            creature.initialHunger       = AnimationCurve.Linear(0f, 0.5f, 1f, 0.5f);
            SwimBehaviour behaviour = null;

            if (isWaterCreature)
            {
                behaviour = mainObj.AddOrGet <SwimBehaviour>();
                SwimRandom swim = mainObj.AddOrGet <SwimRandom>();
                swim.swimVelocity = swimSpeed;
                swim.swimRadius   = swimRadius;
                swim.swimInterval = 1f;
            }
            else
            {
                behaviour = mainObj.AddOrGet <WalkBehaviour>();
                WalkOnGround      walk = mainObj.AddOrGet <WalkOnGround>();
                OnSurfaceMovement move = mainObj.AddOrGet <OnSurfaceMovement>();
                move.onSurfaceTracker = mainObj.AddOrGet <OnSurfaceTracker>();
            }
            Locomotion loco = mainObj.AddOrGet <Locomotion>();

            loco.useRigidbody = rb;
            mainObj.AddOrGet <EcoTarget>().type = EcoTargetType.Peeper;
            mainObj.AddOrGet <CreatureUtils>();
            mainObj.AddOrGet <VFXSchoolFishRepulsor>();
            SplineFollowing spline = mainObj.AddOrGet <SplineFollowing>();

            spline.locomotion    = loco;
            spline.levelOfDetail = mainObj.AddOrGet <BehaviourLOD>();
            spline.GoTo(mainObj.transform.position + mainObj.transform.forward, mainObj.transform.forward, 5f);
            behaviour.splineFollowing = spline;
            creature.ScanCreatureActions();

            Console.WriteLine("[FishFramework] Adding pickupable component");
            if (pickupable)
            {
                mainObj.AddOrGet <Pickupable>();
            }

            Console.WriteLine("[FishFramework] Adding custom components");

            foreach (Type type in componentsToAdd)
            {
                try
                {
                    mainObj.AddComponent(type);
                }
                catch
                {
                    Console.WriteLine("[FishFramework] Failed to add component " + type.Name + " to GameObject");
                }
            }

            return(mainObj);
        }