first commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 914613548ded44a43a59eb9852503f18
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using UnityEngine;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
public class TMP_CanvasTests
|
||||
{
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (!Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")))
|
||||
{
|
||||
Debug.Log("Skipping over Editor tests as TMP Essential Resources are missing from the current test project.");
|
||||
Assert.Ignore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnablingAndDisablingCanvasDoesNotRegenerateText() // (UUM-45320)
|
||||
{
|
||||
var go = new GameObject();
|
||||
var canvas = go.AddComponent<Canvas>();
|
||||
|
||||
var goChild = new GameObject();
|
||||
var text = goChild.AddComponent<TextMeshProUGUI>();
|
||||
|
||||
goChild.transform.SetParent(go.transform);
|
||||
|
||||
// Force text to be generated
|
||||
text.text = "Hello World";
|
||||
text.ForceMeshUpdate();
|
||||
|
||||
Assert.IsFalse(text.havePropertiesChanged, "Text should not have changed yet");
|
||||
|
||||
canvas.enabled = false;
|
||||
canvas.enabled = true;
|
||||
|
||||
Assert.IsFalse(text.havePropertiesChanged, "Text should not have changed after enabling / disabling canvas");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5348cbfcd4f74699b33fe6b43747a016
|
||||
timeCreated: 1703006962
|
||||
@@ -0,0 +1,278 @@
|
||||
using UnityEngine;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace TMPro
|
||||
{
|
||||
[Category("Text Parsing & Layout")]
|
||||
class TMP_RuntimeTests
|
||||
{
|
||||
private TextMeshPro m_TextComponent;
|
||||
|
||||
// Characters: 22 Spaces: 4 Words: 5 Lines:
|
||||
private const string m_TextBlock_00 = "A simple line of text.";
|
||||
|
||||
// Characters: 104 Spaces: 14 Words: 15 Lines:
|
||||
private const string m_TextBlock_01 = "Unity 2017 introduces new features that help teams of artists and developers build experiences together.";
|
||||
|
||||
// Characters: 1500 Spaces: 228 Words: 241
|
||||
private const string m_TextBlock_02 = "The European languages are members of the same family. Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary. The languages only differ in their grammar, their pronunciation and their most common words." +
|
||||
"Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages." +
|
||||
"The new common language will be more simple and regular than the existing European languages.It will be as simple as Occidental; in fact, it will be Occidental.To an English person, it will seem like simplified English, as a skeptical Cambridge friend of mine told me what Occidental is. The European languages are members of the same family." +
|
||||
"Their separate existence is a myth. For science, music, sport, etc, Europe uses the same vocabulary.The languages only differ in their grammar, their pronunciation and their most common words.Everyone realizes why a new common language would be desirable: one could refuse to pay expensive translators.To achieve this, it would be necessary to" +
|
||||
"have uniform grammar, pronunciation and more common words.If several languages coalesce, the grammar of the resulting language is more simple and regular than that of the individual languages.The new common language will be";
|
||||
|
||||
// Characters: 2500 Spaces: 343 Words: 370
|
||||
private const string m_TextBlock_03 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. " +
|
||||
"Nullam dictum felis eu pede mollis pretium.Integer tincidunt.Cras dapibus.Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. " +
|
||||
"Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante.Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. " +
|
||||
"Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. " +
|
||||
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. " +
|
||||
"Etiam imperdiet imperdiet orci. Nunc nec neque.Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent nan. The end of this of this long block of text.";
|
||||
|
||||
// Characters: 3423 Spaces: 453 Words: 500
|
||||
private const string m_TextBlock_04 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Aenean commodo ligula eget dolor.Aenean massa.Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.Nulla consequat massa quis enim.Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.Nullam dictum felis eu pede mollis pretium.Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus." +
|
||||
"Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim.Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.Phasellus viverra nulla ut metus varius laoreet.Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.Curabitur ullamcorper ultricies nisi. Nam eget dui.Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.Maecenas nec odio et ante tincidunt tempus.Donec vitae sapien ut libero venenatis faucibus.Nullam quis ante." +
|
||||
"Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus.Nullam accumsan lorem in dui.Cras ultricies mi eu turpis hendrerit fringilla.Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.Nam pretium turpis et arcu." +
|
||||
"Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris.Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris.Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc.Nunc nonummy metus.Vestibulum volutpat pretium libero. Cras id dui.Aenean ut eros et nisl sagittis vestibulum.Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede.Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis.Etiam imperdiet imperdiet orci. Nunc nec neque." +
|
||||
"Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo.Maecenas malesuada. Praesent congue erat at massa.Sed cursus turpis vitae tortor.Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci.Phasellus consectetuer vestibulum elit.Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.Vestibulum fringilla pede sit amet augue." +
|
||||
"In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis.Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus.Ut varius tincidunt libero.Phasellus dolor.Maecenas vestibulum mollis";
|
||||
|
||||
//
|
||||
private const string m_TextBlock_05 = "This block of text contains <b>bold</b> and <i>italicized</i> characters.";
|
||||
|
||||
private const string m_TextBlock_06 = "<align=center><style=H1><#ffffff><u>Multiple<#80f0ff> Alignment</color> per text object</u></color></style></align><line-height=2em>\n" +
|
||||
"</line-height> The <<#ffffa0>align</color>> tag in TextMesh<#40a0ff>Pro</color> provides the ability to control the alignment of lines and paragraphs which is essential when working with text.\n" +
|
||||
"<align=left> You may want some block of text to be<#80f0ff>left aligned</color> <<#ffffa0>align=<#80f0ff>left</color></color>> which is sort of the standard.</align>\n" +
|
||||
"<style=Quote><#ffffa0>\"Using <#80f0ff>Center Alignment</color> <<#ffffa0>align=<#80f0ff>center</color></color>> for a title or displaying a quote is another good example of text alignment.\"</color></style>\n" +
|
||||
"<align=right><#80f0ff>Right Alignment</color> <<#ffffa0>align=<#80f0ff>right</color></color>> can be useful to create contrast between lines and paragraphs of text.\n" +
|
||||
"<align=justified><#80f0ff>Justified Alignment</color> <<#ffffa0>align=<#80f0ff>justified</color></color>> results in text that is flush on both the left and right margins. Used well, justified type can look clean and classy.\n" +
|
||||
"<style=Quote><align=left><#ffffa0>\"Text formatting and alignment has a huge impact on how people will read and perceive your text.\"</color>\n" +
|
||||
"<size=65%><align=right> -Stephan Bouchard</style>";
|
||||
|
||||
private readonly string[] testStrings = new string[] { m_TextBlock_00, m_TextBlock_01, m_TextBlock_02, m_TextBlock_03, m_TextBlock_04, m_TextBlock_05, m_TextBlock_06 };
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (Directory.Exists(Path.GetFullPath("Assets/TextMesh Pro")) || Directory.Exists(Path.GetFullPath("Packages/com.unity.textmeshpro.tests/TextMesh Pro")))
|
||||
{
|
||||
GameObject textObject = new GameObject("Text Object");
|
||||
m_TextComponent = textObject.AddComponent<TextMeshPro>();
|
||||
|
||||
m_TextComponent.fontSize = 18;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Skipping over Editor tests as TMP Essential Resources are missing from the current test project.");
|
||||
Assert.Ignore();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_WordWrapDisabled()
|
||||
{
|
||||
yield return new object[] { 0, 22, 4, 5, 1 };
|
||||
yield return new object[] { 1, 104, 14, 15, 1 };
|
||||
yield return new object[] { 2, 1500, 228, 241, 1 };
|
||||
yield return new object[] { 3, 2500, 343, 370, 1 };
|
||||
yield return new object[] { 4, 3423, 453, 500, 1 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("TestCases_Parsing_TextInfo_WordWrapDisabled")]
|
||||
public void Parsing_TextInfo_WordWrapDisabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
|
||||
{
|
||||
m_TextComponent.text = testStrings[sourceTextIndex];
|
||||
m_TextComponent.textWrappingMode = TextWrappingModes.NoWrap;
|
||||
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
|
||||
|
||||
// Size the RectTransform
|
||||
m_TextComponent.rectTransform.sizeDelta = new Vector2(50, 5);
|
||||
|
||||
// Force text generation to populate the TextInfo data structure.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_WordWrapEnabled()
|
||||
{
|
||||
yield return new object[] { 0, 22, 4, 5, 1 };
|
||||
yield return new object[] { 1, 104, 14, 15, 1 };
|
||||
yield return new object[] { 2, 1500, 228, 241, 13 };
|
||||
yield return new object[] { 3, 2500, 343, 370, 21 };
|
||||
yield return new object[] { 4, 3423, 453, 500, 29 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("TestCases_Parsing_TextInfo_WordWrapEnabled")]
|
||||
public void Parsing_TextInfo_WordWrapEnabled(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
|
||||
{
|
||||
m_TextComponent.text = testStrings[sourceTextIndex];
|
||||
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
|
||||
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
|
||||
|
||||
// Size the RectTransform
|
||||
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
|
||||
|
||||
// Force text generation to populate the TextInfo data structure.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_AlignmentTopJustified()
|
||||
{
|
||||
yield return new object[] { 2, 1500, 228, 241, 13 };
|
||||
yield return new object[] { 3, 2500, 343, 370, 20 };
|
||||
yield return new object[] { 4, 3423, 453, 500, 27 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("TestCases_Parsing_TextInfo_AlignmentTopJustified")]
|
||||
public void Parsing_TextInfo_AlignmentTopJustified(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
|
||||
{
|
||||
m_TextComponent.text = testStrings[sourceTextIndex];
|
||||
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
|
||||
m_TextComponent.alignment = TextAlignmentOptions.TopJustified;
|
||||
|
||||
// Size the RectTransform
|
||||
m_TextComponent.rectTransform.sizeDelta = new Vector2(100, 50);
|
||||
|
||||
// Force text generation to populate the TextInfo data structure.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<object[]> TestCases_Parsing_TextInfo_RichText()
|
||||
{
|
||||
yield return new object[] { 5, 59, 8, 9, 1 };
|
||||
yield return new object[] { 6, 768, 124, 126, 14 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("TestCases_Parsing_TextInfo_RichText")]
|
||||
public void Parsing_TextInfo_RichText(int sourceTextIndex, int characterCount, int spaceCount, int wordCount, int lineCount)
|
||||
{
|
||||
m_TextComponent.text = testStrings[sourceTextIndex];
|
||||
m_TextComponent.textWrappingMode = TextWrappingModes.Normal;
|
||||
m_TextComponent.alignment = TextAlignmentOptions.TopLeft;
|
||||
|
||||
// Size the RectTransform
|
||||
m_TextComponent.rectTransform.sizeDelta = new Vector2(70, 35);
|
||||
|
||||
// Force text generation to populate the TextInfo data structure.
|
||||
m_TextComponent.ForceMeshUpdate();
|
||||
|
||||
Assert.AreEqual(m_TextComponent.textInfo.characterCount, characterCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.spaceCount, spaceCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.wordCount, wordCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, lineCount);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TestCases_MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine()
|
||||
{
|
||||
yield return new object[] { 1, 1 };
|
||||
yield return new object[] { 2, 2 };
|
||||
yield return new object[] { 3, 3 };
|
||||
yield return new object[] { 4, 4 };
|
||||
yield return new object[] { 5, 5 };
|
||||
yield return new object[] { 6, 6 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(nameof(TestCases_MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine))]
|
||||
public void MultiLineNewline_OnLastLine_WhenPressedEnter_Caret_ShouldNotGoto_NextLine(int lineLimit,
|
||||
int expectedLineCount)
|
||||
{
|
||||
MultiLineNewline_LineLimit_ExpectedLineCount_Logic(lineLimit, lineLimit, 3);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, expectedLineCount);
|
||||
}
|
||||
|
||||
private void MultiLineNewline_LineLimit_ExpectedLineCount_Logic(int lineLimitValue, int lineLimitApplied,
|
||||
int extraKeyDownEventCount)
|
||||
{
|
||||
GameObject cameraObject = new GameObject("Camera Object", typeof(Camera));
|
||||
GameObject canvasObject = new GameObject("Canvas Object", typeof(Canvas), typeof(GraphicRaycaster));
|
||||
canvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
GameObject inputObject = new GameObject("Input Object", typeof(TMP_InputField));
|
||||
inputObject.transform.parent = canvasObject.transform;
|
||||
inputObject.AddComponent<Image>();
|
||||
TMP_InputField m_InputField = inputObject.GetComponent<TMP_InputField>();
|
||||
m_InputField.targetGraphic = inputObject.GetComponent<Image>();
|
||||
m_InputField.textComponent = m_TextComponent;
|
||||
m_InputField.lineType = TMP_InputField.LineType.MultiLineNewline;
|
||||
m_InputField.lineLimit = lineLimitValue;
|
||||
|
||||
GameObject eventGameObject = new GameObject("Event Object", typeof(EventSystem), typeof(StandaloneInputModule));
|
||||
Event enterKeyDownEvent = new Event { type = EventType.KeyDown, keyCode = KeyCode.KeypadEnter, modifiers = EventModifiers.None, character = '\n' };
|
||||
|
||||
m_InputField.text = "POTUS";
|
||||
EventSystem.current.SetSelectedGameObject(inputObject);
|
||||
m_InputField.ActivateInputField();
|
||||
int count = lineLimitApplied + extraKeyDownEventCount;
|
||||
while (count > 0)
|
||||
{
|
||||
m_InputField.ProcessEvent(enterKeyDownEvent);
|
||||
m_InputField.ForceLabelUpdate();
|
||||
count--;
|
||||
}
|
||||
|
||||
m_InputField.textComponent.ForceMeshUpdate();
|
||||
CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(m_InputField);
|
||||
|
||||
m_InputField.DeactivateInputField();
|
||||
GameObject.Destroy(eventGameObject);
|
||||
GameObject.Destroy(inputObject);
|
||||
GameObject.Destroy(canvasObject);
|
||||
GameObject.Destroy(cameraObject);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TestCases_MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine()
|
||||
{
|
||||
yield return new object[] { 0, 0, 1 };
|
||||
yield return new object[] { 0, 0, 4 };
|
||||
yield return new object[] { -1, 0, 2 };
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(nameof(TestCases_MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine))]
|
||||
public void MultiLineNewLine_NegativeOrZeroLineLimit_AddsNewLine(int lineLimitValue, int lineLimitApplied,
|
||||
int extraKeyDownEventCount)
|
||||
{
|
||||
MultiLineNewline_LineLimit_ExpectedLineCount_Logic(lineLimitValue, lineLimitApplied, extraKeyDownEventCount);
|
||||
Assert.AreEqual(m_TextComponent.textInfo.lineCount, extraKeyDownEventCount + 1);
|
||||
}
|
||||
|
||||
//[OneTimeTearDown]
|
||||
//public void Cleanup()
|
||||
//{
|
||||
// // Remove TMP Essential Resources if they were imported in the project as a result of running tests.
|
||||
// if (TMPro_EventManager.temporaryResourcesImported == true)
|
||||
// {
|
||||
// string testResourceFolderPath = Path.GetFullPath("Assets/TextMesh Pro");
|
||||
|
||||
// if (Directory.Exists(testResourceFolderPath))
|
||||
// {
|
||||
// Directory.Delete(testResourceFolderPath);
|
||||
// File.Delete(Path.GetFullPath("Assets/TextMesh Pro.meta"));
|
||||
// }
|
||||
|
||||
// TMPro_EventManager.temporaryResourcesImported = false;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9de24983a2c6cbe4f925c3e98a79b804
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Unity.TextMeshPro.Tests",
|
||||
"references": [
|
||||
"Unity.TextMeshPro"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb05cab7d802aa5468f8f2f86840d984
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53caebc5909234b4ebe1fcaf3dc913a5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 239dd6edc8e5cd14585c03e09e86a747
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine;
|
||||
|
||||
public class ButtonTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/ButtonPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
var canvas = canvasGO.GetComponent<Canvas>();
|
||||
canvas.referencePixelsPerUnit = 100;
|
||||
GameObject eventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
|
||||
eventSystemGO.transform.SetParent(rootGO.transform);
|
||||
GameObject TestButtonGO = new GameObject("TestButton", typeof(RectTransform), typeof(TestButton));
|
||||
TestButtonGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("ButtonPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PressShouldCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.True(called);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PressInactiveShouldNotCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.enabled = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.False(called);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PressNotInteractableShouldNotCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.interactable = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.False(called);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectShouldHoldThePreviousStateAfterDisablingAndEnabling()
|
||||
{
|
||||
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
|
||||
button.onClick.AddListener(() => {
|
||||
button.Select();
|
||||
button.enabled = false;
|
||||
});
|
||||
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.False(button.enabled, "Expected button to not be enabled");
|
||||
button.enabled = true;
|
||||
Assert.True(button.isStateSelected, "Expected selected state to be true");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubmitShouldCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnSubmit(null);
|
||||
Assert.True(called);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubmitInactiveShouldNotCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.enabled = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.False(called);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SubmitNotInteractableShouldNotCallClickHandler()
|
||||
{
|
||||
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
|
||||
bool called = false;
|
||||
button.interactable = false;
|
||||
button.onClick.AddListener(() => { called = true; });
|
||||
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
|
||||
Assert.False(called);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SubmitShouldTransitionToPressedStateAndBackToNormal()
|
||||
{
|
||||
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
|
||||
Assert.True(button.IsTransitionToNormal(0));
|
||||
|
||||
button.OnSubmit(null);
|
||||
Assert.True(button.isStateNormal);
|
||||
Assert.True(button.IsTransitionToPressed(1));
|
||||
yield return new WaitWhile(() => button.StateTransitionCount == 2);
|
||||
|
||||
// 3rd transition back to normal should have started
|
||||
Assert.True(button.IsTransitionToNormal(2));
|
||||
yield return null;
|
||||
|
||||
Assert.True(button.isStateNormal);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ef2923b9c5521948a04299da53ae750
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UI;
|
||||
|
||||
class TestButton : Button
|
||||
{
|
||||
public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } }
|
||||
public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } }
|
||||
public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } }
|
||||
public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } }
|
||||
public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } }
|
||||
|
||||
private bool IsTransitionTo(int index, SelectionState selectionState)
|
||||
{
|
||||
return index < m_StateTransitions.Count && m_StateTransitions[index] == selectionState;
|
||||
}
|
||||
|
||||
public bool IsTransitionToNormal(int index) { return IsTransitionTo(index, SelectionState.Normal); }
|
||||
public bool IsTransitionToHighlighted(int index) { return IsTransitionTo(index, SelectionState.Highlighted); }
|
||||
public bool IsTransitionToPressed(int index) { return IsTransitionTo(index, SelectionState.Pressed); }
|
||||
public bool IsTransitionToDisabled(int index) { return IsTransitionTo(index, SelectionState.Disabled); }
|
||||
|
||||
private readonly List<SelectionState> m_StateTransitions = new List<SelectionState>();
|
||||
|
||||
public int StateTransitionCount { get { return m_StateTransitions.Count; } }
|
||||
|
||||
protected override void DoStateTransition(SelectionState state, bool instant)
|
||||
{
|
||||
m_StateTransitions.Add(state);
|
||||
base.DoStateTransition(state, instant);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f5ed95515938d14189b094f8654d0bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a3557da07c729b4eb774b8e30e157a4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class BridgeScriptForRetainingObjects : MonoBehaviour
|
||||
{
|
||||
public const string bridgeObjectName = "BridgeGameObject";
|
||||
|
||||
public GameObject canvasGO;
|
||||
public GameObject nestedCanvasGO;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a26e19d51cbfac42a02631ad1f9e39e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,203 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[TestFixture]
|
||||
public class CanvasGroupTests
|
||||
{
|
||||
GameObject m_CanvasObject;
|
||||
CanvasGroup m_CanvasGroup;
|
||||
|
||||
CanvasRenderer m_ChildCanvasRenderer;
|
||||
CanvasGroup m_ChildCanvasGroup;
|
||||
|
||||
CanvasRenderer m_GrandChildCanvasRenderer;
|
||||
CanvasGroup m_GrandChildCanvasGroup;
|
||||
|
||||
GameObject m_CanvasTwoObject;
|
||||
CanvasGroup m_CanvasTwoGroup;
|
||||
|
||||
CanvasRenderer m_ChildCanvasTwoRenderer;
|
||||
|
||||
const float m_CanvasAlpha = 0.25f;
|
||||
const float m_ChildAlpha = 0.5f;
|
||||
const float m_GrandChildAlpha = 0.8f;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CanvasObject = new GameObject("Canvas", typeof(Canvas));
|
||||
m_CanvasGroup = m_CanvasObject.AddComponent<CanvasGroup>();
|
||||
m_CanvasGroup.alpha = m_CanvasAlpha;
|
||||
|
||||
var childObject = new GameObject("Child Object", typeof(Image));
|
||||
childObject.transform.SetParent(m_CanvasObject.transform);
|
||||
m_ChildCanvasGroup = childObject.AddComponent<CanvasGroup>();
|
||||
m_ChildCanvasGroup.alpha = m_ChildAlpha;
|
||||
m_ChildCanvasRenderer = childObject.GetComponent<CanvasRenderer>();
|
||||
|
||||
var grandChildObject = new GameObject("Grand Child Object", typeof(Image));
|
||||
grandChildObject.transform.SetParent(childObject.transform);
|
||||
m_GrandChildCanvasGroup = grandChildObject.AddComponent<CanvasGroup>();
|
||||
m_GrandChildCanvasGroup.alpha = m_GrandChildAlpha;
|
||||
m_GrandChildCanvasRenderer = grandChildObject.GetComponent<CanvasRenderer>();
|
||||
|
||||
m_CanvasTwoObject = new GameObject("CanvasTwo", typeof(Canvas));
|
||||
m_CanvasTwoObject.transform.SetParent(m_CanvasObject.transform);
|
||||
m_CanvasTwoGroup = m_CanvasTwoObject.AddComponent<CanvasGroup>();
|
||||
m_CanvasTwoGroup.alpha = m_CanvasAlpha;
|
||||
|
||||
var childTwoObject = new GameObject("Child Two Object", typeof(Image));
|
||||
childTwoObject.transform.SetParent(m_CanvasTwoObject.transform);
|
||||
m_ChildCanvasTwoRenderer = childTwoObject.GetComponent<CanvasRenderer>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasObject);
|
||||
}
|
||||
|
||||
private void SetUpCanvasGroupState()
|
||||
{
|
||||
m_CanvasGroup.enabled = false;
|
||||
m_CanvasGroup.ignoreParentGroups = false;
|
||||
m_ChildCanvasGroup.enabled = false;
|
||||
m_ChildCanvasGroup.ignoreParentGroups = false;
|
||||
m_GrandChildCanvasGroup.enabled = false;
|
||||
m_GrandChildCanvasGroup.ignoreParentGroups = false;
|
||||
|
||||
m_CanvasTwoGroup.enabled = false;
|
||||
m_CanvasTwoGroup.ignoreParentGroups = false;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupEffectSelfAndChildrenAlpha()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the child CanvasGroup. It and its children should now have the same alpha value.
|
||||
m_ChildCanvasGroup.enabled = true;
|
||||
|
||||
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnACanvasEffectAllChildrenAlpha()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Children under a different nest canvas should also obey the alpha
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
|
||||
m_CanvasGroup.enabled = true;
|
||||
|
||||
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_CanvasAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Children under a different nest canvas should also obey the alpha
|
||||
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnLeafChildEffectOnlyThatChild()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Leaf child CanvasGroup. Only it should have a modified alpha
|
||||
m_GrandChildCanvasGroup.enabled = true;
|
||||
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnCanvasAndChildMultipleAlphaValuesCorrectly()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
|
||||
m_CanvasGroup.enabled = true;
|
||||
m_ChildCanvasGroup.enabled = true;
|
||||
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnCanvasAndChildWithChildIgnoringParentGroupMultipleAlphaValuesCorrectly()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
|
||||
m_CanvasGroup.enabled = true;
|
||||
m_ChildCanvasGroup.enabled = true;
|
||||
m_ChildCanvasGroup.ignoreParentGroups = true;
|
||||
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnCanvasAndChildrenWithAllChildrenIgnoringParentGroupMultipleAlphaValuesCorrectly()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
|
||||
m_CanvasGroup.enabled = true;
|
||||
m_ChildCanvasGroup.enabled = true;
|
||||
m_GrandChildCanvasGroup.enabled = true;
|
||||
m_ChildCanvasGroup.ignoreParentGroups = true;
|
||||
m_GrandChildCanvasGroup.ignoreParentGroups = true;
|
||||
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
|
||||
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EnabledCanvasGroupOnNestedCanvasIgnoringParentGroupMultipleAlphaValuesCorrectly()
|
||||
{
|
||||
// Set up the states of the canvas groups for the tests.
|
||||
SetUpCanvasGroupState();
|
||||
|
||||
// With no enabled CanvasGroup the Alphas should be 1
|
||||
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
|
||||
|
||||
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
|
||||
m_CanvasGroup.enabled = true;
|
||||
m_CanvasTwoGroup.enabled = true;
|
||||
m_CanvasTwoGroup.ignoreParentGroups = true;
|
||||
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a14a59f2a5c757e469c3e4e17b798c2e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor;
|
||||
|
||||
[TestFixture]
|
||||
public class CanvasResizeCorrectlyForRenderTexture
|
||||
{
|
||||
Canvas m_Canvas;
|
||||
Camera m_Camera;
|
||||
RenderTexture m_RenderTexture;
|
||||
|
||||
[Test]
|
||||
public void CanvasResizeCorrectly()
|
||||
{
|
||||
var cameraGameObject = new GameObject("PreviewCamera", typeof(Camera));
|
||||
var canvasGameObject = new GameObject("Canvas", typeof(Canvas));
|
||||
m_Camera = cameraGameObject.GetComponent<Camera>();
|
||||
m_Canvas = canvasGameObject.GetComponent<Canvas>();
|
||||
|
||||
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
m_Canvas.worldCamera = m_Camera;
|
||||
var rectTransform = canvasGameObject.transform as RectTransform;
|
||||
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Disabled;
|
||||
m_RenderTexture = new RenderTexture(100, 100, 0);
|
||||
m_Camera.targetTexture = m_RenderTexture;
|
||||
|
||||
m_Camera.Render();
|
||||
|
||||
Assert.AreNotEqual(new Vector2(100, 100), rectTransform.sizeDelta);
|
||||
|
||||
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Enabled;
|
||||
m_Camera.Render();
|
||||
Assert.AreEqual(new Vector2(100, 100), rectTransform.sizeDelta);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_Canvas.gameObject);
|
||||
GameObject.DestroyImmediate(m_Camera.gameObject);
|
||||
UnityEngine.Object.DestroyImmediate(m_RenderTexture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4dbe29df1b294c4f8f0a2fb529d19fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[TestFixture]
|
||||
[Category("RegressionTest")]
|
||||
[Description("CoveredBugID = 734299")]
|
||||
public class CanvasScalerWithChildTextObjectDoesNotCrash
|
||||
{
|
||||
GameObject m_CanvasObject;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.ExecuteMenuItem("Window/General/Game");
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CanvasScalerWithChildTextObjectWithTextFontDoesNotCrash()
|
||||
{
|
||||
//This adds a Canvas component as well
|
||||
m_CanvasObject = new GameObject("Canvas");
|
||||
var canvasScaler = m_CanvasObject.AddComponent<CanvasScaler>();
|
||||
m_CanvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
|
||||
|
||||
//the crash only reproduces if the text component is a child of the game object
|
||||
//that has the CanvasScaler component and if it has an actual font and text set
|
||||
var textObject = new GameObject("Text").AddComponent<UnityEngine.UI.Text>();
|
||||
textObject.font = Font.CreateDynamicFontFromOSFont("Arial", 14);
|
||||
textObject.text = "New Text";
|
||||
textObject.transform.SetParent(m_CanvasObject.transform);
|
||||
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
canvasScaler.referenceResolution = new Vector2(1080, 1020);
|
||||
|
||||
//The crash happens when setting the referenceResolution to a small value
|
||||
canvasScaler.referenceResolution = new Vector2(9, 9);
|
||||
|
||||
//We need to wait a few milliseconds for the crash to happen, otherwise Debug.Log will
|
||||
//get executed and the test will pass
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
|
||||
Assert.That(true);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13d161b14bb3ab74e8a9634e26fb7a5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor;
|
||||
|
||||
[TestFixture]
|
||||
public class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup
|
||||
{
|
||||
const string k_SceneName = "CanvasSizeCorrectInAwakeAndStartScene";
|
||||
GameObject m_CanvasGameObject;
|
||||
Scene m_InitScene;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Action codeToExecute = delegate()
|
||||
{
|
||||
var canvasGO = new GameObject("CanvasToAddImage", typeof(Canvas));
|
||||
var imageGO = new GameObject("ImageOnCanvas", typeof(UnityEngine.UI.Image));
|
||||
imageGO.transform.localPosition = Vector3.one;
|
||||
imageGO.transform.SetParent(canvasGO.transform);
|
||||
imageGO.AddComponent<CanvasSizeCorrectInAwakeAndStartScript>();
|
||||
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
imageGO.SetActive(false);
|
||||
};
|
||||
CreateSceneUtility.CreateScene(k_SceneName, codeToExecute);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_InitScene = SceneManager.GetActiveScene();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CanvasSizeIsCorrectInAwakeAndStart()
|
||||
{
|
||||
AsyncOperation operation = SceneManager.LoadSceneAsync(k_SceneName, LoadSceneMode.Additive);
|
||||
yield return operation;
|
||||
|
||||
SceneManager.SetActiveScene(SceneManager.GetSceneByName(k_SceneName));
|
||||
m_CanvasGameObject = GameObject.Find("CanvasToAddImage");
|
||||
var imageGO = m_CanvasGameObject.transform.Find("ImageOnCanvas");
|
||||
imageGO.gameObject.SetActive(true);
|
||||
var component = imageGO.GetComponent<CanvasSizeCorrectInAwakeAndStartScript>();
|
||||
|
||||
yield return new WaitUntil(() => component.isAwakeCalled && component.isStartCalled);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGameObject);
|
||||
SceneManager.SetActiveScene(m_InitScene);
|
||||
SceneManager.UnloadSceneAsync(k_SceneName);
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset("Assets/" + k_SceneName + ".unity");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec35c13a8280a8d4e817bc4afd8a95de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
public class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour
|
||||
{
|
||||
public bool isStartCalled { get; private set; }
|
||||
public bool isAwakeCalled { get; private set; }
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
|
||||
isAwakeCalled = true;
|
||||
}
|
||||
|
||||
protected void Start()
|
||||
{
|
||||
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
|
||||
isStartCalled = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df1ba932d4ce4534e97a0f10c85cd3c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
[TestFixture]
|
||||
public class CheckMeshColorsAndColors32Match
|
||||
{
|
||||
GameObject m_CanvasGO;
|
||||
GameObject m_ColorMeshGO;
|
||||
GameObject m_Color32MeshGO;
|
||||
Texture2D m_ScreenTexture;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
// Create Canvas
|
||||
m_CanvasGO = new GameObject("Canvas");
|
||||
Canvas canvas = m_CanvasGO.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
// Create Color UI GameObject
|
||||
m_ColorMeshGO = new GameObject("ColorMesh");
|
||||
CanvasRenderer colorMeshCanvasRenderer = m_ColorMeshGO.AddComponent<CanvasRenderer>();
|
||||
RectTransform colorMeshRectTransform = m_ColorMeshGO.AddComponent<RectTransform>();
|
||||
colorMeshRectTransform.pivot = colorMeshRectTransform.anchorMin = colorMeshRectTransform.anchorMax = Vector2.zero;
|
||||
m_ColorMeshGO.transform.SetParent(m_CanvasGO.transform);
|
||||
|
||||
// Create Color32 UI GameObject
|
||||
m_Color32MeshGO = new GameObject("Color32Mesh");
|
||||
CanvasRenderer color32MeshCanvasRenderer = m_Color32MeshGO.AddComponent<CanvasRenderer>();
|
||||
RectTransform color32MeshRectTransform = m_Color32MeshGO.AddComponent<RectTransform>();
|
||||
color32MeshRectTransform.pivot = color32MeshRectTransform.anchorMin = color32MeshRectTransform.anchorMax = Vector2.zero;
|
||||
m_Color32MeshGO.transform.SetParent(m_CanvasGO.transform);
|
||||
|
||||
Material material = new Material(Shader.Find("UI/Default"));
|
||||
|
||||
// Setup Color mesh and add it to Color CanvasRenderer
|
||||
Mesh meshColor = new Mesh();
|
||||
meshColor.vertices = new Vector3[3] { new Vector3(0, 0, 0), new Vector3(0, 10, 0), new Vector3(10, 0, 0) };
|
||||
meshColor.triangles = new int[3] { 0, 1, 2 };
|
||||
meshColor.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
|
||||
meshColor.colors = new Color[3] { Color.white, Color.white, Color.white };
|
||||
meshColor.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
|
||||
|
||||
colorMeshCanvasRenderer.SetMesh(meshColor);
|
||||
colorMeshCanvasRenderer.SetMaterial(material, null);
|
||||
|
||||
// Setup Color32 mesh and add it to Color32 CanvasRenderer
|
||||
Mesh meshColor32 = new Mesh();
|
||||
meshColor32.vertices = new Vector3[3] { new Vector3(10, 0, 0), new Vector3(10, 10, 0), new Vector3(20, 0, 0) };
|
||||
meshColor32.triangles = new int[3] { 0, 1, 2 };
|
||||
meshColor32.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
|
||||
meshColor32.colors32 = new Color32[3] { Color.white, Color.white, Color.white };
|
||||
meshColor32.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
|
||||
|
||||
color32MeshCanvasRenderer.SetMesh(meshColor32);
|
||||
color32MeshCanvasRenderer.SetMaterial(material, null);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGO);
|
||||
GameObject.DestroyImmediate(m_ScreenTexture);
|
||||
}
|
||||
|
||||
[Ignore("UnityTest yielded WaitForEndOfFrame, which is not evoked in batchmode.")]
|
||||
[UnityTest]
|
||||
public IEnumerator CheckMeshColorsAndColors32Matches()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
// Create a Texture2D
|
||||
m_ScreenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
|
||||
m_ScreenTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
|
||||
m_ScreenTexture.Apply();
|
||||
|
||||
Color screenPixelColorForMeshColor = m_ScreenTexture.GetPixel(1, 0);
|
||||
Color screenPixelColorForMesh32Color = m_ScreenTexture.GetPixel(11, 0);
|
||||
|
||||
Assert.That(screenPixelColorForMesh32Color, Is.EqualTo(screenPixelColorForMeshColor).Using(new ColorEqualityComparer(0.0f)), "UI Mesh with Colors does not match UI Mesh with Colors32");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9390296e78291b543b2f4a9761ef8139
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[TestFixture]
|
||||
[UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })]
|
||||
[Category("RegressionTest")]
|
||||
[Description("CoveredBugID = 904415")]
|
||||
public class CoroutineWorksIfUIObjectIsAttached
|
||||
{
|
||||
GameObject m_CanvasMaster;
|
||||
GameObject m_ImageObject;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CanvasMaster = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
||||
m_ImageObject = new GameObject("Image", typeof(Image));
|
||||
m_ImageObject.SetActive(false);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CoroutineWorksOnAttachingUIObject()
|
||||
{
|
||||
// Generating Basic scene
|
||||
m_CanvasMaster.AddComponent<CoroutineObject>();
|
||||
|
||||
yield return null;
|
||||
|
||||
m_ImageObject.transform.SetParent(m_CanvasMaster.transform);
|
||||
m_ImageObject.AddComponent<BugObject>();
|
||||
m_ImageObject.SetActive(true);
|
||||
|
||||
yield return null;
|
||||
yield return null;
|
||||
yield return null;
|
||||
|
||||
Assert.That(m_CanvasMaster.GetComponent<CoroutineObject>().coroutineCount, Is.GreaterThan(1), "The Coroutine wasn't supposed to stop but continue to run, something made it stopped");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasMaster);
|
||||
GameObject.DestroyImmediate(m_ImageObject);
|
||||
}
|
||||
}
|
||||
|
||||
public class BugObject : MonoBehaviour
|
||||
{
|
||||
void Awake()
|
||||
{
|
||||
GameObject newObject = new GameObject("NewGameObjectThatTriggersBug");
|
||||
newObject.transform.SetParent(transform);
|
||||
newObject.AddComponent<Text>();
|
||||
}
|
||||
}
|
||||
|
||||
public class CoroutineObject : MonoBehaviour
|
||||
{
|
||||
public int coroutineCount { get; private set; }
|
||||
|
||||
public IEnumerator Start()
|
||||
{
|
||||
// This coroutine should not stop and continue adding to the timer
|
||||
while (true)
|
||||
{
|
||||
coroutineCount++;
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8573c56c34e616248a3881b2c56280ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
class CreateSceneUtility
|
||||
{
|
||||
public static void CreateScene(string sceneName, Action delegateToExecute)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
string scenePath = "Assets/" + sceneName + ".unity";
|
||||
var initScene = SceneManager.GetActiveScene();
|
||||
var list = UnityEditor.EditorBuildSettings.scenes.ToList();
|
||||
var newScene = UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects, UnityEditor.SceneManagement.NewSceneMode.Additive);
|
||||
GameObject.DestroyImmediate(Camera.main.GetComponent<AudioListener>());
|
||||
delegateToExecute();
|
||||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(newScene, scenePath);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.UnloadSceneAsync(newScene);
|
||||
|
||||
list.Add(new UnityEditor.EditorBuildSettingsScene(scenePath, true));
|
||||
UnityEditor.EditorBuildSettings.scenes = list.ToArray();
|
||||
SceneManager.SetActiveScene(initScene);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db339ef553721e94999125c0b9f909dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
public class NestedCanvas : IPrebuildSetup
|
||||
{
|
||||
Object m_GO1;
|
||||
Object m_GO2;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/NestedCanvasPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
var rootGO = new GameObject("RootGO");
|
||||
|
||||
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasGroup));
|
||||
rootCanvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var nestedCanvas = new GameObject("Nested Canvas", typeof(Canvas), typeof(Image));
|
||||
nestedCanvas.transform.SetParent(rootCanvasGO.transform);
|
||||
|
||||
var nestedCanvasCamera = new GameObject("Nested Canvas Camera", typeof(Camera));
|
||||
nestedCanvasCamera.transform.SetParent(rootCanvasGO.transform);
|
||||
|
||||
var rootCanvas = rootCanvasGO.GetComponent<Canvas>();
|
||||
rootCanvas.renderMode = RenderMode.WorldSpace;
|
||||
rootCanvas.worldCamera = nestedCanvasCamera.GetComponent<Camera>();
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[Description("[UI] Button does not interact after nested canvas is used(case 892913)")]
|
||||
public IEnumerator WorldCanvas_CanFindCameraAfterDisablingAndEnablingRootCanvas()
|
||||
{
|
||||
m_GO1 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
|
||||
yield return null;
|
||||
|
||||
var nestedCanvasGo = GameObject.Find("Nested Canvas");
|
||||
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
|
||||
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after loading the scene.");
|
||||
|
||||
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
|
||||
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
|
||||
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after the parent canvas has been re-enabled.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WorldCanvas_CanFindTheSameCameraAfterDisablingAndEnablingRootCanvas()
|
||||
{
|
||||
m_GO2 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
|
||||
yield return null;
|
||||
|
||||
var nestedCanvasGo = GameObject.Find("Nested Canvas");
|
||||
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
|
||||
var worldCamera = nestedCanvas.worldCamera;
|
||||
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
|
||||
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
|
||||
Assert.AreEqual(worldCamera, nestedCanvas.worldCamera, "Expected the same world camera to be returned after the root canvas was disabled and then re-enabled.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NestedCanvasHasProperInheritedAlpha()
|
||||
{
|
||||
GameObject root = (GameObject)Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
|
||||
CanvasGroup group = root.GetComponentInChildren<CanvasGroup>();
|
||||
Image image = root.GetComponentInChildren<Image>();
|
||||
|
||||
group.alpha = 0.5f;
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.True(image.canvasRenderer.GetInheritedAlpha() == 0.5f);
|
||||
GameObject.DestroyImmediate(root);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_GO1);
|
||||
GameObject.DestroyImmediate(m_GO2);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc8d686a4c18b8d49bb1db4150de0459
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
|
||||
public class NestedCanvasMaintainsCorrectSize : IPrebuildSetup
|
||||
{
|
||||
BridgeScriptForRetainingObjects m_BridgeComponent;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
var nestedCanvasGO = new GameObject("NestedCanvas", typeof(Canvas));
|
||||
nestedCanvasGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
var rectTransform = (RectTransform)nestedCanvasGO.transform;
|
||||
rectTransform.anchorMin = Vector2.zero;
|
||||
rectTransform.anchorMax = Vector2.one;
|
||||
rectTransform.anchoredPosition = Vector2.zero;
|
||||
rectTransform.sizeDelta = new Vector2(-20f, -20f);
|
||||
|
||||
var bridgeObject = GameObject.Find(BridgeScriptForRetainingObjects.bridgeObjectName) ?? new GameObject(BridgeScriptForRetainingObjects.bridgeObjectName);
|
||||
var component = bridgeObject.GetComponent<BridgeScriptForRetainingObjects>() ?? bridgeObject.AddComponent<BridgeScriptForRetainingObjects>();
|
||||
component.canvasGO = canvasGO;
|
||||
component.nestedCanvasGO = nestedCanvasGO;
|
||||
|
||||
canvasGO.SetActive(false);
|
||||
nestedCanvasGO.SetActive(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_BridgeComponent = GameObject.Find(BridgeScriptForRetainingObjects.bridgeObjectName).GetComponent<BridgeScriptForRetainingObjects>();
|
||||
m_BridgeComponent.canvasGO.SetActive(true);
|
||||
m_BridgeComponent.nestedCanvasGO.SetActive(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedCanvasMaintainsCorrectSizeAtGameStart()
|
||||
{
|
||||
var rectTransform = (RectTransform)m_BridgeComponent.nestedCanvasGO.transform;
|
||||
Assert.That(rectTransform.anchoredPosition, Is.EqualTo(Vector2.zero));
|
||||
Assert.That(rectTransform.sizeDelta, Is.EqualTo(new Vector2(-20f, -20f)));
|
||||
Assert.That(rectTransform.anchorMin, Is.EqualTo(Vector2.zero));
|
||||
Assert.That(rectTransform.anchorMax, Is.EqualTo(Vector2.one));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_BridgeComponent.canvasGO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be07f70ee67e6d74e851a9333719bbb6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor;
|
||||
|
||||
[TestFixture]
|
||||
[UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })]
|
||||
[Category("RegressionTest")]
|
||||
[Description("CoveredBugID = 883807, CoveredBugDescription = \"Object::GetInstanceID crash when trying to switch canvas\"")]
|
||||
public class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup
|
||||
{
|
||||
Scene m_InitScene;
|
||||
const string k_SceneName = "NoActiveCameraInSceneDoesNotCrashEditorScene";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Action codeToExecute = delegate()
|
||||
{
|
||||
UnityEditor.EditorApplication.ExecuteMenuItem("GameObject/UI/Legacy/Button");
|
||||
};
|
||||
|
||||
CreateSceneUtility.CreateScene(k_SceneName, codeToExecute);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_InitScene = SceneManager.GetActiveScene();
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator EditorShouldNotCrashWithoutActiveCamera()
|
||||
{
|
||||
AsyncOperation operationResult = SceneManager.LoadSceneAsync(k_SceneName, LoadSceneMode.Additive);
|
||||
yield return operationResult;
|
||||
|
||||
SceneManager.SetActiveScene(SceneManager.GetSceneByName(k_SceneName));
|
||||
|
||||
Profiler.enabled = true;
|
||||
Camera.main.gameObject.SetActive(false);
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
Assert.That(Profiler.enabled, Is.True, "Expected the profiler to be enabled. Unable to test if the profiler will crash the editor if it is not enabled.");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
SceneManager.SetActiveScene(m_InitScene);
|
||||
SceneManager.UnloadSceneAsync(k_SceneName);
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset("Assets/" + k_SceneName + ".unity");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c21cfda3336137438c3001d40564be0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Graphics
|
||||
{
|
||||
[Category("RegressionTest")]
|
||||
[Description("CoveredBugID = 1395695, CoveredBugDescription = \"RectMask2D hides all content when parented from other display to first dislpay in the Game view window\"")]
|
||||
public class RectMask2DReparentedToDifferentCanvas
|
||||
{
|
||||
GameObject m_GameObjectA;
|
||||
GameObject m_GameObjectB;
|
||||
Canvas m_CanvasA;
|
||||
Canvas m_CanvasB;
|
||||
RectMask2D m_Mask;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_GameObjectA = new GameObject("Canvas A");
|
||||
m_GameObjectB = new GameObject("Canvas B");
|
||||
m_CanvasA = m_GameObjectA.AddComponent<Canvas>();
|
||||
m_CanvasB = m_GameObjectB.AddComponent<Canvas>();
|
||||
|
||||
var rectMaskGameObject = new GameObject("RectMask2D");
|
||||
m_Mask = rectMaskGameObject.AddComponent<RectMask2D>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_Mask.gameObject);
|
||||
Object.DestroyImmediate(m_GameObjectA);
|
||||
Object.DestroyImmediate(m_GameObjectB);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReparentingRectMask2D_UpdatesCanvas()
|
||||
{
|
||||
m_Mask.transform.SetParent(m_GameObjectA.transform);
|
||||
Assert.AreSame(m_CanvasA, m_Mask.Canvas);
|
||||
|
||||
m_Mask.transform.SetParent(m_GameObjectB.transform);
|
||||
Assert.AreSame(m_CanvasB, m_Mask.Canvas, "Expected Canvas to be updated after parent changed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ba506934dc2ce14591a37f3b00dca92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Graphics
|
||||
{
|
||||
[TestFixture]
|
||||
[Category("RegressionTest")]
|
||||
[Description(
|
||||
"CoveredBugID = 782957, CoveredBugDescription = \"Some element from scroll view are invisible when they're masked with RectMask2D and sub-canvases\"")]
|
||||
public class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect
|
||||
{
|
||||
GameObject m_RootCanvasGO;
|
||||
GameObject m_MaskGO;
|
||||
GameObject m_ImageGO;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_RootCanvasGO = new GameObject("Canvas");
|
||||
m_MaskGO = new GameObject("Mask", typeof(RectMask2D));
|
||||
m_ImageGO = new GameObject("Image");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator RectMask2DShouldNotCullImagesWithCanvas()
|
||||
{
|
||||
//Root Canvas
|
||||
var canvas = m_RootCanvasGO.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
|
||||
// Rectmaskk2D
|
||||
var maskRect = m_MaskGO.GetComponent<RectTransform>();
|
||||
maskRect.sizeDelta = new Vector2(200, 200);
|
||||
|
||||
// Our image that will be in the RectMask2D
|
||||
var image = m_ImageGO.AddComponent<Image>();
|
||||
var imageRenderer = m_ImageGO.GetComponent<CanvasRenderer>();
|
||||
var imageRect = m_ImageGO.GetComponent<RectTransform>();
|
||||
m_ImageGO.AddComponent<Canvas>();
|
||||
imageRect.sizeDelta = new Vector2(10, 10);
|
||||
|
||||
m_MaskGO.transform.SetParent(canvas.transform);
|
||||
image.transform.SetParent(m_MaskGO.transform);
|
||||
imageRect.position = maskRect.position = Vector3.zero;
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
|
||||
Assert.That(imageRenderer.cull, Is.False,
|
||||
"Expected image(with canvas) to not be culled by the RectMask2D but it was.");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_RootCanvasGO);
|
||||
GameObject.DestroyImmediate(m_MaskGO);
|
||||
GameObject.DestroyImmediate(m_ImageGO);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 735d54f21944f834f931716514c87a84
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
|
||||
[TestFixture]
|
||||
public class RectTransformValidAfterEnable : IPrebuildSetup
|
||||
{
|
||||
const string kSceneName = "DisabledCanvasScene";
|
||||
const string kGameObjectName = "DisabledCanvas";
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Action codeToExecute = delegate()
|
||||
{
|
||||
var canvasGameObject = new GameObject(kGameObjectName, typeof(Canvas));
|
||||
canvasGameObject.SetActive(false);
|
||||
canvasGameObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
canvasGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 0);
|
||||
canvasGameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, 0);
|
||||
CanvasScaler canvasScaler = canvasGameObject.AddComponent<CanvasScaler>();
|
||||
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
canvasScaler.referenceResolution = new Vector2(1024, 768);
|
||||
};
|
||||
CreateSceneUtility.CreateScene(kSceneName, codeToExecute);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Ignore("UnityTest yielded WaitForEndOfFrame, which is not evoked in batchmode.")]
|
||||
[UnityTest]
|
||||
public IEnumerator CheckRectTransformValidAfterEnable()
|
||||
{
|
||||
AsyncOperation operation = SceneManager.LoadSceneAsync(kSceneName, LoadSceneMode.Additive);
|
||||
yield return operation;
|
||||
|
||||
Scene scene = SceneManager.GetSceneByName(kSceneName);
|
||||
GameObject[] gameObjects = scene.GetRootGameObjects();
|
||||
GameObject canvasGameObject = null;
|
||||
foreach (GameObject gameObject in gameObjects)
|
||||
{
|
||||
if (gameObject.name == kGameObjectName)
|
||||
{
|
||||
canvasGameObject = gameObject;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert.IsNotNull(canvasGameObject);
|
||||
|
||||
RectTransform rectTransform = canvasGameObject.GetComponent<RectTransform>();
|
||||
canvasGameObject.SetActive(true);
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
Rect rect = rectTransform.rect;
|
||||
Assert.Greater(rect.width, 0);
|
||||
Assert.Greater(rect.height, 0);
|
||||
|
||||
operation = SceneManager.UnloadSceneAsync(kSceneName);
|
||||
yield return operation;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
//Manually add Assets/ and .unity as CreateSceneUtility does that for you.
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset("Assets/" + kSceneName + ".unity");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 811d999912a5f3f459a637aad029fbc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
public class RectangleContainsScreenPointTest : MonoBehaviour
|
||||
{
|
||||
RectTransform m_RectTransform;
|
||||
Camera m_MainCamera;
|
||||
GameObject m_CanvasObject;
|
||||
GameObject m_RectObject;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
m_MainCamera = new GameObject("MainCamera").AddComponent<Camera>();
|
||||
m_MainCamera.transform.position = new Vector3(0, 1, -10);
|
||||
m_MainCamera.depth = -1;
|
||||
|
||||
m_CanvasObject = new GameObject("Canvas");
|
||||
Canvas m_canvas = m_CanvasObject.AddComponent<Canvas>();
|
||||
m_canvas.transform.localPosition = new Vector3(0, 1, 90);
|
||||
m_canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
m_canvas.worldCamera = m_MainCamera;
|
||||
|
||||
m_RectObject = new GameObject("RectTransformObject");
|
||||
m_RectTransform = m_RectObject.AddComponent<RectTransform>();
|
||||
m_RectTransform.SetParent(m_CanvasObject.transform, false);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Destroy(m_MainCamera.gameObject);
|
||||
Destroy(m_CanvasObject);
|
||||
Destroy(m_RectObject);
|
||||
Destroy(m_RectTransform);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RectangleContainsScreenPoint_ReturnsTrue_ForAllPointsInTheRectangle()
|
||||
{
|
||||
var fourCourners = new Vector3[4];
|
||||
m_RectTransform.GetWorldCorners(fourCourners);
|
||||
|
||||
var worldCorners = fourCourners
|
||||
.Select(p => m_MainCamera.WorldToScreenPoint(p))
|
||||
.ToArray();
|
||||
|
||||
var minValue = new Vector2(
|
||||
x: worldCorners.Min(p => p.x),
|
||||
y: worldCorners.Min(p => p.y));
|
||||
|
||||
var maxValue = new Vector2(
|
||||
x: worldCorners.Max(p => p.x),
|
||||
y: worldCorners.Max(p => p.y));
|
||||
|
||||
var steps = 10000;
|
||||
bool ErrorHit = false;
|
||||
|
||||
for (float i = 0; i < steps; i++)
|
||||
{
|
||||
var point = Vector2.Lerp(minValue, maxValue, i / steps);
|
||||
if (!RectTransformUtility.RectangleContainsScreenPoint(m_RectTransform, point, m_MainCamera))
|
||||
{
|
||||
ErrorHit = true;
|
||||
Assert.Fail("Rectangle does not Contains ScreenPoint");
|
||||
}
|
||||
}
|
||||
|
||||
if (!ErrorHit)
|
||||
{
|
||||
Assert.Pass();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08a8587e5f07fb64f88a0cbe2ebe327e
|
||||
@@ -0,0 +1,84 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[TestFixture]
|
||||
[Category("RegressionTest")]
|
||||
[Description("Case 723062")]
|
||||
public class SiblingOrderChangesLayout
|
||||
{
|
||||
GameObject m_CanvasGO;
|
||||
GameObject m_ParentGO;
|
||||
GameObject m_Child1GO;
|
||||
GameObject m_Child2GO;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CanvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
m_ParentGO = new GameObject("ParentRenderer");
|
||||
m_Child1GO = CreateTextObject("ChildRenderer1");
|
||||
m_Child2GO = CreateTextObject("ChildRenderer2");
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.ExecuteMenuItem("Window/General/Game");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Ignore("UnityTest yielded WaitForEndOfFrame, which is not evoked in batchmode.")]
|
||||
[UnityTest]
|
||||
public IEnumerator ReorderingSiblingChangesLayout()
|
||||
{
|
||||
m_ParentGO.transform.SetParent(m_CanvasGO.transform);
|
||||
m_Child1GO.transform.SetParent(m_ParentGO.transform);
|
||||
m_Child2GO.transform.SetParent(m_ParentGO.transform);
|
||||
|
||||
m_ParentGO.AddComponent<CanvasRenderer>();
|
||||
m_ParentGO.AddComponent<RectTransform>();
|
||||
m_ParentGO.AddComponent<VerticalLayoutGroup>();
|
||||
m_ParentGO.AddComponent<ContentSizeFitter>();
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
Vector2 child1Pos = m_Child1GO.GetComponent<RectTransform>().anchoredPosition;
|
||||
Vector2 child2Pos = m_Child2GO.GetComponent<RectTransform>().anchoredPosition;
|
||||
|
||||
Assert.That(child1Pos, Is.Not.EqualTo(child2Pos));
|
||||
Assert.That(m_Child1GO.GetComponent<CanvasRenderer>().hasMoved, Is.False, "CanvasRenderer.hasMoved should be false");
|
||||
|
||||
m_Child2GO.transform.SetAsFirstSibling();
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
Assert.That(m_Child1GO.GetComponent<CanvasRenderer>().hasMoved, Is.True, "CanvasRenderer.hasMoved should be true");
|
||||
Vector2 newChild1Pos = m_Child1GO.GetComponent<RectTransform>().anchoredPosition;
|
||||
Vector2 newChild2Pos = m_Child2GO.GetComponent<RectTransform>().anchoredPosition;
|
||||
|
||||
Assert.That(newChild1Pos, Is.EqualTo(child2Pos), "Child1 should have moved to Child2's position");
|
||||
Assert.That(newChild2Pos, Is.EqualTo(child1Pos), "Child2 should have moved to Child1's position");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGO);
|
||||
}
|
||||
|
||||
// Factory method for creating UI text objects taken from the original bug repro scene:
|
||||
private GameObject CreateTextObject(string name)
|
||||
{
|
||||
GameObject outputTextGameObject = new GameObject("OutputContent", typeof(CanvasRenderer));
|
||||
|
||||
RectTransform outputTextTransform = outputTextGameObject.AddComponent<RectTransform>();
|
||||
outputTextTransform.pivot = new Vector2(0.5f, 0);
|
||||
outputTextTransform.anchorMin = Vector2.zero;
|
||||
outputTextTransform.anchorMax = new Vector2(1, 0);
|
||||
outputTextTransform.anchoredPosition = Vector2.zero;
|
||||
outputTextTransform.sizeDelta = Vector2.zero;
|
||||
|
||||
Text outputText = outputTextGameObject.AddComponent<Text>();
|
||||
outputText.text = "Hello World!";
|
||||
outputTextGameObject.name = name;
|
||||
return outputTextGameObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c32df609537c54c46adf92992a673693
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bae197be297529d4fa735fbe7c91828d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class DropdownTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
GameObject m_CameraGO;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/DropdownPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
var canvas = canvasGO.GetComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.WorldSpace;
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var dropdownGO = new GameObject("Dropdown", typeof(RectTransform), typeof(Dropdown));
|
||||
var dropdownTransform = dropdownGO.GetComponent<RectTransform>();
|
||||
dropdownTransform.SetParent(canvas.transform);
|
||||
dropdownTransform.anchoredPosition = Vector2.zero;
|
||||
var dropdown = dropdownGO.GetComponent<Dropdown>();
|
||||
|
||||
var templateGO = new GameObject("Template", typeof(RectTransform));
|
||||
templateGO.SetActive(false);
|
||||
var templateTransform = templateGO.GetComponent<RectTransform>();
|
||||
templateTransform.SetParent(dropdownTransform);
|
||||
|
||||
var itemGo = new GameObject("Item", typeof(RectTransform), typeof(Toggle));
|
||||
itemGo.transform.SetParent(templateTransform);
|
||||
|
||||
dropdown.template = templateTransform;
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
|
||||
|
||||
// add a custom sorting layer before test. It doesn't seem to be serialized so no need to remove it after test
|
||||
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty sortingLayers = tagManager.FindProperty("m_SortingLayers");
|
||||
sortingLayers.InsertArrayElementAtIndex(sortingLayers.arraySize);
|
||||
var arrayElement = sortingLayers.GetArrayElementAtIndex(sortingLayers.arraySize - 1);
|
||||
foreach (SerializedProperty a in arrayElement)
|
||||
{
|
||||
switch (a.name)
|
||||
{
|
||||
case "name":
|
||||
a.stringValue = "test layer";
|
||||
break;
|
||||
case "uniqueID":
|
||||
a.intValue = 314159265;
|
||||
break;
|
||||
case "locked":
|
||||
a.boolValue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tagManager.ApplyModifiedProperties();
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("DropdownPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
}
|
||||
|
||||
// test for case 958281 - [UI] Dropdown list does not copy the parent canvas layer when the panel is opened
|
||||
[UnityTest]
|
||||
public IEnumerator Dropdown_Canvas()
|
||||
{
|
||||
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
|
||||
var rootCanvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
|
||||
rootCanvas.sortingLayerName = "test layer";
|
||||
dropdown.Show();
|
||||
yield return null;
|
||||
var dropdownList = dropdown.transform.Find("Dropdown List");
|
||||
var dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
|
||||
Assert.AreEqual(rootCanvas.sortingLayerID, dropdownListCanvas.sortingLayerID, "Sorting layers should match");
|
||||
}
|
||||
|
||||
// test for case 1343542 - [UI] Child Canvas' Sorting Layer is changed to the same value as the parent
|
||||
[UnityTest]
|
||||
public IEnumerator Dropdown_Canvas_Already_Exists()
|
||||
{
|
||||
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
|
||||
var rootCanvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
|
||||
var templateCanvas = dropdown.transform.Find("Template").gameObject.AddComponent<Canvas>();
|
||||
templateCanvas.overrideSorting = true;
|
||||
templateCanvas.sortingLayerName = "test layer";
|
||||
dropdown.Show();
|
||||
yield return null;
|
||||
var dropdownList = dropdown.transform.Find("Dropdown List");
|
||||
var dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
|
||||
Assert.AreNotEqual(rootCanvas.sortingLayerName, dropdownListCanvas.sortingLayerName, "Sorting layers should not match");
|
||||
}
|
||||
|
||||
// test for case 935649 - open dropdown menus become unresponsive when disabled and reenabled
|
||||
[UnityTest]
|
||||
public IEnumerator Dropdown_Disable()
|
||||
{
|
||||
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
|
||||
dropdown.Show();
|
||||
dropdown.gameObject.SetActive(false);
|
||||
yield return null;
|
||||
var dropdownList = dropdown.transform.Find("Dropdown List");
|
||||
Assert.IsNull(dropdownList);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Dropdown_ResetAndClear()
|
||||
{
|
||||
var options = new List<string> { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
|
||||
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
|
||||
|
||||
// generate a first dropdown
|
||||
dropdown.ClearOptions();
|
||||
dropdown.AddOptions(options);
|
||||
dropdown.value = 3;
|
||||
yield return null;
|
||||
|
||||
|
||||
// clear it and generate a new one
|
||||
dropdown.ClearOptions();
|
||||
yield return null;
|
||||
|
||||
// check is the value is 0
|
||||
Assert.IsTrue(dropdown.value == 0);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
GameObject.DestroyImmediate(m_CameraGO);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
|
||||
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty sortingLayers = tagManager.FindProperty("m_SortingLayers");
|
||||
sortingLayers.DeleteArrayElementAtIndex(sortingLayers.arraySize);
|
||||
tagManager.ApplyModifiedProperties();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 358a618bc6bd9354d81cc206fd2ed80e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab93e1a81defc3243a6e9cd0df3cb443
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
public class GraphicRaycasterTests
|
||||
{
|
||||
Camera m_Camera;
|
||||
EventSystem m_EventSystem;
|
||||
Canvas m_Canvas;
|
||||
RectTransform m_CanvasRectTrans;
|
||||
Text m_TextComponent;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_Camera = new GameObject("GraphicRaycaster Camera").AddComponent<Camera>();
|
||||
m_Camera.transform.position = Vector3.zero;
|
||||
m_Camera.transform.LookAt(Vector3.forward);
|
||||
m_Camera.farClipPlane = 10;
|
||||
|
||||
m_EventSystem = new GameObject("Event System").AddComponent<EventSystem>();
|
||||
|
||||
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
|
||||
m_Canvas.renderMode = RenderMode.WorldSpace;
|
||||
m_Canvas.worldCamera = m_Camera;
|
||||
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||
m_CanvasRectTrans = m_Canvas.GetComponent<RectTransform>();
|
||||
m_CanvasRectTrans.sizeDelta = new Vector2(100, 100);
|
||||
|
||||
var textGO = new GameObject("Text");
|
||||
m_TextComponent = textGO.AddComponent<Text>();
|
||||
var textRectTrans = m_TextComponent.rectTransform;
|
||||
textRectTrans.SetParent(m_Canvas.transform);
|
||||
textRectTrans.anchorMin = Vector2.zero;
|
||||
textRectTrans.anchorMax = Vector2.one;
|
||||
textRectTrans.offsetMin = Vector2.zero;
|
||||
textRectTrans.offsetMax = Vector2.zero;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterDoesNotHitGraphicBehindCameraFarClipPlane()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
|
||||
Assert.IsEmpty(results, "Expected no results from a raycast against a graphic behind the camera's far clip plane.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterReturnsWorldPositionAndWorldNormal()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
m_Camera.farClipPlane = 12;
|
||||
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
// on katana on 10.13 agents world position returned is 0, -0.00952, 11
|
||||
// it does not reproduce for me localy, so we just tweak the comparison threshold
|
||||
Assert.That(new Vector3(0, 0, 11), Is.EqualTo(results[0].worldPosition).Using(new Vector3EqualityComparer(0.01f)));
|
||||
Assert.That(new Vector3(0, 0, -1), Is.EqualTo(results[0].worldNormal).Using(new Vector3EqualityComparer(0.001f)));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterUsesGraphicPadding()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
m_TextComponent.raycastPadding = new Vector4(-50, -50, -50, -50);
|
||||
m_Camera.farClipPlane = 12;
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2((Screen.width / 2f) - 60, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
|
||||
Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast outside the graphics RectTransform whose padding would make the click hit.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicOnTheSamePlaneAsTheCameraCanBeTargetedForEvents()
|
||||
{
|
||||
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
m_Canvas.planeDistance = 0;
|
||||
m_Camera.orthographic = true;
|
||||
m_Camera.orthographicSize = 1;
|
||||
m_Camera.nearClipPlane = 0;
|
||||
m_Camera.farClipPlane = 12;
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2((Screen.width / 2f), Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
|
||||
Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast ");
|
||||
}
|
||||
#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterIgnoresEventsFromTheWrongDisplay()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
m_Camera.farClipPlane = 12;
|
||||
|
||||
yield return null;
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f),
|
||||
displayIndex = 1,
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
|
||||
Assert.IsEmpty(results, "Pointer event on display 1 was not ignored on display 0");
|
||||
}
|
||||
#endif
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_Camera.gameObject);
|
||||
Object.DestroyImmediate(m_EventSystem.gameObject);
|
||||
Object.DestroyImmediate(m_Canvas.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6323ebef616fee4486ee155cd56d191
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
public class GraphicRaycasterWorldSpaceCanvasTests
|
||||
{
|
||||
Camera m_Camera;
|
||||
EventSystem m_EventSystem;
|
||||
Canvas m_Canvas;
|
||||
RectTransform m_CanvasRectTrans;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_Camera = new GameObject("GraphicRaycaster Camera").AddComponent<Camera>();
|
||||
m_Camera.transform.position = Vector3.zero;
|
||||
m_Camera.transform.LookAt(Vector3.forward);
|
||||
m_Camera.farClipPlane = 10;
|
||||
|
||||
m_EventSystem = new GameObject("Event System").AddComponent<EventSystem>();
|
||||
|
||||
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
|
||||
m_Canvas.renderMode = RenderMode.WorldSpace;
|
||||
m_Canvas.worldCamera = m_Camera;
|
||||
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||
m_CanvasRectTrans = m_Canvas.GetComponent<RectTransform>();
|
||||
m_CanvasRectTrans.sizeDelta = new Vector2(100, 100);
|
||||
|
||||
var textRectTrans = new GameObject("Text").AddComponent<Text>().rectTransform;
|
||||
textRectTrans.SetParent(m_Canvas.transform);
|
||||
textRectTrans.anchorMin = Vector2.zero;
|
||||
textRectTrans.anchorMax = Vector2.one;
|
||||
textRectTrans.offsetMin = Vector2.zero;
|
||||
textRectTrans.offsetMax = Vector2.zero;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterDoesNotHitGraphicBehindCameraFarClipPlane()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
|
||||
Assert.IsEmpty(results, "Expected no results from a raycast against a graphic behind the camera's far clip plane.");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GraphicRaycasterReturnsWorldPositionAndWorldNormal()
|
||||
{
|
||||
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
|
||||
m_Camera.farClipPlane = 12;
|
||||
|
||||
yield return null;
|
||||
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
// on katana on 10.13 agents world position returned is 0, -0.00952, 11
|
||||
// it does not reproduce for me localy, so we just tweak the comparison threshold
|
||||
Assert.That(new Vector3(0, 0, 11), Is.EqualTo(results[0].worldPosition).Using(new Vector3EqualityComparer(0.01f)));
|
||||
Assert.That(new Vector3(0, 0, -1), Is.EqualTo(results[0].worldNormal).Using(new Vector3EqualityComparer(0.001f)));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_Camera.gameObject);
|
||||
Object.DestroyImmediate(m_EventSystem.gameObject);
|
||||
Object.DestroyImmediate(m_Canvas.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d42c4854f9093e409cd90c00ef26de0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,260 @@
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[UnityPlatform()]
|
||||
public class InputModuleTests
|
||||
{
|
||||
EventSystem m_EventSystem;
|
||||
FakeBaseInput m_FakeBaseInput;
|
||||
StandaloneInputModule m_StandaloneInputModule;
|
||||
Canvas m_Canvas;
|
||||
Image m_Image;
|
||||
Image m_NestedImage;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
// Camera | Canvas (Image) | Event System
|
||||
|
||||
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
|
||||
m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
|
||||
|
||||
m_Image = new GameObject("Image").AddComponent<Image>();
|
||||
m_Image.gameObject.transform.SetParent(m_Canvas.transform);
|
||||
RectTransform imageRectTransform = m_Image.GetComponent<RectTransform>();
|
||||
imageRectTransform.sizeDelta = new Vector2(400f, 400f);
|
||||
imageRectTransform.localPosition = Vector3.zero;
|
||||
|
||||
m_NestedImage = new GameObject("NestedImage").AddComponent<Image>();
|
||||
m_NestedImage.gameObject.transform.SetParent(m_Image.transform);
|
||||
RectTransform nestedImageRectTransform = m_NestedImage.GetComponent<RectTransform>();
|
||||
nestedImageRectTransform.sizeDelta = new Vector2(200f, 200f);
|
||||
nestedImageRectTransform.localPosition = Vector3.zero;
|
||||
|
||||
GameObject go = new GameObject("Event System");
|
||||
m_EventSystem = go.AddComponent<EventSystem>();
|
||||
m_EventSystem.pixelDragThreshold = 1;
|
||||
|
||||
m_StandaloneInputModule = go.AddComponent<StandaloneInputModule>();
|
||||
m_FakeBaseInput = go.AddComponent<FakeBaseInput>();
|
||||
|
||||
// Override input with FakeBaseInput so we can send fake mouse/keyboards button presses and touches
|
||||
m_StandaloneInputModule.inputOverride = m_FakeBaseInput;
|
||||
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator DragCallbacksDoGetCalled()
|
||||
{
|
||||
// While left mouse button is pressed and the mouse is moving, OnBeginDrag and OnDrag callbacks should be called
|
||||
// Then when the left mouse button is released, OnEndDrag callback should be called
|
||||
|
||||
// Add script to EventSystem to update the mouse position
|
||||
m_EventSystem.gameObject.AddComponent<MouseUpdate>();
|
||||
|
||||
// Add script to Image which implements OnBeginDrag, OnDrag & OnEndDrag callbacks
|
||||
DragCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<DragCallbackCheck>();
|
||||
|
||||
// Setting required input.mousePresent to fake mouse presence
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
|
||||
var canvasRT = m_Canvas.gameObject.transform as RectTransform;
|
||||
m_FakeBaseInput.MousePosition = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
yield return null;
|
||||
|
||||
// Left mouse button down simulation
|
||||
m_FakeBaseInput.MouseButtonDown[0] = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
// Left mouse button down flag needs to reset in the next frame
|
||||
m_FakeBaseInput.MouseButtonDown[0] = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
// Left mouse button up simulation
|
||||
m_FakeBaseInput.MouseButtonUp[0] = true;
|
||||
|
||||
yield return null;
|
||||
|
||||
// Left mouse button up flag needs to reset in the next frame
|
||||
m_FakeBaseInput.MouseButtonUp[0] = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.IsTrue(callbackCheck.onBeginDragCalled, "OnBeginDrag not called");
|
||||
Assert.IsTrue(callbackCheck.onDragCalled, "OnDragCalled not called");
|
||||
Assert.IsTrue(callbackCheck.onEndDragCalled, "OnEndDragCalled not called");
|
||||
Assert.IsTrue(callbackCheck.onDropCalled, "OnDrop not called");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator MouseOutsideMaskRectTransform_WhileInsidePaddedArea_PerformsClick()
|
||||
{
|
||||
var mask = new GameObject("Panel").AddComponent<RectMask2D>();
|
||||
mask.gameObject.transform.SetParent(m_Canvas.transform);
|
||||
RectTransform panelRectTransform = mask.GetComponent<RectTransform>();
|
||||
panelRectTransform.sizeDelta = new Vector2(100, 100f);
|
||||
panelRectTransform.localPosition = Vector3.zero;
|
||||
|
||||
m_Image.gameObject.transform.SetParent(mask.transform, true);
|
||||
mask.padding = new Vector4(-30, -30, -30, -30);
|
||||
|
||||
|
||||
PointerClickCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerClickCallbackCheck>();
|
||||
|
||||
var canvasRT = m_Canvas.gameObject.transform as RectTransform;
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
|
||||
yield return null;
|
||||
// Click the center of the screen should hit the middle of the image.
|
||||
m_FakeBaseInput.MouseButtonDown[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonDown[0] = false;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = false;
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerDown);
|
||||
|
||||
//Reset the callbackcheck and click outside the mask but still in the image.
|
||||
callbackCheck.pointerDown = false;
|
||||
m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 60, screenMiddle.y);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonDown[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonDown[0] = false;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = false;
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerDown);
|
||||
|
||||
//Reset the callbackcheck and click outside the mask and outside in the image.
|
||||
callbackCheck.pointerDown = false;
|
||||
m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 100, screenMiddle.y);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonDown[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonDown[0] = false;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = true;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MouseButtonUp[0] = false;
|
||||
yield return null;
|
||||
Assert.IsFalse(callbackCheck.pointerDown);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerEnterChildShouldNotFullyExit_NotSendPointerEventToParent()
|
||||
{
|
||||
m_StandaloneInputModule.sendPointerHoverToParent = false;
|
||||
PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
|
||||
m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData.fullyExited == false);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerEnterChildShouldNotExit_SendPointerEventToParent()
|
||||
{
|
||||
m_StandaloneInputModule.sendPointerHoverToParent = true;
|
||||
PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
|
||||
m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData == null);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerEnterChildShouldNotReenter()
|
||||
{
|
||||
PointerEnterCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData.reentered == false);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerExitChildShouldReenter_NotSendPointerEventToParent()
|
||||
{
|
||||
m_StandaloneInputModule.sendPointerHoverToParent = false;
|
||||
PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData.reentered == true);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerExitChildShouldNotSendEnter_SendPointerEventToParent()
|
||||
{
|
||||
m_StandaloneInputModule.sendPointerHoverToParent = true;
|
||||
m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData == null);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator PointerExitChildShouldFullyExit()
|
||||
{
|
||||
PointerExitCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
|
||||
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
|
||||
|
||||
m_FakeBaseInput.MousePresent = true;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle;
|
||||
yield return null;
|
||||
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
|
||||
yield return null;
|
||||
Assert.IsTrue(callbackCheck.pointerData.fullyExited == true);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_EventSystem.gameObject);
|
||||
GameObject.DestroyImmediate(m_Canvas.gameObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4e290d31ab7fb54880746bb8f818e0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a892c920c8ad2848b469ec9579c5219
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler
|
||||
{
|
||||
private bool loggedOnDrag = false;
|
||||
public bool onBeginDragCalled = false;
|
||||
public bool onDragCalled = false;
|
||||
public bool onEndDragCalled = false;
|
||||
public bool onDropCalled = false;
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
onBeginDragCalled = true;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (loggedOnDrag)
|
||||
return;
|
||||
|
||||
loggedOnDrag = true;
|
||||
onDragCalled = true;
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
onEndDragCalled = true;
|
||||
}
|
||||
|
||||
public void OnDrop(PointerEventData eventData)
|
||||
{
|
||||
onDropCalled = true;
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
// Empty to ensure we get the drop if we have a pointer handle as well.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76c82729ad712f14bae1a8a279c52ac3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class FakeBaseInput : BaseInput
|
||||
{
|
||||
[NonSerialized]
|
||||
public String CompositionString = "";
|
||||
|
||||
private IMECompositionMode m_ImeCompositionMode = IMECompositionMode.Auto;
|
||||
private Vector2 m_CompositionCursorPos = Vector2.zero;
|
||||
|
||||
[NonSerialized]
|
||||
public bool MousePresent = false;
|
||||
|
||||
[NonSerialized]
|
||||
public bool[] MouseButtonDown = new bool[3];
|
||||
|
||||
[NonSerialized]
|
||||
public bool[] MouseButtonUp = new bool[3];
|
||||
|
||||
[NonSerialized]
|
||||
public bool[] MouseButton = new bool[3];
|
||||
|
||||
[NonSerialized]
|
||||
public Vector2 MousePosition = Vector2.zero;
|
||||
|
||||
[NonSerialized]
|
||||
public Vector2 MouseScrollDelta = Vector2.zero;
|
||||
|
||||
[NonSerialized]
|
||||
public bool TouchSupported = false;
|
||||
|
||||
[NonSerialized]
|
||||
public int TouchCount = 0;
|
||||
|
||||
[NonSerialized]
|
||||
public Touch TouchData;
|
||||
|
||||
[NonSerialized]
|
||||
public float AxisRaw = 0f;
|
||||
|
||||
[NonSerialized]
|
||||
public bool ButtonDown = false;
|
||||
|
||||
public override string compositionString
|
||||
{
|
||||
get { return CompositionString; }
|
||||
}
|
||||
|
||||
public override IMECompositionMode imeCompositionMode
|
||||
{
|
||||
get { return m_ImeCompositionMode; }
|
||||
set { m_ImeCompositionMode = value; }
|
||||
}
|
||||
|
||||
public override Vector2 compositionCursorPos
|
||||
{
|
||||
get { return m_CompositionCursorPos; }
|
||||
set { m_CompositionCursorPos = value; }
|
||||
}
|
||||
|
||||
public override bool mousePresent
|
||||
{
|
||||
get { return MousePresent; }
|
||||
}
|
||||
|
||||
public override bool GetMouseButtonDown(int button)
|
||||
{
|
||||
return MouseButtonDown[button];
|
||||
}
|
||||
|
||||
public override bool GetMouseButtonUp(int button)
|
||||
{
|
||||
return MouseButtonUp[button];
|
||||
}
|
||||
|
||||
public override bool GetMouseButton(int button)
|
||||
{
|
||||
return MouseButton[button];
|
||||
}
|
||||
|
||||
public override Vector2 mousePosition
|
||||
{
|
||||
get { return MousePosition; }
|
||||
}
|
||||
|
||||
public override Vector2 mouseScrollDelta
|
||||
{
|
||||
get { return MouseScrollDelta; }
|
||||
}
|
||||
|
||||
public override bool touchSupported
|
||||
{
|
||||
get { return TouchSupported; }
|
||||
}
|
||||
|
||||
public override int touchCount
|
||||
{
|
||||
get { return TouchCount; }
|
||||
}
|
||||
|
||||
public override Touch GetTouch(int index)
|
||||
{
|
||||
return TouchData;
|
||||
}
|
||||
|
||||
public override float GetAxisRaw(string axisName)
|
||||
{
|
||||
return AxisRaw;
|
||||
}
|
||||
|
||||
public override bool GetButtonDown(string buttonName)
|
||||
{
|
||||
return ButtonDown;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 138dbec4f8742654fbceb0a19d68b9c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class MouseUpdate : MonoBehaviour
|
||||
{
|
||||
FakeBaseInput m_FakeBaseInput;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_FakeBaseInput = GetComponent<FakeBaseInput>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
Debug.Assert(m_FakeBaseInput, "FakeBaseInput component has not been added to the EventSystem");
|
||||
|
||||
// Update mouse position
|
||||
m_FakeBaseInput.MousePosition.x += 10f;
|
||||
m_FakeBaseInput.MousePosition.y += 10f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19c6f364c1e81cb4f829a057824639ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
public class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler
|
||||
{
|
||||
public bool pointerDown = false;
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
pointerDown = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0573713975c6b8246b7544ed524ef1dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
public class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler
|
||||
{
|
||||
public PointerEventData pointerData { get; private set; }
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
pointerData = eventData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb4fb871430ff484e9ee3850946c504d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
public class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler
|
||||
{
|
||||
public PointerEventData pointerData { get; private set; }
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
pointerData = eventData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af94bd3a805f27e42ab86647265be74e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,139 @@
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class Physics2DRaycasterTests
|
||||
{
|
||||
GameObject m_CamGO;
|
||||
SpriteRenderer m_RedSprite;
|
||||
SpriteRenderer m_BlueSprite;
|
||||
SpriteRenderer m_GreenSprite;
|
||||
EventSystem m_EventSystem;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CamGO = new GameObject("Physics2DRaycaster Camera");
|
||||
m_CamGO.transform.position = new Vector3(0, 0, -10);
|
||||
m_CamGO.transform.LookAt(Vector3.zero);
|
||||
var cam = m_CamGO.AddComponent<Camera>();
|
||||
cam.orthographic = true;
|
||||
m_CamGO.AddComponent<Physics2DRaycaster>();
|
||||
m_EventSystem = m_CamGO.AddComponent<EventSystem>();
|
||||
|
||||
var texture = new Texture2D(64, 64);
|
||||
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0));
|
||||
|
||||
m_RedSprite = CreateTestSprite("Red", Color.red, sprite);
|
||||
m_BlueSprite = CreateTestSprite("Blue", Color.blue, sprite);
|
||||
m_GreenSprite = CreateTestSprite("Green", Color.green, sprite);
|
||||
}
|
||||
|
||||
static SpriteRenderer CreateTestSprite(string name, Color color, Sprite sprite)
|
||||
{
|
||||
var go = new GameObject(name);
|
||||
var sr = go.AddComponent<SpriteRenderer>();
|
||||
sr.sprite = sprite;
|
||||
sr.color = color;
|
||||
go.AddComponent<BoxCollider2D>();
|
||||
return sr;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CamGO);
|
||||
GameObject.DestroyImmediate(m_RedSprite.gameObject);
|
||||
GameObject.DestroyImmediate(m_BlueSprite.gameObject);
|
||||
GameObject.DestroyImmediate(m_GreenSprite.gameObject);
|
||||
}
|
||||
|
||||
static void AssertRaycastResultsOrder(List<RaycastResult> results, params SpriteRenderer[] expectedOrder)
|
||||
{
|
||||
Assert.AreEqual(expectedOrder.Length, results.Count);
|
||||
|
||||
for (int i = 0; i < expectedOrder.Length; ++i)
|
||||
{
|
||||
Assert.AreSame(expectedOrder[i].gameObject, results[i].gameObject, "Expected {0} at index {1} but got {2}", expectedOrder[i], i, results[i].gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
List<RaycastResult> PerformRaycast()
|
||||
{
|
||||
var results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(m_EventSystem)
|
||||
{
|
||||
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
|
||||
};
|
||||
|
||||
m_EventSystem.RaycastAll(pointerEvent, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastAllResultsAreSortedByRendererSortingOrder()
|
||||
{
|
||||
m_RedSprite.sortingOrder = -10;
|
||||
m_BlueSprite.sortingOrder = 0;
|
||||
m_GreenSprite.sortingOrder = 5;
|
||||
|
||||
var results = PerformRaycast();
|
||||
AssertRaycastResultsOrder(results, m_GreenSprite, m_BlueSprite, m_RedSprite);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastAllResultsAreSortedBySortGroupOrder()
|
||||
{
|
||||
var blueSg = m_BlueSprite.gameObject.AddComponent<SortingGroup>();
|
||||
blueSg.sortingLayerID = 0;
|
||||
blueSg.sortingOrder = -10;
|
||||
|
||||
var redSg = m_RedSprite.gameObject.AddComponent<SortingGroup>();
|
||||
redSg.sortingLayerID = 0;
|
||||
redSg.sortingOrder = 10;
|
||||
|
||||
SortingGroup.UpdateAllSortingGroups();
|
||||
|
||||
var results = PerformRaycast();
|
||||
AssertRaycastResultsOrder(results, m_RedSprite, m_GreenSprite, m_BlueSprite);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastAllResultsAreSortedBySortGroupOrderAndSortingOrder()
|
||||
{
|
||||
m_RedSprite.sortingOrder = -10;
|
||||
m_BlueSprite.sortingOrder = 0;
|
||||
m_GreenSprite.sortingOrder = 5;
|
||||
|
||||
var sg = m_BlueSprite.gameObject.AddComponent<SortingGroup>();
|
||||
sg.sortingLayerID = 0;
|
||||
sg.sortingOrder = 100;
|
||||
SortingGroup.UpdateAllSortingGroups();
|
||||
|
||||
var results = PerformRaycast();
|
||||
AssertRaycastResultsOrder(results, m_BlueSprite, m_GreenSprite, m_RedSprite);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastAllResultsAreSortedBySortGroupDistanceAlongRay()
|
||||
{
|
||||
// Ensure we use the distance along the raycast to sort the results
|
||||
var sortingGroupRed = new GameObject("Sorting Group Red", typeof(SortingGroup));
|
||||
var sortingGroupBlue = new GameObject("Sorting Group Blue", typeof(SortingGroup));
|
||||
var sortingGroupGreen = new GameObject("Sorting Group Green", typeof(SortingGroup));
|
||||
sortingGroupRed.transform.position = new Vector3(0, 0, -1);
|
||||
sortingGroupBlue.transform.position = new Vector3(1000, 1000, 0);
|
||||
sortingGroupGreen.transform.position = new Vector3(0, 0, 1);
|
||||
|
||||
m_RedSprite.transform.SetParent(sortingGroupRed.transform, true);
|
||||
m_BlueSprite.transform.SetParent(sortingGroupBlue.transform, true);
|
||||
m_GreenSprite.transform.SetParent(sortingGroupGreen.transform, true);
|
||||
|
||||
SortingGroup.UpdateAllSortingGroups();
|
||||
|
||||
var results = PerformRaycast();
|
||||
AssertRaycastResultsOrder(results, m_RedSprite, m_BlueSprite, m_GreenSprite);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fb761a492f57d84586a8264df7b3cc0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class PhysicsRaycasterTests
|
||||
{
|
||||
GameObject m_CamGO;
|
||||
GameObject m_Collider;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CamGO = new GameObject("PhysicsRaycaster Camera");
|
||||
m_Collider = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PhysicsRaycasterDoesNotCastOutsideCameraViewRect()
|
||||
{
|
||||
m_CamGO.transform.position = new Vector3(0, 0, -10);
|
||||
m_CamGO.transform.LookAt(Vector3.zero);
|
||||
var cam = m_CamGO.AddComponent<Camera>();
|
||||
cam.rect = new Rect(0.5f, 0, 0.5f, 1);
|
||||
m_CamGO.AddComponent<PhysicsRaycaster>();
|
||||
var eventSystem = m_CamGO.AddComponent<EventSystem>();
|
||||
|
||||
// Create an object that will be hit if a raycast does occur.
|
||||
m_Collider.transform.localScale = new Vector3(100, 100, 1);
|
||||
List<RaycastResult> results = new List<RaycastResult>();
|
||||
var pointerEvent = new PointerEventData(eventSystem)
|
||||
{
|
||||
position = new Vector2(0, 0) // Raycast from the left side of the screen which is outside of the camera's view rect.
|
||||
};
|
||||
|
||||
eventSystem.RaycastAll(pointerEvent, results);
|
||||
Assert.IsEmpty(results, "Expected no results from a raycast that is outside of the camera's viewport.");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CamGO);
|
||||
GameObject.DestroyImmediate(m_Collider);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 833143c443f979e44ae0b8ed899e3b59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class RaycastSortingTests : IPrebuildSetup
|
||||
{
|
||||
// Test to check that a a raycast over two canvases will not use hierarchal depth to compare two results
|
||||
// from different canvases (case 912396 - Raycast hits ignores 2nd Canvas which is drawn in front)
|
||||
GameObject m_PrefabRoot;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/RaycastSortingPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("RootGO");
|
||||
var cameraGO = new GameObject("Camera", typeof(Camera));
|
||||
var camera = cameraGO.GetComponent<Camera>();
|
||||
cameraGO.transform.SetParent(rootGO.transform);
|
||||
var eventSystemGO = new GameObject("EventSystem", typeof(EventSystem), typeof(StandaloneInputModule));
|
||||
eventSystemGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var backCanvasGO = new GameObject("BackCanvas", typeof(Canvas), typeof(GraphicRaycaster));
|
||||
backCanvasGO.transform.SetParent(rootGO.transform);
|
||||
var backCanvas = backCanvasGO.GetComponent<Canvas>();
|
||||
backCanvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
backCanvas.planeDistance = 100;
|
||||
backCanvas.worldCamera = camera;
|
||||
|
||||
var backCanvasBackground = new GameObject("BackCanvasBackground", typeof(RectTransform), typeof(Image));
|
||||
var backCanvasBackgroundTransform = backCanvasBackground.GetComponent<RectTransform>();
|
||||
backCanvasBackgroundTransform.SetParent(backCanvasGO.transform);
|
||||
backCanvasBackgroundTransform.anchorMin = Vector2.zero;
|
||||
backCanvasBackgroundTransform.anchorMax = Vector2.one;
|
||||
backCanvasBackgroundTransform.sizeDelta = Vector2.zero;
|
||||
backCanvasBackgroundTransform.anchoredPosition3D = Vector3.zero;
|
||||
backCanvasBackgroundTransform.localScale = Vector3.one;
|
||||
|
||||
var backCanvasDeeper = new GameObject("BackCanvasDeeperHierarchy", typeof(RectTransform), typeof(Image));
|
||||
var backCanvasDeeperTransform = backCanvasDeeper.GetComponent<RectTransform>();
|
||||
backCanvasDeeperTransform.SetParent(backCanvasBackgroundTransform);
|
||||
backCanvasDeeperTransform.anchorMin = new Vector2(0.5f, 0);
|
||||
backCanvasDeeperTransform.anchorMax = Vector2.one;
|
||||
backCanvasDeeperTransform.sizeDelta = Vector2.zero;
|
||||
backCanvasDeeperTransform.anchoredPosition3D = Vector3.zero;
|
||||
backCanvasDeeperTransform.localScale = Vector3.one;
|
||||
backCanvasDeeper.GetComponent<Image>().color = new Color(0.6985294f, 0.7754564f, 1f);
|
||||
|
||||
var frontCanvasGO = new GameObject("FrontCanvas", typeof(Canvas), typeof(GraphicRaycaster));
|
||||
frontCanvasGO.transform.SetParent(rootGO.transform);
|
||||
var frontCanvas = frontCanvasGO.GetComponent<Canvas>();
|
||||
frontCanvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
frontCanvas.planeDistance = 50;
|
||||
frontCanvas.worldCamera = camera;
|
||||
|
||||
var frontCanvasTopLevel = new GameObject("FrontCanvasTopLevel", typeof(RectTransform), typeof(Text));
|
||||
var frontCanvasTopLevelTransform = frontCanvasTopLevel.GetComponent<RectTransform>();
|
||||
frontCanvasTopLevelTransform.SetParent(frontCanvasGO.transform);
|
||||
frontCanvasTopLevelTransform.anchorMin = Vector2.zero;
|
||||
frontCanvasTopLevelTransform.anchorMax = new Vector2(1, 0.5f);
|
||||
frontCanvasTopLevelTransform.sizeDelta = Vector2.zero;
|
||||
frontCanvasTopLevelTransform.anchoredPosition3D = Vector3.zero;
|
||||
frontCanvasTopLevelTransform.localScale = Vector3.one;
|
||||
var text = frontCanvasTopLevel.GetComponent<Text>();
|
||||
text.text = "FrontCanvasTopLevel";
|
||||
text.color = Color.black;
|
||||
text.fontSize = 97;
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("RaycastSortingPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator RaycastResult_Sorting()
|
||||
{
|
||||
Camera cam = m_PrefabRoot.GetComponentInChildren<Camera>();
|
||||
EventSystem eventSystem = m_PrefabRoot.GetComponentInChildren<EventSystem>();
|
||||
GameObject shouldHit = m_PrefabRoot.GetComponentInChildren<Text>().gameObject;
|
||||
|
||||
PointerEventData eventData = new PointerEventData(eventSystem);
|
||||
//bottom left quadrant
|
||||
eventData.position = cam.ViewportToScreenPoint(new Vector3(0.75f, 0.25f));
|
||||
|
||||
List<RaycastResult> results = new List<RaycastResult>();
|
||||
eventSystem.RaycastAll(eventData, results);
|
||||
|
||||
Assert.IsTrue(results[0].gameObject.name == shouldHit.name);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ca2545d76d1fb34fa45a9f1e432d259
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,498 @@
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
class SelectableTests
|
||||
{
|
||||
private class SelectableTest : Selectable
|
||||
{
|
||||
public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } }
|
||||
public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } }
|
||||
public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } }
|
||||
public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } }
|
||||
public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } }
|
||||
|
||||
public Selectable GetSelectableAtIndex(int index)
|
||||
{
|
||||
return s_Selectables[index];
|
||||
}
|
||||
|
||||
public int GetSelectableCurrentIndex()
|
||||
{
|
||||
return m_CurrentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private SelectableTest selectable;
|
||||
private GameObject m_CanvasRoot;
|
||||
private GameObject m_EventSystemGO;
|
||||
|
||||
private CanvasGroup CreateAndParentGroupTo(string name, GameObject child)
|
||||
{
|
||||
GameObject canvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
GameObject groupGO = new GameObject(name, typeof(RectTransform), typeof(CanvasGroup));
|
||||
groupGO.transform.SetParent(canvasRoot.transform);
|
||||
child.transform.SetParent(groupGO.transform);
|
||||
return groupGO.GetComponent<CanvasGroup>();
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_EventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
|
||||
EventSystem.current = m_EventSystemGO.GetComponent<EventSystem>();
|
||||
m_CanvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
GameObject SelectableGO = new GameObject("Selectable", typeof(RectTransform), typeof(CanvasRenderer));
|
||||
|
||||
SelectableGO.transform.SetParent(m_CanvasRoot.transform);
|
||||
selectable = SelectableGO.AddComponent<SelectableTest>();
|
||||
selectable.targetGraphic = selectable.gameObject.AddComponent<ConcreteGraphic>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasRoot);
|
||||
GameObject.DestroyImmediate(m_EventSystemGO);
|
||||
}
|
||||
|
||||
[Test] // regression test 1160054
|
||||
public void SelectableArrayRemovesReferenceUponDisable()
|
||||
{
|
||||
int originalSelectableCount = Selectable.allSelectableCount;
|
||||
|
||||
selectable.enabled = false;
|
||||
|
||||
Assert.AreEqual(originalSelectableCount - 1, Selectable.allSelectableCount, "We have more then originalSelectableCount - 1 selectable objects.");
|
||||
//ensure the item as the last index is nulled out as it replaced the item that was disabled.
|
||||
Assert.IsNull(selectable.GetSelectableAtIndex(Selectable.allSelectableCount));
|
||||
|
||||
selectable.enabled = true;
|
||||
}
|
||||
|
||||
#region Selected object
|
||||
|
||||
[Test]
|
||||
public void SettingCurrentSelectedSelectableNonInteractableShouldNullifyCurrentSelected()
|
||||
{
|
||||
EventSystem.current.SetSelectedGameObject(selectable.gameObject);
|
||||
selectable.interactable = false;
|
||||
|
||||
// it should be unselected now that it is not interactable anymore
|
||||
Assert.IsNull(EventSystem.current.currentSelectedGameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterDownShouldMakeItSelectedGameObject()
|
||||
{
|
||||
Assert.IsNull(EventSystem.current.currentSelectedGameObject);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current));
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnSelectShouldSetSelectedState()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.OnSelect(new BaseEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStateSelected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnDeselectShouldUnsetSelectedState()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.OnSelect(new BaseEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStateSelected);
|
||||
selectable.OnDeselect(new BaseEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStateNormal);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interactable
|
||||
|
||||
[Test]
|
||||
public void SettingCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
|
||||
{
|
||||
// Canvas Group on same object
|
||||
var group = selectable.gameObject.AddComponent<CanvasGroup>();
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
group.interactable = false;
|
||||
// actual call happens on the native side, cause by interactable = false
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
|
||||
Assert.IsFalse(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisablingCanvasGroupShouldMakeSelectableAsInteractable()
|
||||
{
|
||||
var group = selectable.gameObject.AddComponent<CanvasGroup>();
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
group.enabled = false;
|
||||
group.interactable = false;
|
||||
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
|
||||
{
|
||||
var canvasGroup = CreateAndParentGroupTo("CanvasGroup", selectable.gameObject);
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
canvasGroup.interactable = false;
|
||||
// actual call happens on the native side, cause by interactable = false
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
|
||||
Assert.IsFalse(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingParentParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
|
||||
{
|
||||
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
|
||||
var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
canvasGroup2.interactable = false;
|
||||
// actual call happens on the native side, cause by interactable = false
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
|
||||
Assert.IsFalse(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingParentParentCanvasGroupInteractableShouldMakeSelectableInteractable()
|
||||
{
|
||||
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
|
||||
CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
// actual call happens on the native side, cause by interactable
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingParentParentCanvasGroupNotInteractableShouldNotMakeSelectableNotInteractableIfIgnoreParentGroups()
|
||||
{
|
||||
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
|
||||
canvasGroup1.ignoreParentGroups = true;
|
||||
var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
|
||||
canvasGroup2.interactable = false;
|
||||
// actual call happens on the native side, cause by interactable = false
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
|
||||
Assert.IsTrue(selectable.IsInteractable());
|
||||
}
|
||||
|
||||
[Test]// regression test 861736
|
||||
public void PointerEnterThenSetNotInteractableThenExitThenSetInteractableShouldSetStateToDefault()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
selectable.interactable = false;
|
||||
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.interactable = true;
|
||||
Assert.False(selectable.isStateHighlighted);
|
||||
Assert.True(selectable.isStateNormal);
|
||||
}
|
||||
|
||||
[Test]// regression test 861736
|
||||
public void PointerEnterThenSetNotInteractableThenSetInteractableShouldStayHighlighted()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
selectable.interactable = false;
|
||||
selectable.interactable = true;
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InstantiatingSelectableUnderNotInteractableCanvasGroupShouldAlsoNotBeInteractable()
|
||||
{
|
||||
var canvasGroup = CreateAndParentGroupTo("ParentGroup", selectable.gameObject);
|
||||
canvasGroup.interactable = false;
|
||||
Assert.False(canvasGroup.interactable);
|
||||
var newSelectable = Object.Instantiate(selectable.gameObject, canvasGroup.transform).GetComponent<SelectableTest>();
|
||||
Assert.False(newSelectable.IsInteractable());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tweening
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SettingNotInteractableShouldTweenToDisabledColor()
|
||||
{
|
||||
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
|
||||
selectable.InvokeOnEnable();
|
||||
canvasRenderer.SetColor(selectable.colors.normalColor);
|
||||
|
||||
selectable.interactable = false;
|
||||
|
||||
yield return new WaitForSeconds(1);
|
||||
|
||||
Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor());
|
||||
|
||||
selectable.interactable = true;
|
||||
|
||||
yield return new WaitForSeconds(1);
|
||||
|
||||
Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor());
|
||||
}
|
||||
|
||||
[UnityTest][Ignore("Fails")] // regression test 742140
|
||||
public IEnumerator SettingNotInteractableThenInteractableShouldNotTweenToDisabledColor()
|
||||
{
|
||||
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
|
||||
selectable.enabled = false;
|
||||
selectable.enabled = true;
|
||||
canvasRenderer.SetColor(selectable.colors.normalColor);
|
||||
|
||||
selectable.interactable = false;
|
||||
selectable.interactable = true;
|
||||
Color c = canvasRenderer.GetColor();
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
yield return null;
|
||||
Color c2 = canvasRenderer.GetColor();
|
||||
Assert.AreNotEqual(c2, c);
|
||||
}
|
||||
Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor());
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SettingInteractableToFalseTrueFalseShouldTweenToDisabledColor()
|
||||
{
|
||||
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
|
||||
selectable.InvokeOnEnable();
|
||||
canvasRenderer.SetColor(selectable.colors.normalColor);
|
||||
|
||||
selectable.interactable = false;
|
||||
selectable.interactable = true;
|
||||
selectable.interactable = false;
|
||||
|
||||
yield return new WaitForSeconds(1);
|
||||
|
||||
Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor());
|
||||
}
|
||||
|
||||
#if PACKAGE_ANIMATION
|
||||
[Test]
|
||||
public void TriggerAnimationWithNoAnimator()
|
||||
{
|
||||
Assert.Null(selectable.animator);
|
||||
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TriggerAnimationWithDisabledAnimator()
|
||||
{
|
||||
var an = selectable.gameObject.AddComponent<Animator>();
|
||||
an.enabled = false;
|
||||
Assert.NotNull(selectable.animator);
|
||||
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TriggerAnimationAnimatorWithNoRuntimeController()
|
||||
{
|
||||
var an = selectable.gameObject.AddComponent<Animator>();
|
||||
an.runtimeAnimatorController = null;
|
||||
Assert.NotNull(selectable.animator);
|
||||
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Selection state and pointer
|
||||
|
||||
[Test]
|
||||
public void SelectShouldSetSelectedObject()
|
||||
{
|
||||
Assert.Null(EventSystem.current.currentSelectedGameObject);
|
||||
selectable.Select();
|
||||
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SelectWhenAlreadySelectingShouldNotSetSelectedObject()
|
||||
{
|
||||
Assert.Null(EventSystem.current.currentSelectedGameObject);
|
||||
var fieldInfo = typeof(EventSystem).GetField("m_SelectionGuard", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
fieldInfo
|
||||
.SetValue(EventSystem.current, true);
|
||||
selectable.Select();
|
||||
Assert.Null(EventSystem.current.currentSelectedGameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterShouldHighlight()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterOnSelectedObjectShouldStaySelected()
|
||||
{
|
||||
selectable.InvokeOnSelect(null);
|
||||
Assert.True(selectable.isStateSelected);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
Assert.True(selectable.isStateSelected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterAndRightClickShouldHighlightNotPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
button = PointerEventData.InputButton.Right
|
||||
});
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterAndRightClickShouldPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStatePressed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterLeftClickExitShouldPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
Assert.True(selectable.isStatePressed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterLeftClickExitReleaseShouldSelect()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStateSelected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerDownShouldSetSelectedObject()
|
||||
{
|
||||
Assert.Null(EventSystem.current.currentSelectedGameObject);
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerLeftDownRightDownRightUpShouldNotChangeState()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
pointerEnter = selectable.gameObject
|
||||
});
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Left });
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right });
|
||||
selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right });
|
||||
Assert.True(selectable.isStatePressed);
|
||||
}
|
||||
|
||||
[Test, Ignore("No disabled state assigned ? Investigate")]
|
||||
public void SettingNotInteractableShouldDisable()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.interactable = false;
|
||||
selectable.InvokeOnCanvasGroupChanged();
|
||||
Assert.True(selectable.isStateDisabled);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region No event system
|
||||
|
||||
[Test] // regression test 787563
|
||||
public void SettingInteractableWithNoEventSystemShouldNotCrash()
|
||||
{
|
||||
EventSystem.current.enabled = false;
|
||||
selectable.interactable = false;
|
||||
}
|
||||
|
||||
[Test] // regression test 787563
|
||||
public void OnPointerDownWithNoEventSystemShouldNotCrash()
|
||||
{
|
||||
EventSystem.current.enabled = false;
|
||||
selectable.OnPointerDown(new PointerEventData(EventSystem.current) {button = PointerEventData.InputButton.Left});
|
||||
}
|
||||
|
||||
[Test] // regression test 787563
|
||||
public void SelectWithNoEventSystemShouldNotCrash()
|
||||
{
|
||||
EventSystem.current.enabled = false;
|
||||
selectable.Select();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39dcddcb5895328489c92214aa73e3bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8313ea704470a264295ec9e09aec6ebc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,264 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Tests;
|
||||
|
||||
namespace Graphics
|
||||
{
|
||||
class GraphicTests : IPrebuildSetup
|
||||
{
|
||||
private GameObject m_PrefabRoot;
|
||||
private ConcreteGraphic m_graphic;
|
||||
private Canvas m_canvas;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/GraphicTestsPrefab.prefab";
|
||||
|
||||
bool m_dirtyVert;
|
||||
bool m_dirtyLayout;
|
||||
bool m_dirtyMaterial;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
var canvasGO = new GameObject("CanvasRoot", typeof(Canvas), typeof(GraphicRaycaster));
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var graphicGO = new GameObject("Graphic", typeof(RectTransform), typeof(ConcreteGraphic));
|
||||
graphicGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
var gameObject = new GameObject("EventSystem", typeof(EventSystem));
|
||||
gameObject.transform.SetParent(rootGO.transform);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("GraphicTestsPrefab")) as GameObject;
|
||||
|
||||
m_canvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
|
||||
m_graphic = m_PrefabRoot.GetComponentInChildren<ConcreteGraphic>();
|
||||
|
||||
m_graphic.RegisterDirtyVerticesCallback(() => m_dirtyVert = true);
|
||||
m_graphic.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
|
||||
m_graphic.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
|
||||
|
||||
ResetDirtyFlags();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
m_graphic = null;
|
||||
m_canvas = null;
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
private void ResetDirtyFlags()
|
||||
{
|
||||
m_dirtyVert = m_dirtyLayout = m_dirtyMaterial = false;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingDirtyOnActiveGraphicCallsCallbacks()
|
||||
{
|
||||
m_graphic.enabled = false;
|
||||
m_graphic.enabled = true;
|
||||
m_graphic.SetAllDirty();
|
||||
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
|
||||
ResetDirtyFlags();
|
||||
|
||||
m_graphic.SetLayoutDirty();
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
|
||||
m_graphic.SetVerticesDirty();
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
|
||||
m_graphic.SetMaterialDirty();
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
private bool ContainsGraphic(IList<Graphic> array, int size, Graphic element)
|
||||
{
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
if (array[i] == element)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RefreshGraphicByRaycast()
|
||||
{
|
||||
// force refresh by raycast
|
||||
List<RaycastResult> raycastResultCache = new List<RaycastResult>();
|
||||
PointerEventData data = new PointerEventData(EventSystem.current);
|
||||
var raycaster = m_canvas.GetComponent<GraphicRaycaster>();
|
||||
raycaster.Raycast(data, raycastResultCache);
|
||||
}
|
||||
|
||||
private bool CheckGraphicAddedToGraphicRegistry()
|
||||
{
|
||||
var graphicList = GraphicRegistry.GetGraphicsForCanvas(m_canvas);
|
||||
var graphicListSize = graphicList.Count;
|
||||
return ContainsGraphic(graphicList, graphicListSize, m_graphic);
|
||||
}
|
||||
|
||||
private bool CheckGraphicAddedToRaycastGraphicRegistry()
|
||||
{
|
||||
var graphicList = GraphicRegistry.GetRaycastableGraphicsForCanvas(m_canvas);
|
||||
var graphicListSize = graphicList.Count;
|
||||
return ContainsGraphic(graphicList, graphicListSize, m_graphic);
|
||||
}
|
||||
|
||||
private void CheckGraphicRaycastDisableValidity()
|
||||
{
|
||||
RefreshGraphicByRaycast();
|
||||
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should no longer be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnEnableLeavesGraphicInExpectedState()
|
||||
{
|
||||
m_graphic.enabled = false;
|
||||
m_graphic.enabled = true; // on enable is called directly
|
||||
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
|
||||
|
||||
Assert.AreEqual(Texture2D.whiteTexture, m_graphic.mainTexture, "mainTexture should be Texture2D.whiteTexture");
|
||||
|
||||
Assert.NotNull(m_graphic.canvas);
|
||||
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnEnableTwiceLeavesGraphicInExpectedState()
|
||||
{
|
||||
m_graphic.enabled = true;
|
||||
|
||||
// force onEnable by reflection to call it second time
|
||||
m_graphic.InvokeOnEnable();
|
||||
|
||||
m_graphic.enabled = false;
|
||||
|
||||
CheckGraphicRaycastDisableValidity();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnDisableLeavesGraphicInExpectedState()
|
||||
{
|
||||
m_graphic.enabled = true;
|
||||
m_graphic.enabled = false;
|
||||
|
||||
CheckGraphicRaycastDisableValidity();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnPopulateMeshWorksAsExpected()
|
||||
{
|
||||
m_graphic.rectTransform.anchoredPosition = new Vector2(100, 100);
|
||||
m_graphic.rectTransform.sizeDelta = new Vector2(150, 742);
|
||||
m_graphic.color = new Color(50, 100, 150, 200);
|
||||
|
||||
VertexHelper vh = new VertexHelper();
|
||||
m_graphic.InvokeOnPopulateMesh(vh);
|
||||
|
||||
GraphicTestHelper.TestOnPopulateMeshDefaultBehavior(m_graphic, vh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnDidApplyAnimationPropertiesSetsAllDirty()
|
||||
{
|
||||
m_graphic.enabled = true; // Usually set through SetEnabled, from Behavior
|
||||
|
||||
m_graphic.InvokeOnDidApplyAnimationProperties();
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MakingGraphicNonRaycastableRemovesGraphicFromProperLists()
|
||||
{
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
|
||||
|
||||
m_graphic.raycastTarget = false;
|
||||
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnEnableLeavesNonRaycastGraphicInExpectedState()
|
||||
{
|
||||
m_graphic.enabled = false;
|
||||
m_graphic.raycastTarget = false;
|
||||
m_graphic.enabled = true; // on enable is called directly
|
||||
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
|
||||
Assert.AreEqual(Texture2D.whiteTexture, m_graphic.mainTexture, "mainTexture should be Texture2D.whiteTexture");
|
||||
|
||||
Assert.NotNull(m_graphic.canvas);
|
||||
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingRaycastTargetOnDisabledGraphicDoesntAddItRaycastList()
|
||||
{
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
|
||||
|
||||
m_graphic.raycastTarget = false;
|
||||
|
||||
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
|
||||
m_graphic.enabled = false;
|
||||
|
||||
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should NOT be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
|
||||
m_graphic.raycastTarget = true;
|
||||
|
||||
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should NOT be registered in m_CanvasGraphics");
|
||||
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e88a766c2b8b47841936c136f4afbba9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,557 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
class ImageTests
|
||||
{
|
||||
Image m_Image;
|
||||
private Sprite m_Sprite;
|
||||
private Sprite m_OverrideSprite;
|
||||
Texture2D texture = new Texture2D(128, 128);
|
||||
Texture2D overrideTexture = new Texture2D(512, 512);
|
||||
|
||||
bool m_dirtyVert;
|
||||
bool m_dirtyLayout;
|
||||
bool m_dirtyMaterial;
|
||||
|
||||
Camera m_camera;
|
||||
GameObject m_CanvasRoot;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CanvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
GameObject gameObject = new GameObject("Image", typeof(RectTransform), typeof(Image));
|
||||
gameObject.transform.SetParent(m_CanvasRoot.transform);
|
||||
|
||||
m_camera = new GameObject("Camera", typeof(Camera)).GetComponent<Camera>();
|
||||
|
||||
m_Image = gameObject.GetComponent<Image>();
|
||||
|
||||
Color[] colors = new Color[128 * 128];
|
||||
for (int y = 0; y < 128; y++)
|
||||
for (int x = 0; x < 128; x++)
|
||||
colors[x + 128 * y] = new Color(0, 0, 0, 1 - x / 128f);
|
||||
texture.SetPixels(colors);
|
||||
texture.Apply();
|
||||
|
||||
Color[] overrideColors = new Color[512 * 512];
|
||||
for (int y = 0; y < 512; y++)
|
||||
for (int x = 0; x < 512; x++)
|
||||
overrideColors[x + 512 * y] = new Color(0, 0, 0, y / 512f);
|
||||
overrideTexture.SetPixels(overrideColors);
|
||||
overrideTexture.Apply();
|
||||
|
||||
m_Sprite = Sprite.Create(texture, new Rect(0, 0, 128, 128), new Vector2(0.5f, 0.5f), 100);
|
||||
m_OverrideSprite = Sprite.Create(overrideTexture, new Rect(0, 0, 512, 512), new Vector2(0.5f, 0.5f), 200);
|
||||
|
||||
m_Image.rectTransform.anchoredPosition = new Vector2(0, 0);
|
||||
m_Image.rectTransform.sizeDelta = new Vector2(100, 100);
|
||||
m_Image.RegisterDirtyVerticesCallback(() => m_dirtyVert = true);
|
||||
m_Image.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
|
||||
m_Image.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
|
||||
|
||||
ResetDirtyFlags();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
m_Image = null;
|
||||
m_Sprite = null;
|
||||
|
||||
GameObject.DestroyImmediate(m_CanvasRoot);
|
||||
GameObject.DestroyImmediate(m_camera.gameObject);
|
||||
m_camera = null;
|
||||
}
|
||||
|
||||
private void ResetDirtyFlags()
|
||||
{
|
||||
m_dirtyVert = m_dirtyLayout = m_dirtyMaterial = false;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetTestSprite()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.AreEqual(m_Sprite, m_Image.sprite);
|
||||
m_Image.sprite = null;
|
||||
Assert.AreEqual(null, m_Image.sprite);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPixelsPerUnit()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
Assert.AreEqual(1.0f, m_Image.pixelsPerUnit);
|
||||
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.AreEqual(2.0f, m_Image.pixelsPerUnit);
|
||||
|
||||
m_Image.overrideSprite = null;
|
||||
Assert.AreEqual(1.0f, m_Image.pixelsPerUnit);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastOverImageWithoutASpriteReturnTrue()
|
||||
{
|
||||
m_Image.sprite = null;
|
||||
bool raycast = m_Image.Raycast(new Vector2(10, 10), m_camera);
|
||||
Assert.AreEqual(true, raycast);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(0.0f, 1000, 1000)]
|
||||
[TestCase(1.0f, 1000, 1000)]
|
||||
[TestCase(0.0f, -1000, 1000)]
|
||||
[TestCase(1.0f, -1000, 1000)]
|
||||
[TestCase(0.0f, 1000, -1000)]
|
||||
[TestCase(1.0f, 1000, -1000)]
|
||||
[TestCase(0.0f, -1000, -1000)]
|
||||
[TestCase(1.0f, -1000, -1000)]
|
||||
public void RaycastOverImageWithoutASpriteReturnsTrueWithCoordinatesOutsideTheBoundaries(float alphaThreshold, float x, float y)
|
||||
{
|
||||
m_Image.alphaHitTestMinimumThreshold = 1.0f - alphaThreshold;
|
||||
bool raycast = m_Image.Raycast(new Vector2(x, y), m_camera);
|
||||
Assert.IsTrue(raycast);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastOverImageWithNonZeroSpritePosition_AlphaHitTestMinimumThreshold()
|
||||
{
|
||||
var canvas = m_CanvasRoot.GetComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
canvas.worldCamera = m_camera;
|
||||
|
||||
// Create a square sprite (64x64) in the middle of a transparent area (128x128).
|
||||
Color[] colors = new Color[128 * 128];
|
||||
for (int y = 32; y < 96; y++)
|
||||
for (int x = 32; x < 96; x++)
|
||||
colors[x + 128 * y] = Color.red;
|
||||
texture.SetPixels(colors);
|
||||
texture.Apply();
|
||||
|
||||
// Set it so that the red square fills the entire screen. Clicking anywehere inside the canvas should hit the image and pass.
|
||||
m_Sprite = Sprite.Create(texture, new Rect(32, 32, 64, 64), new Vector2(0.5f, 0.5f), 100);
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.alphaHitTestMinimumThreshold = 0.5f;
|
||||
m_Image.rectTransform.anchorMin = Vector2.zero;
|
||||
m_Image.rectTransform.anchorMax = Vector2.one;
|
||||
|
||||
Assert.True(m_Image.Raycast(new Vector2(0, 0), m_camera), "Expected raycast to hit when clicking bottom left corner of screen.");
|
||||
Assert.True(m_Image.Raycast(new Vector2(0, Screen.height), m_camera), "Expected raycast to hit when clicking top left corner of screen.");
|
||||
Assert.True(m_Image.Raycast(new Vector2(Screen.width, 0), m_camera), "Expected raycast to hit when clicking bottom right corner of screen.");
|
||||
Assert.True(m_Image.Raycast(new Vector2(Screen.width, Screen.height), m_camera), "Expected raycast to hit when clicking top right corner of screen.");
|
||||
Assert.True(m_Image.Raycast(new Vector2(Screen.width / 2.0f, Screen.height / 2.0f), m_camera), "Expected raycast to hit when clicking center of screen.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RaycastOverImage_IgnoresDisabledCanvasGroup()
|
||||
{
|
||||
var canvasGroup = m_CanvasRoot.AddComponent<CanvasGroup>();
|
||||
canvasGroup.blocksRaycasts = false;
|
||||
canvasGroup.enabled = false;
|
||||
|
||||
bool raycast = m_Image.Raycast(new Vector2(1000, 1000), m_camera);
|
||||
Assert.IsTrue(raycast);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingSpriteMarksAllAsDirty()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingOverrideSpriteMarksAllAsDirty()
|
||||
{
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingTypeMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.type = Image.Type.Filled;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingPreserveAspectMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.preserveAspect = true;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingFillCenterMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.fillCenter = false;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingFillMethodMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.fillMethod = Image.FillMethod.Horizontal;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingFillAmountMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.fillAmount = 0.5f;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingFillClockwiseMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.fillClockwise = false;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingFillOriginMarksVerticesAsDirty()
|
||||
{
|
||||
m_Image.fillOrigin = 1;
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SettingEventAlphaThresholdMarksNothingAsDirty()
|
||||
{
|
||||
m_Image.alphaHitTestMinimumThreshold = 0.5f;
|
||||
Assert.False(m_dirtyVert, "Vertices have been dirtied");
|
||||
Assert.False(m_dirtyLayout, "Layout has been dirtied");
|
||||
Assert.False(m_dirtyMaterial, "Material has been dirtied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnAfterDeserializeMakeFillOriginZeroIfNotBetweenZeroAndThree()
|
||||
{
|
||||
for (int i = -10; i < 0; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(0, m_Image.fillOrigin);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(i, m_Image.fillOrigin);
|
||||
}
|
||||
|
||||
for (int i = 4; i < 10; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(0, m_Image.fillOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnAfterDeserializeMakeFillOriginZeroIfFillOriginGreaterThan1AndFillMethodHorizontalOrVertical()
|
||||
{
|
||||
m_Image.fillMethod = Image.FillMethod.Horizontal;
|
||||
Image.FillMethod[] fillMethodsToTest = {Image.FillMethod.Horizontal, Image.FillMethod.Vertical};
|
||||
|
||||
foreach (var fillMethod in fillMethodsToTest)
|
||||
{
|
||||
m_Image.fillMethod = fillMethod;
|
||||
for (int i = -10; i < 0; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(0, m_Image.fillOrigin);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(i, m_Image.fillOrigin);
|
||||
}
|
||||
|
||||
for (int i = 2; i < 100; i++)
|
||||
{
|
||||
m_Image.fillOrigin = i;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(0, m_Image.fillOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnAfterDeserializeClampsFillAmountBetweenZeroAndOne()
|
||||
{
|
||||
for (float f = -5; f < 0; f += 0.1f)
|
||||
{
|
||||
m_Image.fillAmount = f;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(0, m_Image.fillAmount);
|
||||
}
|
||||
|
||||
for (float f = 0; f < 1; f += 0.1f)
|
||||
{
|
||||
m_Image.fillAmount = f;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(f, m_Image.fillAmount);
|
||||
}
|
||||
|
||||
for (float f = 1; f < 5; f += 0.1f)
|
||||
{
|
||||
m_Image.fillAmount = f;
|
||||
m_Image.OnAfterDeserialize();
|
||||
Assert.AreEqual(1, m_Image.fillAmount);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetNativeSizeSetsAllAsDirtyAndSetsAnchorMaxAndSizeDeltaWhenOverrideSpriteIsNotNull()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
m_Image.rectTransform.anchorMax = new Vector2(100, 100);
|
||||
m_Image.rectTransform.anchorMin = new Vector2(0, 0);
|
||||
m_Image.SetNativeSize();
|
||||
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
|
||||
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
|
||||
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
|
||||
Assert.AreEqual(m_Image.rectTransform.anchorMin, m_Image.rectTransform.anchorMax);
|
||||
Assert.AreEqual(m_OverrideSprite.rect.size / m_Image.pixelsPerUnit, m_Image.rectTransform.sizeDelta);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnPopulateMeshWhenNoOverrideSpritePresentDefersToGraphicImplementation()
|
||||
{
|
||||
m_OverrideSprite = null;
|
||||
m_Image.rectTransform.anchoredPosition = new Vector2(100, 452);
|
||||
m_Image.rectTransform.sizeDelta = new Vector2(881, 593);
|
||||
m_Image.color = new Color(0.1f, 0.2f, 0.8f, 0);
|
||||
|
||||
VertexHelper vh = new VertexHelper();
|
||||
|
||||
m_Image.InvokeOnPopulateMesh(vh);
|
||||
Assert.AreEqual(4, vh.currentVertCount);
|
||||
List<UIVertex> verts = new List<UIVertex>();
|
||||
vh.GetUIVertexStream(verts);
|
||||
|
||||
// The vertices for the 2 triangles of the canvas
|
||||
UIVertex[] expectedVertices =
|
||||
{
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = m_Image.rectTransform.rect.min,
|
||||
uv0 = new Vector2(0f, 0f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = new Vector3(m_Image.rectTransform.rect.xMin, m_Image.rectTransform.rect.yMax),
|
||||
uv0 = new Vector2(0f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = m_Image.rectTransform.rect.max,
|
||||
uv0 = new Vector2(1f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = m_Image.rectTransform.rect.max,
|
||||
uv0 = new Vector2(1f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = new Vector3(m_Image.rectTransform.rect.xMax, m_Image.rectTransform.rect.yMin),
|
||||
uv0 = new Vector2(1f, 0f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = m_Image.color,
|
||||
position = m_Image.rectTransform.rect.min,
|
||||
uv0 = new Vector2(0f, 0f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
};
|
||||
|
||||
for (int i = 0; i < verts.Count; i++)
|
||||
{
|
||||
Assert.AreEqual(expectedVertices[i], verts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void TestOnPopulateMeshTypeSimple(VertexHelper vh, Vector4 UVs)
|
||||
{
|
||||
List<UIVertex> verts = new List<UIVertex>();
|
||||
vh.GetUIVertexStream(verts);
|
||||
|
||||
Assert.AreEqual(4, vh.currentVertCount);
|
||||
Assert.AreEqual(6, vh.currentIndexCount);
|
||||
|
||||
var imgRect = m_Image.rectTransform.rect;
|
||||
Vector3[] expectedVertices =
|
||||
{
|
||||
imgRect.min,
|
||||
new Vector3(imgRect.xMin, imgRect.yMax),
|
||||
imgRect.max,
|
||||
imgRect.max,
|
||||
new Vector3(imgRect.xMax, imgRect.yMin),
|
||||
imgRect.min
|
||||
};
|
||||
|
||||
Vector2[] expectedUV0s =
|
||||
{
|
||||
new Vector2(UVs.x, UVs.y),
|
||||
new Vector2(UVs.x, UVs.w),
|
||||
new Vector2(UVs.z, UVs.w),
|
||||
new Vector2(UVs.z, UVs.w),
|
||||
new Vector2(UVs.z, UVs.y),
|
||||
new Vector2(UVs.x, UVs.y),
|
||||
};
|
||||
|
||||
var expectedNormal = new Vector3(0, 0, -1);
|
||||
var expectedTangent = new Vector4(1, 0, 0, -1);
|
||||
Color32 expectedColor = m_Image.color;
|
||||
Vector2 expectedUV1 = new Vector2(0, 0);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Assert.AreEqual(expectedVertices[i], verts[i].position);
|
||||
Assert.AreEqual(expectedUV0s[i], verts[i].uv0);
|
||||
Assert.AreEqual(expectedUV1, verts[i].uv1);
|
||||
Assert.AreEqual(expectedNormal, verts[i].normal);
|
||||
Assert.AreEqual(expectedTangent, verts[i].tangent);
|
||||
Assert.AreEqual(expectedColor, verts[i].color);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnPopulateMeshWithTypeTiledNoBorderGeneratesExpectedResults()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.sprite.texture.wrapMode = TextureWrapMode.Repeat;
|
||||
|
||||
m_Image.type = Image.Type.Tiled;
|
||||
|
||||
VertexHelper vh = new VertexHelper();
|
||||
|
||||
m_Image.InvokeOnPopulateMesh(vh);
|
||||
|
||||
Assert.AreEqual(4, vh.currentVertCount);
|
||||
Assert.AreEqual(6, vh.currentIndexCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MinWidthHeightAreZeroWithNoImage()
|
||||
{
|
||||
Assert.AreEqual(0, m_Image.minWidth);
|
||||
Assert.AreEqual(0, m_Image.minHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FlexibleWidthHeightAreCorrectWithNoImage()
|
||||
{
|
||||
Assert.AreEqual(-1, m_Image.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_Image.flexibleHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PreferredWidthHeightAreCorrectWithNoImage()
|
||||
{
|
||||
Assert.AreEqual(0, m_Image.preferredWidth);
|
||||
Assert.AreEqual(0, m_Image.preferredHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MinWidthHeightAreZeroWithImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
Assert.AreEqual(0, m_Image.minWidth);
|
||||
Assert.AreEqual(0, m_Image.minHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FlexibleWidthHeightAreCorrectWithImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
Assert.AreEqual(-1, m_Image.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_Image.flexibleHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PreferredWidthHeightAreCorrectWithImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
Assert.AreEqual(128, m_Image.preferredWidth);
|
||||
Assert.AreEqual(128, m_Image.preferredHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MinWidthHeightAreZeroWithOverrideImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.AreEqual(0, m_Image.minWidth);
|
||||
Assert.AreEqual(0, m_Image.minHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FlexibleWidthHeightAreCorrectWithOverrideImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.AreEqual(-1, m_Image.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_Image.flexibleHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PreferredWidthHeightAreCorrectWithOverrideImage()
|
||||
{
|
||||
m_Image.sprite = m_Sprite;
|
||||
m_Image.overrideSprite = m_OverrideSprite;
|
||||
Assert.AreEqual(256, m_Image.preferredWidth);
|
||||
Assert.AreEqual(256, m_Image.preferredHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0bae4ff8f5baf64aad3b92b8aea0603
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,163 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Graphics
|
||||
{
|
||||
class MaskTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/MaskTestsPrefab.prefab";
|
||||
|
||||
Mask m_mask;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
GameObject canvasGO = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var canvas = canvasGO.GetComponent<Canvas>();
|
||||
canvas.referencePixelsPerUnit = 100;
|
||||
|
||||
var gameObject = new GameObject("Mask", typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
gameObject.transform.SetParent(canvasGO.transform);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("MaskTestsPrefab")) as GameObject;
|
||||
m_mask = m_PrefabRoot.GetComponentInChildren<Mask>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
m_mask = null;
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator GetModifiedMaterialReturnsOriginalMaterialWhenNoGraphicComponentIsAttached()
|
||||
{
|
||||
Object.DestroyImmediate(m_mask.gameObject.GetComponent<Image>());
|
||||
yield return null;
|
||||
Material material = new Material(Graphic.defaultGraphicMaterial);
|
||||
Material modifiedMaterial = m_mask.GetModifiedMaterial(material);
|
||||
Assert.AreEqual(material, modifiedMaterial);
|
||||
}
|
||||
|
||||
private Dictionary<string, GameObject> CreateMaskHierarchy(string suffix, int hierarchyDepth, out GameObject root)
|
||||
{
|
||||
var nameToObjectMapping = new Dictionary<string, GameObject>();
|
||||
|
||||
root = new GameObject("root", typeof(RectTransform), typeof(Canvas));
|
||||
nameToObjectMapping["root"] = root;
|
||||
|
||||
GameObject current = root;
|
||||
|
||||
for (int i = 0; i < hierarchyDepth; i++)
|
||||
{
|
||||
string name = suffix + (i + 1);
|
||||
var gameObject = new GameObject(name, typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
gameObject.transform.SetParent(current.transform);
|
||||
nameToObjectMapping[name] = gameObject;
|
||||
current = gameObject;
|
||||
}
|
||||
|
||||
return nameToObjectMapping;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetModifiedMaterialReturnsOriginalMaterialWhenDepthIsEightOrMore()
|
||||
{
|
||||
GameObject root;
|
||||
var objectsMap = CreateMaskHierarchy("subMask", 9, out root);
|
||||
Mask mask = objectsMap["subMask" + 9].GetComponent<Mask>();
|
||||
Material material = new Material(Graphic.defaultGraphicMaterial);
|
||||
Material modifiedMaterial = mask.GetModifiedMaterial(material);
|
||||
Assert.AreEqual(material, modifiedMaterial);
|
||||
GameObject.DestroyImmediate(root);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetModifiedMaterialReturnsDesiredMaterialWithSingleMask()
|
||||
{
|
||||
Material material = new Material(Graphic.defaultGraphicMaterial);
|
||||
Material modifiedMaterial = m_mask.GetModifiedMaterial(material);
|
||||
|
||||
Assert.AreNotEqual(material, modifiedMaterial);
|
||||
Assert.AreEqual(1, modifiedMaterial.GetInt("_Stencil"));
|
||||
Assert.AreEqual(StencilOp.Replace, (StencilOp)modifiedMaterial.GetInt("_StencilOp"));
|
||||
Assert.AreEqual(CompareFunction.Always, (CompareFunction)modifiedMaterial.GetInt("_StencilComp"));
|
||||
Assert.AreEqual(255, modifiedMaterial.GetInt("_StencilReadMask"));
|
||||
Assert.AreEqual(255, modifiedMaterial.GetInt("_StencilWriteMask"));
|
||||
Assert.AreEqual(ColorWriteMask.All, (ColorWriteMask)modifiedMaterial.GetInt("_ColorMask"));
|
||||
Assert.AreEqual(1, modifiedMaterial.GetInt("_UseUIAlphaClip"));
|
||||
|
||||
Assert.IsTrue(modifiedMaterial.IsKeywordEnabled("UNITY_UI_ALPHACLIP"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetModifiedMaterialReturnsDesiredMaterialWithMultipleMasks()
|
||||
{
|
||||
for (int i = 2; i < 8; i++)
|
||||
{
|
||||
GameObject root;
|
||||
var objectsMap = CreateMaskHierarchy("subMask", i, out root);
|
||||
Mask mask = objectsMap["subMask" + i].GetComponent<Mask>();
|
||||
|
||||
int stencilDepth = MaskUtilities.GetStencilDepth(mask.transform, objectsMap["root"].transform);
|
||||
|
||||
int desiredStencilBit = 1 << stencilDepth;
|
||||
Material material = new Material(Graphic.defaultGraphicMaterial);
|
||||
Material modifiedMaterial = mask.GetModifiedMaterial(material);
|
||||
int stencil = modifiedMaterial.GetInt("_Stencil");
|
||||
|
||||
Assert.AreNotEqual(material, modifiedMaterial);
|
||||
Assert.AreEqual(desiredStencilBit | (desiredStencilBit - 1), stencil);
|
||||
Assert.AreEqual(StencilOp.Replace, (StencilOp)modifiedMaterial.GetInt("_StencilOp"));
|
||||
Assert.AreEqual(CompareFunction.Equal, (CompareFunction)modifiedMaterial.GetInt("_StencilComp"));
|
||||
Assert.AreEqual(desiredStencilBit - 1, modifiedMaterial.GetInt("_StencilReadMask"));
|
||||
Assert.AreEqual(desiredStencilBit | (desiredStencilBit - 1), modifiedMaterial.GetInt("_StencilWriteMask"));
|
||||
Assert.AreEqual(ColorWriteMask.All, (ColorWriteMask)modifiedMaterial.GetInt("_ColorMask"));
|
||||
Assert.AreEqual(1, modifiedMaterial.GetInt("_UseUIAlphaClip"));
|
||||
Assert.IsTrue(modifiedMaterial.IsKeywordEnabled("UNITY_UI_ALPHACLIP"));
|
||||
|
||||
GameObject.DestroyImmediate(root);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GraphicComponentWithMaskIsMarkedAsIsMaskingGraphicWhenEnabled()
|
||||
{
|
||||
var graphic = m_PrefabRoot.GetComponentInChildren<Image>();
|
||||
Assert.AreEqual(true, graphic.isMaskingGraphic);
|
||||
m_mask.enabled = false;
|
||||
Assert.AreEqual(false, graphic.isMaskingGraphic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b611b0a598aeada419afa9737807c598
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,169 @@
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
class NavigationTests
|
||||
{
|
||||
GameObject canvasRoot;
|
||||
Selectable topLeftSelectable;
|
||||
Selectable bottomLeftSelectable;
|
||||
Selectable topRightSelectable;
|
||||
Selectable bottomRightSelectable;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
canvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
GameObject topLeftGO = new GameObject("topLeftGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
|
||||
topLeftGO.transform.SetParent(canvasRoot.transform);
|
||||
(topLeftGO.transform as RectTransform).anchoredPosition = new Vector2(50, 200);
|
||||
topLeftSelectable = topLeftGO.GetComponent<Selectable>();
|
||||
|
||||
GameObject bottomLeftGO = new GameObject("bottomLeftGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
|
||||
bottomLeftGO.transform.SetParent(canvasRoot.transform);
|
||||
(bottomLeftGO.transform as RectTransform).anchoredPosition = new Vector2(50, 50);
|
||||
bottomLeftSelectable = bottomLeftGO.GetComponent<Selectable>();
|
||||
|
||||
GameObject topRightGO = new GameObject("topRightGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
|
||||
topRightGO.transform.SetParent(canvasRoot.transform);
|
||||
(topRightGO.transform as RectTransform).anchoredPosition = new Vector2(200, 200);
|
||||
topRightSelectable = topRightGO.GetComponent<Selectable>();
|
||||
|
||||
GameObject bottomRightGO = new GameObject("bottomRightGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
|
||||
bottomRightGO.transform.SetParent(canvasRoot.transform);
|
||||
(bottomRightGO.transform as RectTransform).anchoredPosition = new Vector2(200, 50);
|
||||
bottomRightSelectable = bottomRightGO.GetComponent<Selectable>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(canvasRoot);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnRight_ReturnsNextSelectableRightOfTarget()
|
||||
{
|
||||
Selectable selectableRightOfTopLeft = topLeftSelectable.FindSelectableOnRight();
|
||||
Selectable selectableRightOfBottomLeft = bottomLeftSelectable.FindSelectableOnRight();
|
||||
|
||||
Assert.AreEqual(topRightSelectable, selectableRightOfTopLeft, "Wrong selectable to right of Top Left Selectable");
|
||||
Assert.AreEqual(bottomRightSelectable, selectableRightOfBottomLeft, "Wrong selectable to right of Bottom Left Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnLeft_ReturnsNextSelectableLeftOfTarget()
|
||||
{
|
||||
Selectable selectableLeftOfTopRight = topRightSelectable.FindSelectableOnLeft();
|
||||
Selectable selectableLeftOfBottomRight = bottomRightSelectable.FindSelectableOnLeft();
|
||||
|
||||
Assert.AreEqual(topLeftSelectable, selectableLeftOfTopRight, "Wrong selectable to left of Top Right Selectable");
|
||||
Assert.AreEqual(bottomLeftSelectable, selectableLeftOfBottomRight, "Wrong selectable to left of Bottom Right Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnRDown_ReturnsNextSelectableBelowTarget()
|
||||
{
|
||||
Selectable selectableDownOfTopLeft = topLeftSelectable.FindSelectableOnDown();
|
||||
Selectable selectableDownOfTopRight = topRightSelectable.FindSelectableOnDown();
|
||||
|
||||
Assert.AreEqual(bottomLeftSelectable, selectableDownOfTopLeft, "Wrong selectable to Bottom of Top Left Selectable");
|
||||
Assert.AreEqual(bottomRightSelectable, selectableDownOfTopRight, "Wrong selectable to Bottom of top Right Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnUp_ReturnsNextSelectableAboveTarget()
|
||||
{
|
||||
Selectable selectableUpOfBottomLeft = bottomLeftSelectable.FindSelectableOnUp();
|
||||
Selectable selectableUpOfBottomRight = bottomRightSelectable.FindSelectableOnUp();
|
||||
|
||||
Assert.AreEqual(topLeftSelectable, selectableUpOfBottomLeft, "Wrong selectable to Up of bottom Left Selectable");
|
||||
Assert.AreEqual(topRightSelectable, selectableUpOfBottomRight, "Wrong selectable to Up of bottom Right Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnRight__WrappingEnabled_ReturnsFurthestSelectableOnLeft()
|
||||
{
|
||||
Navigation nav = topRightSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Horizontal;
|
||||
topRightSelectable.navigation = nav;
|
||||
|
||||
nav = bottomRightSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Horizontal;
|
||||
bottomRightSelectable.navigation = nav;
|
||||
|
||||
Selectable selectableRightOfTopRight = topRightSelectable.FindSelectableOnRight();
|
||||
Selectable selectableRightOfBottomRight = bottomRightSelectable.FindSelectableOnRight();
|
||||
|
||||
Assert.AreEqual(bottomLeftSelectable, selectableRightOfTopRight, "Wrong selectable to right of Top Right Selectable");
|
||||
Assert.AreEqual(topLeftSelectable, selectableRightOfBottomRight, "Wrong selectable to right of Bottom Right Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnLeft_WrappingEnabled_ReturnsFurthestSelectableOnRight()
|
||||
{
|
||||
Navigation nav = topLeftSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Horizontal;
|
||||
topLeftSelectable.navigation = nav;
|
||||
|
||||
nav = bottomLeftSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Horizontal;
|
||||
bottomLeftSelectable.navigation = nav;
|
||||
|
||||
Selectable selectableLeftOfTopLeft = topLeftSelectable.FindSelectableOnLeft();
|
||||
Selectable selectableLeftOfBottomLeft = bottomLeftSelectable.FindSelectableOnLeft();
|
||||
|
||||
Assert.AreEqual(bottomRightSelectable, selectableLeftOfTopLeft, "Wrong selectable to left of Top Left Selectable");
|
||||
Assert.AreEqual(topRightSelectable, selectableLeftOfBottomLeft, "Wrong selectable to left of Bottom Left Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnDown_WrappingEnabled_ReturnsFurthestSelectableAbove()
|
||||
{
|
||||
Navigation nav = bottomLeftSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Vertical;
|
||||
bottomLeftSelectable.navigation = nav;
|
||||
|
||||
nav = bottomRightSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Vertical;
|
||||
bottomRightSelectable.navigation = nav;
|
||||
|
||||
Selectable selectableDownOfBottomLeft = bottomLeftSelectable.FindSelectableOnDown();
|
||||
Selectable selectableDownOfBottomRight = bottomRightSelectable.FindSelectableOnDown();
|
||||
|
||||
Assert.AreEqual(topRightSelectable, selectableDownOfBottomLeft, "Wrong selectable to Bottom of Bottom Left Selectable");
|
||||
Assert.AreEqual(topLeftSelectable, selectableDownOfBottomRight, "Wrong selectable to Bottom of Bottom Right Selectable");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindSelectableOnUp_WrappingEnabled_ReturnsFurthestSelectableBelow()
|
||||
{
|
||||
Navigation nav = topLeftSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Vertical;
|
||||
topLeftSelectable.navigation = nav;
|
||||
|
||||
nav = topRightSelectable.navigation;
|
||||
nav.wrapAround = true;
|
||||
nav.mode = Navigation.Mode.Vertical;
|
||||
topRightSelectable.navigation = nav;
|
||||
|
||||
Selectable selectableUpOfTopLeft = topLeftSelectable.FindSelectableOnUp();
|
||||
Selectable selectableUpOfTopRight = topRightSelectable.FindSelectableOnUp();
|
||||
|
||||
Assert.AreEqual(bottomRightSelectable, selectableUpOfTopLeft, "Wrong selectable to Up of Top Left Selectable");
|
||||
Assert.AreEqual(bottomLeftSelectable, selectableUpOfTopRight, "Wrong selectable to Up of Top Right Selectable");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aca0de4e74f6cdf41a449805f345a4f5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Graphics
|
||||
{
|
||||
public class RawImageTest : IPrebuildSetup
|
||||
{
|
||||
private const int Width = 32;
|
||||
private const int Height = 32;
|
||||
|
||||
private GameObject m_PrefabRoot;
|
||||
private RawImageTestHook m_image;
|
||||
private Texture2D m_defaultTexture;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/RawImageUpdatePrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("Root");
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
var canvas = canvasGO.GetComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.WorldSpace;
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var imageGO = new GameObject("Image", typeof(RectTransform), typeof(RawImageTestHook));
|
||||
var imageTransform = imageGO.GetComponent<RectTransform>();
|
||||
imageTransform.SetParent(canvas.transform);
|
||||
|
||||
imageTransform.anchoredPosition = Vector2.zero;
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("RawImageUpdatePrefab")) as GameObject;
|
||||
|
||||
m_image = m_PrefabRoot.transform.Find("Canvas/Image").GetComponent<RawImageTestHook>();
|
||||
m_defaultTexture = new Texture2D(Width, Height);
|
||||
m_image.texture = m_defaultTexture;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Sprite_Material()
|
||||
{
|
||||
m_image.ResetTest();
|
||||
|
||||
// can test only on texture change, same texture is bypass by RawImage property
|
||||
m_image.texture = new Texture2D(Width, Height);
|
||||
yield return new WaitUntil(() => m_image.isGeometryUpdated);
|
||||
|
||||
// validate that layout change rebuild is called
|
||||
Assert.IsTrue(m_image.isMaterialRebuild);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acfa3573efc38c844be021fdaa8cf8a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class RawImageTestHook : RawImage
|
||||
{
|
||||
public bool isGeometryUpdated;
|
||||
public bool isCacheUsed;
|
||||
public bool isLayoutRebuild;
|
||||
public bool isMaterialRebuild;
|
||||
|
||||
public void ResetTest()
|
||||
{
|
||||
isGeometryUpdated = false;
|
||||
isLayoutRebuild = false;
|
||||
isMaterialRebuild = false;
|
||||
isCacheUsed = false;
|
||||
}
|
||||
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
base.SetLayoutDirty();
|
||||
isLayoutRebuild = true;
|
||||
}
|
||||
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
base.SetMaterialDirty();
|
||||
isMaterialRebuild = true;
|
||||
}
|
||||
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
base.UpdateGeometry();
|
||||
isGeometryUpdated = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40c83ba6a1a64cb4baac27028dd1acc1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ToggleTestImageHook : Image
|
||||
{
|
||||
public float durationTween;
|
||||
public override void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB)
|
||||
{
|
||||
durationTween = duration;
|
||||
base.CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha, useRGB);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c004b1354944164fb076276c289afc1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1091bc2ad06e3234aac2b2fa2841c09d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
[TestFixture]
|
||||
[Category("RegressionTest")]
|
||||
public class ImageFilledGenerateWork
|
||||
{
|
||||
GameObject m_CanvasGO;
|
||||
GameObject m_ImageGO;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
m_CanvasGO = new GameObject("Canvas");
|
||||
m_ImageGO = new GameObject("Image");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImageFilledGenerateWorks()
|
||||
{
|
||||
m_CanvasGO.AddComponent<Canvas>();
|
||||
m_ImageGO.transform.SetParent(m_CanvasGO.transform);
|
||||
var image = m_ImageGO.AddComponent<TestableImage>();
|
||||
image.type = Image.Type.Filled;
|
||||
var texture = new Texture2D(32, 32);
|
||||
image.sprite = Sprite.Create(texture, new Rect(0, 0, 32, 32), Vector2.zero);
|
||||
image.fillMethod = Image.FillMethod.Horizontal;
|
||||
image.fillAmount = 0.5f;
|
||||
|
||||
// Generate the image data now.
|
||||
VertexHelper vh = new VertexHelper();
|
||||
|
||||
// Image is a "TestableImage" which has the Assert in the GenerateImageData as we need to validate
|
||||
// the data which is protected.
|
||||
image.GenerateImageData(vh);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a70a790a43cd0d4a96f75746841f764
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using System.Reflection;
|
||||
|
||||
public class ImageTests
|
||||
{
|
||||
private const int Width = 32;
|
||||
private const int Height = 32;
|
||||
|
||||
GameObject m_CanvasGO;
|
||||
TestableImage m_Image;
|
||||
private Texture2D m_defaultTexture;
|
||||
|
||||
private bool m_dirtyLayout;
|
||||
private bool m_dirtyMaterial;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
m_CanvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
GameObject imageObject = new GameObject("Image", typeof(TestableImage));
|
||||
imageObject.transform.SetParent(m_CanvasGO.transform);
|
||||
m_Image = imageObject.GetComponent<TestableImage>();
|
||||
m_Image.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
|
||||
m_Image.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
|
||||
|
||||
m_defaultTexture = new Texture2D(Width, Height);
|
||||
Color[] colors = new Color[Width * Height];
|
||||
for (int i = 0; i < Width * Height; i++)
|
||||
colors[i] = Color.magenta;
|
||||
m_defaultTexture.Apply();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TightMeshSpritePopulatedVertexHelperProperly()
|
||||
{
|
||||
Texture2D texture = new Texture2D(64, 64);
|
||||
m_Image.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0));
|
||||
m_Image.type = Image.Type.Simple;
|
||||
m_Image.useSpriteMesh = true;
|
||||
|
||||
VertexHelper vh = new VertexHelper();
|
||||
|
||||
m_Image.GenerateImageData(vh);
|
||||
|
||||
Assert.AreEqual(vh.currentVertCount, m_Image.sprite.vertices.Length);
|
||||
Assert.AreEqual(vh.currentIndexCount, m_Image.sprite.triangles.Length);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator CanvasCustomRefPixPerUnitToggleWillUpdateImageMesh()
|
||||
{
|
||||
var canvas = m_CanvasGO.GetComponent<Canvas>();
|
||||
var canvasScaler = m_CanvasGO.AddComponent<CanvasScaler>();
|
||||
|
||||
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
m_Image.transform.SetParent(m_CanvasGO.transform);
|
||||
m_Image.type = Image.Type.Sliced;
|
||||
var texture = new Texture2D(120, 120);
|
||||
m_Image.sprite = Sprite.Create(texture, new Rect(0, 0, 120, 120), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight, new Vector4(30, 30, 30, 30), true);
|
||||
m_Image.fillCenter = true;
|
||||
|
||||
|
||||
canvasScaler.referencePixelsPerUnit = 200;
|
||||
yield return null; // skip frame to update canvas properly
|
||||
//setup done
|
||||
|
||||
canvas.enabled = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
canvas.enabled = true;
|
||||
m_Image.isOnPopulateMeshCalled = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.IsTrue(m_Image.isOnPopulateMeshCalled);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Sprite_Layout()
|
||||
{
|
||||
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero);
|
||||
yield return null;
|
||||
|
||||
m_Image.isGeometryUpdated = false;
|
||||
m_dirtyLayout = false;
|
||||
|
||||
var Texture = new Texture2D(Width * 2, Height * 2);
|
||||
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width, Height), Vector2.zero);
|
||||
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
|
||||
|
||||
// validate that layout change rebuil is not called
|
||||
Assert.IsFalse(m_dirtyLayout);
|
||||
|
||||
m_Image.isGeometryUpdated = false;
|
||||
m_dirtyLayout = false;
|
||||
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
|
||||
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
|
||||
|
||||
// validate that layout change rebuil is called
|
||||
Assert.IsTrue(m_dirtyLayout);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Sprite_Material()
|
||||
{
|
||||
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero);
|
||||
yield return null;
|
||||
|
||||
m_Image.isGeometryUpdated = false;
|
||||
m_dirtyMaterial = false;
|
||||
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
|
||||
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
|
||||
|
||||
// validate that material change rebuild is not called
|
||||
Assert.IsFalse(m_dirtyMaterial);
|
||||
|
||||
m_Image.isGeometryUpdated = false;
|
||||
m_dirtyMaterial = false;
|
||||
var Texture = new Texture2D(Width * 2, Height * 2);
|
||||
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
|
||||
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
|
||||
|
||||
// validate that layout change rebuil is called
|
||||
Assert.IsTrue(m_dirtyMaterial);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGO);
|
||||
GameObject.DestroyImmediate(m_defaultTexture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a598580d0cfc7224ebed8d2b627d9e00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.UI;
|
||||
using System.Reflection;
|
||||
|
||||
public class TestableImage : Image
|
||||
{
|
||||
public bool isOnPopulateMeshCalled = false;
|
||||
public bool isGeometryUpdated = false;
|
||||
|
||||
// Hook into the mesh generation so we can do our check.
|
||||
protected override void OnPopulateMesh(VertexHelper toFill)
|
||||
{
|
||||
base.OnPopulateMesh(toFill);
|
||||
Assert.That(toFill.currentVertCount, Is.GreaterThan(0), "Expected the mesh to be filled but it was not. Should not have a mesh with zero vertices.");
|
||||
isOnPopulateMeshCalled = true;
|
||||
}
|
||||
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
base.UpdateGeometry();
|
||||
isGeometryUpdated = true;
|
||||
}
|
||||
|
||||
public void GenerateImageData(VertexHelper vh)
|
||||
{
|
||||
OnPopulateMesh(vh);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user