InfamyKing

Adding Light component to "batteryPack" part's indicator

Recommended Posts

Hello everyone! So as to train myself in the art of KSP modding, I am attempting to develop my first mod. Its purpose is simple: adding a Light emitting component to the z-100Battery indicator, the little green bell-shaped thing on top of the part. However, I've hit a roadblock. The following error (from the log file) has been haunting me for the past day or so:

Spoiler

[LOG 23:48:46.860] PartLoader: Compiling Part 'Squad/Parts/Electrical/z-100Battery/z-100Battery/batteryPack'
[EXC 23:48:46.866] TypeLoadException: Could not load type 'System.Runtime.CompilerServices.IteratorStateMachineAttribute' from assembly 'BatteryIndicatorLight'.
	System.MonoCustomAttrs.GetCustomAttributesBase (ICustomAttributeProvider obj, System.Type attributeType)
	System.MonoCustomAttrs.GetCustomAttributes (ICustomAttributeProvider obj, System.Type attributeType, Boolean inherit)
	System.MonoType.GetCustomAttributes (System.Type attributeType, Boolean inherit)
	UnityEngine.AttributeHelperEngine.GetParentTypeDisallowingMultipleInclusion (System.Type type)
	UnityEngine.GameObject:AddComponent(Type)
	Part:AddModule(String, Boolean)
	Part:AddModule(ConfigNode, Boolean)
	PartLoader:ParsePart(UrlConfig, ConfigNode)
	:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[EXC 23:48:46.871] TypeLoadException: Could not load type 'System.Runtime.CompilerServices.IteratorStateMachineAttribute' from assembly 'BatteryIndicatorLight'.
	System.MonoCustomAttrs.GetCustomAttributesBase (ICustomAttributeProvider obj, System.Type attributeType)
	System.MonoCustomAttrs.GetCustomAttributes (ICustomAttributeProvider obj, System.Type attributeType, Boolean inherit)
	System.Reflection.MonoMethod.GetCustomAttributes (System.Type attributeType, Boolean inherit)
	BaseEventList+ReflectedData..ctor (System.Type type)
	BaseEventList.GetReflectedAttributes (System.Type type)
	BaseEventList.CreateDelegates (System.Object part)
	BaseEventList..ctor (.Part part, .PartModule module)
	PartModule.ModularSetup ()
	PartModule.Awake ()
	UnityEngine.GameObject:AddComponent(Type)
	Part:AddModule(String, Boolean)
	Part:AddModule(ConfigNode, Boolean)
	PartLoader:ParsePart(UrlConfig, ConfigNode)
	:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[ERR 23:48:46.876] PartLoader: Encountered exception during compilation. System.NullReferenceException: Object reference not set to an instance of an object
  at PartModule.Load (.ConfigNode node) [0x00000] in <filename unknown>:0 
  at Part.AddModule (.ConfigNode node, Boolean forceAwake) [0x00000] in <filename unknown>:0 
  at PartLoader.ParsePart (.UrlConfig urlConfig, .ConfigNode node) [0x00000] in <filename unknown>:0 
  at PartLoader+.MoveNext () [0x00000] in <filename unknown>:0 

[ERR 23:48:46.877] PartCompiler: Cannot compile part

 

This results in the part not even loading, obviously.

The mod consists of 2 files:

  • BatteryIndicatorLight.dll
Spoiler

using System;
using System.Collections;
using UnityEngine;

namespace BatteryIndicatorLight
{
    public class BatteryIndicatorLight : PartModule
    {
        //Variables:
        [KSPField]
        public float lightDuration = 1f;
        [KSPField]
        public float lightIntensity = 10f;
        [KSPField]
        public float lightRange = 15f;

        private Material lightMaterial = null;
        private PartResource electricCharge = null;

        public Light batteryIndicatorLight = null;

        private void GetLightMaterial()
        {
            int i = 0;
            Transform[] ts = part.GetComponentsInChildren<Transform>();
            while (i < ts.Length && lightMaterial == null)
            {
                Renderer renderer = ts[i++].GetComponent<Renderer>();
                if (renderer != null && renderer.material != null && renderer.material.name.Contains("light"))
                    lightMaterial = renderer.material;
            }
            electricCharge = part.Resources["ElectricCharge"];
        }

        public override void OnStart(PartModule.StartState state)
        {
            try
            {
                if (state == StartState.Editor || state == StartState.None)
                {
                    return; //Beware the bugs!
                }

                this.GetLightMaterial();

                if (lightMaterial != null)
                {
                    Debug.Log("[BatteryIndicatorLight] lightMaterial.name = " + lightMaterial.name);
                    GameObject batteryIndicatorLightGM = new GameObject();
                    batteryIndicatorLightGM.AddComponent<Light>();
                    batteryIndicatorLightGM.transform.position = part.transform.position;
                    batteryIndicatorLightGM.transform.parent = part.transform.parent;
                    //batteryIndicatorLightGM.transform.rotation = part.transform.rotation;
                    //part.transform.up

                    batteryIndicatorLightGM.GetComponent<Light>().enabled = (electricCharge.amount > 0f) ? true : false;
                    batteryIndicatorLightGM.GetComponent<Light>().range = lightRange;
                    batteryIndicatorLightGM.GetComponent<Light>().intensity = lightIntensity;
                    batteryIndicatorLightGM.GetComponent<Light>().color = lightMaterial.color; // new Color(lightRed, lightGreen, lightBlue);
                    Debug.Log(String.Format("[BatteryIndicatorLight] Light Material Color = ({0}, {1}, {2}, {3})",
                                            lightMaterial.color.r, lightMaterial.color.g, lightMaterial.color.b, lightMaterial.color.a));

                    batteryIndicatorLight = batteryIndicatorLightGM.GetComponent<Light>();
                } 
                else
                {
                    Debug.Log("[BatteryIndicatorLight] no lightMaterial found");
                }
                //base.OnStart(state);
            }
            catch (Exception e)
            {
                Debug.LogError("[BatteryIndicatorLight] Error onStart: " + e.Message);
            }
        }

        public override void OnUpdate()
        {
            try
            {
                if (batteryIndicatorLight != null)
                {
                    if (electricCharge.amount > 0f)
                    {
                        batteryIndicatorLight.color = lightMaterial.color;
                    }
                    else
                    {
                        StartCoroutine("shutLightDown");
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError("[BatteryIndicatorLight] Error onUpdate: " + e.Message);
            }
        }

        //Coroutines are really easy in C#/Unity
        IEnumerator shutLightDown()
        {
            yield return new WaitForSeconds(lightDuration);
            batteryIndicatorLight.enabled = false;
        }
    }
}

 

  • z-100Battery.cfg
Spoiler

@PART[batteryPack]
{
	MODULE
	{
		name = BatteryIndicatorLight
		lightDuration = 1.0
		lightIntensity = 10.0
		lightRange = 15.0
	}
}

 

Additionally, the file structure is as follows:

mhYT780.png

For reference, the code developed here is based on BatteryIndicator and EngineLightning. If anyone would be able to assist me in finding the cause of the error, I would be most grateful!

Share this post


Link to post
Share on other sites

It's throwing an error on a method in the System namesapce, the only reason I can think that would happen is you're compiling against the wrong .NET level.

Check your project's properties and make sure you are compiling for .NET 3.5, not something newer.

D.

Share this post


Link to post
Share on other sites

Many thanks @Diazo, that was exactly my problem! I had no idea that the .NET framework level mattered in regards to KSP. I owe you one.

Also, I had no idea that mod existed @Fwiffo, thanks as well for sharing it here.

Share this post


Link to post
Share on other sites
This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.