Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Box Shape for the Dynamic Origin behavior on the On-Screen Stick. #1654

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .yamato/analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ code_analyser:
- upm-ci project test --project-path Tools/CodeAnalyzerTestProject -u 2019.4
triggers:
cancel_old_ci: true
branches:
only:
- "/gh-readonly-queue/develop/.*/"
pull_requests:
- targets:
only:
Expand Down
5 changes: 4 additions & 1 deletion .yamato/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ check_formatting:
- perl unity-meta/Tools/Format/format.pl Assets Packages --dry-run
triggers:
cancel_old_ci: true
branches:
only:
- "/gh-readonly-queue/develop/.*/"
pull_requests:
- targets:
only:
- "develop"
- "develop"
4 changes: 4 additions & 0 deletions .yamato/sonarqube.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ Windows-Dotnet-SonarScanner:
paths:
- "**/*.log"
triggers:
cancel_old_ci: true
branches:
only:
- "/gh-readonly-queue/develop/.*/"
pull_requests:
- targets:
only:
Expand Down
3 changes: 3 additions & 0 deletions .yamato/test-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ test_sample_projects_{{ editor.version }}:
- Editor=.Editor/Unity.app/Contents/MacOS/Unity Method=DryRun sh ExternalSampleProjects/publish.sh
triggers:
cancel_old_ci: true
branches:
only:
- "/gh-readonly-queue/develop/.*/"
pull_requests:
- targets:
only:
Expand Down
3 changes: 3 additions & 0 deletions .yamato/upm-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ all_tests:
- .yamato/upm-ci.yml#publish_dryrun
triggers:
cancel_old_ci: true
branches:
only:
- "/gh-readonly-queue/develop/.*/"
pull_requests:
- targets:
only:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,30 @@ private void Start()
m_PointerDownPos = m_StartPos;

var dynamicOrigin = new GameObject(kDynamicOriginClickable, typeof(Image));
dynamicOrigin.transform.SetParent(transform);
var image = dynamicOrigin.GetComponent<Image>();
image.color = new Color(1, 1, 1, 0);
var image = dynamicOrigin.GetComponent<Image>();;
var rectTransform = (RectTransform)dynamicOrigin.transform;
rectTransform.sizeDelta = new Vector2(m_DynamicOriginRange * 2, m_DynamicOriginRange * 2);
rectTransform.localScale = new Vector3(1, 1, 0);
rectTransform.anchoredPosition3D = Vector3.zero;

image.sprite = SpriteUtilities.CreateCircleSprite(16, new Color32(255, 255, 255, 255));
image.color = new Color(1, 1, 1, 0);
if (m_OriginType == OriginType.Circle)
{
rectTransform.SetParent(transform);
rectTransform.sizeDelta = new Vector2(m_dynamicOriginRange * 2, m_dynamicOriginRange * 2);
rectTransform.localScale = new Vector3(1, 1, 0);
image.sprite = SpriteUtilities.CreateCircleSprite(16, new Color32(255, 255, 255, 255));
rectTransform.anchoredPosition3D = Vector3.zero;
}
else
{
// Use a 1x1 square sprite and align the width, height, and position of the dynamic origin's RectTransform.
Texture2D spriteTexture = new Texture2D(1,1);
image.sprite = Sprite.Create(spriteTexture,new Rect(0,0,1,1),new Vector2(0.5f,0.5f));
rectTransform.SetParent(originTransfrom.gameObject.transform.parent, false);
rectTransform.anchorMin = originTransfrom.anchorMin;
rectTransform.anchorMax = originTransfrom.anchorMax;
rectTransform.anchoredPosition = originTransfrom.anchoredPosition;
rectTransform.sizeDelta = originTransfrom.sizeDelta;
rectTransform.SetParent(transform);

}
image.alphaHitTestMinimumThreshold = 0.5f;
}

Expand All @@ -137,6 +152,7 @@ private void BeginInteraction(Vector2 pointerPosition, Camera uiCamera)
{
Debug.LogError("OnScreenStick needs to be attached as a child to a UI Canvas to function properly.");
return;

}

switch (m_Behaviour)
Expand All @@ -150,7 +166,7 @@ private void BeginInteraction(Vector2 pointerPosition, Camera uiCamera)
break;
case Behaviour.ExactPositionWithDynamicOrigin:
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, pointerPosition, uiCamera, out var pointerDown);
m_PointerDownPos = ((RectTransform)transform).anchoredPosition = pointerDown;
m_PointerDownPos = ((RectTransform)transform).anchoredPosition = pointerDown;
break;
}
}
Expand Down Expand Up @@ -202,7 +218,7 @@ private void OnPointerDown(InputAction.CallbackContext ctx)
var screenPosition = Vector2.zero;
if (ctx.control?.device is Pointer pointer)
screenPosition = pointer.position.ReadValue();

