Silly Trigger for project's machines

 avatar
unknown
csharp
a month ago
7.1 kB
10
Indexable
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Reflection;


public enum VariableType
{
    Int,
    Float,
    String,
    GameObject
}

[Serializable]
public class DynamicVariable
{
    public VariableType type;
    public string name; // Optional: Give the variable a name for identification
    public string stringValue;
    public int intValue;
    public float floatValue;
    public GameObject gameObjectValue;
    public bool assignFromTrigger;

    // Retrieve the value as an object
    public object GetValue()
    {
        return type switch
        {
            VariableType.Int => intValue,
            VariableType.Float => floatValue,
            VariableType.String => stringValue,
            VariableType.GameObject => gameObjectValue,
            _ => null,
        };
    }
}

public class TriggerMachine : MonoBehaviour
{

      public MonoBehaviour assignedClass; // The class whose method will be called
      public string methodName; // The name of the method to call
      public List<DynamicVariable> parameters = new List<DynamicVariable>();

    // Example: Hide GameObjects based on a boolean
    public bool hideGameObject = false;

    public void ExecuteFunction()
    {
        if (assignedClass == null || string.IsNullOrEmpty(methodName))
        {
            Debug.LogWarning("Assigned class or method name is not set.");
            return;
        }

        // Get the method info
        Type classType = assignedClass.GetType();
        MethodInfo methodInfo = classType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance);

        if (methodInfo == null)
        {
            Debug.LogError($"Method '{methodName}' not found in class '{classType.Name}'.");
            return;
        }

        // Prepare parameter values
        ParameterInfo[] parameterInfos = methodInfo.GetParameters();
        if (parameterInfos.Length != parameters.Count)
        {
            Debug.LogError($"Parameter count mismatch: Method '{methodName}' expects {parameterInfos.Length} parameters but {parameters.Count} were provided.");
            return;
        }

        object[] parameterValues = new object[parameters.Count];
        for (int i = 0; i < parameters.Count; i++)
        {
            parameterValues[i] = parameters[i].GetValue();
        }

        // Call the method
        try
        {
            methodInfo.Invoke(assignedClass, parameterValues);
            Debug.Log($"Successfully called method '{methodName}' on class '{classType.Name}'.");
        }
        catch (Exception ex)
        {
            Debug.LogError($"Error invoking method '{methodName}': {ex.Message}");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("We entered Trigger");

        // Check if any parameter of type GameObject exists
        foreach (var parameter in parameters)
        {
            if (parameter.type == VariableType.GameObject)
            {
                parameter.gameObjectValue = other.gameObject; // Assign the triggering GameObject
                Debug.Log($"Assigned GameObject '{other.gameObject.name}' to parameter '{parameter.name}'");
            }
        }
    }
}

Editor one:
using UnityEditor;
using UnityEditor.Rendering;
using UnityEngine;

[CustomEditor(typeof(TriggerMachine))]
public class TriggerMachineEditor : Editor
{
 private SerializedProperty parameters;
 private SerializedProperty assignedClass;
 private SerializedProperty methodName;

    private void OnEnable()
    {
        parameters = serializedObject.FindProperty("parameters");
        assignedClass = serializedObject.FindProperty("assignedClass");
        methodName = serializedObject.FindProperty("methodName");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        // Display assigned class and method name fields
        EditorGUILayout.LabelField("Method Call Settings", EditorStyles.boldLabel);
        EditorGUILayout.PropertyField(assignedClass, new GUIContent("Assigned Class"));
        EditorGUILayout.PropertyField(methodName, new GUIContent("Method Name"));

         // Display and edit the parameter list
        EditorGUILayout.LabelField("Dynamic Parameters", EditorStyles.boldLabel);


        for (int i = 0; i < parameters.arraySize; i++)
        {
            var parameter = parameters.GetArrayElementAtIndex(i);

            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.PropertyField(parameter.FindPropertyRelative("name"), new GUIContent("Name"));
            EditorGUILayout.PropertyField(parameter.FindPropertyRelative("type"), new GUIContent("Type"));

            var type = (VariableType)parameter.FindPropertyRelative("type").enumValueIndex;

            // Display value field based on selected type
            switch (type)
            {
                case (int)VariableType.Int:
                    EditorGUILayout.PropertyField(parameter.FindPropertyRelative("intValue"), new GUIContent("Value"));
                    break;
                case (VariableType)(int)VariableType.Float:
                    EditorGUILayout.PropertyField(parameter.FindPropertyRelative("floatValue"), new GUIContent("Value"));
                    break;
                case (VariableType)(int)VariableType.String:
                    EditorGUILayout.PropertyField(parameter.FindPropertyRelative("stringValue"), new GUIContent("Value"));
                    break;
                case (VariableType)(int)VariableType.GameObject:
                    // Add the boolean toggle
                    var assignFromTrigger = parameter.FindPropertyRelative("assignFromTrigger");
                    EditorGUILayout.PropertyField(assignFromTrigger, new GUIContent("Assign From Trigger"));

                    // Only show the GameObject field if assignFromTrigger is false
                    if (!assignFromTrigger.boolValue)
                    {
                        EditorGUILayout.PropertyField(parameter.FindPropertyRelative("gameObjectValue"), new GUIContent("Value"));
                    }
                    else
                    {
                        EditorGUILayout.HelpBox("This GameObject will be assigned from OnTriggerEnter at runtime.", MessageType.Info);
                    }
                    break;
            }

            if (GUILayout.Button("Remove Parameter"))
            {
                parameters.DeleteArrayElementAtIndex(i);
            }

            EditorGUILayout.EndVertical();
        }

        if (GUILayout.Button("Add Parameter"))
        {
            parameters.InsertArrayElementAtIndex(parameters.arraySize);
        }

        if (GUILayout.Button("Execute Function"))
        {
            ((TriggerMachine)target).ExecuteFunction();
        }

        serializedObject.ApplyModifiedProperties();
    }
}
Leave a Comment