From 738d511002b7a8850bf48438f8ffe596856b084a Mon Sep 17 00:00:00 2001 From: Dogukan Erenel Date: Thu, 25 Aug 2016 15:02:57 -0500 Subject: [PATCH 1/5] * Added camera target with path --- Prefabs/TouchManager.prefab | 5 +- Scripts/Camera/CameraTarget.cs | 149 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 2 deletions(-) diff --git a/Prefabs/TouchManager.prefab b/Prefabs/TouchManager.prefab index 28d241758..e4619dcf9 100644 --- a/Prefabs/TouchManager.prefab +++ b/Prefabs/TouchManager.prefab @@ -68,6 +68,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 456440} m_RootOrder: 0 @@ -80,6 +81,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: - {fileID: 438902} - {fileID: 22440388} @@ -350,7 +352,7 @@ MonoBehaviour: sendMessageEvents: 60 sendMessageTarget: {fileID: 0} layers: - - {fileID: 11437114} + - {fileID: 0} --- !u!114 &11495534 MonoBehaviour: m_ObjectHideFlags: 1 @@ -402,6 +404,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0, y: 0, z: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_Children: [] m_Father: {fileID: 456440} m_RootOrder: 1 diff --git a/Scripts/Camera/CameraTarget.cs b/Scripts/Camera/CameraTarget.cs index 7d7f655f8..8b41cecfc 100644 --- a/Scripts/Camera/CameraTarget.cs +++ b/Scripts/Camera/CameraTarget.cs @@ -18,6 +18,7 @@ using UnityEngine; using IBM.Watson.DeveloperCloud.Logging; +using System.Collections.Generic; namespace IBM.Watson.DeveloperCloud.Camera { @@ -44,6 +45,15 @@ public class CameraTarget : MonoBehaviour private bool m_UseTargetObjectToRotate = false; [SerializeField] private GameObject m_CustomTargetObjectToLookAt = null; + [SerializeField] + private GameObject m_CameraPathRootObject = null; + [SerializeField] + private float m_RatioAtCameraPath = 0.0f; + [SerializeField] + private Vector3 m_DistanceFromCamera = Vector3.zero; + [SerializeField] + private SplineInterpolator m_SplineInterpolator; + private Transform[] m_PathTransforms; [SerializeField] private bool m_TextEnableCamera = false; @@ -88,6 +98,74 @@ public bool UseCustomRotation } } + /// + /// Gets or sets the ratio at camera path. It is used if there is path root object assigned to the system + /// + /// The ratio at camera path. + public float RatioAtCameraPath + { + get + { + return m_RatioAtCameraPath; + } + set + { + m_RatioAtCameraPath = Mathf.Repeat(value, 1.0f); + } + } + + /// + /// Gets or sets the camera path root object. + /// + /// The camera path root object. + public GameObject CameraPathRootObject + { + get + { + return m_CameraPathRootObject; + } + set + { + m_CameraPathRootObject = value; + } + } + + public Vector3 OffsetPosition + { + get + { + return m_OffsetPosition; + } + set + { + m_OffsetPosition = value; + } + } + + public Vector3 DistanceFromCamera + { + get + { + return m_DistanceFromCamera; + } + set + { + m_DistanceFromCamera = value; + } + } + + public Quaternion OffsetPositionRotation + { + get + { + return m_OffsetPositionRotation; + } + set + { + m_OffsetPositionRotation = value; + } + } + /// /// Gets or sets the target position. /// @@ -96,8 +174,41 @@ public Vector3 TargetPosition { get { + if (m_CameraPathRootObject != null) + { + if (m_PathTransforms == null) + { + List childrenTransforms = new List(m_CameraPathRootObject.GetComponentsInChildren()); + + childrenTransforms.Remove(m_CameraPathRootObject.transform); + childrenTransforms.Sort(delegate(Transform t1, Transform t2) + { + return t1.name.CompareTo(t2.name); + }); + + m_PathTransforms = childrenTransforms.ToArray(); + + if (m_SplineInterpolator == null) + { + m_SplineInterpolator = this.gameObject.GetComponent(); + if (m_SplineInterpolator == null) + m_SplineInterpolator = this.gameObject.AddComponent(); + } + + m_SplineInterpolator.SetupSplineInterpolator(m_PathTransforms); + } + + if (m_OffsetPosition != Vector3.zero) + { + return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath) + (TargetRotation * m_OffsetPosition); + } + else + { + return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath); + } - if (m_UseCustomPosition) + } + else if (m_UseCustomPosition) { return m_CustomPosition; } @@ -298,6 +409,42 @@ public void SetTargetPositionWithOffset(Vector3 offsetPosition) } #endregion + + void OnDrawGizmos() + { + if (m_CameraPathRootObject != null) + { + List childrenTransforms = new List(m_CameraPathRootObject.GetComponentsInChildren()); + + childrenTransforms.Remove(m_CameraPathRootObject.transform); + childrenTransforms.Sort(delegate(Transform t1, Transform t2) + { + return t1.name.CompareTo(t2.name); + }); + + m_PathTransforms = childrenTransforms.ToArray(); + + if (m_SplineInterpolator == null) + { + m_SplineInterpolator = this.gameObject.GetComponent(); + if (m_SplineInterpolator == null) + m_SplineInterpolator = this.gameObject.AddComponent(); + } + + m_SplineInterpolator.SetupSplineInterpolator(m_PathTransforms); + + Vector3 prevPos = m_PathTransforms[0].position; + for (int c = 1; c <= 100; c++) + { + float currTime = c * 1.0f / 100; + Vector3 currPos = m_SplineInterpolator.GetHermiteAtTime(currTime); + float mag = (currPos - prevPos).magnitude * 2; + Gizmos.color = new Color(mag, 0, 0, 1); + Gizmos.DrawLine(prevPos, currPos); + prevPos = currPos; + } + } + } } } From 69dd2d1197f4faa9930da77cf05f139cdb13375c Mon Sep 17 00:00:00 2001 From: Dogukan Erenel Date: Fri, 26 Aug 2016 18:51:40 -0500 Subject: [PATCH 2/5] * Added distance to make it more flexible with path --- Scripts/Camera/CameraTarget.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Camera/CameraTarget.cs b/Scripts/Camera/CameraTarget.cs index 8b41cecfc..70ba62c4c 100644 --- a/Scripts/Camera/CameraTarget.cs +++ b/Scripts/Camera/CameraTarget.cs @@ -200,11 +200,11 @@ public Vector3 TargetPosition if (m_OffsetPosition != Vector3.zero) { - return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath) + (TargetRotation * m_OffsetPosition); + return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath) + (TargetRotation * m_OffsetPosition) + DistanceFromCamera; } else { - return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath); + return m_SplineInterpolator.GetHermiteAtTime(m_RatioAtCameraPath) + DistanceFromCamera; } } From b4420bfc70c28c235e097da917eb02d2a7bc34b3 Mon Sep 17 00:00:00 2001 From: Dogukan Erenel Date: Mon, 29 Aug 2016 17:51:02 -0500 Subject: [PATCH 3/5] * Minor fix touch-event-manager --- Scripts/Utilities/TouchEventManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Utilities/TouchEventManager.cs b/Scripts/Utilities/TouchEventManager.cs index 8f8cbdacf..067372138 100644 --- a/Scripts/Utilities/TouchEventManager.cs +++ b/Scripts/Utilities/TouchEventManager.cs @@ -383,7 +383,7 @@ public UnityEngine.Camera MainCamera { get { - if (m_mainCamera == null) + if (m_mainCamera == null || !m_mainCamera.transform.CompareTag("MainCamera")) m_mainCamera = UnityEngine.Camera.main; return m_mainCamera; From b1ba562e3f6f83140c408494bc098077fe631857 Mon Sep 17 00:00:00 2001 From: Dogukan Erenel Date: Wed, 31 Aug 2016 20:14:09 -0500 Subject: [PATCH 4/5] * Fix unregistration from taps - TouchManager * Added Epoch Milliseconds / Seconds and added conversion from millisecond / second to epoch time. --- Scripts/Utilities/TouchEventManager.cs | 66 +++++++++++++++++++++----- Scripts/Utilities/Utility.cs | 23 ++++++++- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/Scripts/Utilities/TouchEventManager.cs b/Scripts/Utilities/TouchEventManager.cs index 067372138..c9d89958c 100644 --- a/Scripts/Utilities/TouchEventManager.cs +++ b/Scripts/Utilities/TouchEventManager.cs @@ -275,6 +275,15 @@ public override int GetHashCode() return base.GetHashCode(); } + /// + /// Returns a that represents the current . + /// + /// A that represents the current . + public override string ToString() + { + return string.Format("[TouchEventData: GameObjectAttached={0}, Collider={1}, Collider2D={2}, RectTransform={3}, ColliderList={4}, ColliderList2D={5}, RectTransformList={6}, IsInside={7}, TapCallback={8}, DragCallback={9}, SortingLayer={10}, CanDragObject={11}]", GameObjectAttached, Collider, Collider2D, RectTransform, ColliderList, ColliderList2D, RectTransformList, IsInside, TapCallback, DragCallback, SortingLayer, CanDragObject); + } + } #region Private Data @@ -1154,7 +1163,9 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) } else { - Log.Warning("TouchEventManager", "There is no 3D collider of given gameobjectToTouch"); + #if ENABLE_DEBUGGING + Log.Debug("TouchEventManager", "There is no 3D collider of given gameobjectToTouch"); + #endif } if (!success) @@ -1182,7 +1193,9 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) success = true; } else { - Log.Warning ("TouchEventManager", "There is no 2D collider of given gameobjectToTouch"); + #if ENABLE_DEBUGGING + Log.Debug ("TouchEventManager", "There is no 2D collider of given gameobjectToTouch"); + #endif } } #if UNITY_4_6 || UNITY_5 || UNITY_5_3_OR_NEWER @@ -1211,7 +1224,9 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) success = true; } else { - Log.Warning ("TouchEventManager", "There is no Rect Transform of given gameobjectToTouch"); + #if ENABLE_DEBUGGING + Log.Debug ("TouchEventManager", "There is no Rect Transform of given gameobjectToTouch"); + #endif } } #endif @@ -1258,15 +1273,19 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) foreach (Collider itemCollider in colliderList) { int numberOfRemovedCallbacks = m_TapEvents[layerMaskAsKey].RemoveAll( - e => - e.Collider == itemCollider && - e.TapCallback == callback && - e.SortingLayer == SortingLayer && - e.IsInside == isTapInside); + e => + e.Collider == itemCollider && + e.TapCallback == callback && + e.SortingLayer == SortingLayer && + e.IsInside == isTapInside); success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } if (!success) { @@ -1286,7 +1305,13 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } } + + #if UNITY_4_6 || UNITY_5 || UNITY_5_3_OR_NEWER if (!success) { @@ -1306,6 +1331,10 @@ private void TwoFingerTransformedHandler(object sender, System.EventArgs e) success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } } #endif } @@ -1392,16 +1421,16 @@ private void TapGesture_Tapped(object sender, System.EventArgs e) { TouchEventData tapEventData = kp.Value[i]; - if (kp.Value[i].Collider == null && kp.Value[i].Collider2D == null && kp.Value[i].RectTransform == null ) + if (kp.Value[i].Collider == null && kp.Value[i].Collider2D == null && kp.Value[i].RectTransform == null && kp.Value[i].RectTransformList == null ) { - Log.Warning("TouchEventManager", "Removing invalid collider event receiver from TapEventList"); + Log.Warning("TouchEventManager", "Removing invalid collider event receiver from TapEventList from {0}", kp.Value[i].ToString()); kp.Value.RemoveAt(i--); continue; } if (string.IsNullOrEmpty(tapEventData.TapCallback)) { - Log.Warning("TouchEventManager", "Removing invalid event receiver from TapEventList"); + Log.Warning("TouchEventManager", "Removing invalid event receiver from TapEventList {0}", kp.Value[i]); kp.Value.RemoveAt(i--); continue; } @@ -1801,6 +1830,10 @@ private void TapGesture_Tapped(object sender, System.EventArgs e) success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } if (!success) { @@ -1820,6 +1853,11 @@ private void TapGesture_Tapped(object sender, System.EventArgs e) success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } + } #if UNITY_4_6 || UNITY_5 || UNITY_5_3_OR_NEWER if (!success) @@ -1840,6 +1878,10 @@ private void TapGesture_Tapped(object sender, System.EventArgs e) success &= (numberOfRemovedCallbacks > 0); } } + else + { + success = false; + } } #endif } @@ -1927,7 +1969,7 @@ private void DoubleTapGesture_Tapped(object sender, System.EventArgs e) { TouchEventData tapEventData = kp.Value[i]; - if (kp.Value[i].Collider == null && kp.Value[i].Collider2D == null && kp.Value[i].RectTransform == null ) + if (kp.Value[i].Collider == null && kp.Value[i].Collider2D == null && kp.Value[i].RectTransform == null && kp.Value[i].RectTransformList == null) { Log.Warning("TouchEventManager", "Removing invalid collider event receiver from DoubleTapEventList"); kp.Value.RemoveAt(i--); diff --git a/Scripts/Utilities/Utility.cs b/Scripts/Utilities/Utility.cs index 6cf89c50d..4775cccd0 100644 --- a/Scripts/Utilities/Utility.cs +++ b/Scripts/Utilities/Utility.cs @@ -278,12 +278,22 @@ public static string StripString(string s) /// Gets the EPOCH time in UTC time zome /// /// Double EPOCH in UTC - public static double GetEpochUTC() + public static double GetEpochUTCMilliseconds() { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return (DateTime.UtcNow - epoch).TotalMilliseconds; } + /// + /// Gets the epoch UTC seconds. + /// + /// The epoch UTC seconds. + public static double GetEpochUTCSeconds() + { + DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + return (DateTime.UtcNow - epoch).TotalSeconds; + } + /// /// Gets the date time from epoch. /// @@ -293,7 +303,16 @@ public static double GetEpochUTC() public static DateTime GetLocalDateTimeFromEpoch(double epochTime) { DateTime dateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc); - dateTime = dateTime.AddMilliseconds(epochTime).ToLocalTime(); + try + { + dateTime = dateTime.AddSeconds(epochTime).ToLocalTime(); + } + catch (ArgumentOutOfRangeException ex) + { + Log.Debug("Utility", "Time conversion assuming time is in Milliseconds: {0}, {1}", epochTime, ex.Message); + dateTime = dateTime.AddMilliseconds(epochTime).ToLocalTime(); + } + return dateTime; } From 885894a2302096974b3be1713bfa936d7d3aba9d Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 31 Aug 2016 20:25:10 -0500 Subject: [PATCH 5/5] encrypt config --- Config.json.enc | Bin 5184 -> 5248 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Config.json.enc b/Config.json.enc index 7a85c1700cb39d6eb5fa703eae9713476ec1eb4f..35ff60fe0b9e421a35509362b6dbb18b4a2a42bd 100644 GIT binary patch literal 5248 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 Gn67QXxk*0& literal 5184 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