m_PointerEventData.position = screenPosition;
EventSystem.current.RaycastAll(m_PointerEventData, m_RaycastResults);
if (m_RaycastResults.Count == 0)
Expand All @@ -212,7 +228,7 @@ private void OnPointerDown(InputAction.CallbackContext ctx)
foreach (var result in m_RaycastResults)
{
if (result.gameObject != gameObject) continue;

stickSelected = true;
break;
}
Expand Down Expand Up @@ -253,24 +269,26 @@ private Camera GetCameraFromCanvas()

private void OnDrawGizmosSelected()
{
Gizmos.matrix = ((RectTransform)transform.parent).localToWorldMatrix;
if (m_OriginType == OriginType.Circle) {
Gizmos.matrix = ((RectTransform)transform.parent).localToWorldMatrix;

var startPos = ((RectTransform)transform).anchoredPosition;
if (Application.isPlaying)
startPos = m_StartPos;
var startPos = ((RectTransform)transform).anchoredPosition;
if (Application.isPlaying)
startPos = m_StartPos;

Gizmos.color = new Color32(84, 173, 219, 255);
Gizmos.color = new Color32(84, 173, 219, 255);

var center = startPos;
if (Application.isPlaying && m_Behaviour == Behaviour.ExactPositionWithDynamicOrigin)
center = m_PointerDownPos;
var center = startPos;
if (Application.isPlaying && m_Behaviour == Behaviour.ExactPositionWithDynamicOrigin)
center = m_PointerDownPos;

DrawGizmoCircle(center, m_MovementRange);
DrawGizmoCircle(center, m_MovementRange);

if (m_Behaviour != Behaviour.ExactPositionWithDynamicOrigin) return;
if (m_Behaviour != Behaviour.ExactPositionWithDynamicOrigin) return;

Gizmos.color = new Color32(158, 84, 219, 255);
DrawGizmoCircle(startPos, m_DynamicOriginRange);
Gizmos.color = new Color32(158, 84, 219, 255);
DrawGizmoCircle(startPos, m_dynamicOriginRange);
}
}

private void DrawGizmoCircle(Vector2 center, float radius)
Expand All @@ -291,7 +309,7 @@ private void UpdateDynamicOriginClickableArea()
if (dynamicOriginTransform)
{
var rectTransform = (RectTransform)dynamicOriginTransform;
rectTransform.sizeDelta = new Vector2(m_DynamicOriginRange * 2, m_DynamicOriginRange * 2);
rectTransform.sizeDelta = new Vector2(m_dynamicOriginRange * 2, m_dynamicOriginRange * 2);
}
}

Expand All @@ -311,21 +329,29 @@ public float movementRange
/// This only applies if <see cref="behaviour"/> is set to <see cref="Behaviour.ExactPositionWithDynamicOrigin"/>.
/// When the first press is within this region, then the control will appear at that position and have it's origin of motion placed there.
/// Otherwise, if pressed outside of this region the control will ignore it.
/// This property defines the radius of the circular region. The center point being defined by the component position in the scene.
/// This property defines the radius of the circular region. The center point being defined by the pivot of the parent's RectTransform in the scene.
/// </remarks>
public float dynamicOriginRange
{
get => m_DynamicOriginRange;
get => m_dynamicOriginRange;
set
{
// ReSharper disable once CompareOfFloatsByEqualityOperator
if (m_DynamicOriginRange != value)
if (m_dynamicOriginRange != value)
{
m_DynamicOriginRange = value;
m_dynamicOriginRange = value;
UpdateDynamicOriginClickableArea();
}
}
}
/// <summary>
///
/// </summary>
public RectTransform originTransfrom
{
get => m_originTransform;
set => m_originTransform = value;
}

/// <summary>
/// Prevents stick interactions from getting cancelled due to device switching.
Expand Down Expand Up @@ -357,7 +383,10 @@ public bool useIsolatedInputActions
[SerializeField]
[Tooltip("Defines the circular region where the onscreen control may have it's origin placed.")]
[Min(0)]
private float m_DynamicOriginRange = 100;
private float m_dynamicOriginRange = 100;
[SerializeField]
[Tooltip("Alternate dynamic origin Collider2D. Anything inside the Collider2D will be an area where you can place the joystick's origin,.")]
private RectTransform m_originTransform;

[InputControl(layout = "Vector2")]
[SerializeField]
Expand All @@ -372,12 +401,16 @@ public bool useIsolatedInputActions
"ExactPositionWithDynamicOrigin: The control's center of origin is determined by the initial press position. " +
"The stick will begin un-actuated at this center position and then track the current pointer or finger position.")]
private Behaviour m_Behaviour;
[SerializeField]
[Tooltip("Choose which origin shape you want to use for the stick.\n\n" +
"Circle: Define the radius of the circle around the pivot.\n\n" +
"Rect Transform: Attach a GameObject with a BoxCollider2D. The joystick will begin from anywhere in the collider.")]
private OriginType m_OriginType;

[SerializeField]
[Tooltip("Set this to true to prevent cancellation of pointer events due to device switching. Cancellation " +
"will appear as the stick jumping back and forth between the pointer position and the stick center.")]
private bool m_UseIsolatedInputActions;

[SerializeField]
[Tooltip("The action that will be used to detect pointer down events on the stick control. Note that if no bindings " +
"are set, default ones will be provided.")]
Expand All @@ -401,7 +434,22 @@ protected override string controlPathInternal
get => m_ControlPath;
set => m_ControlPath = value;
}

public OriginType originType
{
get => m_OriginType;
set => m_OriginType = value;
}
public enum OriginType
{
/// <summary>
/// Circle: Define the radius of the circle around the pivot.
/// </summary>
Circle,
/// <summary>
/// Rect Transform: Attach a GameObject with a BoxCollider2D. The joystick will begin from anywhere in the collider.
/// </summary>
RectTransform
}
/// <summary>Defines how the onscreen stick will move relative to it's origin and the press position.</summary>
public Behaviour behaviour
{
Expand Down Expand Up @@ -429,28 +477,36 @@ public enum Behaviour
[CustomEditor(typeof(OnScreenStick))]
internal class OnScreenStickEditor : UnityEditor.Editor
{
private AnimBool m_ShowDynamicOriginOptions;
private AnimBool m_ShowDynamicOriginDropdown;
private AnimBool m_ShowIsolatedInputActions;
private AnimBool m_ShowDynamicBoxOrigin;
private AnimBool m_ShowDynamicCircleOrigin;

private SerializedProperty m_UseIsolatedInputActions;
private SerializedProperty m_Behaviour;
private SerializedProperty m_OriginType;
private SerializedProperty m_ControlPathInternal;
private SerializedProperty m_MovementRange;
private SerializedProperty m_DynamicOriginRange;
private SerializedProperty m_dynamicOriginRange;
private SerializedProperty m_originTransform;
private SerializedProperty m_PointerDownAction;
private SerializedProperty m_PointerMoveAction;

public void OnEnable()
{
m_ShowDynamicOriginOptions = new AnimBool(false);
m_ShowDynamicOriginDropdown = new AnimBool(false);
m_ShowDynamicBoxOrigin = new AnimBool(false);
m_ShowDynamicCircleOrigin = new AnimBool(false);
m_ShowIsolatedInputActions = new AnimBool(false);

m_UseIsolatedInputActions = serializedObject.FindProperty(nameof(OnScreenStick.m_UseIsolatedInputActions));

m_Behaviour = serializedObject.FindProperty(nameof(OnScreenStick.m_Behaviour));
m_OriginType = serializedObject.FindProperty(nameof(OnScreenStick.m_OriginType));
m_ControlPathInternal = serializedObject.FindProperty(nameof(OnScreenStick.m_ControlPath));
m_MovementRange = serializedObject.FindProperty(nameof(OnScreenStick.m_MovementRange));
m_DynamicOriginRange = serializedObject.FindProperty(nameof(OnScreenStick.m_DynamicOriginRange));
m_dynamicOriginRange = serializedObject.FindProperty(nameof(OnScreenStick.m_dynamicOriginRange));
m_originTransform = serializedObject.FindProperty(nameof(OnScreenStick.m_originTransform));
m_PointerDownAction = serializedObject.FindProperty(nameof(OnScreenStick.m_PointerDownAction));
m_PointerMoveAction = serializedObject.FindProperty(nameof(OnScreenStick.m_PointerMoveAction));
}
Expand All @@ -461,17 +517,44 @@ public override void OnInspectorGUI()
EditorGUILayout.PropertyField(m_ControlPathInternal);
EditorGUILayout.PropertyField(m_Behaviour);

m_ShowDynamicOriginOptions.target = ((OnScreenStick)target).behaviour ==
m_ShowDynamicOriginDropdown.target = ((OnScreenStick)target).behaviour ==
Behaviour.ExactPositionWithDynamicOrigin;
if (EditorGUILayout.BeginFadeGroup(m_ShowDynamicOriginOptions.faded))

m_ShowDynamicBoxOrigin.target = ((OnScreenStick)target).originType ==
OriginType.RectTransform;

m_ShowDynamicCircleOrigin.target = ((OnScreenStick)target).originType ==
OriginType.Circle;

if (EditorGUILayout.BeginFadeGroup(m_ShowDynamicOriginDropdown.faded))
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_DynamicOriginRange);
if (EditorGUI.EndChangeCheck())
EditorGUILayout.PropertyField(m_OriginType);
if (EditorGUILayout.BeginFadeGroup(m_ShowDynamicBoxOrigin.faded))
{

EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_originTransform);
if (EditorGUI.EndChangeCheck())
{
((OnScreenStick)target).UpdateDynamicOriginClickableArea();
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
if (EditorGUILayout.BeginFadeGroup(m_ShowDynamicCircleOrigin.faded))
{
((OnScreenStick)target).UpdateDynamicOriginClickableArea();
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_dynamicOriginRange);
if (EditorGUI.EndChangeCheck())
{
((OnScreenStick)target).UpdateDynamicOriginClickableArea();
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFadeGroup();
Expand Down