//============= Copyright (c) Ludic GmbH, All rights reserved. ============== // // Purpose: Part of the My Behaviour Tree Code // //============================================================================= using System; using System.Reflection; using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Globalization; namespace MyBT { [System.Serializable] public class TaskParameter : ScriptableObject { // TypeCode.DBNull is considered invalid or undefined [SerializeField] public System.TypeCode valType = TypeCode.DBNull; // public object valValue = null; public object valValue { set { if (value == null) { valSerialized = "n"; return; } var type = value.GetType(); if (type == typeof(int)) valSerialized = "i"+value.ToString(); else if (type == typeof(float)) valSerialized = "f"+value.ToString(); else if (type == typeof(string)) valSerialized = "s"+value; // else if (type == typeof(Color)) { // Color32 c = (Color)valValue; // uint v = (byte)c.r + (byte)c.g<<8 + (byte)c.b<<16 + (byte)c.a<<24; // valSerialized = "c" + v; // } // else if (type == typeof()) else if (type == typeof(Vector3)) { Vector3 v = (Vector3)value; valSerialized = "v" + v.x + "|" +v.y + "|" + v.z; } } get { if (valSerialized.Length == 0) return null; char type = valSerialized[0]; if (type == 'n') return null; else if (type == 'i') return int.Parse(valSerialized.Substring(1)); else if (type == 'f') return float.Parse(valSerialized.Substring(1)); else if (type == 's') return valSerialized.Substring(1); // else if (type == 'c') { // byte v = byte.Parse(valSerialized.Substring(1)); // Color c = new Color32(v & 0xFF, (v>>8) & 0xFF, (v>>16) & 0xFF,(v>>24) & 0xFF); // valValue = c; // } else if (type == 'v') { string[] v = valSerialized.Substring(1).Split('|'); return new Vector3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2])); } return null; } } [SerializeField, HideInInspector] private string valSerialized = ""; /// /// init taskparameters from string /// return null on success, return string with error details on error /// /// /// public string Init(string stringValue) { bool boolValue; int intValue; float floatValue; Type thisType = Type.GetType(stringValue); if (thisType != null) { Debug.Log("TaskScriptParser.ParseValue: thisType " + thisType.FullName); } NumberStyles style = NumberStyles.Any; CultureInfo culture = CultureInfo.InvariantCulture; // Place checks higher in if-else statement to give higher priority to type. if (bool.TryParse(stringValue, out boolValue)) { valType = TypeCode.Boolean; valValue = boolValue; return null; } else if (int.TryParse(stringValue, style, culture, out intValue)) { valType = TypeCode.Int32; valValue = intValue; return null; } else if (float.TryParse(stringValue, style, culture, out floatValue)) { valType = TypeCode.Single; valValue = floatValue; return null; } // handle string and enum else { // is null value if (stringValue == "null") { valType = TypeCode.Empty; valValue = null; return null; } // is empty value if (stringValue == "") { // no content return null; } string[] splitValue = stringValue.Split('"'); // is string with "" if (splitValue.Length == 3) { valType = TypeCode.String; valValue = splitValue[1]; return null; } // is enum? -> currently dont handle enums else { // Debug.Log($"TaskParameter: detected enum: {stringValue}"); string[] enumSplit = stringValue.Split('.'); try { string enumNamespace = null; System.Type enumType = null; string convertValue = null; // object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType())); if (enumSplit.Length == 3) { enumNamespace = enumSplit[0]; enumType = GetEnumType(enumSplit[1]); convertValue = enumSplit[2]; } else if (enumSplit.Length == 2) { enumType = GetEnumType(enumSplit[0]); convertValue = enumSplit[1]; } object enumValue = Enum.Parse(enumType, convertValue); valType = TypeCode.Int32; valValue = (int)enumValue; // Debug.Log($"TaskParameter: detected enum: {enumType} {enumValue} string: {stringValue} type: {valType} value: {valValue}"); return null; } catch (Exception e) { // Debug.LogError("failed conversion of string '" + stringValue + "' error: " + e.ToString()); return "failed conversion of string '" + stringValue + "' error: " + e.ToString(); } } } } public bool IsValid() { return (valType != TypeCode.DBNull); } public static Assembly[] GetEnumAssembly (string enumNamespace=null) { if (enumNamespace != null) { try { Assembly assembly = System.Reflection.Assembly.Load(enumNamespace); if (assembly != null) { return new Assembly[] {assembly}; } } catch { } // ignore load error } return AppDomain.CurrentDomain.GetAssemblies(); } public static Type GetEnumType(string enumName, string enumNamespace=null) { foreach (var assembly in GetEnumAssembly(enumNamespace)) { var type = assembly.GetType(enumName); if (type == null) continue; if (type.IsEnum) return type; } return null; } public TaskParameter Duplicate () { TaskParameter tp = ScriptableObject.CreateInstance(); tp.valType = valType; tp.valSerialized = valSerialized; tp.valValue = valValue; return tp; } } }