question is in the Title. I want to make a function exclusively for button presses, and not having it exposed to the outside world where misuse of it can happen.
That is what [SerialiseField] does - exposes a variable to the inspector but without changing its access modifier.
If you want to have read-only view of private vars, set the inspector to Debug mode.
At runtime there is no private or public. So if you want you can build a custom inspector that lets you use private functions as well.
But a better implementation might be to write your own component that implements IPointerClickHandler. Then call the private function from within the class.
Yeah, you can expose a function name in the inspector using reflexion:
public class ObjectLinker : MonoBehaviour
{
public string methodToCall;
public void OnClick ()
{
typeof(ObjectLinker)
.GetMethod(methodToCall, BindingFlags.Instance |BindingFlags.NonPublic | BindingFlags.Public)
.Invoke(this, new object[0]);
}
}
and ObjectLinkerEditor which you place in the editor folder.
This will create a selector in the editor for functions, all of them.
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using System.Linq;
using System.Collections;
using System.Reflection;
using System;
[CustomEditor(typeof(ObjectLinker))]
public class ObjectLinkerEditor : Editor
{
static string[] methods;
static string[] ignoreMethods = new string[] { "Start", "Update", "OnClick" };
static ObjectLinkerEditor()
{
methods =
typeof(ObjectLinker)
.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) // Instance methods, both public and private/protected
.Where(x => x.DeclaringType == typeof(ObjectLinker)) // Only list methods defined in our own class
.Where(x => x.GetParameters().Length == 0) // Make sure we only get methods with zero argumenrts
.Where(x => !ignoreMethods.Any(n => n == x.Name)) // Don't list methods in the ignoreMethods array (so we can exclude Unity specific methods, etc.)
.Select(x => x.Name)
.ToArray();
}
public override void OnInspectorGUI()
{
ObjectLinker obj = target as ObjectLinker;
if (obj != null)
{
int index;
try
{
index = methods
.Select((v, i) => new { Name = v, Index = i })
.First(x => x.Name == obj.methodToCall)
.Index;
}
catch
{
index = 0;
}
obj.methodToCall = methods[EditorGUILayout.Popup(index, methods)];
}
}
}