This commit is contained in:
2020-07-04 14:41:25 +08:00
parent 70c346d2c1
commit a8f02e4da5
3748 changed files with 587372 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa35a23a042f14b12ae57cd621e8a6e8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
// ----------------------------------------------------------------------------
// The MIT License
// UnityMobileInput https://github.com/mopsicus/UnityMobileInput
// Copyright (c) 2018 Mopsicus <mail@mopsicus.ru>
// ----------------------------------------------------------------------------
using UnityEditor;
using UnityEngine;
namespace Mopsicus.Plugins {
/// <summary>
/// Custom editor for MobileInput
/// </summary>
[CustomEditor (typeof (MobileInputField))]
public class MobileInputEditor : Editor {
/// <summary>
/// Offset size
/// </summary>
const int OFFSET = 20;
/// <summary>
/// Space between labels
/// </summary>
const int SPACE = 5;
/// <summary>
/// MobileInput target
/// </summary>
private MobileInputField _target;
/// <summary>
/// Serialized target object
/// </summary>
private SerializedObject _object;
/// <summary>
/// Return press event
/// </summary>
private SerializedProperty _onReturnPressedEvent;
#if UNITY_IOS
/// <summary>
/// Visible Done button
/// </summary>
private SerializedProperty _isWithDoneButton;
/// <summary>
/// Visible Clear buttonƒ
/// </summary>
private SerializedProperty _isWithClearButton;
#endif
/// <summary>
/// Init data
/// </summary>
private void OnEnable () {
_target = (MobileInputField) target;
_object = new SerializedObject (target);
_onReturnPressedEvent = _object.FindProperty ("OnReturnPressedEvent");
#if UNITY_IOS
_isWithDoneButton = _object.FindProperty ("IsWithDoneButton");
_isWithClearButton = _object.FindProperty ("IsWithClearButton");
#endif
}
/// <summary>
/// Draw inspector
/// </summary>
public override void OnInspectorGUI () {
_object.Update ();
EditorGUI.BeginChangeCheck ();
GUILayout.Space (OFFSET);
GUILayout.Label ("Select type for Return button:");
_target.ReturnKey = (MobileInputField.ReturnKeyType) GUILayout.Toolbar ((int) _target.ReturnKey, new string[] { "Default", "Next", "Done", "Search" });
GUILayout.Space (OFFSET);
#if UNITY_IOS
GUILayout.Label ("Options:");
_target.IsWithDoneButton = GUILayout.Toggle (_target.IsWithDoneButton, " Show \"Done\" button");
GUILayout.Space (SPACE);
_target.IsWithClearButton = GUILayout.Toggle (_target.IsWithClearButton, " Show \"Clear\" button");
GUILayout.Space (OFFSET);
#endif
EditorGUILayout.PropertyField (_onReturnPressedEvent);
if (EditorGUI.EndChangeCheck ()) {
_object.ApplyModifiedProperties ();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd55cea5e8ce949a395e88966d10f0bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,320 @@
// ----------------------------------------------------------------------------
// The MIT License
// UnityMobileInput https://github.com/mopsicus/UnityMobileInput
// Copyright (c) 2018 Mopsicus <mail@mopsicus.ru>
// ----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using NiceJson;
using UnityEngine;
#if UNITY_IOS
using System.Runtime.InteropServices;
#endif
namespace Mopsicus.Plugins {
/// <summary>
/// Base class for InputField
/// </summary>
public abstract class MobileInputReceiver : MonoBehaviour {
/// <summary>
/// Current input id
/// </summary>
private int _id;
/// <summary>
/// Init input and register interface
/// </summary>
protected virtual void Start () {
_id = MobileInput.Register (this);
}
/// <summary>
/// Action on destroy
/// </summary>
protected virtual void OnDestroy () {
MobileInput.RemoveReceiver (_id);
}
/// <summary>
/// Send data to plugin
/// </summary>
/// <param name="data">Data</param>
protected void Execute (JsonObject data) {
MobileInput.Execute (_id, data);
}
/// <summary>
/// Send data to plugin manually
/// </summary>
/// <param name="data">Data</param>
public abstract void Send (JsonObject data);
/// <summary>
/// Hide input
/// </summary>
public abstract void Hide ();
}
/// <summary>
/// Mobile native input plugin
/// </summary>
public class MobileInput : MonoBehaviour, IPlugin {
/// <summary>
/// Event name for keyboard prepare to change
/// </summary>
const string KEYBOARD_PREPARE = "KEYBOARD_PREPARE";
/// <summary>
/// Event name for keyboard show/hide
/// </summary>
const string KEYBOARD_ACTION = "KEYBOARD_ACTION";
/// <summary>
/// Delegate for show/hide keyboard action
/// </summary>
public delegate void ShowDelegate (bool isShow, int height);
/// <summary>
/// Delegate for prepare show keyboard
/// </summary>
public delegate void PrepareDelegate ();
/// <summary>
/// Handler for ShowDelegate
/// </summary>
public static ShowDelegate OnShowKeyboard = delegate { };
/// <summary>
/// Handler for PrepareDelegate
/// </summary>
public static PrepareDelegate OnPrepareKeyboard = delegate { };
/// <summary>
/// Mobile fields dictionary
/// </summary>
private Dictionary<int, MobileInputReceiver> _inputs = new Dictionary<int, MobileInputReceiver> ();
/// <summary>
/// Current instance
/// </summary>
private static MobileInput _instance;
/// <summary>
/// Cache data for hidden app state
/// </summary>
private JsonObject _data;
/// <summary>
/// Cache error for hidden app state
/// </summary>
private JsonObject _error;
/// <summary>
/// MobileInput counter
/// </summary>
private int _counter = 0;
#if UNITY_IOS
/// <summary>
/// Send data to plugin input
/// </summary>
[DllImport ("__Internal")]
private static extern void inputExecute (int id, string json);
/// <summary>
/// Init MobileInput plugin
/// </summary>
[DllImport ("__Internal")]
private static extern void inputInit ();
/// <summary>
/// Destroy MobileInput plugin
/// </summary>
[DllImport ("__Internal")]
private static extern void inputDestroy ();
#endif
/// <summary>
/// Constructor
/// </summary>
private void Awake () {
if ((object) _instance == null) {
_instance = GetComponent<MobileInput> ();
Init ();
}
}
/// <summary>
/// Plugin name
/// </summary>
public string Name {
get {
return GetType ().Name.ToLower ();
}
}
/// <summary>
/// Current instance for external access
/// </summary>
public static MobileInput Plugin {
get {
return _instance;
}
}
/// <summary>
/// Callback on data
/// </summary>
public void OnData (JsonObject data) {
Debug.Log (string.Format ("{0} plugin OnData: {1}", GetType ().Name, data.ToJsonPrettyPrintString ()));
_data = data;
try {
JsonObject response = (JsonObject) JsonNode.ParseJsonString (data["data"]);
string code = response["msg"];
switch (code) {
case KEYBOARD_PREPARE:
OnPrepareKeyboard ();
break;
case KEYBOARD_ACTION:
bool isShow = response["show"];
int height = 0;
#if UNITY_ANDROID
height = (int) (response["height"] * (float) Screen.height);
#elif UNITY_IOS
height = response["height"];
#endif
OnShowKeyboard (isShow, height);
break;
default:
int id = response["id"];
if (_inputs.ContainsKey (id)) {
GetReceiver (id).Send (response);
}
break;
}
_data = null;
} catch (Exception e) {
Debug.LogError (string.Format ("{0} plugin OnData error: {1}", GetType ().Name, e.Message));
}
}
/// <summary>
/// Callback on error
/// </summary>
public void OnError (JsonObject data) {
Debug.LogError (string.Format ("{0} plugin OnError: {0}", GetType ().Name, data.ToJsonPrettyPrintString ()));
_error = data;
try {
_error = null;
} catch (Exception e) {
Debug.LogError (string.Format ("{0} plugin OnError error: {1}", GetType ().Name, e.Message));
}
}
/// <summary>
/// Init and save new MobileInput
/// </summary>
/// <param name="receiver">Receiver</param>
/// <returns>Id</returns>
public static int Register (MobileInputReceiver receiver) {
int index = _instance._counter;
_instance._counter++;
_instance._inputs[index] = receiver;
return index;
}
/// <summary>
/// Remove MobileInput
/// </summary>
/// <param name="id">Input id</param>
public static void RemoveReceiver (int id) {
_instance._inputs.Remove (id);
}
/// <summary>
/// Get MobileInput by index
/// </summary>
/// <param name="id">Input id</param>
/// <returns>Receiver</returns>
public static MobileInputReceiver GetReceiver (int id) {
return _instance._inputs[id];
}
/// <summary>
/// Send data to plugin
/// </summary>
/// <param name="id">id</param>
/// <param name="data">json</param>
public static void Execute (int id, JsonObject data) {
data["id"] = id;
string json = data.ToJsonString ();
#if UNITY_EDITOR
Debug.Log ("MobileInput execute " + json);
#elif UNITY_ANDROID
using (AndroidJavaClass plugin = new AndroidJavaClass (string.Format (Plugins.ANDROID_CLASS_MASK, _instance.Name))) {
plugin.CallStatic ("execute", id, json);
}
#elif UNITY_IOS
inputExecute (id, json);
#endif
}
/// <summary>
/// Init plugin
/// </summary>
public static void Init () {
#if UNITY_EDITOR
#elif UNITY_ANDROID
using (AndroidJavaClass plugin = new AndroidJavaClass (string.Format (Plugins.ANDROID_CLASS_MASK, _instance.Name))) {
plugin.CallStatic ("init");
}
#elif UNITY_IOS
inputInit ();
#endif
}
/// <summary>
/// Destructor
/// </summary>
public static void Destroy () {
#if UNITY_EDITOR
#elif UNITY_ANDROID
using (AndroidJavaClass plugin = new AndroidJavaClass (string.Format (Plugins.ANDROID_CLASS_MASK, _instance.Name))) {
plugin.CallStatic ("destroy");
}
#elif UNITY_IOS
inputDestroy ();
#endif
}
/// <summary>
/// Handler to check data on focus change
/// </summary>
private void OnApplicationPause (bool pauseStatus) {
if (!pauseStatus) {
if (_data != null) {
OnData (_data);
} else if (_error != null) {
OnError (_error);
}
}
}
/// <summary>
/// Handler on app focus
/// </summary>
void OnApplicationFocus (bool focusStatus) {
if (!focusStatus) {
foreach (var item in _instance._inputs.Values) {
item.Hide ();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ec5c22f648534b2490352b23199aae1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,621 @@
// ----------------------------------------------------------------------------
// The MIT License
// UnityMobileInput https://github.com/mopsicus/UnityMobileInput
// Copyright (c) 2018 Mopsicus <mail@mopsicus.ru>
// ----------------------------------------------------------------------------
using System;
using System.Collections;
using NiceJson;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Mopsicus.Plugins {
/// <summary>
/// Wrapper for Unity InputField
/// Add this component on your InputField
/// </summary>
[RequireComponent (typeof (InputField))]
public class MobileInputField : MobileInputReceiver {
/// <summary>
/// Config structure
/// </summary>
private struct MobileInputConfig {
public bool Multiline;
public Color TextColor;
public Color BackgroundColor;
public string ContentType;
public string InputType;
public string KeyboardType;
public float FontSize;
public string Align;
public string Placeholder;
public Color PlaceholderColor;
public int CharacterLimit;
}
/// <summary>
/// Button type
/// </summary>
public enum ReturnKeyType {
Default,
Next,
Done,
Search
}
/// <summary>
/// "Done" button visible (for iOS)
/// </summary>
public bool IsWithDoneButton = true;
/// <summary>
/// "(x)" button visible (for iOS)
/// </summary>
public bool IsWithClearButton = true;
/// <summary>
/// Type for return button
/// </summary>
public ReturnKeyType ReturnKey;
/// <summary>
/// Action when Return pressed, for subscribe
/// </summary>
public Action OnReturnPressed = delegate { };
/// <summary>
/// Action when Focus changed
/// </summary>
public Action<bool> OnFocusChanged = delegate { };
/// <summary>
/// Event when Return pressed, for Unity inspector
/// </summary>
public UnityEvent OnReturnPressedEvent;
/// <summary>
/// Mobile input creation flag
/// </summary>
private bool _isMobileInputCreated = false;
/// <summary>
/// InputField object
/// </summary>
private InputField _inputObject;
/// <summary>
/// Text object from _inputObject
/// </summary>
private Text _inputObjectText;
/// <summary>
/// Set focus on create flag
/// </summary>
private bool _isFocusOnCreate;
/// <summary>
/// Set visible on create flag
/// </summary>
private bool _isVisibleOnCreate = true;
/// <summary>
/// Last field position cache
/// </summary>
private Rect _lastRect;
/// <summary>
/// Current config
/// </summary>
private MobileInputConfig _config;
/// <summary>
/// InputField create event
/// </summary>
const string CREATE = "CREATE_EDIT";
/// <summary>
/// InputField remove event
/// </summary>
const string REMOVE = "REMOVE_EDIT";
/// <summary>
/// Set text to InputField
/// </summary>
const string SET_TEXT = "SET_TEXT";
/// <summary>
/// Set new Rect, position, size
/// </summary>
const string SET_RECT = "SET_RECT";
/// <summary>
/// Set focus to InputField
/// </summary>
const string SET_FOCUS = "SET_FOCUS";
/// <summary>
/// Event when InputField is focused
/// </summary>
const string ON_FOCUS = "ON_FOCUS";
/// <summary>
/// Event when InputField is unfocused
/// </summary>
const string ON_UNFOCUS = "ON_UNFOCUS";
/// <summary>
/// Set visible to InputField
/// </summary>
const string SET_VISIBLE = "SET_VISIBLE";
/// <summary>
/// Event when text changing in InputField
/// </summary>
const string TEXT_CHANGE = "TEXT_CHANGE";
/// <summary>
/// Event when text end changing in InputField
/// </summary>
const string TEXT_END_EDIT = "TEXT_END_EDIT";
/// <summary>
/// Event for Android
/// </summary>
const string ANDROID_KEY_DOWN = "ANDROID_KEY_DOWN";
/// <summary>
/// Event when Return key pressed
/// </summary>
const string RETURN_PRESSED = "RETURN_PRESSED";
/// <summary>
/// Ready event
/// </summary>
const string READY = "READY";
/// <summary>
/// Constructor
/// </summary>
private void Awake () {
_inputObject = this.GetComponent<InputField> ();
if ((object) _inputObject == null) {
Debug.LogError (string.Format ("No found InputField for {0} MobileInput", this.name));
throw new MissingComponentException ();
}
_inputObjectText = _inputObject.textComponent;
}
/// <summary>
/// Create mobile input on Start with coroutine
/// </summary>
protected override void Start () {
base.Start ();
StartCoroutine (InitialzieOnNextFrame ());
}
/// <summary>
/// Show native on enable
/// </summary>
private void OnEnable () {
if (_isMobileInputCreated) {
this.SetVisible (true);
}
}
/// <summary>
/// Hide native on disable
/// </summary>
private void OnDisable () {
if (_isMobileInputCreated) {
this.SetFocus (false);
this.SetVisible (false);
}
}
/// <summary>
/// Destructor
/// </summary>
protected override void OnDestroy () {
RemoveNative ();
base.OnDestroy ();
}
/// <summary>
/// Handler for app focus lost
/// </summary>
private void OnApplicationFocus (bool hasFocus) {
if (!_isMobileInputCreated || !this.Visible) {
return;
}
this.SetVisible (hasFocus);
}
/// <summary>
/// Current InputField for external access
/// </summary>
public InputField InputField {
get {
return _inputObject;
}
}
/// <summary>
/// MobileInput visible
/// </summary>
public bool Visible {
get;
private set;
}
/// <summary>
/// MobileInput text
/// </summary>
public string Text {
get {
return _inputObject.text;
}
set {
_inputObject.text = value;
SetTextNative (value);
}
}
/// <summary>
/// Initialization coroutine
/// </summary>
private IEnumerator InitialzieOnNextFrame () {
yield return null;
this.PrepareNativeEdit ();
#if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR
this.CreateNativeEdit ();
this.SetTextNative (this._inputObjectText.text);
_inputObject.placeholder.gameObject.SetActive (false);
_inputObject.enabled = false;
_inputObjectText.enabled = false;
#endif
}
/// <summary>
/// Check position on each frame
/// If changed - send to plugin
/// It's need when app rotate on input field chage position
/// </summary>
private void Update () {
#if UNITY_ANDROID && !UNITY_EDITOR
this.UpdateForceKeyeventForAndroid ();
#endif
if (this._inputObject != null && _isMobileInputCreated) {
#if !UNITY_EDITOR
if (Input.touchCount > 0) {
for (int i = 0; i < Input.touches.Length; i++) {
if (!this._inputObjectText.rectTransform.rect.Contains (Input.touches[i].position)) {
Hide ();
return;
}
}
}
#endif
SetRectNative (this._inputObjectText.rectTransform);
}
}
/// <summary>
/// Get sizes and convert to current screen size
/// </summary>
/// <param name="rect">RectTranform from Gameobject</param>
/// <returns>Rect</returns>
public static Rect GetScreenRectFromRectTransform (RectTransform rect) {
Vector3[] corners = new Vector3[4];
rect.GetWorldCorners (corners);
float xMin = float.PositiveInfinity;
float xMax = float.NegativeInfinity;
float yMin = float.PositiveInfinity;
float yMax = float.NegativeInfinity;
for (int i = 0; i < 4; i++) {
Vector3 screenCoord;
if (rect.GetComponentInParent<Canvas> ().renderMode == RenderMode.ScreenSpaceOverlay) {
screenCoord = corners[i];
} else {
screenCoord = RectTransformUtility.WorldToScreenPoint (Camera.main, corners[i]);
}
if (screenCoord.x < xMin) {
xMin = screenCoord.x;
}
if (screenCoord.x > xMax) {
xMax = screenCoord.x;
}
if (screenCoord.y < yMin) {
yMin = screenCoord.y;
}
if (screenCoord.y > yMax) {
yMax = screenCoord.y;
}
}
Rect result = new Rect (xMin, Screen.height - yMax, xMax - xMin, yMax - yMin);
return result;
}
/// <summary>
/// Prepare config
/// </summary>
private void PrepareNativeEdit () {
Text placeHolder = _inputObject.placeholder.GetComponent<Text> ();
_config.Placeholder = placeHolder.text;
_config.PlaceholderColor = placeHolder.color;
_config.CharacterLimit = _inputObject.characterLimit;
Rect rect = GetScreenRectFromRectTransform (this._inputObjectText.rectTransform);
float ratio = rect.height / _inputObjectText.rectTransform.rect.height;
_config.FontSize = ((float) _inputObjectText.fontSize) * ratio;
_config.TextColor = _inputObjectText.color;
_config.Align = _inputObjectText.alignment.ToString ();
_config.ContentType = _inputObject.contentType.ToString ();
_config.BackgroundColor = _inputObject.colors.normalColor;
_config.Multiline = (_inputObject.lineType == InputField.LineType.SingleLine) ? false : true;
_config.KeyboardType = _inputObject.keyboardType.ToString ();
_config.InputType = _inputObject.inputType.ToString ();
}
/// <summary>
/// Text change callback
/// </summary>
/// <param name="text">new text</param>
private void OnTextChange (string text) {
if (text == this._inputObject.text) {
return;
}
this._inputObject.text = text;
if (this._inputObject.onValueChanged != null) {
this._inputObject.onValueChanged.Invoke (text);
}
}
/// <summary>
/// Text change end callback
/// </summary>
/// <param name="text">text</param>
private void OnTextEditEnd (string text) {
this._inputObject.text = text;
if (this._inputObject.onEndEdit != null) {
this._inputObject.onEndEdit.Invoke (text);
}
SetFocus (false);
}
/// <summary>
/// Sending data to plugin
/// </summary>
/// <param name="data">JSON</param>
public override void Send (JsonObject data) {
MobileInput.Plugin.StartCoroutine (PluginsMessageRoutine (data));
}
/// <summary>
/// Remove focus, keyboard when app lose focus
/// </summary>
public override void Hide () {
this.SetFocus (false);
}
/// <summary>
/// Coroutine for send, so its not freeze main thread
/// </summary>
/// <param name="data">JSON</param>
private IEnumerator PluginsMessageRoutine (JsonObject data) {
yield return null;
string msg = data["msg"];
if (msg.Equals (TEXT_CHANGE)) {
string text = data["text"];
this.OnTextChange (text);
} else if (msg.Equals (READY)) {
this.Ready ();
} else if (msg.Equals (ON_FOCUS)) {
OnFocusChanged (true);
} else if (msg.Equals (ON_UNFOCUS)) {
OnFocusChanged (false);
} else if (msg.Equals (TEXT_END_EDIT)) {
string text = data["text"];
this.OnTextEditEnd (text);
} else if (msg.Equals (RETURN_PRESSED)) {
OnReturnPressed ();
if (OnReturnPressedEvent != null) {
OnReturnPressedEvent.Invoke ();
}
}
}
/// <summary>
/// Convert float value to InvariantCulture string
/// </summary>
/// <param name="value">float value</param>
/// <returns></returns>
private string InvariantCultureString (float value){
return value.ToString ("G", System.Globalization.CultureInfo.InvariantCulture);
}
/// <summary>
/// Create native input field
/// </summary>
private void CreateNativeEdit () {
Rect rect = GetScreenRectFromRectTransform (this._inputObjectText.rectTransform);
JsonObject data = new JsonObject ();
data["msg"] = CREATE;
data["x"] = InvariantCultureString(rect.x / Screen.width);
data["y"] = InvariantCultureString(rect.y / Screen.height);
data["width"] = InvariantCultureString(rect.width / Screen.width);
data["height"] = InvariantCultureString(rect.height / Screen.height);
data["character_limit"] = _config.CharacterLimit;
data["text_color_r"] = InvariantCultureString(_config.TextColor.r);
data["text_color_g"] = InvariantCultureString(_config.TextColor.g);
data["text_color_b"] = InvariantCultureString(_config.TextColor.b);
data["text_color_a"] = InvariantCultureString(_config.TextColor.a);
data["back_color_r"] = InvariantCultureString(_config.BackgroundColor.r);
data["back_color_g"] = InvariantCultureString(_config.BackgroundColor.g);
data["back_color_b"] = InvariantCultureString(_config.BackgroundColor.b);
data["back_color_a"] = InvariantCultureString(_config.BackgroundColor.a);
data["font_size"] = InvariantCultureString(_config.FontSize);
data["content_type"] = _config.ContentType;
data["align"] = _config.Align;
data["with_done_button"] = this.IsWithDoneButton;
data["with_clear_button"] = this.IsWithClearButton;
data["placeholder"] = _config.Placeholder;
data["placeholder_color_r"] = InvariantCultureString(_config.PlaceholderColor.r);
data["placeholder_color_g"] = InvariantCultureString(_config.PlaceholderColor.g);
data["placeholder_color_b"] = InvariantCultureString(_config.PlaceholderColor.b);
data["placeholder_color_a"] = InvariantCultureString(_config.PlaceholderColor.a);
data["multiline"] = _config.Multiline;
data["input_type"] = _config.InputType;
data["keyboard_type"] = _config.KeyboardType;
switch (ReturnKey) {
case ReturnKeyType.Next:
data["return_key_type"] = "Next";
break;
case ReturnKeyType.Done:
data["return_key_type"] = "Done";
break;
case ReturnKeyType.Search:
data["return_key_type"] = "Search";
break;
default:
data["return_key_type"] = "Default";
break;
}
this.Execute (data);
}
/// <summary>
/// New field successfully added
/// </summary>
void Ready () {
_isMobileInputCreated = true;
if (!_isVisibleOnCreate) {
SetVisible (false);
}
if (_isFocusOnCreate) {
SetFocus (true);
}
}
/// <summary>
/// Set text to field
/// </summary>
/// <param name="text">New text</param>
void SetTextNative (string text) {
JsonObject data = new JsonObject ();
data["msg"] = SET_TEXT;
data["text"] = text;
this.Execute (data);
}
/// <summary>
/// Remove field
/// </summary>
private void RemoveNative () {
JsonObject data = new JsonObject ();
data["msg"] = REMOVE;
this.Execute (data);
}
/// <summary>
/// Set new size and position
/// </summary>
/// <param name="inputRect">RectTransform</param>
public void SetRectNative (RectTransform inputRect) {
Rect rect = GetScreenRectFromRectTransform (inputRect);
if (_lastRect == rect) {
return;
}
_lastRect = rect;
JsonObject data = new JsonObject ();
data["msg"] = SET_RECT;
data["x"] = InvariantCultureString(rect.x / Screen.width);
data["y"] = InvariantCultureString(rect.y / Screen.height);
data["width"] = InvariantCultureString(rect.width / Screen.width);
data["height"] = InvariantCultureString(rect.height / Screen.height);
this.Execute (data);
}
/// <summary>
/// Set focus on field
/// </summary>
/// <param name="isFocus">true | false</param>
public void SetFocus (bool isFocus) {
#if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR
if (!_isMobileInputCreated) {
_isFocusOnCreate = isFocus;
return;
}
JsonObject data = new JsonObject ();
data["msg"] = SET_FOCUS;
data["is_focus"] = isFocus;
this.Execute (data);
#else
if (gameObject.activeInHierarchy) {
if (isFocus) {
_inputObject.ActivateInputField ();
} else {
_inputObject.DeactivateInputField ();
}
} else {
_isFocusOnCreate = isFocus;
}
#endif
}
/// <summary>
/// Set field visible
/// </summary>
/// <param name="isVisible">true | false</param>
public void SetVisible (bool isVisible) {
if (!_isMobileInputCreated) {
_isVisibleOnCreate = isVisible;
return;
}
JsonObject data = new JsonObject ();
data["msg"] = SET_VISIBLE;
data["is_visible"] = isVisible;
this.Execute (data);
this.Visible = isVisible;
}
#if UNITY_ANDROID && !UNITY_EDITOR
/// <summary>
/// Send android button state
/// </summary>
/// <param name="key">Code</param>
private void ForceSendKeydownAndroid (string key) {
JsonObject data = new JsonObject ();
data["msg"] = ANDROID_KEY_DOWN;
data["key"] = key;
this.Execute (data);
}
/// <summary>
/// Keyboard handler
/// </summary>
private void UpdateForceKeyeventForAndroid () {
if (UnityEngine.Input.anyKeyDown) {
if (UnityEngine.Input.GetKeyDown (KeyCode.Backspace)) {
this.ForceSendKeydownAndroid ("backspace");
} else {
foreach (char c in UnityEngine.Input.inputString) {
if (c == '\n') {
this.ForceSendKeydownAndroid ("enter");
} else {
this.ForceSendKeydownAndroid (Input.inputString);
}
}
}
}
}
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7efa08dd091db4556b539d69d5505878
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
// ----------------------------------------------------------------------------
// The MIT License
// UnityMobileInput https://github.com/mopsicus/UnityMobileInput
// Copyright (c) 2018 Mopsicus <mail@mopsicus.ru>
// ----------------------------------------------------------------------------
using UnityEngine;
using System;
using System.Collections.Generic;
using NiceJson;
#if UNITY_IOS
using System.Runtime.InteropServices;
#endif
namespace Mopsicus.Plugins {
/// <summary>
/// Mobile plugin interface
/// Each plugin must implement it
/// </summary>
public interface IPlugin {
/// <summary>
/// Plaugin name
/// </summary>
string Name { get; }
/// <summary>
/// Callback on get data
/// </summary>
void OnData (JsonObject data);
/// <summary>
/// Callback on get error
/// </summary>
void OnError (JsonObject data);
}
/// <summary>
/// Plugin service to manager all mobile plugins
/// </summary>
public class Plugins : MonoBehaviour {
#if UNITY_ANDROID
/// <summary>
/// Mask for Java classes
/// </summary>
public const string ANDROID_CLASS_MASK = "ru.mopsicus.{0}.Plugin";
#elif UNITY_IOS
/// <summary>
/// Init iOS plugins
/// </summary>
[DllImport ("__Internal")]
private static extern void pluginsInit (string data);
#endif
/// <summary>
/// Gameobject name on scene to receive data
/// ACHTUNG! Do not change it
/// </summary>
const string _dataObject = "Plugins";
/// <summary>
/// Function name to receive data
/// ACHTUNG! Do not change it
/// </summary>
const string _dataReceiver = "OnDataReceive";
/// <summary>
/// Dictionary of plugins
/// </summary>
private Dictionary<string, IPlugin> _plugins;
private void Awake () {
name = _dataObject;
DontDestroyOnLoad (gameObject);
InitPlugins ();
}
private void OnDestroy () {
_plugins = null;
}
/// <summary>
/// Init all plugins in app
/// </summary>
void InitPlugins () {
gameObject.AddComponent<MobileInput> ();
//
// other plugins
//
IPlugin[] plugins = GetComponents<IPlugin> ();
_plugins = new Dictionary<string, IPlugin> (plugins.Length);
foreach (var item in plugins) {
_plugins.Add (item.Name, item);
}
JsonObject data = new JsonObject ();
data["object"] = _dataObject;
data["receiver"] = _dataReceiver;
#if UNITY_IOS
pluginsInit (data.ToJsonString ());
#endif
Debug.Log ("Plugins init");
}
/// <summary>
/// Handler to process data to plugin
/// </summary>
/// <param name="data">data from plugin</param>
void OnDataReceive (string data) {
Debug.Log ("Plugins receive data: " + data);
try {
JsonObject info = (JsonObject) JsonNode.ParseJsonString (data);
if (_plugins.ContainsKey (info["name"])) {
IPlugin plugin = _plugins[info["name"]];
if (info.ContainsKey ("error")) {
plugin.OnError (info);
} else {
plugin.OnData (info);
}
} else {
Debug.LogError (string.Format ("{0} plugin does not exists", info["name"]));
}
} catch (Exception e) {
Debug.LogError (string.Format ("Plugins receive error: {0}, stack: {1}", e.Message, e.StackTrace));
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: af391257446ba4bc6b9124b683ceb46a
timeCreated: 1522834071
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: