6 заметок с тегом

с#

Кликабельные ссылки в TextMeshPro

Как сделать чтобы ссылки в тексте, стали «ссылками» и при клике на них открывалась страница? Просто! Достаточно открыть примеры из TextMeshPro (TMP) и добавить немного кода.

Пускай у нас есть компонент ТМР с текстом, в котором встречаются ссылки на страницы в сети, например: http://mopsicus.ru, www.unity3d.com, и другие. И нужно чтобы это выглядело примерно так, и было кликабельно:

Для этого, находим ссылки в тексте с помощью регулярного выражения, сокращаем их (по желанию) и приводим к формату для обработки ТМР.

// Check links in text
void CheckLinks () {
	Regex regx = new Regex ("((http://|https://|www\\.)([A-Z0-9.-:]{1,})\\.[0-9A-Z?;~&#=\\-_\\./]{2,})" , RegexOptions.IgnoreCase | RegexOptions.Singleline); 
	MatchCollection matches = regx.Matches (textMessage.text); 
	foreach (Match match in matches) 
		textMessage.text = textMessage.text.Replace (match.Value, ShortLink(match.Value));     	
}

// Cut long url
string ShortLink (string link) {
	string text = link;
	int left = 9; 		
	int right = 16; 		
	string cut = "..."; 	
	if (link.Length > (left + right + cut.Length)) 
		text = string.Format ("{0}{1}{2}", link.Substring (0, left), cut, link.Substring (link.Length - right, right));
	return string.Format("<#7f7fe5><u><link=\"{0}\">{1}</link></u></color>", link, text);
}

Как установить подчеркивание, цвет текста и другое смотрите в документации ТМР. Осталось повесить обработчик нажатия и определить на какую ссылку кликнули:

// Get link and open page
public void OnPointerClick (PointerEventData eventData) {
	int linkIndex = TMP_TextUtilities.FindIntersectingLink (textMessage, eventData.position, eventData.pressEventCamera);
	if (linkIndex == -1) 
		return;
	TMP_LinkInfo linkInfo = textMessage.textInfo.linkInfo[linkIndex];
	string selectedLink = linkInfo.GetLinkID();
	if (selectedLink != "") {
		Debug.LogFormat ("Open link {0}", selectedLink);
		Application.OpenURL (selectedLink);        
	}
}

Исходник на Github

17 мая   unity   разработка   с#

Баг в userInfo NotificationItem [iOS]

Если вы работаете с пуш уведомлениями в iOS и делаете это стандартными средствами Unity, то при обработке уведомления у вас могут возникнуть сложности с цифровыми значениями. Видимо Unity сам преобразует их в Int64. В тоже время, с текстовыми полями все в порядке.
Чтобы получить «нормальное» цифровое значение из пуша и преобразовать в Int, можно воспользоваться таким способом:

...
int my_int_value = 0;
object data = push.userInfo["my_int_value"];
if (data is Int64)
	my_int_value = ConvertInt64ToInt32((Int64)data);
...
// Convert function
int ConvertInt64ToInt32 (Int64 val) {
	return (int)(val & 0xFFFFFFFF);
}

Но как показывает практика, лучше использовать нативный плагин :)

13 мая   ios   unity   с#

SSL/TLS в Unity

А сегодня мы будем шифровать весь трафик. А зачем? А чтобы усложнить жизнь читерам.

Если у вас мультиплеер на авторитарном сервере, естественно все действия должны контролироваться на нем. Но зная, какие команды отправлять, можно легко написать бота, который автоматизирует некоторые процессы, нарушая баланс и игру «правильных» игроков. Конечно, если сильно захотеть, можно сломать все что угодно, но усложнить жизнь взломщикам и читерам тоже можно. Будем использовать SSL.

Ничего изобретать не буду, потому что «все уже придумано до нас» :)
Для теста серверной части (на node.js) и генерации ключей используем эти скрипты. Единственное, чего там нет — это как из сертификата и ключа сделать PFX файл:

openssl pkcs12 -export -in client.crt -inkey client.key -out mycert.pfx

Этот файл понадобится для клиента. Для проверки SSL соединения берем пример с сокетами с MSDN и немного переделываем его. Получаем поток и прокидываем его через SSL.

IEnumerator UseSSL () {
	NetworkStream stream = new NetworkStream (socket);
	SslStream sslStream = new SslStream (stream, false, new RemoteCertificateValidationCallback (CertificateValidationCallback), new LocalCertificateSelectionCallback (CertificateSelectionCallback));
	bool authenticationPassed = true;		
	#if UNITY_EDITOR
		X509Certificate2 cert = new X509Certificate2(certPath, certPassword);
	#elif UNITY_ANDROID || UNITY_IOS
		WWW reader = new WWW (certPath);
		while (!reader.isDone) 
			yield return null;
		X509Certificate2 cert = new X509Certificate2 (reader.bytes, certPassword);
	#endif
	X509Certificate2Collection certs = new X509Certificate2Collection();
	certs.Add (cert);
	sslStream.AuthenticateAsClient (server, certs, SslProtocols.Tls, true);
	authenticationPassed = sslStream.IsAuthenticated;
	if (authenticationPassed) {
              ///
	}
	yield break;
}

Вот и весь квест. Теперь трафик между игровым сервером и клиентом зашифрован.

Ccылка на Github

2017   git   unity   разработка   с#

Система плагинов для iOS и Android

Простая система плагинов для мобилок. Контроллер инициализирует все плагины и обрабатывает приходящие сообщения. Обмен данными в формате JSON.

Вообще, печаль конечно, что Unity не реализует даже самые простые варианты работы с мобильными платформами, тот же браузер или камера. Может когда-нибудь...

Ссылка на Github

2017   android   ios   plugin   unity   разработка   с#

Cериализация в XML и обратно

Обновлено 17.04.17
Продвинутая версия сериализации в XML, работает в несколько раз быстрее штатной

Как преобразовать объект в строку, например для сохранения или передачи, а потом обратно? Есть две простые функции, которые я использовал в одном из Unity проектов:

public static object Deserialize<T> (string toDeserialize) {
	XmlSerializer xmlSerializer = new XmlSerializer (typeof (T));
	StringReader textReader = new StringReader (toDeserialize);
	return xmlSerializer.Deserialize (textReader);
}

public static string Serialize<T> (T toSerialize) {
	XmlSerializer xmlSerializer = new XmlSerializer (typeof (T));
	StringWriter textWriter = new StringWriter ();
	xmlSerializer.Serialize (textWriter, toSerialize);
	return textWriter.ToString ();
}

Использовать очень просто:

Vectror3 vector = new Vector3 (10f, 10f, 10f); // какой-то объект
string data = Serialize<Vector3> (vector); // преобразовываем в строку
vector = (Vector3) Deserialize<Vector3> (data); // обратно из строки в объект
2017   unity   разработка   с#