using System;
using System.Reflection;
using UnityEngine;
namespace Passer {
///
/// A function which can be called
///
[Serializable]
public partial class FunctionCall {
///
/// The target GameObject on which the function should be called.
///
public GameObject targetGameObject;
///
/// The name of the method to call on the GameObject
///
/// The format of this string is <fully qualified component type>.<function name>
public string methodName;
public FunctionCall() { }
///
/// Creates a new FunctionCall
///
/// The GameObject on which the functioncall is executed
/// The full method name: component/methodName
public FunctionCall(GameObject targetGameObject, string methodName) {
this.targetGameObject = targetGameObject;
this.methodName = methodName;
}
protected INetworkObject networkObject;
protected Delegate targetDelegate;
protected delegate void Method();
protected delegate void MethodBool(bool value);
protected delegate void MethodFloat(float value);
protected delegate void MethodInt(int value);
protected delegate void MethodVector3(Vector3 value);
protected delegate void MethodGameObject(GameObject value);
protected delegate void MethodRigidbody(Rigidbody value);
// For animation parameter calls
protected delegate void MethodStringBool(string s, bool value);
protected delegate void MethodStringFloat(string s, float value);
protected delegate void MethodStringInt(string s, int value);
public enum ParameterType {
Void,
Float,
Int,
Bool,
Vector3,
GameObject,
Rigidbody,
String,
}
public static Type ToSystemType(ParameterType parameterType) {
switch (parameterType) {
default:
case ParameterType.Void:
return typeof(void);
case ParameterType.Bool:
return typeof(bool);
case ParameterType.Int:
return typeof(int);
case ParameterType.Float:
return typeof(float);
case ParameterType.Vector3:
return typeof(Vector3);
case ParameterType.GameObject:
return typeof(GameObject);
case ParameterType.Rigidbody:
return typeof(Rigidbody);
case ParameterType.String:
return typeof(string);
}
}
///
/// Function Parameter
///
[Serializable]
public class Parameter {
///
/// The parameter value comes from the event
///
/// When false one of the constant values is used, based on the type of the parameter
public bool fromEvent = false;
///
/// For future use...
///
public string localProperty;
///
/// The type of the parameter
///
/// May be converted to a System.Type later...
public ParameterType type;
///
/// The constant float value when the parameter type is float and fromEvent is false.
///
public float floatConstant;
///
/// The constant integer value when the parameter type is int and fromEvent is false.
///
public int intConstant;
///
/// The constant boolean value when the parameter type is bool and fromEvent is false.
///
public bool boolConstant;
///
/// The constant string value when the parameter type is string and fromEvent is false.
///
public string stringConstant;
///
/// The constant Vector3 value when the parameter type is Vector3 and fromEvent is false.
///
public Vector3 vector3Constant;
///
/// The constant GameObject value when the parameter type is GameObject and fromEvent is false.
///
public GameObject gameObjectConstant;
///
/// The constant Rigidbody value when the parameter type is Rigidbody and fromEvent is false.
///
public Rigidbody rigidbodyConstant;
}
///
/// For future use...
///
public Parameter[] parameters;
///
/// Adds a new Parameter to the function call
///
/// The new Parameter
public Parameter AddParameter() {
if (parameters == null || parameters.Length == 0)
parameters = new Parameter[1];
parameters[parameters.Length - 1] = new Parameter();
return parameters[parameters.Length - 1];
}
public static void Execute(GameObject target, string methodName) {
UnityEngine.Object component = GetComponent(target, methodName);
Method method = CreateMethod(component, methodName);
method();
}
///
/// For future use...
///
public enum Networking {
No,
Yes
}
///
/// Execute the void function call
///
/// For future use...
public virtual void Execute(Networking networking = Networking.No) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
if (targetDelegate is Method) {
((Method)targetDelegate)();
ExecuteRemote();
}
else if (targetDelegate is MethodBool) {
((MethodBool)targetDelegate)(parameters[0].boolConstant);
ExecuteRemote(parameters[0].boolConstant);
}
else if (targetDelegate is MethodInt)
((MethodInt)targetDelegate)(parameters[0].intConstant);
else if (targetDelegate is MethodFloat)
((MethodFloat)targetDelegate)(parameters[0].floatConstant);
else if (targetDelegate is MethodGameObject) {
((MethodGameObject)targetDelegate)(parameters[0].gameObjectConstant);
}
else if (targetDelegate is MethodVector3)
((MethodVector3)targetDelegate)(parameters[0].vector3Constant);
else if (targetDelegate is MethodRigidbody)
((MethodRigidbody)targetDelegate)(parameters[0].rigidbodyConstant);
}
private void ExecuteRemote() {
if (NetworkObject.connected == false)
return;
if (networkObject == null)
networkObject = NetworkObject.GetINetworkObject(this);
if (networkObject != null)
networkObject.RPC(this);
}
private void ExecuteRemote(bool value) {
if (NetworkObject.connected == false)
return;
if (networkObject == null)
networkObject = NetworkObject.GetINetworkObject(this);
if (networkObject != null)
networkObject.RPC(this, value);
}
private void ExecuteRemote(float value) {
if (NetworkObject.connected == false)
return;
if (networkObject == null)
networkObject = NetworkObject.GetINetworkObject(this);
if (networkObject != null)
networkObject.RPC(this, value);
}
public static void Execute(GameObject target, string methodName, bool boolValue) {
UnityEngine.Object component = GetComponent(target, methodName);
MethodBool method = CreateMethodBool(component, methodName);
method(boolValue);
}
public static void Execute(GameObject target, string methodName, float floatValue) {
UnityEngine.Object component = GetComponent(target, methodName);
MethodFloat method = CreateMethodFloat(component, methodName);
method(floatValue);
}
///
/// Execute a function call with a boolean parameter
///
/// The boolean value to pass to the function
/// For future use...
public void Execute(bool value, Networking networking = Networking.No) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodBool)targetDelegate)(value);
ExecuteRemote(value);
}
///
/// Call the function with an integer parameter
///
/// The integer value to pass to the function
public void Execute(int value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodInt)targetDelegate)(value);
}
///
/// Call the function with a float parameter
///
/// The float value to pass to the function
public virtual void Execute(float value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodFloat)targetDelegate)(value);
}
///
/// Call the function with a Vector3 parameter
///
/// The Vector3 value to pass to the function
public void Execute(Vector3 value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodVector3)targetDelegate)(value);
}
///
/// Call the funtion with a GameObject parameter
///
/// The GameObject value to pass to the function
public void Execute(GameObject value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodGameObject)targetDelegate)(value);
}
///
/// Call the function with a Rigidbody parameter
///
/// The Rigidbody value to pass to the function
protected void Execute(Rigidbody value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodRigidbody)targetDelegate)(value);
}
///
/// Call the function with a string and a boolean parameter
///
/// The string value to pass to the function as the first parameter
/// The boolean value to pass to the function as the second parameter
public void ExecuteString(string s, bool value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodStringBool)targetDelegate)(s, value);
}
///
/// Call the function with a string and a float parameter
///
/// The string value to pass to the function as the first parameter
/// The float value to pass to the function as the second parameter
public void ExecuteString(string s, float value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodStringFloat)targetDelegate)(s, value);
}
///
/// Call the function with a string and a integer parameter
///
/// The string value to pass to the function as the first parameter
/// The integer value to pass to the function as the second parameter
public void ExecuteString(string s, int value) {
if (targetDelegate == null) {
GetTargetMethod();
if (targetDelegate == null)
return;
}
((MethodStringInt)targetDelegate)(s, value);
}
protected virtual void GetTargetMethod() {
if (targetGameObject == null)
return;
string localMethodName;
if (methodName != null && methodName.Length > 21 &&
methodName.Substring(0, 21).Equals("SetAnimatorParameter/")) {
CreateAnimationParameterMethod(targetGameObject, methodName);
if (targetDelegate != null)
return;
}
UnityEngine.Object targetComponent = GetComponent(targetGameObject, methodName, out localMethodName);
if (targetComponent == null)
return;
if (targetComponent is Script) {
Script script = (Script)targetComponent;
targetDelegate = (Method)(() => script.Execute());
return;
}
if (parameters == null || parameters.Length == 0) {
targetDelegate = CreateMethod(targetGameObject, methodName);
return;
}
switch (parameters[0].type) {
case ParameterType.Void:
targetDelegate = CreateMethod(targetGameObject, methodName);
break;
case ParameterType.Bool:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].boolConstant);
break;
case ParameterType.Int:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].intConstant);
break;
case ParameterType.Float:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].floatConstant);
break;
case ParameterType.String:
CreateTargetMethodString(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].stringConstant);
break;
case ParameterType.Vector3:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].vector3Constant);
break;
case ParameterType.GameObject:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].gameObjectConstant);
break;
case ParameterType.Rigidbody:
CreateTargetMethod(targetComponent, localMethodName, parameters[0].fromEvent, parameters[0].rigidbodyConstant);
break;
default:
return;
}
}
protected static UnityEngine.Object GetComponent(GameObject target, string fullMethodName) {
string methodName;
return GetComponent(target, fullMethodName, out methodName);
}
protected static UnityEngine.Object GetComponent(GameObject target, string fullMethodName, out string methodName) {
methodName = fullMethodName;
string componentName = "";
int slashPos = methodName.LastIndexOf("/");
if (slashPos >= 0) {
methodName = methodName.Substring(slashPos + 1);
componentName = fullMethodName.Substring(0, slashPos);
}
if (componentName == "")
return null;
if (componentName == "UnityEngine.GameObject")
return target;
if (componentName == "Script") {
Script[] scriptComponents = target.GetComponents