resharp
parent
35325c8899
commit
3df190382a
|
@ -1,85 +1,87 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Coffee.UIExtensions;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
public class CFX_Demo_With_UIParticle : MonoBehaviour
|
namespace Coffee.UIExtensions.Demo
|
||||||
{
|
{
|
||||||
private UIParticle UiParticle;
|
public class CFX_Demo_With_UIParticle : MonoBehaviour
|
||||||
private Toggle spawnOnUI;
|
|
||||||
private MonoBehaviour demo;
|
|
||||||
|
|
||||||
// Start is called before the first frame update
|
|
||||||
private void Start()
|
|
||||||
{
|
{
|
||||||
UiParticle = GetComponentInChildren<UIParticle>();
|
private MonoBehaviour _demo;
|
||||||
spawnOnUI = GetComponentInChildren<Toggle>();
|
private Toggle _spawnOnUI;
|
||||||
|
private UIParticle _uiParticle;
|
||||||
|
|
||||||
demo = FindObjectOfType("CFX_Demo_New") as MonoBehaviour
|
// Start is called before the first frame update
|
||||||
?? FindObjectOfType("WFX_Demo_New") as MonoBehaviour;
|
private void Start()
|
||||||
|
|
||||||
SetCanvasWidth(800);
|
|
||||||
SetCanvasRenderOverlay(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object FindObjectOfType(string typeName)
|
|
||||||
{
|
|
||||||
var type = AppDomain.CurrentDomain.GetAssemblies()
|
|
||||||
.SelectMany(x => x.GetTypes())
|
|
||||||
.FirstOrDefault(x => x.Name == typeName);
|
|
||||||
|
|
||||||
return type == null ? null : FindObjectOfType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (!spawnOnUI.isOn || !demo || !Input.GetMouseButtonDown(0)) return;
|
|
||||||
|
|
||||||
foreach (Transform child in UiParticle.transform)
|
|
||||||
{
|
{
|
||||||
Destroy(child.gameObject);
|
_uiParticle = GetComponentInChildren<UIParticle>();
|
||||||
|
_spawnOnUI = GetComponentInChildren<Toggle>();
|
||||||
|
_demo = FindObjectOfType("CFX_Demo_New") as MonoBehaviour
|
||||||
|
?? FindObjectOfType("WFX_Demo_New") as MonoBehaviour;
|
||||||
|
|
||||||
|
SetCanvasWidth(800);
|
||||||
|
SetCanvasRenderOverlay(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
var particle = demo.GetType()
|
// Update is called once per frame
|
||||||
.GetMethod("spawnParticle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
|
private void Update()
|
||||||
.Invoke(demo, new object[0]) as GameObject;
|
|
||||||
particle.transform.localScale = Vector3.one;
|
|
||||||
UiParticle.SetParticleSystemInstance(particle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetCanvasWidth(int width)
|
|
||||||
{
|
|
||||||
var scaler = GetComponentInParent<CanvasScaler>();
|
|
||||||
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
|
||||||
scaler.matchWidthOrHeight = 0;
|
|
||||||
var resolution = scaler.referenceResolution;
|
|
||||||
resolution.x = width;
|
|
||||||
scaler.referenceResolution = resolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetCanvasRenderOverlay(bool enable)
|
|
||||||
{
|
|
||||||
var canvas = GetComponentInParent<Canvas>();
|
|
||||||
if (enable)
|
|
||||||
{
|
{
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
if (!_spawnOnUI.isOn || !_demo || !Input.GetMouseButtonDown(0)) return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
canvas.worldCamera = Camera.main;
|
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
|
||||||
canvas.planeDistance = 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadScene(string scene)
|
foreach (Transform child in _uiParticle.transform)
|
||||||
{
|
{
|
||||||
SceneManager.LoadScene(scene);
|
Destroy(child.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
var particle = _demo.GetType()
|
||||||
|
.GetMethod("spawnParticle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
|
||||||
|
?.Invoke(_demo, Array.Empty<object>()) as GameObject;
|
||||||
|
if (!particle) return;
|
||||||
|
|
||||||
|
particle.transform.localScale = Vector3.one;
|
||||||
|
_uiParticle.SetParticleSystemInstance(particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object FindObjectOfType(string typeName)
|
||||||
|
{
|
||||||
|
var type = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
|
.SelectMany(x => x.GetTypes())
|
||||||
|
.FirstOrDefault(x => x.Name == typeName);
|
||||||
|
|
||||||
|
return type == null ? null : FindObjectOfType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCanvasWidth(int width)
|
||||||
|
{
|
||||||
|
var scaler = GetComponentInParent<CanvasScaler>();
|
||||||
|
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
||||||
|
scaler.matchWidthOrHeight = 0;
|
||||||
|
var resolution = scaler.referenceResolution;
|
||||||
|
resolution.x = width;
|
||||||
|
scaler.referenceResolution = resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCanvasRenderOverlay(bool enable)
|
||||||
|
{
|
||||||
|
var canvas = GetComponentInParent<Canvas>();
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
canvas.worldCamera = Camera.main;
|
||||||
|
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||||
|
canvas.planeDistance = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadScene(string scene)
|
||||||
|
{
|
||||||
|
SceneManager.LoadScene(scene);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions.Demo
|
namespace Coffee.UIExtensions.Demo
|
||||||
{
|
{
|
||||||
public class CopyItemOnStart : MonoBehaviour
|
public class CopyItemOnStart : MonoBehaviour
|
||||||
{
|
{
|
||||||
public GameObject origin;
|
[FormerlySerializedAs("origin")]
|
||||||
public int count;
|
[SerializeField]
|
||||||
|
private GameObject m_Origin;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("count")]
|
||||||
|
[SerializeField]
|
||||||
|
private int m_Count;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
if (!origin) return;
|
if (!m_Origin) return;
|
||||||
origin.SetActive(false);
|
m_Origin.SetActive(false);
|
||||||
|
|
||||||
var parent = origin.transform.parent;
|
var parent = m_Origin.transform.parent;
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < m_Count; i++)
|
||||||
{
|
{
|
||||||
var go = Instantiate(origin, parent, false);
|
var go = Instantiate(m_Origin, parent, false);
|
||||||
go.name = string.Format("{0} {1}", origin.name, i + 1);
|
go.name = $"{m_Origin.name} {i + 1}";
|
||||||
go.hideFlags = HideFlags.DontSave;
|
go.hideFlags = HideFlags.DontSave;
|
||||||
go.SetActive(true);
|
go.SetActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
using UnityEngine;
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
|
public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||||
{
|
{
|
||||||
public enum Target
|
[SerializeField]
|
||||||
{
|
private Target m_Target;
|
||||||
Self,
|
|
||||||
Parent,
|
|
||||||
Custom,
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform rectTransform;
|
[SerializeField]
|
||||||
private Canvas canvas;
|
private Transform m_CustomTarget;
|
||||||
public Target m_Target;
|
|
||||||
public Transform m_CustomTarget;
|
[FormerlySerializedAs("ex2")]
|
||||||
public bool ex2;
|
[SerializeField]
|
||||||
|
private bool m_UseCanvasScale;
|
||||||
|
|
||||||
|
private Canvas _canvas;
|
||||||
|
private RectTransform _rectTransform;
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
rectTransform = GetComponent<RectTransform>();
|
_rectTransform = GetComponent<RectTransform>();
|
||||||
canvas = GetComponentInParent<Canvas>();
|
_canvas = GetComponentInParent<Canvas>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBeginDrag(PointerEventData eventData)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDrag(PointerEventData eventData)
|
public void OnDrag(PointerEventData eventData)
|
||||||
|
@ -29,57 +35,59 @@ public class UIElementDragger : MonoBehaviour, IBeginDragHandler, IDragHandler,
|
||||||
switch (m_Target)
|
switch (m_Target)
|
||||||
{
|
{
|
||||||
case Target.Self:
|
case Target.Self:
|
||||||
rectTransform.localPosition += delta;
|
_rectTransform.localPosition += delta;
|
||||||
break;
|
break;
|
||||||
case Target.Parent:
|
case Target.Parent:
|
||||||
rectTransform.parent.localPosition += delta;
|
_rectTransform.parent.localPosition += delta;
|
||||||
break;
|
break;
|
||||||
case Target.Custom:
|
case Target.Custom:
|
||||||
rectTransform.localPosition += delta;
|
_rectTransform.localPosition += delta;
|
||||||
if (m_CustomTarget)
|
if (m_CustomTarget)
|
||||||
{
|
{
|
||||||
if (ex2)
|
if (m_UseCanvasScale)
|
||||||
delta.Scale(canvas.rootCanvas.transform.localScale);
|
{
|
||||||
|
delta.Scale(_canvas.rootCanvas.transform.localScale);
|
||||||
|
}
|
||||||
|
|
||||||
m_CustomTarget.localPosition += delta;
|
m_CustomTarget.localPosition += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBeginDrag(PointerEventData eventData)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEndDrag(PointerEventData eventData)
|
public void OnEndDrag(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 GetLocalDelta(Vector2 evDelta)
|
private Vector2 GetLocalDelta(Vector2 evDelta)
|
||||||
{
|
{
|
||||||
switch (canvas.renderMode)
|
switch (_canvas.renderMode)
|
||||||
{
|
{
|
||||||
case RenderMode.ScreenSpaceOverlay:
|
case RenderMode.ScreenSpaceOverlay:
|
||||||
{
|
{
|
||||||
var zero = transform.InverseTransformPoint(Vector2.zero);
|
var zero = transform.InverseTransformPoint(Vector2.zero);
|
||||||
var delta = transform.InverseTransformPoint(evDelta);
|
var delta = transform.InverseTransformPoint(evDelta);
|
||||||
return delta - zero;
|
return delta - zero;
|
||||||
}
|
}
|
||||||
case RenderMode.ScreenSpaceCamera:
|
case RenderMode.ScreenSpaceCamera:
|
||||||
{
|
|
||||||
Vector2 zero, delta;
|
|
||||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Vector2.zero, canvas.worldCamera, out zero);
|
|
||||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, evDelta, canvas.worldCamera, out delta);
|
|
||||||
return delta - zero;
|
|
||||||
}
|
|
||||||
case RenderMode.WorldSpace:
|
case RenderMode.WorldSpace:
|
||||||
{
|
{
|
||||||
Vector3 zero, delta;
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, Vector2.zero,
|
||||||
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, Vector2.zero, canvas.worldCamera, out zero);
|
_canvas.worldCamera, out var zero);
|
||||||
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, evDelta, canvas.worldCamera, out delta);
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, evDelta,
|
||||||
return delta - zero;
|
_canvas.worldCamera, out var delta);
|
||||||
}
|
return delta - zero;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new System.NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private enum Target
|
||||||
|
{
|
||||||
|
Self,
|
||||||
|
Parent,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions.Demo
|
namespace Coffee.UIExtensions.Demo
|
||||||
{
|
{
|
||||||
public class UIParticle_Demo : MonoBehaviour
|
public class UIParticle_Demo : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Canvas root;
|
[FormerlySerializedAs("root")]
|
||||||
|
[SerializeField]
|
||||||
|
private Canvas m_RootCanvas;
|
||||||
|
|
||||||
private int _width;
|
|
||||||
private int _height;
|
private int _height;
|
||||||
|
private int _score;
|
||||||
|
private int _width;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
@ -24,11 +28,18 @@ namespace Coffee.UIExtensions.Demo
|
||||||
case RuntimePlatform.WindowsPlayer:
|
case RuntimePlatform.WindowsPlayer:
|
||||||
case RuntimePlatform.LinuxPlayer:
|
case RuntimePlatform.LinuxPlayer:
|
||||||
if (Screen.width == _width && Screen.height == _height)
|
if (Screen.width == _width && Screen.height == _height)
|
||||||
|
{
|
||||||
Screen.SetResolution(_height, _width, Screen.fullScreen);
|
Screen.SetResolution(_height, _width, Screen.fullScreen);
|
||||||
|
}
|
||||||
else if (Screen.width == _height && Screen.height == _width)
|
else if (Screen.width == _height && Screen.height == _width)
|
||||||
|
{
|
||||||
Screen.SetResolution(Mathf.Min(_width, _height), Mathf.Min(_width, _height), Screen.fullScreen);
|
Screen.SetResolution(Mathf.Min(_width, _height), Mathf.Min(_width, _height), Screen.fullScreen);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Screen.SetResolution(_width, _height, Screen.fullScreen);
|
Screen.SetResolution(_width, _height, Screen.fullScreen);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,27 +49,31 @@ namespace Coffee.UIExtensions.Demo
|
||||||
Screen.fullScreen = !Screen.fullScreen;
|
Screen.fullScreen = !Screen.fullScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnableAnimations(bool enabled)
|
public void EnableAnimations(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var animator in FindObjectsOfType<Animator>())
|
foreach (var animator in FindObjectsOfType<Animator>())
|
||||||
{
|
{
|
||||||
animator.enabled = enabled;
|
animator.enabled = flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_MeshSharing(bool enabled)
|
public void UIParticle_MeshSharing(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.meshSharing = enabled ? UIParticle.MeshSharing.Auto : UIParticle.MeshSharing.None;
|
uip.meshSharing = flag
|
||||||
|
? UIParticle.MeshSharing.Auto
|
||||||
|
: UIParticle.MeshSharing.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_RandomGroup(bool enabled)
|
public void UIParticle_RandomGroup(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.groupMaxId = enabled ? 4 : 0;
|
uip.groupMaxId = flag
|
||||||
|
? 4
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,38 +85,40 @@ namespace Coffee.UIExtensions.Demo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParticleSystem_WorldSpaseSimulation(bool enabled)
|
public void ParticleSystem_WorldSpaseSimulation(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
foreach (var p in FindObjectsOfType<ParticleSystem>())
|
||||||
{
|
{
|
||||||
var main = ps.main;
|
var main = p.main;
|
||||||
main.simulationSpace = enabled ? ParticleSystemSimulationSpace.World : ParticleSystemSimulationSpace.Local;
|
main.simulationSpace = flag
|
||||||
|
? ParticleSystemSimulationSpace.World
|
||||||
|
: ParticleSystemSimulationSpace.Local;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParticleSystem_WorldSpaseSimulation(ParticleSystem particleSystem)
|
public void ParticleSystem_WorldSpaseSimulation(ParticleSystem ps)
|
||||||
{
|
{
|
||||||
foreach (var ps in particleSystem.GetComponentsInChildren<ParticleSystem>())
|
foreach (var p in ps.GetComponentsInChildren<ParticleSystem>())
|
||||||
{
|
{
|
||||||
var main = ps.main;
|
var main = p.main;
|
||||||
main.simulationSpace = ParticleSystemSimulationSpace.World;
|
main.simulationSpace = ParticleSystemSimulationSpace.World;
|
||||||
ps.Clear();
|
p.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParticleSystem_LocalSpaseSimulation(ParticleSystem particleSystem)
|
public void ParticleSystem_LocalSpaseSimulation(ParticleSystem ps)
|
||||||
{
|
{
|
||||||
foreach (var ps in particleSystem.GetComponentsInChildren<ParticleSystem>())
|
foreach (var p in ps.GetComponentsInChildren<ParticleSystem>())
|
||||||
{
|
{
|
||||||
var main = ps.main;
|
var main = p.main;
|
||||||
main.simulationSpace = ParticleSystemSimulationSpace.Local;
|
main.simulationSpace = ParticleSystemSimulationSpace.Local;
|
||||||
ps.Clear();
|
p.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParticleSystem_Emit(ParticleSystem particleSystem)
|
public void ParticleSystem_Emit(ParticleSystem ps)
|
||||||
{
|
{
|
||||||
particleSystem.Emit(5);
|
ps.Emit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ParticleSystem_SetScale(float scale)
|
public void ParticleSystem_SetScale(float scale)
|
||||||
|
@ -127,41 +144,37 @@ namespace Coffee.UIExtensions.Demo
|
||||||
attractor.movement = UIParticleAttractor.Movement.Sphere;
|
attractor.movement = UIParticleAttractor.Movement.Sphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
int score = 0;
|
|
||||||
public void UIParticleAttractor_OnAttract(Text scoreText)
|
public void UIParticleAttractor_OnAttract(Text scoreText)
|
||||||
{
|
{
|
||||||
score++;
|
_score++;
|
||||||
scoreText.text = score.ToString();
|
scoreText.text = _score.ToString();
|
||||||
scoreText.GetComponent<Animator>().Play(0);
|
scoreText.GetComponent<Animator>().Play(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Canvas_WorldSpace(bool flag)
|
public void Canvas_WorldSpace(bool flag)
|
||||||
{
|
{
|
||||||
if (flag)
|
if (!flag) return;
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
var canvas = FindObjectOfType<Canvas>();
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||||
canvas.renderMode = RenderMode.WorldSpace;
|
canvas.renderMode = RenderMode.WorldSpace;
|
||||||
canvas.transform.rotation = Quaternion.Euler(new Vector3(0, 10, 0));
|
canvas.transform.rotation = Quaternion.Euler(new Vector3(0, 10, 0));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Canvas_CameraSpace(bool flag)
|
public void Canvas_CameraSpace(bool flag)
|
||||||
{
|
{
|
||||||
if (flag)
|
if (!flag) return;
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
var canvas = FindObjectOfType<Canvas>();
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Canvas_Overlay(bool flag)
|
public void Canvas_Overlay(bool flag)
|
||||||
{
|
{
|
||||||
if (flag)
|
if (!flag) return;
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
var canvas = FindObjectOfType<Canvas>();
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,37 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions.Demo
|
namespace Coffee.UIExtensions.Demo
|
||||||
{
|
{
|
||||||
public class UIParticle_Demo_UIParticleController : MonoBehaviour
|
public class UIParticle_Demo_UIParticleController : MonoBehaviour
|
||||||
{
|
{
|
||||||
public Transform root;
|
[FormerlySerializedAs("root")]
|
||||||
|
[SerializeField]
|
||||||
|
private Transform m_RootTransform;
|
||||||
|
|
||||||
public void UIParticle_MeshSharing(bool enabled)
|
public void UIParticle_MeshSharing(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootTransform.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.meshSharing = enabled ? UIParticle.MeshSharing.Auto : UIParticle.MeshSharing.None;
|
uip.meshSharing = flag
|
||||||
|
? UIParticle.MeshSharing.Auto
|
||||||
|
: UIParticle.MeshSharing.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_RandomGroup(bool enabled)
|
public void UIParticle_RandomGroup(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootTransform.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.groupMaxId = enabled ? 4 : 0;
|
uip.groupMaxId = flag
|
||||||
|
? 4
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_Scale(float scale)
|
public void UIParticle_Scale(float scale)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootTransform.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.scale = scale;
|
uip.scale = scale;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 70069a8db1df148ae8b4c8108c079acf
|
guid: d07e6c2670f164cf7939ab011061a9bf
|
||||||
TrueTypeFontImporter:
|
TrueTypeFontImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 4
|
serializedVersion: 4
|
||||||
|
@ -8,9 +8,9 @@ TrueTypeFontImporter:
|
||||||
characterSpacing: 0
|
characterSpacing: 0
|
||||||
characterPadding: 1
|
characterPadding: 1
|
||||||
includeFontData: 1
|
includeFontData: 1
|
||||||
fontName: Falstin
|
fontName: Share Tech Mono
|
||||||
fontNames:
|
fontNames:
|
||||||
- Falstin
|
- Share Tech Mono
|
||||||
fallbackFontReferences: []
|
fallbackFontReferences: []
|
||||||
customCharacters:
|
customCharacters:
|
||||||
fontRenderingMode: 1
|
fontRenderingMode: 1
|
|
@ -127,7 +127,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -206,7 +206,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -285,7 +285,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -366,7 +366,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -516,7 +516,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -595,7 +595,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -736,7 +736,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 16
|
m_FontSize: 16
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -889,7 +889,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 16
|
m_FontSize: 16
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -1042,7 +1042,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -1206,7 +1206,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 16
|
m_FontSize: 16
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -1418,7 +1418,7 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_Interval: 0.5
|
m_Interval: 0.5
|
||||||
m_Precision: 2
|
m_Precision: 2
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_Opened: 1
|
m_Opened: 1
|
||||||
m_FoldoutObject: {fileID: 8720459857733317289}
|
m_FoldoutObject: {fileID: 8720459857733317289}
|
||||||
m_OpenButton: {fileID: 2149219299373497733}
|
m_OpenButton: {fileID: 2149219299373497733}
|
||||||
|
@ -1502,7 +1502,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 16
|
m_FontSize: 16
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
@ -1695,7 +1695,7 @@ MonoBehaviour:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_FontData:
|
m_FontData:
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
m_FontSize: 14
|
m_FontSize: 14
|
||||||
m_FontStyle: 0
|
m_FontStyle: 0
|
||||||
m_BestFit: 0
|
m_BestFit: 0
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Profiling;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.Serialization;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditorInternal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Coffee.NanoMonitor
|
namespace Coffee.NanoMonitor
|
||||||
|
@ -13,24 +14,29 @@ namespace Coffee.NanoMonitor
|
||||||
[CustomEditor(typeof(NanoMonitor))]
|
[CustomEditor(typeof(NanoMonitor))]
|
||||||
internal class NanoMonitorEditor : Editor
|
internal class NanoMonitorEditor : Editor
|
||||||
{
|
{
|
||||||
private UnityEditorInternal.ReorderableList m_MonitorItemList;
|
private ReorderableList _monitorItemList;
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
var items = serializedObject.FindProperty("m_CustomMonitorItems");
|
var items = serializedObject.FindProperty("m_CustomMonitorItems");
|
||||||
m_MonitorItemList = new UnityEditorInternal.ReorderableList(serializedObject, items)
|
_monitorItemList = new ReorderableList(serializedObject, items)
|
||||||
{
|
{
|
||||||
draggable = false,
|
draggable = false,
|
||||||
drawHeaderCallback = r => { EditorGUI.LabelField(r, new GUIContent("Custom Monitor Items")); },
|
drawHeaderCallback = r =>
|
||||||
|
{
|
||||||
|
EditorGUI.LabelField(r, new GUIContent("Custom Monitor Items"));
|
||||||
|
},
|
||||||
drawElementCallback = (r, i, _, __) =>
|
drawElementCallback = (r, i, _, __) =>
|
||||||
{
|
{
|
||||||
EditorGUI.LabelField(new Rect(r.x, r.y, r.width, r.height - 2), GUIContent.none, EditorStyles.textArea);
|
EditorGUI.LabelField(new Rect(r.x, r.y, r.width, r.height - 2), GUIContent.none,
|
||||||
|
EditorStyles.textArea);
|
||||||
var labelWidth = EditorGUIUtility.labelWidth;
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
EditorGUIUtility.labelWidth = 80;
|
EditorGUIUtility.labelWidth = 80;
|
||||||
EditorGUI.PropertyField(new Rect(r.x + 2, r.y + 3, r.width - 4, r.height - 4), items.GetArrayElementAtIndex(i), true);
|
EditorGUI.PropertyField(new Rect(r.x + 2, r.y + 3, r.width - 4, r.height - 4),
|
||||||
|
items.GetArrayElementAtIndex(i), true);
|
||||||
EditorGUIUtility.labelWidth = labelWidth;
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
},
|
},
|
||||||
elementHeightCallback = i => EditorGUI.GetPropertyHeight(items.GetArrayElementAtIndex(i)) + 6,
|
elementHeightCallback = i => EditorGUI.GetPropertyHeight(items.GetArrayElementAtIndex(i)) + 6
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +44,7 @@ namespace Coffee.NanoMonitor
|
||||||
{
|
{
|
||||||
base.OnInspectorGUI();
|
base.OnInspectorGUI();
|
||||||
|
|
||||||
m_MonitorItemList.DoLayoutList();
|
_monitorItemList.DoLayoutList();
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,38 +58,50 @@ namespace Coffee.NanoMonitor
|
||||||
// Serialize Members.
|
// Serialize Members.
|
||||||
//################################
|
//################################
|
||||||
// Settings
|
// Settings
|
||||||
[Header("Settings")] [SerializeField] [Range(0.01f, 2f)]
|
[Header("Settings")]
|
||||||
|
[SerializeField]
|
||||||
|
[Range(0.01f, 2f)]
|
||||||
private float m_Interval = 1f;
|
private float m_Interval = 1f;
|
||||||
|
|
||||||
[SerializeField] [Range(0, 3)] private int m_Precision = 2;
|
[SerializeField]
|
||||||
[SerializeField] private Font m_Font;
|
[Range(0, 3)]
|
||||||
|
private int m_Precision = 2;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Font m_Font;
|
||||||
|
|
||||||
// Foldout
|
// Foldout
|
||||||
[Header("Foldout")] [SerializeField] private bool m_Opened = false;
|
[Header("Foldout")]
|
||||||
|
[SerializeField]
|
||||||
|
private bool m_Opened;
|
||||||
|
|
||||||
[FormerlySerializedAs("m_Collapse")] [SerializeField]
|
[FormerlySerializedAs("m_Collapse")]
|
||||||
private GameObject m_FoldoutObject = null;
|
[SerializeField]
|
||||||
|
private GameObject m_FoldoutObject;
|
||||||
|
|
||||||
[SerializeField] private Button m_OpenButton = null;
|
[SerializeField]
|
||||||
[SerializeField] private Button m_CloseButton = null;
|
private Button m_OpenButton;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button m_CloseButton;
|
||||||
|
|
||||||
// View
|
// View
|
||||||
[Header("View")] [SerializeField] private MonitorUI m_Fps = null;
|
[Header("View")]
|
||||||
[SerializeField] private MonitorUI m_Gc = null;
|
[SerializeField]
|
||||||
[SerializeField] private MonitorUI m_MonoUsage = null;
|
private MonitorUI m_Fps;
|
||||||
[SerializeField] private MonitorUI m_UnityUsage = null;
|
|
||||||
|
|
||||||
[HideInInspector] [SerializeField] private CustomMonitorItem[] m_CustomMonitorItems = new CustomMonitorItem[0];
|
[SerializeField]
|
||||||
|
private MonitorUI m_Gc;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private MonitorUI m_MonoUsage;
|
||||||
|
|
||||||
//################################
|
[SerializeField]
|
||||||
// Public Members.
|
private MonitorUI m_UnityUsage;
|
||||||
//################################
|
|
||||||
public void Clean()
|
[HideInInspector]
|
||||||
{
|
[SerializeField]
|
||||||
Resources.UnloadUnusedAssets();
|
private CustomMonitorItem[] m_CustomMonitorItems = new CustomMonitorItem[0];
|
||||||
GC.Collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
|
@ -93,44 +111,75 @@ namespace Coffee.NanoMonitor
|
||||||
private double _fpsElapsed;
|
private double _fpsElapsed;
|
||||||
private int _frames;
|
private int _frames;
|
||||||
|
|
||||||
private void Open()
|
private void Update()
|
||||||
{
|
{
|
||||||
|
_frames++;
|
||||||
|
_elapsed += Time.unscaledDeltaTime;
|
||||||
|
_fpsElapsed += Time.unscaledDeltaTime;
|
||||||
|
if (_elapsed < m_Interval) return;
|
||||||
|
|
||||||
|
if (m_Fps)
|
||||||
|
{
|
||||||
|
m_Fps.SetText("FPS: {0}", (int)(_frames / _fpsElapsed));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Gc)
|
||||||
|
{
|
||||||
|
m_Gc.SetText("GC: {0}", GC.CollectionCount(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_MonoUsage)
|
||||||
|
{
|
||||||
|
var monoUsed = (Profiler.GetMonoUsedSizeLong() >> 10) / 1024f;
|
||||||
|
var monoTotal = (Profiler.GetMonoHeapSizeLong() >> 10) / 1024f;
|
||||||
|
if (m_Precision == 3)
|
||||||
|
{
|
||||||
|
m_MonoUsage.SetText("Mono: {0:N3}/{1:N3}MB", monoUsed, monoTotal);
|
||||||
|
}
|
||||||
|
else if (m_Precision == 2)
|
||||||
|
{
|
||||||
|
m_MonoUsage.SetText("Mono: {0:N2}/{1:N2}MB", monoUsed, monoTotal);
|
||||||
|
}
|
||||||
|
else if (m_Precision == 1)
|
||||||
|
{
|
||||||
|
m_MonoUsage.SetText("Mono: {0:N1}/{1:N1}MB", monoUsed, monoTotal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_MonoUsage.SetText("Mono: {0:N0}/{1:N0}MB", monoUsed, monoTotal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_UnityUsage)
|
||||||
|
{
|
||||||
|
var unityUsed = (Profiler.GetTotalAllocatedMemoryLong() >> 10) / 1024f;
|
||||||
|
var unityTotal = (Profiler.GetTotalReservedMemoryLong() >> 10) / 1024f;
|
||||||
|
if (m_Precision == 3)
|
||||||
|
{
|
||||||
|
m_UnityUsage.SetText("Unity: {0:N3}/{1:N3}MB", unityUsed, unityTotal);
|
||||||
|
}
|
||||||
|
else if (m_Precision == 2)
|
||||||
|
{
|
||||||
|
m_UnityUsage.SetText("Unity: {0:N2}/{1:N2}MB", unityUsed, unityTotal);
|
||||||
|
}
|
||||||
|
else if (m_Precision == 1)
|
||||||
|
{
|
||||||
|
m_UnityUsage.SetText("Unity: {0:N1}/{1:N1}MB", unityUsed, unityTotal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_UnityUsage.SetText("Unity: {0:N0}/{1:N0}MB", unityUsed, unityTotal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in m_CustomMonitorItems)
|
||||||
|
{
|
||||||
|
item.UpdateText();
|
||||||
|
}
|
||||||
|
|
||||||
_frames = 0;
|
_frames = 0;
|
||||||
_elapsed = m_Interval;
|
_elapsed %= m_Interval;
|
||||||
_fpsElapsed = 0;
|
_fpsElapsed = 0;
|
||||||
|
|
||||||
if (m_FoldoutObject)
|
|
||||||
{
|
|
||||||
m_FoldoutObject.SetActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_CloseButton)
|
|
||||||
{
|
|
||||||
m_CloseButton.gameObject.SetActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_OpenButton)
|
|
||||||
{
|
|
||||||
m_OpenButton.gameObject.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Close()
|
|
||||||
{
|
|
||||||
if (m_FoldoutObject)
|
|
||||||
{
|
|
||||||
m_FoldoutObject.SetActive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_CloseButton)
|
|
||||||
{
|
|
||||||
m_CloseButton.gameObject.SetActive(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_OpenButton)
|
|
||||||
{
|
|
||||||
m_OpenButton.gameObject.SetActive(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,77 +221,6 @@ namespace Coffee.NanoMonitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
_frames++;
|
|
||||||
_elapsed += Time.unscaledDeltaTime;
|
|
||||||
_fpsElapsed += Time.unscaledDeltaTime;
|
|
||||||
if (_elapsed < m_Interval) return;
|
|
||||||
|
|
||||||
if (m_Fps)
|
|
||||||
{
|
|
||||||
m_Fps.SetText("FPS: {0}", (int) (_frames / _fpsElapsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Gc)
|
|
||||||
{
|
|
||||||
m_Gc.SetText("GC: {0}", GC.CollectionCount(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_MonoUsage)
|
|
||||||
{
|
|
||||||
var monoUsed = (UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong() >> 10) / 1024f;
|
|
||||||
var monoTotal = (UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong() >> 10) / 1024f;
|
|
||||||
if (m_Precision == 3)
|
|
||||||
{
|
|
||||||
m_MonoUsage.SetText("Mono: {0:N3}/{1:N3}MB", monoUsed, monoTotal);
|
|
||||||
}
|
|
||||||
else if (m_Precision == 2)
|
|
||||||
{
|
|
||||||
m_MonoUsage.SetText("Mono: {0:N2}/{1:N2}MB", monoUsed, monoTotal);
|
|
||||||
}
|
|
||||||
else if (m_Precision == 1)
|
|
||||||
{
|
|
||||||
m_MonoUsage.SetText("Mono: {0:N1}/{1:N1}MB", monoUsed, monoTotal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_MonoUsage.SetText("Mono: {0:N0}/{1:N0}MB", monoUsed, monoTotal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_UnityUsage)
|
|
||||||
{
|
|
||||||
var unityUsed = (UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong() >> 10) / 1024f;
|
|
||||||
var unityTotal = (UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong() >> 10) / 1024f;
|
|
||||||
if (m_Precision == 3)
|
|
||||||
{
|
|
||||||
m_UnityUsage.SetText("Unity: {0:N3}/{1:N3}MB", unityUsed, unityTotal);
|
|
||||||
}
|
|
||||||
else if (m_Precision == 2)
|
|
||||||
{
|
|
||||||
m_UnityUsage.SetText("Unity: {0:N2}/{1:N2}MB", unityUsed, unityTotal);
|
|
||||||
}
|
|
||||||
else if (m_Precision == 1)
|
|
||||||
{
|
|
||||||
m_UnityUsage.SetText("Unity: {0:N1}/{1:N1}MB", unityUsed, unityTotal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_UnityUsage.SetText("Unity: {0:N0}/{1:N0}MB", unityUsed, unityTotal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in m_CustomMonitorItems)
|
|
||||||
{
|
|
||||||
item.UpdateText();
|
|
||||||
}
|
|
||||||
|
|
||||||
_frames = 0;
|
|
||||||
_elapsed %= m_Interval;
|
|
||||||
_fpsElapsed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
{
|
{
|
||||||
|
@ -264,5 +242,55 @@ namespace Coffee.NanoMonitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//################################
|
||||||
|
// Public Members.
|
||||||
|
//################################
|
||||||
|
public void Clean()
|
||||||
|
{
|
||||||
|
Resources.UnloadUnusedAssets();
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Open()
|
||||||
|
{
|
||||||
|
_frames = 0;
|
||||||
|
_elapsed = m_Interval;
|
||||||
|
_fpsElapsed = 0;
|
||||||
|
|
||||||
|
if (m_FoldoutObject)
|
||||||
|
{
|
||||||
|
m_FoldoutObject.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CloseButton)
|
||||||
|
{
|
||||||
|
m_CloseButton.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_OpenButton)
|
||||||
|
{
|
||||||
|
m_OpenButton.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Close()
|
||||||
|
{
|
||||||
|
if (m_FoldoutObject)
|
||||||
|
{
|
||||||
|
m_FoldoutObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CloseButton)
|
||||||
|
{
|
||||||
|
m_CloseButton.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_OpenButton)
|
||||||
|
{
|
||||||
|
m_OpenButton.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace Coffee.NanoMonitor{
|
namespace Coffee.NanoMonitor
|
||||||
|
{
|
||||||
public class FixedFont
|
public class FixedFont
|
||||||
{
|
{
|
||||||
private readonly UIVertex[] _tmpVerts = new UIVertex[4];
|
private const string k_Characters =
|
||||||
private static readonly Dictionary<Font, FixedFont> _fonts = new Dictionary<Font, FixedFont>();
|
"_!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||||
private static readonly TextGenerator _textGenerator = new TextGenerator(100);
|
|
||||||
|
|
||||||
private static TextGenerationSettings _settings = new TextGenerationSettings
|
private static readonly Dictionary<Font, FixedFont> s_Fonts = new Dictionary<Font, FixedFont>();
|
||||||
|
private static readonly TextGenerator s_TextGenerator = new TextGenerator(100);
|
||||||
|
|
||||||
|
private static TextGenerationSettings s_Settings = new TextGenerationSettings
|
||||||
{
|
{
|
||||||
scaleFactor = 1,
|
scaleFactor = 1,
|
||||||
horizontalOverflow = HorizontalWrapMode.Overflow,
|
horizontalOverflow = HorizontalWrapMode.Overflow,
|
||||||
|
@ -19,25 +22,33 @@ namespace Coffee.NanoMonitor{
|
||||||
color = Color.white
|
color = Color.white
|
||||||
};
|
};
|
||||||
|
|
||||||
private int _resolution = 0;
|
|
||||||
private readonly Font _font;
|
private readonly Font _font;
|
||||||
private UIVertex[] _verts;
|
private readonly UIVertex[] _tmpVerts = new UIVertex[4];
|
||||||
private UICharInfo[] _charInfos;
|
private UICharInfo[] _charInfos;
|
||||||
|
|
||||||
|
private int _resolution;
|
||||||
|
private UIVertex[] _verts;
|
||||||
|
|
||||||
private FixedFont(Font font)
|
private FixedFont(Font font)
|
||||||
{
|
{
|
||||||
_font = font;
|
_font = font;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int fontSize => _font.dynamic ? 32 : _font.fontSize;
|
public int fontSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _font.dynamic ? 32 : _font.fontSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static FixedFont GetOrCreate(Font font)
|
public static FixedFont GetOrCreate(Font font)
|
||||||
{
|
{
|
||||||
if (font == null) return null;
|
if (font == null) return null;
|
||||||
if (_fonts.TryGetValue(font, out var data)) return data;
|
if (s_Fonts.TryGetValue(font, out var data)) return data;
|
||||||
|
|
||||||
data = new FixedFont(font);
|
data = new FixedFont(font);
|
||||||
_fonts.Add(font, data);
|
s_Fonts.Add(font, data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,18 +72,20 @@ namespace Coffee.NanoMonitor{
|
||||||
if (_resolution == currentResolution) return;
|
if (_resolution == currentResolution) return;
|
||||||
_resolution = currentResolution;
|
_resolution = currentResolution;
|
||||||
|
|
||||||
_settings.font = _font;
|
s_Settings.font = _font;
|
||||||
_textGenerator.Invalidate();
|
s_TextGenerator.Invalidate();
|
||||||
_textGenerator.Populate("_!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", _settings);
|
s_TextGenerator.Populate(k_Characters, s_Settings);
|
||||||
|
|
||||||
_verts = _textGenerator.GetVerticesArray();
|
_verts = s_TextGenerator.GetVerticesArray();
|
||||||
_charInfos = _textGenerator.GetCharactersArray();
|
_charInfos = s_TextGenerator.GetCharactersArray();
|
||||||
|
|
||||||
float offsetX = 0;
|
float offsetX = 0;
|
||||||
for (var i = 0; i < _verts.Length; i++)
|
for (var i = 0; i < _verts.Length; i++)
|
||||||
{
|
{
|
||||||
if ((i & 3) == 0)
|
if ((i & 3) == 0)
|
||||||
|
{
|
||||||
offsetX = _verts[i].position.x;
|
offsetX = _verts[i].position.x;
|
||||||
|
}
|
||||||
|
|
||||||
var v = _verts[i];
|
var v = _verts[i];
|
||||||
v.position -= new Vector3(offsetX, 0);
|
v.position -= new Vector3(offsetX, 0);
|
||||||
|
@ -118,18 +131,27 @@ namespace Coffee.NanoMonitor{
|
||||||
|
|
||||||
for (var i = 0; i < 4; i++)
|
for (var i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
_tmpVerts[i] = new UIVertex();
|
_tmpVerts[i] = new UIVertex
|
||||||
_tmpVerts[i].uv0 = uv;
|
{
|
||||||
_tmpVerts[i].color = color;
|
uv0 = uv,
|
||||||
|
color = color
|
||||||
|
};
|
||||||
|
|
||||||
if (i == 0)
|
switch (i)
|
||||||
_tmpVerts[i].position = new Vector2(-size.x, -size.y) + offset;
|
{
|
||||||
else if (i == 1)
|
case 0:
|
||||||
_tmpVerts[i].position = new Vector2(-size.x, size.y) + offset;
|
_tmpVerts[i].position = new Vector2(-size.x, -size.y) + offset;
|
||||||
else if (i == 2)
|
break;
|
||||||
_tmpVerts[i].position = new Vector2(size.x, size.y) + offset;
|
case 1:
|
||||||
else
|
_tmpVerts[i].position = new Vector2(-size.x, size.y) + offset;
|
||||||
_tmpVerts[i].position = new Vector2(size.x, -size.y) + offset;
|
break;
|
||||||
|
case 2:
|
||||||
|
_tmpVerts[i].position = new Vector2(size.x, size.y) + offset;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_tmpVerts[i].position = new Vector2(size.x, -size.y) + offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toFill.AddUIVertexQuad(_tmpVerts);
|
toFill.AddUIVertexQuad(_tmpVerts);
|
||||||
|
|
|
@ -1,50 +1,46 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace Coffee.NanoMonitor{
|
namespace Coffee.NanoMonitor
|
||||||
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
|
||||||
|
|
||||||
[CustomEditor(typeof(MonitorUI))]
|
[CustomEditor(typeof(MonitorUI))]
|
||||||
public class MonitorTextEditor : Editor
|
public class MonitorTextEditor : Editor
|
||||||
{
|
{
|
||||||
private SerializedProperty m_Mode;
|
private SerializedProperty _color;
|
||||||
private SerializedProperty m_TextAnchor;
|
private SerializedProperty _font;
|
||||||
private SerializedProperty m_FontSize;
|
private SerializedProperty _fontSize;
|
||||||
private SerializedProperty m_Font;
|
private SerializedProperty _mode;
|
||||||
private SerializedProperty m_Text;
|
private SerializedProperty _text;
|
||||||
private SerializedProperty m_Color;
|
private SerializedProperty _textAnchor;
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
m_Mode = serializedObject.FindProperty("m_Mode");
|
_mode = serializedObject.FindProperty("m_Mode");
|
||||||
|
_text = serializedObject.FindProperty("m_Text");
|
||||||
m_Text = serializedObject.FindProperty("m_Text");
|
_color = serializedObject.FindProperty("m_Color");
|
||||||
m_Color = serializedObject.FindProperty("m_Color");
|
|
||||||
var fontData = serializedObject.FindProperty("m_FontData");
|
var fontData = serializedObject.FindProperty("m_FontData");
|
||||||
m_FontSize = fontData.FindPropertyRelative("m_FontSize");
|
_fontSize = fontData.FindPropertyRelative("m_FontSize");
|
||||||
m_Font = fontData.FindPropertyRelative("m_Font");
|
_font = fontData.FindPropertyRelative("m_Font");
|
||||||
m_TextAnchor = serializedObject.FindProperty("m_TextAnchor");
|
_textAnchor = serializedObject.FindProperty("m_TextAnchor");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
public override void OnInspectorGUI()
|
||||||
{
|
{
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
|
|
||||||
EditorGUILayout.PropertyField(m_Mode);
|
EditorGUILayout.PropertyField(_mode);
|
||||||
if ((MonitorUI.Mode) m_Mode.intValue == MonitorUI.Mode.Text)
|
if ((MonitorUI.Mode)_mode.intValue == MonitorUI.Mode.Text)
|
||||||
{
|
{
|
||||||
EditorGUILayout.PropertyField(m_Text);
|
EditorGUILayout.PropertyField(_text);
|
||||||
EditorGUILayout.PropertyField(m_FontSize);
|
EditorGUILayout.PropertyField(_fontSize);
|
||||||
EditorGUILayout.PropertyField(m_TextAnchor);
|
EditorGUILayout.PropertyField(_textAnchor);
|
||||||
|
EditorGUILayout.PropertyField(_font);
|
||||||
//EditorGUI.BeginDisabledGroup(true);
|
|
||||||
EditorGUILayout.PropertyField(m_Font);
|
|
||||||
//EditorGUI.EndDisabledGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUILayout.PropertyField(m_Color);
|
EditorGUILayout.PropertyField(_color);
|
||||||
|
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +52,7 @@ namespace Coffee.NanoMonitor{
|
||||||
public enum Mode
|
public enum Mode
|
||||||
{
|
{
|
||||||
Text,
|
Text,
|
||||||
Fill,
|
Fill
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TextAnchor
|
public enum TextAnchor
|
||||||
|
@ -74,26 +70,38 @@ namespace Coffee.NanoMonitor{
|
||||||
[SerializeField] private TextAnchor m_TextAnchor;
|
[SerializeField] private TextAnchor m_TextAnchor;
|
||||||
|
|
||||||
|
|
||||||
|
//################################
|
||||||
|
// Private Members.
|
||||||
|
//################################
|
||||||
|
private readonly StringBuilder _sb = new StringBuilder(64);
|
||||||
|
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
// Public Members.
|
// Public Members.
|
||||||
//################################
|
//################################
|
||||||
public override string text
|
public override string text
|
||||||
{
|
{
|
||||||
get => m_StringBuilder.ToString();
|
get
|
||||||
|
{
|
||||||
|
return _sb.ToString();
|
||||||
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
m_Text = value;
|
m_Text = value;
|
||||||
if (m_StringBuilder.IsEqual(m_Text)) return;
|
if (_sb.IsEqual(m_Text)) return;
|
||||||
|
|
||||||
m_StringBuilder.Length = 0;
|
_sb.Length = 0;
|
||||||
m_StringBuilder.Append(m_Text);
|
_sb.Append(m_Text);
|
||||||
SetVerticesDirty();
|
SetVerticesDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextAnchor textAnchor
|
public TextAnchor textAnchor
|
||||||
{
|
{
|
||||||
get => m_TextAnchor;
|
get
|
||||||
|
{
|
||||||
|
return m_TextAnchor;
|
||||||
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (m_TextAnchor == value) return;
|
if (m_TextAnchor == value) return;
|
||||||
|
@ -105,44 +113,11 @@ namespace Coffee.NanoMonitor{
|
||||||
|
|
||||||
public override bool raycastTarget
|
public override bool raycastTarget
|
||||||
{
|
{
|
||||||
get => m_Mode == Mode.Fill;
|
get
|
||||||
set { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetText(string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
|
||||||
{
|
|
||||||
m_StringBuilder.Length = 0;
|
|
||||||
m_StringBuilder.AppendFormatNoAlloc(format, arg0, arg1, arg2, arg3);
|
|
||||||
SetVerticesDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetText(StringBuilder builder)
|
|
||||||
{
|
|
||||||
m_StringBuilder.Length = 0;
|
|
||||||
m_StringBuilder.Append(builder);
|
|
||||||
SetVerticesDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//################################
|
|
||||||
// Private Members.
|
|
||||||
//################################
|
|
||||||
private readonly StringBuilder m_StringBuilder = new StringBuilder(64);
|
|
||||||
|
|
||||||
private void UpdateFont()
|
|
||||||
{
|
|
||||||
//var globalFont = NNanoMonitorttings.Instance.font;
|
|
||||||
//if (globalFont)
|
|
||||||
//{
|
|
||||||
// font = globalFont;
|
|
||||||
//}
|
|
||||||
|
|
||||||
var fontData = FixedFont.GetOrCreate(font);
|
|
||||||
if (fontData != null)
|
|
||||||
{
|
{
|
||||||
fontData.Invalidate();
|
return m_Mode == Mode.Fill;
|
||||||
fontData.UpdateFont();
|
|
||||||
}
|
}
|
||||||
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,19 +126,17 @@ namespace Coffee.NanoMonitor{
|
||||||
//################################
|
//################################
|
||||||
protected override void OnEnable()
|
protected override void OnEnable()
|
||||||
{
|
{
|
||||||
//NaNanoMonitortings.Instance.onFontChanged += UpdateFont;
|
|
||||||
RegisterDirtyMaterialCallback(UpdateFont);
|
RegisterDirtyMaterialCallback(UpdateFont);
|
||||||
|
|
||||||
base.OnEnable();
|
base.OnEnable();
|
||||||
raycastTarget = false;
|
raycastTarget = false;
|
||||||
maskable = false;
|
maskable = false;
|
||||||
m_StringBuilder.Length = 0;
|
_sb.Length = 0;
|
||||||
m_StringBuilder.Append(m_Text);
|
_sb.Append(m_Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDisable()
|
protected override void OnDisable()
|
||||||
{
|
{
|
||||||
//NanNanoMonitorings.Instance.onFontChanged -= UpdateFont;
|
|
||||||
UnregisterDirtyMaterialCallback(UpdateFont);
|
UnregisterDirtyMaterialCallback(UpdateFont);
|
||||||
|
|
||||||
base.OnDisable();
|
base.OnDisable();
|
||||||
|
@ -174,14 +147,38 @@ namespace Coffee.NanoMonitor{
|
||||||
{
|
{
|
||||||
base.OnValidate();
|
base.OnValidate();
|
||||||
|
|
||||||
if (!m_StringBuilder.IsEqual(m_Text))
|
if (!_sb.IsEqual(m_Text))
|
||||||
{
|
{
|
||||||
m_StringBuilder.Length = 0;
|
_sb.Length = 0;
|
||||||
m_StringBuilder.Append(m_Text);
|
_sb.Append(m_Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public void SetText(string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
||||||
|
{
|
||||||
|
_sb.Length = 0;
|
||||||
|
_sb.AppendFormatNoAlloc(format, arg0, arg1, arg2, arg3);
|
||||||
|
SetVerticesDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetText(StringBuilder builder)
|
||||||
|
{
|
||||||
|
_sb.Length = 0;
|
||||||
|
_sb.Append(builder);
|
||||||
|
SetVerticesDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFont()
|
||||||
|
{
|
||||||
|
var fontData = FixedFont.GetOrCreate(font);
|
||||||
|
if (fontData != null)
|
||||||
|
{
|
||||||
|
fontData.Invalidate();
|
||||||
|
fontData.UpdateFont();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnPopulateMesh(VertexHelper toFill)
|
protected override void OnPopulateMesh(VertexHelper toFill)
|
||||||
{
|
{
|
||||||
toFill.Clear();
|
toFill.Clear();
|
||||||
|
@ -197,7 +194,7 @@ namespace Coffee.NanoMonitor{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scale = (float) fontSize / fontData.fontSize;
|
var scale = (float)fontSize / fontData.fontSize;
|
||||||
float offset = 0;
|
float offset = 0;
|
||||||
switch (textAnchor)
|
switch (textAnchor)
|
||||||
{
|
{
|
||||||
|
@ -205,20 +202,26 @@ namespace Coffee.NanoMonitor{
|
||||||
offset = rectTransform.rect.xMin;
|
offset = rectTransform.rect.xMin;
|
||||||
break;
|
break;
|
||||||
case TextAnchor.Center:
|
case TextAnchor.Center:
|
||||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
for (var i = 0; i < _sb.Length; i++)
|
||||||
offset = fontData.Layout(m_StringBuilder[i], offset, scale);
|
{
|
||||||
|
offset = fontData.Layout(_sb[i], offset, scale);
|
||||||
|
}
|
||||||
|
|
||||||
offset = -offset / 2;
|
offset = -offset / 2;
|
||||||
break;
|
break;
|
||||||
case TextAnchor.Right:
|
case TextAnchor.Right:
|
||||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
for (var i = 0; i < _sb.Length; i++)
|
||||||
offset = fontData.Layout(m_StringBuilder[i], offset, scale);
|
{
|
||||||
|
offset = fontData.Layout(_sb[i], offset, scale);
|
||||||
|
}
|
||||||
|
|
||||||
offset = rectTransform.rect.xMax - offset;
|
offset = rectTransform.rect.xMax - offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
for (var i = 0; i < _sb.Length; i++)
|
||||||
{
|
{
|
||||||
offset = fontData.Append(toFill, m_StringBuilder[i], offset, scale, color);
|
offset = fontData.Append(toFill, _sb[i], offset, scale, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
namespace Coffee.MiniProfiler
|
|
||||||
{
|
|
||||||
internal class MiniProfilerSettings : ScriptableSettings<MiniProfilerSettings>
|
|
||||||
{
|
|
||||||
[Header("UI")]
|
|
||||||
[SerializeField] private Font m_Font = null;
|
|
||||||
|
|
||||||
[Header("Instantiate On Boot")]
|
|
||||||
[SerializeField] private GameObject miniProfilerPrefab = null;
|
|
||||||
[SerializeField] private string[] m_SceneNames = new string[0];
|
|
||||||
|
|
||||||
public Font font => m_Font;
|
|
||||||
public event Action onFontChanged;
|
|
||||||
|
|
||||||
protected override void OnBoot()
|
|
||||||
{
|
|
||||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
||||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnSceneLoaded(Scene scene, LoadSceneMode __)
|
|
||||||
{
|
|
||||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
||||||
if (!miniProfilerPrefab || !m_SceneNames.Contains(scene.name)) return;
|
|
||||||
|
|
||||||
var go = Instantiate(miniProfilerPrefab);
|
|
||||||
if (Application.isPlaying)
|
|
||||||
DontDestroyOnLoad(go);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool bootOnPlayMode => true;
|
|
||||||
protected override bool bootOnEditorMode => false;
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
protected override void OnValidate()
|
|
||||||
{
|
|
||||||
onFontChanged?.Invoke();
|
|
||||||
base.OnValidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
m_Font = UnityEngine.Resources.GetBuiltinResource<Font>("Arial.ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnityEditor.SettingsProvider]
|
|
||||||
private static UnityEditor.SettingsProvider CreateSettingsProvider() => new ScriptableSettingsProvider<MiniProfilerSettings>();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 647dad4f8226a49b9874b68b79413d64
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences:
|
|
||||||
- miniProfilerPrefab: {fileID: 7211429669315726685, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,280 +0,0 @@
|
||||||
using UnityEngine;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
using UnityEditor;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Coffee.MiniProfiler
|
|
||||||
{
|
|
||||||
internal abstract class ScriptableSettings : ScriptableObject
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
public virtual string GetSettingPath()
|
|
||||||
{
|
|
||||||
return GetSettingPath(GetType());
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static string GetSettingPath(Type type)
|
|
||||||
{
|
|
||||||
return $"Project/{ObjectNames.NicifyVariableName(type.Name.Replace("ProjectSettings", ""))}";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public virtual string GetDefaultAssetPath()
|
|
||||||
{
|
|
||||||
return $"Assets/ProjectSettings/{GetType().Name}.asset";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal abstract class ScriptableSettings<T> : ScriptableSettings
|
|
||||||
where T : ScriptableSettings<T>
|
|
||||||
{
|
|
||||||
//################################
|
|
||||||
// Public Members.
|
|
||||||
//################################
|
|
||||||
public static T Instance => _instance ? _instance : _instance = GetOrCreate();
|
|
||||||
|
|
||||||
private static T _instance;
|
|
||||||
|
|
||||||
protected virtual bool bootOnEditorMode => true;
|
|
||||||
protected virtual bool bootOnPlayMode => true;
|
|
||||||
|
|
||||||
protected abstract void OnBoot();
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
//################################
|
|
||||||
// Private Members.
|
|
||||||
//################################
|
|
||||||
private bool enabled;
|
|
||||||
|
|
||||||
private static T GetOrCreate()
|
|
||||||
{
|
|
||||||
return PlayerSettings.GetPreloadedAssets()
|
|
||||||
.OfType<T>()
|
|
||||||
.FirstOrDefault() ?? CreateInstance<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case PlayModeStateChange.EnteredEditMode:
|
|
||||||
enabled = true;
|
|
||||||
Boot();
|
|
||||||
break;
|
|
||||||
case PlayModeStateChange.ExitingEditMode:
|
|
||||||
case PlayModeStateChange.ExitingPlayMode:
|
|
||||||
enabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Boot()
|
|
||||||
{
|
|
||||||
var preloadedAssets = PlayerSettings.GetPreloadedAssets();
|
|
||||||
var assets = preloadedAssets.OfType<T>().ToArray();
|
|
||||||
var first = assets.FirstOrDefault() ?? this as T;
|
|
||||||
|
|
||||||
// If there are no preloaded assets, registry the first asset.
|
|
||||||
// If there are multiple preloaded assets, unregisters all but the first one.
|
|
||||||
if (assets.Length != 1)
|
|
||||||
{
|
|
||||||
// The first asset is not saved.
|
|
||||||
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(first)))
|
|
||||||
{
|
|
||||||
if (!AssetDatabase.IsValidFolder("Assets/ProjectSettings"))
|
|
||||||
AssetDatabase.CreateFolder("Assets", "ProjectSettings");
|
|
||||||
|
|
||||||
var assetName = ObjectNames.NicifyVariableName(first.GetType().Name.Replace("ProjectSettings", ""));
|
|
||||||
var assetPath = AssetDatabase.GenerateUniqueAssetPath($"Assets/ProjectSettings/{assetName}.asset");
|
|
||||||
AssetDatabase.CreateAsset(first, assetPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerSettings.SetPreloadedAssets(preloadedAssets
|
|
||||||
.Where(x => x)
|
|
||||||
.Except(assets)
|
|
||||||
.Concat(new[] {first})
|
|
||||||
.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Another asset is registered as a preload asset.
|
|
||||||
if (first != this)
|
|
||||||
{
|
|
||||||
UnityEngine.Debug.LogError($"Another asset '{first}' is registered as a preload '{typeof(T).Name}' asset." +
|
|
||||||
$"\nThis instance ('{this}') will be ignored. Check 'Project Settings > Player > Preload Assets'", this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_instance = first;
|
|
||||||
|
|
||||||
// Do nothing on editor mode.
|
|
||||||
if (!bootOnEditorMode && !EditorApplication.isPlayingOrWillChangePlaymode)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do nothing on play mode.
|
|
||||||
if (!bootOnPlayMode && EditorApplication.isPlayingOrWillChangePlaymode)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OnBoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//################################
|
|
||||||
// Unity Callbacks.
|
|
||||||
//################################
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
enabled = true;
|
|
||||||
Boot();
|
|
||||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable()
|
|
||||||
{
|
|
||||||
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnValidate()
|
|
||||||
{
|
|
||||||
if (enabled)
|
|
||||||
Boot();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
private static T GetOrCreate()
|
|
||||||
{
|
|
||||||
return CreateInstance<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
if (!bootOnPlayMode) return;
|
|
||||||
|
|
||||||
_instance = this as T;
|
|
||||||
OnBoot();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
[CustomEditor(typeof(ScriptablePreferenceSettings<>), true)]
|
|
||||||
internal class ScriptablePreferenceSettingsEditor : Editor
|
|
||||||
{
|
|
||||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
|
||||||
{
|
|
||||||
if (GUILayout.Button(_button))
|
|
||||||
{
|
|
||||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal abstract class ScriptablePreferenceSettings<T> : ScriptableSingleton<T>
|
|
||||||
where T : ScriptablePreferenceSettings<T>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[CustomEditor(typeof(ScriptableSettings), true)]
|
|
||||||
internal class ScriptableSettingsEditor : Editor
|
|
||||||
{
|
|
||||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
|
||||||
{
|
|
||||||
if (GUILayout.Button(_button))
|
|
||||||
{
|
|
||||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class ScriptableSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
|
||||||
{
|
|
||||||
public ScriptableSettingsProvider(string path) : base(path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptableSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SerializedObject serializedObject { get; private set; }
|
|
||||||
protected ScriptableSettings<T> target { get; private set; }
|
|
||||||
|
|
||||||
public sealed override void OnGUI(string searchContext)
|
|
||||||
{
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
target = ScriptableSettings<T>.Instance;
|
|
||||||
serializedObject = new SerializedObject(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnGUI()
|
|
||||||
{
|
|
||||||
serializedObject.UpdateIfRequiredOrScript();
|
|
||||||
var iterator = serializedObject.GetIterator();
|
|
||||||
var enterChildren = true;
|
|
||||||
while (iterator.NextVisible(enterChildren))
|
|
||||||
{
|
|
||||||
if (iterator.propertyPath != "m_Script")
|
|
||||||
EditorGUILayout.PropertyField(iterator, true);
|
|
||||||
|
|
||||||
enterChildren = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class ScriptablePreferenceSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
|
||||||
{
|
|
||||||
public ScriptablePreferenceSettingsProvider(string path) : base(path, SettingsScope.User)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptablePreferenceSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)), SettingsScope.User)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SerializedObject serializedObject { get; private set; }
|
|
||||||
protected ScriptableSettings<T> target { get; private set; }
|
|
||||||
|
|
||||||
public sealed override void OnGUI(string searchContext)
|
|
||||||
{
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
target = ScriptableSettings<T>.Instance;
|
|
||||||
serializedObject = new SerializedObject(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnGUI()
|
|
||||||
{
|
|
||||||
serializedObject.UpdateIfRequiredOrScript();
|
|
||||||
var iterator = serializedObject.GetIterator();
|
|
||||||
var enterChildren = true;
|
|
||||||
while (iterator.NextVisible(enterChildren))
|
|
||||||
{
|
|
||||||
if (iterator.propertyPath != "m_Script")
|
|
||||||
EditorGUILayout.PropertyField(iterator, true);
|
|
||||||
|
|
||||||
enterChildren = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
serializedObject.ApplyModifiedProperties();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 6ea9606f69cee413e9f96f52de99fa5e
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
|
@ -1,4 +1,5 @@
|
||||||
using UnityEngine;
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,12 +12,17 @@ namespace Coffee.NanoMonitor
|
||||||
{
|
{
|
||||||
public override void OnGUI(Rect p, SerializedProperty property, GUIContent label)
|
public override void OnGUI(Rect p, SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 0, p.width, 16), property.FindPropertyRelative("m_Text"));
|
var pos = new Rect(p.x, p.y + 18 * 0, p.width, 16);
|
||||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 1, p.width, 16), property.FindPropertyRelative("m_Format"));
|
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Text"));
|
||||||
|
pos.y += 18;
|
||||||
|
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Format"));
|
||||||
|
pos.y += 18;
|
||||||
EditorGUI.indentLevel++;
|
EditorGUI.indentLevel++;
|
||||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 2, p.width, 16), property.FindPropertyRelative("m_Arg0"));
|
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg0"));
|
||||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 3, p.width, 16), property.FindPropertyRelative("m_Arg1"));
|
pos.y += 18;
|
||||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 4, p.width, 16), property.FindPropertyRelative("m_Arg2"));
|
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg1"));
|
||||||
|
pos.y += 18;
|
||||||
|
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg2"));
|
||||||
EditorGUI.indentLevel--;
|
EditorGUI.indentLevel--;
|
||||||
|
|
||||||
property.serializedObject.ApplyModifiedProperties();
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
|
@ -29,19 +35,21 @@ namespace Coffee.NanoMonitor
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[System.Serializable]
|
[Serializable]
|
||||||
public class CustomMonitorItem
|
public class CustomMonitorItem
|
||||||
{
|
{
|
||||||
[SerializeField] private MonitorUI m_Text = null;
|
[SerializeField] private MonitorUI m_Text;
|
||||||
[SerializeField] private string m_Format = "";
|
[SerializeField] private string m_Format = "";
|
||||||
[SerializeField] private NumericProperty m_Arg0 = null;
|
[SerializeField] private NumericProperty m_Arg0;
|
||||||
[SerializeField] private NumericProperty m_Arg1 = null;
|
[SerializeField] private NumericProperty m_Arg1;
|
||||||
[SerializeField] private NumericProperty m_Arg2 = null;
|
[SerializeField] private NumericProperty m_Arg2;
|
||||||
|
|
||||||
public void UpdateText()
|
public void UpdateText()
|
||||||
{
|
{
|
||||||
if (m_Text)
|
if (m_Text)
|
||||||
|
{
|
||||||
m_Text.SetText(m_Format, m_Arg0.Get(), m_Arg1.Get(), m_Arg2.Get());
|
m_Text.SetText(m_Format, m_Arg0.Get(), m_Arg1.Get(), m_Arg2.Get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Serialization;
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Coffee.NanoMonitor
|
namespace Coffee.NanoMonitor
|
||||||
{
|
{
|
||||||
|
@ -20,39 +16,45 @@ namespace Coffee.NanoMonitor
|
||||||
|
|
||||||
private static readonly Dictionary<Type, string> s_SupportedTypes = new Dictionary<Type, string>
|
private static readonly Dictionary<Type, string> s_SupportedTypes = new Dictionary<Type, string>
|
||||||
{
|
{
|
||||||
{typeof(bool), "bool"},
|
{ typeof(bool), "bool" },
|
||||||
{typeof(sbyte), "sbyte"},
|
{ typeof(sbyte), "sbyte" },
|
||||||
{typeof(short), "short"},
|
{ typeof(short), "short" },
|
||||||
{typeof(int), "int"},
|
{ typeof(int), "int" },
|
||||||
{typeof(long), "long"},
|
{ typeof(long), "long" },
|
||||||
{typeof(byte), "byte"},
|
{ typeof(byte), "byte" },
|
||||||
{typeof(ushort), "ushort"},
|
{ typeof(ushort), "ushort" },
|
||||||
{typeof(uint), "uint"},
|
{ typeof(uint), "uint" },
|
||||||
{typeof(ulong), "ulong"},
|
{ typeof(ulong), "ulong" },
|
||||||
{typeof(float), "float"},
|
{ typeof(float), "float" },
|
||||||
{typeof(double), "double"},
|
{ typeof(double), "double" },
|
||||||
{typeof(decimal), "decimal"},
|
{ typeof(decimal), "decimal" }
|
||||||
};
|
};
|
||||||
|
|
||||||
private static void Init()
|
private static void Init()
|
||||||
{
|
{
|
||||||
if (s_PropertyMenu != null) return;
|
if (s_PropertyMenu != null) return;
|
||||||
|
|
||||||
|
const BindingFlags bindingFlags = BindingFlags.Public
|
||||||
|
| BindingFlags.NonPublic
|
||||||
|
| BindingFlags.Static
|
||||||
|
| BindingFlags.GetProperty;
|
||||||
var properties = AppDomain.CurrentDomain.GetAssemblies()
|
var properties = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
.SelectMany(assembly => assembly.GetTypes())
|
.SelectMany(assembly => assembly.GetTypes())
|
||||||
.SelectMany(type => type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetProperty))
|
.SelectMany(type => type.GetProperties(bindingFlags))
|
||||||
.Where(pi => pi.GetMethod != null && s_SupportedTypes.ContainsKey(pi.PropertyType))
|
.Where(pi => pi.GetMethod != null && s_SupportedTypes.ContainsKey(pi.PropertyType))
|
||||||
.OrderBy(pi => ConvertToMenuItem(pi, false))
|
.OrderBy(pi => ConvertToMenuItem(pi, false))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
s_PropertyMenu = new GenericMenu();
|
s_PropertyMenu = new GenericMenu();
|
||||||
s_PropertyMenu.AddItem(new GUIContent("No Property"), false, arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), null);
|
s_PropertyMenu.AddItem(new GUIContent("No Property"), false,
|
||||||
s_PropertyMenu.AddItem(new GUIContent("(Non Public Properties)/"), false, ()=>{});
|
arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), null);
|
||||||
|
s_PropertyMenu.AddItem(new GUIContent("(Non Public Properties)/"), false, () => { });
|
||||||
s_PropertyMenu.AddSeparator("");
|
s_PropertyMenu.AddSeparator("");
|
||||||
|
|
||||||
foreach (var pi in properties)
|
foreach (var pi in properties)
|
||||||
{
|
{
|
||||||
s_PropertyMenu.AddItem(new GUIContent(ConvertToMenuItem(pi, true)), false, arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), pi);
|
s_PropertyMenu.AddItem(new GUIContent(ConvertToMenuItem(pi, true)), false,
|
||||||
|
arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), pi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +62,17 @@ namespace Coffee.NanoMonitor
|
||||||
{
|
{
|
||||||
var type = p.DeclaringType;
|
var type = p.DeclaringType;
|
||||||
if (type == null) return "";
|
if (type == null) return "";
|
||||||
var category = p.GetMethod.IsPublic && type.IsPublic ? "" : "(Non Public Properties)/";
|
|
||||||
|
var category = p.GetMethod.IsPublic && type.IsPublic
|
||||||
|
? ""
|
||||||
|
: "(Non Public Properties)/";
|
||||||
var typeName = type.FullName;
|
var typeName = type.FullName;
|
||||||
var asmName = type.Assembly.GetName().Name;
|
var asmName = type.Assembly.GetName().Name;
|
||||||
if (asmName == "UnityEngine.CoreModule")
|
if (asmName == "UnityEngine.CoreModule")
|
||||||
|
{
|
||||||
asmName = "UnityEngine";
|
asmName = "UnityEngine";
|
||||||
|
}
|
||||||
|
|
||||||
return propertyType
|
return propertyType
|
||||||
? $"{category}{asmName}/{typeName}/{s_SupportedTypes[p.PropertyType]} {p.Name}"
|
? $"{category}{asmName}/{typeName}/{s_SupportedTypes[p.PropertyType]} {p.Name}"
|
||||||
: $"{category}{asmName}/{typeName}/{p.Name}";
|
: $"{category}{asmName}/{typeName}/{p.Name}";
|
||||||
|
@ -84,7 +92,9 @@ namespace Coffee.NanoMonitor
|
||||||
{
|
{
|
||||||
s_OnMenuSelected = p =>
|
s_OnMenuSelected = p =>
|
||||||
{
|
{
|
||||||
path.stringValue = p == null ? "" : $"{p.DeclaringType?.FullName}, {p.DeclaringType?.Assembly.GetName().Name};{p.Name}";
|
path.stringValue = p == null
|
||||||
|
? ""
|
||||||
|
: $"{p.DeclaringType?.FullName}, {p.DeclaringType?.Assembly.GetName().Name};{p.Name}";
|
||||||
property.serializedObject.ApplyModifiedProperties();
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
};
|
};
|
||||||
s_PropertyMenu.DropDown(position);
|
s_PropertyMenu.DropDown(position);
|
||||||
|
@ -104,6 +114,22 @@ namespace Coffee.NanoMonitor
|
||||||
[SerializeField] private string m_Path = "";
|
[SerializeField] private string m_Path = "";
|
||||||
|
|
||||||
|
|
||||||
|
//################################
|
||||||
|
// Private Members.
|
||||||
|
//################################
|
||||||
|
private Func<double> _get;
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||||
|
{
|
||||||
|
var pInfo = GetPropertyInfo(m_Path);
|
||||||
|
_get = CreateFunc(pInfo?.GetMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
// Public Members.
|
// Public Members.
|
||||||
//################################
|
//################################
|
||||||
|
@ -112,12 +138,6 @@ namespace Coffee.NanoMonitor
|
||||||
return _get?.Invoke() ?? -1;
|
return _get?.Invoke() ?? -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//################################
|
|
||||||
// Private Members.
|
|
||||||
//################################
|
|
||||||
private Func<double> _get = null;
|
|
||||||
|
|
||||||
private static PropertyInfo GetPropertyInfo(string path)
|
private static PropertyInfo GetPropertyInfo(string path)
|
||||||
{
|
{
|
||||||
var p = path.Split(';');
|
var p = path.Split(';');
|
||||||
|
@ -126,14 +146,14 @@ namespace Coffee.NanoMonitor
|
||||||
var type = Type.GetType(p[0]);
|
var type = Type.GetType(p[0]);
|
||||||
if (type == null)
|
if (type == null)
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogException(new Exception($"Type '{p[0]}' is not found"));
|
Debug.LogException(new Exception($"Type '{p[0]}' is not found"));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pInfo = type.GetProperty(p[1], BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static);
|
var pInfo = type.GetProperty(p[1], BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static);
|
||||||
if (pInfo == null)
|
if (pInfo == null)
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogException(new Exception($"Member '{p[1]}' is not found in type '{type}'"));
|
Debug.LogException(new Exception($"Member '{p[1]}' is not found in type '{type}'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return pInfo;
|
return pInfo;
|
||||||
|
@ -145,55 +165,72 @@ namespace Coffee.NanoMonitor
|
||||||
switch (Type.GetTypeCode(mInfo.ReturnType))
|
switch (Type.GetTypeCode(mInfo.ReturnType))
|
||||||
{
|
{
|
||||||
case TypeCode.Boolean:
|
case TypeCode.Boolean:
|
||||||
var f_bool = (Func<bool>) mInfo.CreateDelegate(typeof(Func<bool>));
|
{
|
||||||
return () => f_bool() ? 1 : 0;
|
var func = (Func<bool>)mInfo.CreateDelegate(typeof(Func<bool>));
|
||||||
|
return () => func() ? 1 : 0;
|
||||||
|
}
|
||||||
case TypeCode.Byte:
|
case TypeCode.Byte:
|
||||||
var f_byte = (Func<byte>) mInfo.CreateDelegate(typeof(Func<byte>));
|
{
|
||||||
return () => f_byte();
|
var func = (Func<byte>)mInfo.CreateDelegate(typeof(Func<byte>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.SByte:
|
case TypeCode.SByte:
|
||||||
var f_sbyte = (Func<sbyte>) mInfo.CreateDelegate(typeof(Func<sbyte>));
|
{
|
||||||
return () => f_sbyte();
|
var func = (Func<sbyte>)mInfo.CreateDelegate(typeof(Func<sbyte>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.UInt16:
|
case TypeCode.UInt16:
|
||||||
var f_ushort = (Func<ushort>) mInfo.CreateDelegate(typeof(Func<ushort>));
|
{
|
||||||
return () => f_ushort();
|
var func = (Func<ushort>)mInfo.CreateDelegate(typeof(Func<ushort>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.UInt32:
|
case TypeCode.UInt32:
|
||||||
var f_uint = (Func<uint>) mInfo.CreateDelegate(typeof(Func<uint>));
|
{
|
||||||
return () => f_uint();
|
var func = (Func<uint>)mInfo.CreateDelegate(typeof(Func<uint>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.UInt64:
|
case TypeCode.UInt64:
|
||||||
var f_ulong = (Func<ulong>) mInfo.CreateDelegate(typeof(Func<ulong>));
|
{
|
||||||
return () => f_ulong();
|
var func = (Func<ulong>)mInfo.CreateDelegate(typeof(Func<ulong>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.Int16:
|
case TypeCode.Int16:
|
||||||
var f_short = (Func<short>) mInfo.CreateDelegate(typeof(Func<short>));
|
{
|
||||||
return () => f_short();
|
var func = (Func<short>)mInfo.CreateDelegate(typeof(Func<short>));
|
||||||
|
return () => func();
|
||||||
|
}
|
||||||
case TypeCode.Int32:
|
case TypeCode.Int32:
|
||||||
var f_int = (Func<int>) mInfo.CreateDelegate(typeof(Func<int>));
|
{
|
||||||
return () => f_int();
|
var f = (Func<int>)mInfo.CreateDelegate(typeof(Func<int>));
|
||||||
|
return () => f();
|
||||||
|
}
|
||||||
case TypeCode.Int64:
|
case TypeCode.Int64:
|
||||||
var f_long = (Func<long>) mInfo.CreateDelegate(typeof(Func<long>));
|
{
|
||||||
return () => f_long();
|
var f = (Func<long>)mInfo.CreateDelegate(typeof(Func<long>));
|
||||||
|
return () => f();
|
||||||
|
}
|
||||||
case TypeCode.Decimal:
|
case TypeCode.Decimal:
|
||||||
var f_decimal = (Func<decimal>) mInfo.CreateDelegate(typeof(Func<decimal>));
|
{
|
||||||
return () => (double) f_decimal();
|
var f = (Func<decimal>)mInfo.CreateDelegate(typeof(Func<decimal>));
|
||||||
|
return () => (double)f();
|
||||||
|
}
|
||||||
case TypeCode.Double:
|
case TypeCode.Double:
|
||||||
var f_double = (Func<double>) mInfo.CreateDelegate(typeof(Func<double>));
|
{
|
||||||
return f_double;
|
var f = (Func<double>)mInfo.CreateDelegate(typeof(Func<double>));
|
||||||
|
return f;
|
||||||
|
}
|
||||||
case TypeCode.Single:
|
case TypeCode.Single:
|
||||||
var f_float = (Func<float>) mInfo.CreateDelegate(typeof(Func<float>));
|
{
|
||||||
return () => f_float();
|
var f = (Func<float>)mInfo.CreateDelegate(typeof(Func<float>));
|
||||||
|
return () => f();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UnityEngine.Debug.LogException(new Exception(string.Format("Method '{1}.{0}' is not supported.", mInfo.Name, mInfo.DeclaringType)));
|
{
|
||||||
|
var message = $"Method '{mInfo.DeclaringType}.{mInfo.Name} ({mInfo.ReturnType})' is not supported.";
|
||||||
|
Debug.LogException(new Exception(message));
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
|
||||||
{
|
|
||||||
var pInfo = GetPropertyInfo(m_Path);
|
|
||||||
_get = CreateFunc(pInfo?.GetMethod);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ namespace Coffee.NanoMonitor
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AppendFormatNoAlloc(this StringBuilder sb, string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
public static void AppendFormatNoAlloc(this StringBuilder sb, string format, double arg0 = 0, double arg1 = 0,
|
||||||
|
double arg2 = 0, double arg3 = 0)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < format.Length; i++)
|
for (var i = 0; i < format.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -56,7 +57,7 @@ namespace Coffee.NanoMonitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void AppendInteger(this StringBuilder sb, double number, int padding, int precision, int alignment)
|
private static void AppendInteger(this StringBuilder sb, double number, int padding, int alignment)
|
||||||
{
|
{
|
||||||
number = Math.Truncate(number);
|
number = Math.Truncate(number);
|
||||||
var sign = number < 0;
|
var sign = number < 0;
|
||||||
|
@ -68,8 +69,8 @@ namespace Coffee.NanoMonitor
|
||||||
var n = Math.Truncate(number % 10);
|
var n = Math.Truncate(number % 10);
|
||||||
number /= 10;
|
number /= 10;
|
||||||
|
|
||||||
sb.Append((char) (n + 48));
|
sb.Append((char)(n + 48));
|
||||||
} while (1 <= number || (sb.Length - startIndex) < padding);
|
} while (1 <= number || sb.Length - startIndex < padding);
|
||||||
|
|
||||||
if (sign)
|
if (sign)
|
||||||
{
|
{
|
||||||
|
@ -82,11 +83,12 @@ namespace Coffee.NanoMonitor
|
||||||
sb.Alignment(alignment, startIndex, endIndex);
|
sb.Alignment(alignment, startIndex, endIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void AppendDouble(this StringBuilder sb, double number, int padding, int precision, int alignment)
|
private static void AppendDouble(this StringBuilder sb, double number, int padding, int precision,
|
||||||
|
int alignment)
|
||||||
{
|
{
|
||||||
var integer = Math.Truncate(number);
|
var integer = Math.Truncate(number);
|
||||||
var startIndex = sb.Length;
|
var startIndex = sb.Length;
|
||||||
sb.AppendInteger(integer, padding, precision, 0);
|
sb.AppendInteger(integer, padding, 0);
|
||||||
|
|
||||||
if (0 < precision)
|
if (0 < precision)
|
||||||
{
|
{
|
||||||
|
@ -96,8 +98,8 @@ namespace Coffee.NanoMonitor
|
||||||
for (var p = 0; p < precision; p++)
|
for (var p = 0; p < precision; p++)
|
||||||
{
|
{
|
||||||
number *= 10;
|
number *= 10;
|
||||||
integer = (long) number;
|
integer = (long)number;
|
||||||
sb.Append((char) (integer + 48));
|
sb.Append((char)(integer + 48));
|
||||||
number -= integer;
|
number -= integer;
|
||||||
number = Math.Round(number, precision);
|
number = Math.Round(number, precision);
|
||||||
}
|
}
|
||||||
|
@ -106,20 +108,18 @@ namespace Coffee.NanoMonitor
|
||||||
sb.Alignment(alignment, startIndex, sb.Length - 1);
|
sb.Alignment(alignment, startIndex, sb.Length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Reverse(this StringBuilder sb, int start, int end)
|
private static void Reverse(this StringBuilder sb, int start, int end)
|
||||||
{
|
{
|
||||||
while (start < end)
|
while (start < end)
|
||||||
{
|
{
|
||||||
var c = sb[start];
|
// swap
|
||||||
sb[start] = sb[end];
|
(sb[start], sb[end]) = (sb[end], sb[start]);
|
||||||
sb[end] = c;
|
|
||||||
|
|
||||||
start++;
|
start++;
|
||||||
end--;
|
end--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Alignment(this StringBuilder sb, int alignment, int start, int end)
|
private static void Alignment(this StringBuilder sb, int alignment, int start, int end)
|
||||||
{
|
{
|
||||||
if (alignment == 0) return;
|
if (alignment == 0) return;
|
||||||
|
|
||||||
|
@ -129,9 +129,8 @@ namespace Coffee.NanoMonitor
|
||||||
sb.Append(' ', alignment - len);
|
sb.Append(' ', alignment - len);
|
||||||
for (var i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
var c = sb[end - i];
|
// swap
|
||||||
sb[end - i] = sb[start + alignment - i - 1];
|
(sb[end - i], sb[start + alignment - i - 1]) = (sb[start + alignment - i - 1], sb[end - i]);
|
||||||
sb[start + alignment - i - 1] = c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (alignment < 0 && len < -alignment)
|
else if (alignment < 0 && len < -alignment)
|
||||||
|
@ -140,7 +139,8 @@ namespace Coffee.NanoMonitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int GetFormat(string format, int i, out int argIndex, out int padding, out int precision, out int alignment)
|
private static int GetFormat(string format, int i, out int argIndex, out int padding, out int precision,
|
||||||
|
out int alignment)
|
||||||
{
|
{
|
||||||
argIndex = -1;
|
argIndex = -1;
|
||||||
padding = 0;
|
padding = 0;
|
||||||
|
|
|
@ -1,26 +1,35 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions.Demo
|
namespace Coffee.UIExtensions.Demo
|
||||||
{
|
{
|
||||||
public class UIParticle_PerformanceDemo : MonoBehaviour
|
public class UIParticle_PerformanceDemo : MonoBehaviour
|
||||||
{
|
{
|
||||||
public GameObject copyOrigin;
|
[FormerlySerializedAs("copyOrigin")]
|
||||||
public int copyCount;
|
[SerializeField]
|
||||||
public Canvas root;
|
private GameObject m_CopyOrigin;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("copyCount")]
|
||||||
|
[SerializeField]
|
||||||
|
public int m_CopyCount;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("root")]
|
||||||
|
[SerializeField]
|
||||||
|
public Canvas m_RootCanvas;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
Application.targetFrameRate = 60;
|
Application.targetFrameRate = 60;
|
||||||
|
|
||||||
if (copyOrigin)
|
if (m_CopyOrigin)
|
||||||
{
|
{
|
||||||
copyOrigin.SetActive(false);
|
m_CopyOrigin.SetActive(false);
|
||||||
|
|
||||||
var parent = copyOrigin.transform.parent;
|
var parent = m_CopyOrigin.transform.parent;
|
||||||
for (var i = 0; i < copyCount; i++)
|
for (var i = 0; i < m_CopyCount; i++)
|
||||||
{
|
{
|
||||||
var go = GameObject.Instantiate(copyOrigin, parent, false);
|
var go = Instantiate(m_CopyOrigin, parent, false);
|
||||||
go.name = string.Format("{0} {1}", copyOrigin.name, i + 1);
|
go.name = string.Format("{0} {1}", m_CopyOrigin.name, i + 1);
|
||||||
go.hideFlags = HideFlags.DontSave;
|
go.hideFlags = HideFlags.DontSave;
|
||||||
|
|
||||||
go.SetActive(true);
|
go.SetActive(true);
|
||||||
|
@ -28,32 +37,14 @@ namespace Coffee.UIExtensions.Demo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeScreenSize()
|
public void UIParticle_Enable(bool flag)
|
||||||
{
|
{
|
||||||
if (Screen.width == 400 && Screen.height == 720)
|
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||||
Screen.SetResolution(720, 720, false);
|
|
||||||
else if (Screen.width == 720 && Screen.height == 720)
|
|
||||||
Screen.SetResolution(720, 400, false);
|
|
||||||
else
|
|
||||||
Screen.SetResolution(400, 720, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EnableAnimations(bool enabled)
|
|
||||||
{
|
|
||||||
foreach (var animator in FindObjectsOfType<Animator>())
|
|
||||||
{
|
{
|
||||||
animator.enabled = enabled;
|
uip.enabled = flag;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void UIParticle_Enable(bool enabled)
|
if (!flag)
|
||||||
{
|
|
||||||
|
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
|
||||||
{
|
|
||||||
uip.enabled = enabled;
|
|
||||||
}
|
|
||||||
if (!enabled)
|
|
||||||
{
|
{
|
||||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||||
{
|
{
|
||||||
|
@ -62,36 +53,23 @@ namespace Coffee.UIExtensions.Demo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_MeshSharing(bool enabled)
|
public void UIParticle_MeshSharing(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.meshSharing = enabled ? UIParticle.MeshSharing.Auto : UIParticle.MeshSharing.None;
|
uip.meshSharing = flag
|
||||||
|
? UIParticle.MeshSharing.Auto
|
||||||
|
: UIParticle.MeshSharing.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UIParticle_RandomGroup(bool enabled)
|
public void UIParticle_RandomGroup(bool flag)
|
||||||
{
|
{
|
||||||
foreach (var uip in root.GetComponentsInChildren<UIParticle>(true))
|
foreach (var uip in m_RootCanvas.GetComponentsInChildren<UIParticle>(true))
|
||||||
{
|
{
|
||||||
uip.groupMaxId = enabled ? 4 : 0;
|
uip.groupMaxId = flag
|
||||||
}
|
? 4
|
||||||
}
|
: 0;
|
||||||
|
|
||||||
public void UIParticle_Scale(float scale)
|
|
||||||
{
|
|
||||||
foreach (var uip in FindObjectsOfType<UIParticle>())
|
|
||||||
{
|
|
||||||
uip.scale = scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ParticleSystem_WorldSpaseSimulation(bool enabled)
|
|
||||||
{
|
|
||||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
|
||||||
{
|
|
||||||
var main = ps.main;
|
|
||||||
main.simulationSpace = enabled ? ParticleSystemSimulationSpace.World : ParticleSystemSimulationSpace.Local;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,34 +80,5 @@ namespace Coffee.UIExtensions.Demo
|
||||||
ps.transform.localScale = new Vector3(scale, scale, scale);
|
ps.transform.localScale = new Vector3(scale, scale, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Canvas_WorldSpace(bool flag)
|
|
||||||
{
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
|
||||||
canvas.renderMode = RenderMode.WorldSpace;
|
|
||||||
canvas.transform.rotation = Quaternion.Euler(new Vector3(0, 10, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Canvas_CameraSpace(bool flag)
|
|
||||||
{
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Canvas_Overlay(bool flag)
|
|
||||||
{
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
var canvas = FindObjectOfType<Canvas>();
|
|
||||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ RenderSettings:
|
||||||
m_ReflectionIntensity: 1
|
m_ReflectionIntensity: 1
|
||||||
m_CustomReflection: {fileID: 0}
|
m_CustomReflection: {fileID: 0}
|
||||||
m_Sun: {fileID: 0}
|
m_Sun: {fileID: 0}
|
||||||
m_IndirectSpecularColor: {r: 0.12731704, g: 0.13414726, b: 0.1210787, a: 1}
|
m_IndirectSpecularColor: {r: 0.12731689, g: 0.13414702, b: 0.1210784, a: 1}
|
||||||
m_UseRadianceAmbientProbe: 0
|
m_UseRadianceAmbientProbe: 0
|
||||||
--- !u!157 &3
|
--- !u!157 &3
|
||||||
LightmapSettings:
|
LightmapSettings:
|
||||||
|
@ -757,85 +757,6 @@ Transform:
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 2
|
m_RootOrder: 2
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
--- !u!1 &455490117
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 455490120}
|
|
||||||
- component: {fileID: 455490119}
|
|
||||||
- component: {fileID: 455490118}
|
|
||||||
m_Layer: 5
|
|
||||||
m_Name: Custom 1
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!114 &455490118
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 455490117}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_Material: {fileID: 0}
|
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
m_RaycastTarget: 0
|
|
||||||
m_OnCullStateChanged:
|
|
||||||
m_PersistentCalls:
|
|
||||||
m_Calls: []
|
|
||||||
m_FontData:
|
|
||||||
m_Font: {fileID: 12800000, guid: 70069a8db1df148ae8b4c8108c079acf, type: 3}
|
|
||||||
m_FontSize: 14
|
|
||||||
m_FontStyle: 0
|
|
||||||
m_BestFit: 0
|
|
||||||
m_MinSize: 1
|
|
||||||
m_MaxSize: 40
|
|
||||||
m_Alignment: 0
|
|
||||||
m_AlignByGeometry: 0
|
|
||||||
m_RichText: 1
|
|
||||||
m_HorizontalOverflow: 0
|
|
||||||
m_VerticalOverflow: 0
|
|
||||||
m_LineSpacing: 1
|
|
||||||
m_Text: 'UIParticle: 888'
|
|
||||||
m_Mode: 0
|
|
||||||
m_TextAnchor: 0
|
|
||||||
--- !u!222 &455490119
|
|
||||||
CanvasRenderer:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 455490117}
|
|
||||||
m_CullTransparentMesh: 0
|
|
||||||
--- !u!224 &455490120
|
|
||||||
RectTransform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 455490117}
|
|
||||||
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_Children: []
|
|
||||||
m_Father: {fileID: 1002673088}
|
|
||||||
m_RootOrder: 1
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
m_AnchorMin: {x: 0, y: 1}
|
|
||||||
m_AnchorMax: {x: 0, y: 1}
|
|
||||||
m_AnchoredPosition: {x: 251.8711, y: -10}
|
|
||||||
m_SizeDelta: {x: 247.8711, y: 20}
|
|
||||||
m_Pivot: {x: 0, y: 0.5}
|
|
||||||
--- !u!1 &496349153
|
--- !u!1 &496349153
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -972,12 +893,12 @@ PrefabInstance:
|
||||||
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_AnchoredPosition.x
|
propertyPath: m_AnchoredPosition.x
|
||||||
value: 240.00002
|
value: 240
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_AnchoredPosition.y
|
propertyPath: m_AnchoredPosition.y
|
||||||
value: -179.99998
|
value: -180
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 864895766138689324, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
|
@ -1160,6 +1081,85 @@ CanvasRenderer:
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 608849065}
|
m_GameObject: {fileID: 608849065}
|
||||||
m_CullTransparentMesh: 0
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!1 &733597319
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 733597322}
|
||||||
|
- component: {fileID: 733597321}
|
||||||
|
- component: {fileID: 733597320}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Custom 1
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &733597320
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 733597319}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 0
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_FontData:
|
||||||
|
m_Font: {fileID: 12800000, guid: d07e6c2670f164cf7939ab011061a9bf, type: 3}
|
||||||
|
m_FontSize: 14
|
||||||
|
m_FontStyle: 0
|
||||||
|
m_BestFit: 0
|
||||||
|
m_MinSize: 1
|
||||||
|
m_MaxSize: 40
|
||||||
|
m_Alignment: 0
|
||||||
|
m_AlignByGeometry: 0
|
||||||
|
m_RichText: 1
|
||||||
|
m_HorizontalOverflow: 0
|
||||||
|
m_VerticalOverflow: 0
|
||||||
|
m_LineSpacing: 1
|
||||||
|
m_Text: 'Screen: 8888x8888 Time: 8888.88'
|
||||||
|
m_Mode: 0
|
||||||
|
m_TextAnchor: 0
|
||||||
|
--- !u!222 &733597321
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 733597319}
|
||||||
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!224 &733597322
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 733597319}
|
||||||
|
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_Children: []
|
||||||
|
m_Father: {fileID: 1002673088}
|
||||||
|
m_RootOrder: 1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
|
m_AnchorMax: {x: 0, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 251.8711, y: -10}
|
||||||
|
m_SizeDelta: {x: 247.8711, y: 20}
|
||||||
|
m_Pivot: {x: 0, y: 0.5}
|
||||||
--- !u!1 &879285143
|
--- !u!1 &879285143
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -1287,9 +1287,9 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: 3a595cf9cf93f4e0686f247a5e7e19ce, type: 3}
|
m_Script: {fileID: 11500000, guid: 3a595cf9cf93f4e0686f247a5e7e19ce, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
copyOrigin: {fileID: 1581241706}
|
m_CopyOrigin: {fileID: 1581241706}
|
||||||
copyCount: 266
|
m_CopyCount: 266
|
||||||
root: {fileID: 919637305}
|
m_RootCanvas: {fileID: 919637305}
|
||||||
--- !u!4 &903906985
|
--- !u!4 &903906985
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -1505,11 +1505,6 @@ PrefabInstance:
|
||||||
propertyPath: m_SizeDelta.x
|
propertyPath: m_SizeDelta.x
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 151878254403844079, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
propertyPath: m_TargetGraphic
|
|
||||||
value:
|
|
||||||
objectReference: {fileID: 1002673091}
|
|
||||||
- target: {fileID: 323826319202443003, guid: 784696794bc6345bc80bf49623581c2e,
|
- target: {fileID: 323826319202443003, guid: 784696794bc6345bc80bf49623581c2e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_AnchorMin.y
|
propertyPath: m_AnchorMin.y
|
||||||
|
@ -1530,11 +1525,6 @@ PrefabInstance:
|
||||||
propertyPath: m_AnchoredPosition.y
|
propertyPath: m_AnchoredPosition.y
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1087632561348207336, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
propertyPath: m_TargetGraphic
|
|
||||||
value:
|
|
||||||
objectReference: {fileID: 1002673092}
|
|
||||||
- target: {fileID: 1458366075964155596, guid: 784696794bc6345bc80bf49623581c2e,
|
- target: {fileID: 1458366075964155596, guid: 784696794bc6345bc80bf49623581c2e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_AnchorMin.y
|
propertyPath: m_AnchorMin.y
|
||||||
|
@ -1564,7 +1554,7 @@ PrefabInstance:
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_CustomMonitorItems.Array.data[1].m_Text
|
propertyPath: m_CustomMonitorItems.Array.data[1].m_Text
|
||||||
value:
|
value:
|
||||||
objectReference: {fileID: 455490118}
|
objectReference: {fileID: 733597320}
|
||||||
- target: {fileID: 4567906826058368312, guid: 784696794bc6345bc80bf49623581c2e,
|
- target: {fileID: 4567906826058368312, guid: 784696794bc6345bc80bf49623581c2e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_CustomMonitorItems.Array.data[1].m_Format
|
propertyPath: m_CustomMonitorItems.Array.data[1].m_Format
|
||||||
|
@ -1630,16 +1620,6 @@ PrefabInstance:
|
||||||
propertyPath: m_SizeDelta.x
|
propertyPath: m_SizeDelta.x
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 5526675317024915317, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
propertyPath: m_TargetGraphic
|
|
||||||
value:
|
|
||||||
objectReference: {fileID: 1002673089}
|
|
||||||
- target: {fileID: 5526675317129615258, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
propertyPath: m_TargetGraphic
|
|
||||||
value:
|
|
||||||
objectReference: {fileID: 1002673090}
|
|
||||||
- target: {fileID: 5758968653464739090, guid: 784696794bc6345bc80bf49623581c2e,
|
- target: {fileID: 5758968653464739090, guid: 784696794bc6345bc80bf49623581c2e,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_SizeDelta.y
|
propertyPath: m_SizeDelta.y
|
||||||
|
@ -1803,54 +1783,6 @@ RectTransform:
|
||||||
type: 3}
|
type: 3}
|
||||||
m_PrefabInstance: {fileID: 1002673087}
|
m_PrefabInstance: {fileID: 1002673087}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
--- !u!114 &1002673089 stripped
|
|
||||||
MonoBehaviour:
|
|
||||||
m_CorrespondingSourceObject: {fileID: 5526675317024915314, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
m_PrefabInstance: {fileID: 1002673087}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 0}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!114 &1002673090 stripped
|
|
||||||
MonoBehaviour:
|
|
||||||
m_CorrespondingSourceObject: {fileID: 5526675317129615259, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
m_PrefabInstance: {fileID: 1002673087}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 0}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!114 &1002673091 stripped
|
|
||||||
MonoBehaviour:
|
|
||||||
m_CorrespondingSourceObject: {fileID: 6638879077379268485, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
m_PrefabInstance: {fileID: 1002673087}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 0}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!114 &1002673092 stripped
|
|
||||||
MonoBehaviour:
|
|
||||||
m_CorrespondingSourceObject: {fileID: 6720252555115459274, guid: 784696794bc6345bc80bf49623581c2e,
|
|
||||||
type: 3}
|
|
||||||
m_PrefabInstance: {fileID: 1002673087}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 0}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: b0e08c6080a2e4d8186f97c60518830f, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!1 &1023851109
|
--- !u!1 &1023851109
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -3632,6 +3564,11 @@ PrefabInstance:
|
||||||
m_Modification:
|
m_Modification:
|
||||||
m_TransformParent: {fileID: 1924051224}
|
m_TransformParent: {fileID: 1924051224}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
|
- target: {fileID: 864895764861262036, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
|
type: 3}
|
||||||
|
propertyPath: m_IgnoreCanvasScaler
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 864895765507486433, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 864895765507486433, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_AnchorMax.x
|
propertyPath: m_AnchorMax.x
|
||||||
|
@ -3790,17 +3727,17 @@ PrefabInstance:
|
||||||
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalScale.x
|
propertyPath: m_LocalScale.x
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalScale.y
|
propertyPath: m_LocalScale.y
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
- target: {fileID: 1088568576793901561, guid: a4669dfbba654429bbcddf0c9b79fb8b,
|
||||||
type: 3}
|
type: 3}
|
||||||
propertyPath: m_LocalScale.z
|
propertyPath: m_LocalScale.z
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: a4669dfbba654429bbcddf0c9b79fb8b, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: a4669dfbba654429bbcddf0c9b79fb8b, type: 3}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using UnityEngine;
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
[System.Serializable]
|
[Serializable]
|
||||||
public class AnimatableProperty : ISerializationCallbackReceiver
|
public class AnimatableProperty : ISerializationCallbackReceiver
|
||||||
{
|
{
|
||||||
public enum ShaderPropertyType
|
public enum ShaderPropertyType
|
||||||
|
@ -11,11 +12,11 @@ namespace Coffee.UIExtensions
|
||||||
Vector,
|
Vector,
|
||||||
Float,
|
Float,
|
||||||
Range,
|
Range,
|
||||||
Texture,
|
Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField] string m_Name = "";
|
[SerializeField] private string m_Name = "";
|
||||||
[SerializeField] ShaderPropertyType m_Type = ShaderPropertyType.Vector;
|
[SerializeField] private ShaderPropertyType m_Type = ShaderPropertyType.Vector;
|
||||||
public int id { get; private set; }
|
public int id { get; private set; }
|
||||||
|
|
||||||
public ShaderPropertyType type
|
public ShaderPropertyType type
|
||||||
|
@ -23,6 +24,15 @@ namespace Coffee.UIExtensions
|
||||||
get { return m_Type; }
|
get { return m_Type; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||||
|
{
|
||||||
|
id = Shader.PropertyToID(m_Name);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateMaterialProperties(Material material, MaterialPropertyBlock mpb)
|
public void UpdateMaterialProperties(Material material, MaterialPropertyBlock mpb)
|
||||||
{
|
{
|
||||||
if (!material.HasProperty(id)) return;
|
if (!material.HasProperty(id)) return;
|
||||||
|
@ -31,35 +41,38 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
case ShaderPropertyType.Color:
|
case ShaderPropertyType.Color:
|
||||||
var color = mpb.GetColor(id);
|
var color = mpb.GetColor(id);
|
||||||
if (color != default(Color))
|
if (color != default)
|
||||||
|
{
|
||||||
material.SetColor(id, color);
|
material.SetColor(id, color);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShaderPropertyType.Vector:
|
case ShaderPropertyType.Vector:
|
||||||
var vector = mpb.GetVector(id);
|
var vector = mpb.GetVector(id);
|
||||||
if (vector != default(Vector4))
|
if (vector != default)
|
||||||
|
{
|
||||||
material.SetVector(id, vector);
|
material.SetVector(id, vector);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShaderPropertyType.Float:
|
case ShaderPropertyType.Float:
|
||||||
case ShaderPropertyType.Range:
|
case ShaderPropertyType.Range:
|
||||||
var value = mpb.GetFloat(id);
|
var value = mpb.GetFloat(id);
|
||||||
if (value != default(float))
|
if (!Mathf.Approximately(value, 0))
|
||||||
|
{
|
||||||
material.SetFloat(id, value);
|
material.SetFloat(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ShaderPropertyType.Texture:
|
case ShaderPropertyType.Texture:
|
||||||
var tex = mpb.GetTexture(id);
|
var tex = mpb.GetTexture(id);
|
||||||
if (tex != default(Texture))
|
if (tex != default(Texture))
|
||||||
|
{
|
||||||
material.SetTexture(id, tex);
|
material.SetTexture(id, tex);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBeforeSerialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAfterDeserialize()
|
|
||||||
{
|
|
||||||
id = Shader.PropertyToID(m_Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Coffee.UIExtensions
|
||||||
|
{
|
||||||
|
internal static class AnimatablePropertyEditor
|
||||||
|
{
|
||||||
|
private static readonly GUIContent s_ContentNothing = new GUIContent("Nothing");
|
||||||
|
private static readonly List<string> s_ActiveNames = new List<string>();
|
||||||
|
private static readonly StringBuilder s_Sb = new StringBuilder();
|
||||||
|
private static readonly HashSet<string> s_Names = new HashSet<string>();
|
||||||
|
|
||||||
|
private static string CollectActiveNames(SerializedProperty sp, List<string> result)
|
||||||
|
{
|
||||||
|
result.Clear();
|
||||||
|
for (var i = 0; i < sp.arraySize; i++)
|
||||||
|
{
|
||||||
|
var spName = sp.GetArrayElementAtIndex(i).FindPropertyRelative("m_Name");
|
||||||
|
if (spName == null) continue;
|
||||||
|
|
||||||
|
result.Add(spName.stringValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_Sb.Length = 0;
|
||||||
|
if (result.Count == 0)
|
||||||
|
{
|
||||||
|
s_Sb.Append("Nothing");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
|
||||||
|
s_Sb.Length -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_Sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Draw(SerializedProperty sp, Material[] mats)
|
||||||
|
{
|
||||||
|
bool isClicked;
|
||||||
|
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false)))
|
||||||
|
{
|
||||||
|
var pos = EditorGUILayout.GetControlRect(true);
|
||||||
|
var label = new GUIContent(sp.displayName, sp.tooltip);
|
||||||
|
var rect = EditorGUI.PrefixLabel(pos, label);
|
||||||
|
var text = sp.hasMultipleDifferentValues
|
||||||
|
? "-"
|
||||||
|
: CollectActiveNames(sp, s_ActiveNames);
|
||||||
|
isClicked = GUI.Button(rect, text, EditorStyles.popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isClicked) return;
|
||||||
|
|
||||||
|
var gm = new GenericMenu();
|
||||||
|
gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, () =>
|
||||||
|
{
|
||||||
|
sp.ClearArray();
|
||||||
|
sp.serializedObject.ApplyModifiedProperties();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!sp.hasMultipleDifferentValues)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < sp.arraySize; i++)
|
||||||
|
{
|
||||||
|
var p = sp.GetArrayElementAtIndex(i);
|
||||||
|
var name = p.FindPropertyRelative("m_Name").stringValue;
|
||||||
|
var type = (AnimatableProperty.ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue;
|
||||||
|
AddMenu(gm, sp, new ShaderProperty(name, type), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_Names.Clear();
|
||||||
|
for (var j = 0; j < mats.Length; j++)
|
||||||
|
{
|
||||||
|
var mat = mats[j];
|
||||||
|
if (!mat || !mat.shader) continue;
|
||||||
|
|
||||||
|
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
|
||||||
|
{
|
||||||
|
var name = ShaderUtil.GetPropertyName(mat.shader, i);
|
||||||
|
var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i);
|
||||||
|
if (s_Names.Contains(name)) continue;
|
||||||
|
s_Names.Add(name);
|
||||||
|
|
||||||
|
AddMenu(gm, sp, new ShaderProperty(name, type), true);
|
||||||
|
|
||||||
|
if (type != AnimatableProperty.ShaderPropertyType.Texture) continue;
|
||||||
|
|
||||||
|
AddMenu(gm, sp, new ShaderProperty($"{name}_ST"), true);
|
||||||
|
AddMenu(gm, sp, new ShaderProperty($"{name}_HDR"), true);
|
||||||
|
AddMenu(gm, sp, new ShaderProperty($"{name}_TexelSize"), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gm.ShowAsContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddMenu(GenericMenu menu, SerializedProperty sp, ShaderProperty prop, bool add)
|
||||||
|
{
|
||||||
|
if (add && s_ActiveNames.Contains(prop.name)) return;
|
||||||
|
|
||||||
|
var label = new GUIContent($"{prop.name} ({prop.type})");
|
||||||
|
menu.AddItem(label, s_ActiveNames.Contains(prop.name), () =>
|
||||||
|
{
|
||||||
|
var index = s_ActiveNames.IndexOf(prop.name);
|
||||||
|
if (0 <= index)
|
||||||
|
{
|
||||||
|
sp.DeleteArrayElementAtIndex(index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp.InsertArrayElementAtIndex(sp.arraySize);
|
||||||
|
var p = sp.GetArrayElementAtIndex(sp.arraySize - 1);
|
||||||
|
p.FindPropertyRelative("m_Name").stringValue = prop.name;
|
||||||
|
p.FindPropertyRelative("m_Type").intValue = (int)prop.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.serializedObject.ApplyModifiedProperties();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct ShaderProperty
|
||||||
|
{
|
||||||
|
public readonly string name;
|
||||||
|
public readonly AnimatableProperty.ShaderPropertyType type;
|
||||||
|
|
||||||
|
public ShaderProperty(string name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
type = AnimatableProperty.ShaderPropertyType.Vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderProperty(string name, AnimatableProperty.ShaderPropertyType type)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,123 +0,0 @@
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using ShaderPropertyType = Coffee.UIExtensions.AnimatableProperty.ShaderPropertyType;
|
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
|
||||||
{
|
|
||||||
internal class AnimatedPropertiesEditor
|
|
||||||
{
|
|
||||||
private static readonly List<string> s_ActiveNames = new List<string>();
|
|
||||||
private static readonly System.Text.StringBuilder s_Sb = new System.Text.StringBuilder();
|
|
||||||
private static readonly HashSet<string> s_Names = new HashSet<string>();
|
|
||||||
|
|
||||||
private string _name;
|
|
||||||
private ShaderPropertyType _type;
|
|
||||||
|
|
||||||
static string CollectActiveNames(SerializedProperty sp, List<string> result)
|
|
||||||
{
|
|
||||||
result.Clear();
|
|
||||||
for (var i = 0; i < sp.arraySize; i++)
|
|
||||||
{
|
|
||||||
var spName = sp.GetArrayElementAtIndex(i).FindPropertyRelative("m_Name");
|
|
||||||
if (spName == null) continue;
|
|
||||||
|
|
||||||
result.Add(spName.stringValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
s_Sb.Length = 0;
|
|
||||||
if (result.Count == 0)
|
|
||||||
{
|
|
||||||
s_Sb.Append("Nothing");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.Aggregate(s_Sb, (a, b) => s_Sb.AppendFormat("{0}, ", b));
|
|
||||||
s_Sb.Length -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s_Sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DrawAnimatableProperties(SerializedProperty sp, Material[] mats)
|
|
||||||
{
|
|
||||||
bool isClicked;
|
|
||||||
using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false)))
|
|
||||||
{
|
|
||||||
var r = EditorGUI.PrefixLabel(EditorGUILayout.GetControlRect(true), new GUIContent(sp.displayName, sp.tooltip));
|
|
||||||
var text = sp.hasMultipleDifferentValues ? "-" : CollectActiveNames(sp, s_ActiveNames);
|
|
||||||
isClicked = GUI.Button(r, text, EditorStyles.popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isClicked) return;
|
|
||||||
|
|
||||||
var gm = new GenericMenu();
|
|
||||||
gm.AddItem(new GUIContent("Nothing"), s_ActiveNames.Count == 0, () =>
|
|
||||||
{
|
|
||||||
sp.ClearArray();
|
|
||||||
sp.serializedObject.ApplyModifiedProperties();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
if (!sp.hasMultipleDifferentValues)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < sp.arraySize; i++)
|
|
||||||
{
|
|
||||||
var p = sp.GetArrayElementAtIndex(i);
|
|
||||||
var name = p.FindPropertyRelative("m_Name").stringValue;
|
|
||||||
var type = (ShaderPropertyType) p.FindPropertyRelative("m_Type").intValue;
|
|
||||||
AddMenu(gm, sp, new AnimatedPropertiesEditor {_name = name, _type = type}, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s_Names.Clear();
|
|
||||||
foreach (var mat in mats)
|
|
||||||
{
|
|
||||||
if (!mat || !mat.shader) continue;
|
|
||||||
|
|
||||||
for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
|
|
||||||
{
|
|
||||||
var pName = ShaderUtil.GetPropertyName(mat.shader, i);
|
|
||||||
var type = (ShaderPropertyType) ShaderUtil.GetPropertyType(mat.shader, i);
|
|
||||||
var name = string.Format("{0} ({1})", pName, type);
|
|
||||||
if (s_Names.Contains(name)) continue;
|
|
||||||
s_Names.Add(name);
|
|
||||||
|
|
||||||
AddMenu(gm, sp, new AnimatedPropertiesEditor {_name = pName, _type = type}, true);
|
|
||||||
|
|
||||||
if (type != ShaderPropertyType.Texture) continue;
|
|
||||||
|
|
||||||
AddMenu(gm, sp, new AnimatedPropertiesEditor {_name = pName + "_ST", _type = ShaderPropertyType.Vector}, true);
|
|
||||||
AddMenu(gm, sp, new AnimatedPropertiesEditor {_name = pName + "_HDR", _type = ShaderPropertyType.Vector}, true);
|
|
||||||
AddMenu(gm, sp, new AnimatedPropertiesEditor {_name = pName + "_TexelSize", _type = ShaderPropertyType.Vector}, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gm.ShowAsContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddMenu(GenericMenu menu, SerializedProperty sp, AnimatedPropertiesEditor property, bool add)
|
|
||||||
{
|
|
||||||
if (add && s_ActiveNames.Contains(property._name)) return;
|
|
||||||
|
|
||||||
menu.AddItem(new GUIContent(string.Format("{0} ({1})", property._name, property._type)), s_ActiveNames.Contains(property._name), () =>
|
|
||||||
{
|
|
||||||
var index = s_ActiveNames.IndexOf(property._name);
|
|
||||||
if (0 <= index)
|
|
||||||
{
|
|
||||||
sp.DeleteArrayElementAtIndex(index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sp.InsertArrayElementAtIndex(sp.arraySize);
|
|
||||||
var p = sp.GetArrayElementAtIndex(sp.arraySize - 1);
|
|
||||||
p.FindPropertyRelative("m_Name").stringValue = property._name;
|
|
||||||
p.FindPropertyRelative("m_Type").intValue = (int) property._type;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp.serializedObject.ApplyModifiedProperties();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,11 +32,16 @@ namespace Coffee.UIExtensions
|
||||||
private static void ImportSample(string jsonGuid, string sampleName)
|
private static void ImportSample(string jsonGuid, string sampleName)
|
||||||
{
|
{
|
||||||
var jsonPath = AssetDatabase.GUIDToAssetPath(jsonGuid);
|
var jsonPath = AssetDatabase.GUIDToAssetPath(jsonGuid);
|
||||||
var packageRoot = Path.GetDirectoryName(jsonPath).Replace('\\', '/');
|
if (string.IsNullOrEmpty(jsonPath)) return;
|
||||||
|
|
||||||
|
var jsonDir = Path.GetDirectoryName(jsonPath);
|
||||||
|
if (string.IsNullOrEmpty(jsonDir)) return;
|
||||||
|
|
||||||
|
var packageRoot = jsonDir.Replace('\\', '/');
|
||||||
var json = File.ReadAllText(jsonPath);
|
var json = File.ReadAllText(jsonPath);
|
||||||
var version = Regex.Match(json, "\"version\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
|
var version = Regex.Match(json, "\"version\"\\s*:\\s*\"([^\"]+)\"").Groups[1].Value;
|
||||||
var src = string.Format("{0}/Samples~/{1}", packageRoot, sampleName);
|
var src = $"{packageRoot}/Samples~/{sampleName}";
|
||||||
var dst = string.Format("Assets/Samples/{0}/{1}/{2}", k_DisplayName, version, sampleName);
|
var dst = $"Assets/Samples/{k_DisplayName}/{version}/{sampleName}";
|
||||||
var previousPath = GetPreviousSamplePath(k_DisplayName, sampleName);
|
var previousPath = GetPreviousSamplePath(k_DisplayName, sampleName);
|
||||||
|
|
||||||
// Remove the previous sample directory.
|
// Remove the previous sample directory.
|
||||||
|
@ -46,33 +51,45 @@ namespace Coffee.UIExtensions
|
||||||
+ previousPath
|
+ previousPath
|
||||||
+ "\n\nIt will be deleted when you update. Are you sure you want to continue?";
|
+ "\n\nIt will be deleted when you update. Are you sure you want to continue?";
|
||||||
if (!EditorUtility.DisplayDialog("Sample Importer", msg, "OK", "Cancel"))
|
if (!EditorUtility.DisplayDialog("Sample Importer", msg, "OK", "Cancel"))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FileUtil.DeleteFileOrDirectory(previousPath);
|
FileUtil.DeleteFileOrDirectory(previousPath);
|
||||||
|
|
||||||
var metaFile = previousPath + ".meta";
|
var metaFile = previousPath + ".meta";
|
||||||
if (File.Exists(metaFile))
|
if (File.Exists(metaFile))
|
||||||
|
{
|
||||||
FileUtil.DeleteFileOrDirectory(metaFile);
|
FileUtil.DeleteFileOrDirectory(metaFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(dst))
|
if (!Directory.Exists(dst))
|
||||||
|
{
|
||||||
FileUtil.DeleteFileOrDirectory(dst);
|
FileUtil.DeleteFileOrDirectory(dst);
|
||||||
|
}
|
||||||
|
|
||||||
var dstDir = Path.GetDirectoryName(dst);
|
var dstDir = Path.GetDirectoryName(dst);
|
||||||
if (!Directory.Exists(dstDir))
|
if (!string.IsNullOrEmpty(dstDir) && !Directory.Exists(dstDir))
|
||||||
|
{
|
||||||
Directory.CreateDirectory(dstDir);
|
Directory.CreateDirectory(dstDir);
|
||||||
|
}
|
||||||
|
|
||||||
if (Directory.Exists(src))
|
if (Directory.Exists(src))
|
||||||
|
{
|
||||||
FileUtil.CopyFileOrDirectory(src, dst);
|
FileUtil.CopyFileOrDirectory(src, dst);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
throw new DirectoryNotFoundException(src);
|
throw new DirectoryNotFoundException(src);
|
||||||
|
}
|
||||||
|
|
||||||
AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive);
|
AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetPreviousSamplePath(string displayName, string sampleName)
|
private static string GetPreviousSamplePath(string displayName, string sampleName)
|
||||||
{
|
{
|
||||||
var sampleRoot = string.Format("Assets/Samples/{0}", displayName);
|
var sampleRoot = $"Assets/Samples/{displayName}";
|
||||||
var sampleRootInfo = new DirectoryInfo(sampleRoot);
|
var sampleRootInfo = new DirectoryInfo(sampleRoot);
|
||||||
if (!sampleRootInfo.Exists) return null;
|
if (!sampleRootInfo.Exists) return null;
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
#if UNITY_2019_3_11 || UNITY_2019_3_12 || UNITY_2019_3_13 || UNITY_2019_3_14 || UNITY_2019_3_15 || UNITY_2019_4_OR_NEWER
|
|
||||||
#define SERIALIZE_FIELD_MASKABLE
|
|
||||||
#endif
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEditor.UI;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEditorInternal;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using System;
|
|
||||||
#if UNITY_2021_2_OR_NEWER
|
#if UNITY_2021_2_OR_NEWER
|
||||||
using UnityEditor.Overlays;
|
using UnityEditor.Overlays;
|
||||||
#else
|
#else
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
#endif
|
#endif
|
||||||
|
#if UNITY_2021_2_OR_NEWER
|
||||||
|
using UnityEditor.SceneManagement;
|
||||||
|
#elif UNITY_2018_3_OR_NEWER
|
||||||
|
using UnityEditor.Experimental.SceneManagement;
|
||||||
|
#endif
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.UI;
|
||||||
|
using UnityEditorInternal;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
|
@ -23,7 +26,10 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
#if UNITY_2021_2_OR_NEWER
|
#if UNITY_2021_2_OR_NEWER
|
||||||
#if UNITY_2022_1_OR_NEWER
|
#if UNITY_2022_1_OR_NEWER
|
||||||
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true, defaultDockPosition = DockPosition.Bottom, defaultDockZone = DockZone.Floating, defaultLayout = Layout.Panel)]
|
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true,
|
||||||
|
defaultDockPosition = DockPosition.Bottom,
|
||||||
|
defaultDockZone = DockZone.Floating,
|
||||||
|
defaultLayout = Layout.Panel)]
|
||||||
#else
|
#else
|
||||||
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
|
[Overlay(typeof(SceneView), "Scene View/UI Particles", "UI Particles", true)]
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,27 +58,28 @@ namespace Coffee.UIExtensions
|
||||||
private static readonly GUIContent s_Content3D = new GUIContent("3D");
|
private static readonly GUIContent s_Content3D = new GUIContent("3D");
|
||||||
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
private static readonly GUIContent s_ContentRandom = new GUIContent("Random");
|
||||||
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
|
||||||
private static readonly GUIContent s_ContentAutoScaling = new GUIContent("Auto Scaling", "Transform.lossyScale (=world scale) is automatically set to (1, 1, 1), to prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.");
|
|
||||||
|
private static readonly GUIContent s_ContentAutoScaling = new GUIContent("Auto Scaling",
|
||||||
|
"Transform.lossyScale (=world scale) is automatically set to (1, 1, 1)," +
|
||||||
|
" to prevent the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.");
|
||||||
|
|
||||||
private static SerializedObject s_SerializedObject;
|
private static SerializedObject s_SerializedObject;
|
||||||
|
private static bool s_XYZMode;
|
||||||
|
|
||||||
#if !SERIALIZE_FIELD_MASKABLE
|
private SerializedProperty _maskable;
|
||||||
private SerializedProperty m_Maskable;
|
private SerializedProperty _scale3D;
|
||||||
#endif
|
private SerializedProperty _animatableProperties;
|
||||||
private SerializedProperty m_Scale3D;
|
private SerializedProperty _meshSharing;
|
||||||
private SerializedProperty m_AnimatableProperties;
|
private SerializedProperty _groupId;
|
||||||
private SerializedProperty m_MeshSharing;
|
private SerializedProperty _groupMaxId;
|
||||||
private SerializedProperty m_GroupId;
|
private SerializedProperty _absoluteMode;
|
||||||
private SerializedProperty m_GroupMaxId;
|
private SerializedProperty _ignoreCanvasScaler;
|
||||||
private SerializedProperty m_AbsoluteMode;
|
|
||||||
private SerializedProperty m_IgnoreCanvasScaler;
|
|
||||||
|
|
||||||
|
|
||||||
private ReorderableList _ro;
|
private ReorderableList _ro;
|
||||||
static private bool _xyzMode;
|
|
||||||
private bool _showMax;
|
private bool _showMax;
|
||||||
|
|
||||||
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
|
private static readonly HashSet<Shader> s_Shaders = new HashSet<Shader>();
|
||||||
private static readonly List<ParticleSystemVertexStream> s_Streams = new List<ParticleSystemVertexStream>();
|
private static readonly List<ParticleSystemVertexStream> s_Streams = new List<ParticleSystemVertexStream>();
|
||||||
|
|
||||||
private static readonly List<string> s_MaskablePropertyNames = new List<string>
|
private static readonly List<string> s_MaskablePropertyNames = new List<string>
|
||||||
{
|
{
|
||||||
"_Stencil",
|
"_Stencil",
|
||||||
|
@ -80,21 +87,20 @@ namespace Coffee.UIExtensions
|
||||||
"_StencilOp",
|
"_StencilOp",
|
||||||
"_StencilWriteMask",
|
"_StencilWriteMask",
|
||||||
"_StencilReadMask",
|
"_StencilReadMask",
|
||||||
"_ColorMask",
|
"_ColorMask"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
[InitializeOnLoadMethod]
|
[InitializeOnLoadMethod]
|
||||||
static void Init()
|
private static void Init()
|
||||||
{
|
{
|
||||||
#if !UNITY_2021_2_OR_NEWER
|
#if !UNITY_2021_2_OR_NEWER
|
||||||
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
|
var miSceneViewOverlayWindow = Type.GetType("UnityEditor.SceneViewOverlay, UnityEditor")
|
||||||
.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
?.GetMethods(BindingFlags.Public | BindingFlags.Static)
|
||||||
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
|
.First(x => x.Name == "Window" && 5 <= x.GetParameters().Length);
|
||||||
var windowFunction = (Action<UnityEngine.Object, SceneView>)WindowFunction;
|
var windowFunction = (Action<Object, SceneView>)WindowFunction;
|
||||||
var windowFunctionType = Type.GetType("UnityEditor.SceneViewOverlay+WindowFunction, UnityEditor");
|
var windowFunctionType = Type.GetType("UnityEditor.SceneViewOverlay+WindowFunction, UnityEditor");
|
||||||
var windowFunctionDelegate = Delegate.CreateDelegate(windowFunctionType, windowFunction.Method);
|
var windowFunctionDelegate = Delegate.CreateDelegate(windowFunctionType, windowFunction.Method);
|
||||||
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(typeof(UIParticle).Name));
|
var windowTitle = new GUIContent(ObjectNames.NicifyVariableName(nameof(UIParticle)));
|
||||||
#if UNITY_2019_2_OR_NEWER
|
#if UNITY_2019_2_OR_NEWER
|
||||||
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option, EditorWindow window = null)
|
//public static void Window(GUIContent title, WindowFunction sceneViewFunc, int order, Object target, WindowDisplayOption option, EditorWindow window = null)
|
||||||
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2, null };
|
var sceneViewArgs = new object[] { windowTitle, windowFunctionDelegate, 599, null, 2, null };
|
||||||
|
@ -104,7 +110,7 @@ namespace Coffee.UIExtensions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UNITY_2019_1_OR_NEWER
|
#if UNITY_2019_1_OR_NEWER
|
||||||
SceneView.duringSceneGui += _ => { if (s_SerializedObject != null) miSceneViewOverlayWindow.Invoke(null, sceneViewArgs); };
|
SceneView.duringSceneGui += _ =>
|
||||||
#else
|
#else
|
||||||
SceneView.onSceneGUIDelegate += _ =>
|
SceneView.onSceneGUIDelegate += _ =>
|
||||||
#endif
|
#endif
|
||||||
|
@ -116,25 +122,21 @@ namespace Coffee.UIExtensions
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Func<SerializedObject> createSerializeObject = () =>
|
SerializedObject CreateSerializeObject()
|
||||||
{
|
{
|
||||||
var uiParticles = Selection.gameObjects
|
var uiParticles = Selection.gameObjects.Select(x => x.GetComponent<ParticleSystem>())
|
||||||
.Select(x => x.GetComponent<ParticleSystem>())
|
.Where(x => x)
|
||||||
.Where(x => x)
|
.Select(x => x.GetComponentInParent<UIParticle>())
|
||||||
.Select(x => x.GetComponentInParent<UIParticle>())
|
.Where(x => x && x.canvas)
|
||||||
.Where(x => x && x.canvas)
|
.Concat(Selection.gameObjects.Select(x => x.GetComponent<UIParticle>())
|
||||||
.Concat(
|
.Where(x => x && x.canvas))
|
||||||
Selection.gameObjects
|
.Distinct()
|
||||||
.Select(x => x.GetComponent<UIParticle>())
|
.ToArray();
|
||||||
.Where(x => x && x.canvas)
|
|
||||||
)
|
|
||||||
.Distinct()
|
|
||||||
.ToArray();
|
|
||||||
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
|
return 0 < uiParticles.Length ? new SerializedObject(uiParticles) : null;
|
||||||
};
|
}
|
||||||
|
|
||||||
s_SerializedObject = createSerializeObject();
|
s_SerializedObject = CreateSerializeObject();
|
||||||
Selection.selectionChanged += () => s_SerializedObject = createSerializeObject();
|
Selection.selectionChanged += () => s_SerializedObject = CreateSerializeObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
//################################
|
//################################
|
||||||
|
@ -147,64 +149,71 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
base.OnEnable();
|
base.OnEnable();
|
||||||
|
|
||||||
m_Maskable = serializedObject.FindProperty("m_Maskable");
|
_maskable = serializedObject.FindProperty("m_Maskable");
|
||||||
m_Scale3D = serializedObject.FindProperty("m_Scale3D");
|
_scale3D = serializedObject.FindProperty("m_Scale3D");
|
||||||
m_AnimatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
|
_animatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
|
||||||
m_MeshSharing = serializedObject.FindProperty("m_MeshSharing");
|
_meshSharing = serializedObject.FindProperty("m_MeshSharing");
|
||||||
m_GroupId = serializedObject.FindProperty("m_GroupId");
|
_groupId = serializedObject.FindProperty("m_GroupId");
|
||||||
m_GroupMaxId = serializedObject.FindProperty("m_GroupMaxId");
|
_groupMaxId = serializedObject.FindProperty("m_GroupMaxId");
|
||||||
m_AbsoluteMode = serializedObject.FindProperty("m_AbsoluteMode");
|
_absoluteMode = serializedObject.FindProperty("m_AbsoluteMode");
|
||||||
m_IgnoreCanvasScaler = serializedObject.FindProperty("m_IgnoreCanvasScaler");
|
_ignoreCanvasScaler = serializedObject.FindProperty("m_IgnoreCanvasScaler");
|
||||||
|
|
||||||
var sp = serializedObject.FindProperty("m_Particles");
|
var sp = serializedObject.FindProperty("m_Particles");
|
||||||
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true);
|
_ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true)
|
||||||
_ro.elementHeight = (EditorGUIUtility.singleLineHeight * 3) + 4;
|
|
||||||
_ro.elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2);
|
|
||||||
_ro.drawElementCallback = (rect, index, _, __) =>
|
|
||||||
{
|
{
|
||||||
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
|
elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4,
|
||||||
rect.y += 1;
|
elementHeightCallback = _ => 3 * (EditorGUIUtility.singleLineHeight + 2),
|
||||||
rect.height = EditorGUIUtility.singleLineHeight;
|
drawElementCallback = (rect, index, _, __) =>
|
||||||
var p = sp.GetArrayElementAtIndex(index);
|
|
||||||
EditorGUI.ObjectField(rect, p, GUIContent.none);
|
|
||||||
rect.x += 15;
|
|
||||||
rect.width -= 15;
|
|
||||||
var ps = p.objectReferenceValue as ParticleSystem;
|
|
||||||
var materials = ps
|
|
||||||
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials")
|
|
||||||
: null;
|
|
||||||
rect.y += rect.height + 1;
|
|
||||||
MaterialField(rect, s_ContentMaterial, materials, 0);
|
|
||||||
rect.y += rect.height + 1;
|
|
||||||
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
|
|
||||||
EditorGUI.EndDisabledGroup();
|
|
||||||
if (materials != null && materials.serializedObject.hasModifiedProperties)
|
|
||||||
{
|
{
|
||||||
materials.serializedObject.ApplyModifiedProperties();
|
EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
|
||||||
}
|
rect.y += 1;
|
||||||
};
|
rect.height = EditorGUIUtility.singleLineHeight;
|
||||||
_ro.drawHeaderCallback = rect =>
|
var p = sp.GetArrayElementAtIndex(index);
|
||||||
{
|
EditorGUI.ObjectField(rect, p, GUIContent.none);
|
||||||
#if !UNITY_2019_3_OR_NEWER
|
rect.x += 15;
|
||||||
rect.y -= 1;
|
rect.width -= 15;
|
||||||
#endif
|
var ps = p.objectReferenceValue as ParticleSystem;
|
||||||
EditorGUI.LabelField(new Rect(rect.x, rect.y, 150, rect.height), s_ContentRenderingOrder);
|
var materials = ps
|
||||||
|
? new SerializedObject(ps.GetComponent<ParticleSystemRenderer>()).FindProperty("m_Materials")
|
||||||
if (GUI.Button(new Rect(rect.width - 35, rect.y, 60, rect.height), s_ContentRefresh, EditorStyles.miniButton))
|
: null;
|
||||||
{
|
rect.y += rect.height + 1;
|
||||||
foreach (UIParticle t in targets)
|
MaterialField(rect, s_ContentMaterial, materials, 0);
|
||||||
|
rect.y += rect.height + 1;
|
||||||
|
MaterialField(rect, s_ContentTrailMaterial, materials, 1);
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
if (materials != null && materials.serializedObject.hasModifiedProperties)
|
||||||
{
|
{
|
||||||
t.RefreshParticles();
|
materials.serializedObject.ApplyModifiedProperties();
|
||||||
EditorUtility.SetDirty(t);
|
}
|
||||||
|
},
|
||||||
|
drawHeaderCallback = rect =>
|
||||||
|
{
|
||||||
|
#if !UNITY_2019_3_OR_NEWER
|
||||||
|
rect.y -= 1;
|
||||||
|
#endif
|
||||||
|
var pos = new Rect(rect.x, rect.y, 150, rect.height);
|
||||||
|
EditorGUI.LabelField(pos, s_ContentRenderingOrder);
|
||||||
|
|
||||||
|
pos = new Rect(rect.width - 35, rect.y, 60, rect.height);
|
||||||
|
if (GUI.Button(pos, s_ContentRefresh, EditorStyles.miniButton))
|
||||||
|
{
|
||||||
|
foreach (var uip in targets.OfType<UIParticle>())
|
||||||
|
{
|
||||||
|
uip.RefreshParticles();
|
||||||
|
EditorUtility.SetDirty(uip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// On select UIParticle, refresh particles.
|
// On select UIParticle, refresh particles.
|
||||||
foreach (UIParticle t in targets)
|
if (!Application.isPlaying)
|
||||||
{
|
{
|
||||||
if (Application.isPlaying || PrefabUtility.GetPrefabAssetType(t) != PrefabAssetType.NotAPrefab) continue;
|
foreach (var uip in targets.OfType<UIParticle>())
|
||||||
t.RefreshParticles(t.particles);
|
{
|
||||||
|
if (PrefabUtility.GetPrefabAssetType(uip) != PrefabAssetType.NotAPrefab) continue;
|
||||||
|
uip.RefreshParticles(uip.particles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,11 +242,11 @@ namespace Coffee.UIExtensions
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
|
|
||||||
// Maskable
|
// Maskable
|
||||||
EditorGUILayout.PropertyField(m_Maskable);
|
EditorGUILayout.PropertyField(_maskable);
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
EditorGUI.BeginDisabledGroup(!m_MeshSharing.hasMultipleDifferentValues && m_MeshSharing.intValue == 4);
|
EditorGUI.BeginDisabledGroup(!_meshSharing.hasMultipleDifferentValues && _meshSharing.intValue == 4);
|
||||||
_xyzMode = DrawFloatOrVector3Field(m_Scale3D, _xyzMode);
|
s_XYZMode = DrawFloatOrVector3Field(_scale3D, s_XYZMode);
|
||||||
EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
|
|
||||||
// AnimatableProperties
|
// AnimatableProperties
|
||||||
|
@ -247,12 +256,11 @@ namespace Coffee.UIExtensions
|
||||||
.Where(x => x)
|
.Where(x => x)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
// Animated properties
|
AnimatablePropertyEditor.Draw(_animatableProperties, mats);
|
||||||
AnimatedPropertiesEditor.DrawAnimatableProperties(m_AnimatableProperties, mats);
|
|
||||||
|
|
||||||
// Mesh sharing
|
// Mesh sharing
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
_showMax = DrawMeshSharing(m_MeshSharing, m_GroupId, m_GroupMaxId, _showMax);
|
_showMax = DrawMeshSharing(_meshSharing, _groupId, _groupMaxId, _showMax);
|
||||||
if (EditorGUI.EndChangeCheck())
|
if (EditorGUI.EndChangeCheck())
|
||||||
{
|
{
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
@ -263,10 +271,10 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Absolute Mode
|
// Absolute Mode
|
||||||
EditorGUILayout.PropertyField(m_AbsoluteMode);
|
EditorGUILayout.PropertyField(_absoluteMode);
|
||||||
|
|
||||||
// Auto Scaling
|
// Auto Scaling
|
||||||
DrawInversedToggle(m_IgnoreCanvasScaler, s_ContentAutoScaling, () =>
|
DrawInversedToggle(_ignoreCanvasScaler, s_ContentAutoScaling, () =>
|
||||||
{
|
{
|
||||||
foreach (var uip in targets.OfType<UIParticle>())
|
foreach (var uip in targets.OfType<UIParticle>())
|
||||||
{
|
{
|
||||||
|
@ -292,6 +300,7 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the shader support UI masks?
|
// Does the shader support UI masks?
|
||||||
|
|
||||||
if (current.maskable && current.GetComponentInParent<Mask>())
|
if (current.maskable && current.GetComponentInParent<Mask>())
|
||||||
{
|
{
|
||||||
foreach (var mat in current.materials)
|
foreach (var mat in current.materials)
|
||||||
|
@ -304,15 +313,19 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
if (mat.HasProperty(propName)) continue;
|
if (mat.HasProperty(propName)) continue;
|
||||||
|
|
||||||
EditorGUILayout.HelpBox(string.Format("Shader '{0}' doesn't have '{1}' property. This graphic cannot be masked.", shader.name, propName), MessageType.Warning);
|
EditorGUILayout.HelpBox(
|
||||||
|
$"Shader '{shader.name}' doesn't have '{propName}' property. This graphic cannot be masked.",
|
||||||
|
MessageType.Warning);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_Shaders.Clear();
|
s_Shaders.Clear();
|
||||||
|
|
||||||
// UIParticle for trail should be removed.
|
// UIParticle for trail should be removed.
|
||||||
if (FixButton(current.m_IsTrail, "This UIParticle component should be removed. The UIParticle for trails is no longer needed."))
|
var label = "This UIParticle component should be removed. The UIParticle for trails is no longer needed.";
|
||||||
|
if (FixButton(current.m_IsTrail, label))
|
||||||
{
|
{
|
||||||
DestroyUIParticle(current);
|
DestroyUIParticle(current);
|
||||||
}
|
}
|
||||||
|
@ -328,7 +341,9 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
var so = new SerializedObject(allPsRenderers);
|
var so = new SerializedObject(allPsRenderers);
|
||||||
var sp = so.FindProperty("m_ApplyActiveColorSpace");
|
var sp = so.FindProperty("m_ApplyActiveColorSpace");
|
||||||
if (FixButton(sp.boolValue || sp.hasMultipleDifferentValues, "When using linear color space, the particle colors are not output correctly.\nTo fix, set 'Apply Active Color Space' in renderer module to false."))
|
label = "When using linear color space, the particle colors are not output correctly.\n" +
|
||||||
|
"To fix, set 'Apply Active Color Space' in renderer module to false.";
|
||||||
|
if (FixButton(sp.boolValue || sp.hasMultipleDifferentValues, label))
|
||||||
{
|
{
|
||||||
sp.boolValue = false;
|
sp.boolValue = false;
|
||||||
so.ApplyModifiedProperties();
|
so.ApplyModifiedProperties();
|
||||||
|
@ -343,8 +358,13 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
if (2 < s_Streams.Select(GetUsedComponentCount).Sum())
|
if (2 < s_Streams.Select(GetUsedComponentCount).Sum())
|
||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox(string.Format("ParticleSystem '{0}' uses 'TEXCOORD*.zw' components as custom vertex stream.\nUIParticle does not support it (See README.md).", psr.name), MessageType.Warning);
|
EditorGUILayout.HelpBox(
|
||||||
|
$"ParticleSystem '{psr.name}' uses 'TEXCOORD*.zw' components as custom vertex stream.\n" +
|
||||||
|
"UIParticle does not support it (See README.md).",
|
||||||
|
MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_Streams.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,10 +424,12 @@ namespace Coffee.UIExtensions
|
||||||
case ParticleSystemVertexStream.Custom2XYZW:
|
case ParticleSystemVertexStream.Custom2XYZW:
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool DrawMeshSharing(SerializedProperty spMeshSharing, SerializedProperty spGroupId, SerializedProperty spGroupMaxId, bool showMax)
|
private static bool DrawMeshSharing(SerializedProperty spMeshSharing, SerializedProperty spGroupId,
|
||||||
|
SerializedProperty spGroupMaxId, bool showMax)
|
||||||
{
|
{
|
||||||
showMax |= spGroupId.intValue != spGroupMaxId.intValue ||
|
showMax |= spGroupId.intValue != spGroupMaxId.intValue ||
|
||||||
spGroupId.hasMultipleDifferentValues ||
|
spGroupId.hasMultipleDifferentValues ||
|
||||||
|
@ -419,7 +441,10 @@ namespace Coffee.UIExtensions
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
showMax = GUILayout.Toggle(showMax, s_ContentRandom, EditorStyles.miniButton, GUILayout.Width(60));
|
showMax = GUILayout.Toggle(showMax, s_ContentRandom, EditorStyles.miniButton, GUILayout.Width(60));
|
||||||
if (EditorGUI.EndChangeCheck() && !showMax)
|
if (EditorGUI.EndChangeCheck() && !showMax)
|
||||||
|
{
|
||||||
spGroupMaxId.intValue = spGroupId.intValue;
|
spGroupMaxId.intValue = spGroupId.intValue;
|
||||||
|
}
|
||||||
|
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
EditorGUI.BeginDisabledGroup(spMeshSharing.intValue == 0);
|
EditorGUI.BeginDisabledGroup(spMeshSharing.intValue == 0);
|
||||||
|
@ -432,23 +457,25 @@ namespace Coffee.UIExtensions
|
||||||
else if (spMeshSharing.intValue == 1 || spMeshSharing.intValue == 4)
|
else if (spMeshSharing.intValue == 1 || spMeshSharing.intValue == 4)
|
||||||
{
|
{
|
||||||
EditorGUI.BeginDisabledGroup(true);
|
EditorGUI.BeginDisabledGroup(true);
|
||||||
EditorGUILayout.ObjectField("Primary", UIParticleUpdater.GetPrimary(spGroupId.intValue), typeof(UIParticle), false);
|
var obj = UIParticleUpdater.GetPrimary(spGroupId.intValue);
|
||||||
|
EditorGUILayout.ObjectField("Primary", obj, typeof(UIParticle), false);
|
||||||
EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUI.indentLevel--;
|
EditorGUI.indentLevel--;
|
||||||
EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
|
|
||||||
return showMax;
|
return showMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawInversedToggle(SerializedProperty inversedProperty, GUIContent label, Action onChanged)
|
private static void DrawInversedToggle(SerializedProperty sp, GUIContent label, Action onChanged)
|
||||||
{
|
{
|
||||||
EditorGUI.showMixedValue = inversedProperty.hasMultipleDifferentValues;
|
EditorGUI.showMixedValue = sp.hasMultipleDifferentValues;
|
||||||
var autoScaling = !inversedProperty.boolValue;
|
var autoScaling = !sp.boolValue;
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
if (autoScaling != EditorGUILayout.Toggle(label, autoScaling))
|
if (autoScaling != EditorGUILayout.Toggle(label, autoScaling))
|
||||||
{
|
{
|
||||||
inversedProperty.boolValue = autoScaling;
|
sp.boolValue = autoScaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EditorGUI.EndChangeCheck())
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
@ -459,7 +486,7 @@ namespace Coffee.UIExtensions
|
||||||
EditorGUI.showMixedValue = false;
|
EditorGUI.showMixedValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WindowFunction(UnityEngine.Object target, SceneView sceneView)
|
private static void WindowFunction(Object target, SceneView sceneView)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -472,48 +499,45 @@ namespace Coffee.UIExtensions
|
||||||
var labelWidth = EditorGUIUtility.labelWidth;
|
var labelWidth = EditorGUIUtility.labelWidth;
|
||||||
EditorGUIUtility.labelWidth = 100;
|
EditorGUIUtility.labelWidth = 100;
|
||||||
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
|
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_Enabled"));
|
||||||
_xyzMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), _xyzMode);
|
s_XYZMode = DrawFloatOrVector3Field(s_SerializedObject.FindProperty("m_Scale3D"), s_XYZMode);
|
||||||
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_AbsoluteMode"));
|
EditorGUILayout.PropertyField(s_SerializedObject.FindProperty("m_AbsoluteMode"));
|
||||||
DrawInversedToggle(s_SerializedObject.FindProperty("m_IgnoreCanvasScaler"), s_ContentAutoScaling,
|
DrawInversedToggle(s_SerializedObject.FindProperty("m_IgnoreCanvasScaler"),
|
||||||
|
s_ContentAutoScaling,
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
foreach (var uip in s_SerializedObject.targetObjects.OfType<UIParticle>())
|
s_SerializedObject.targetObjects
|
||||||
{
|
.OfType<UIParticle>()
|
||||||
if (uip && !uip.autoScaling)
|
.Where(x => x && !x.autoScaling)
|
||||||
{
|
.ToList()
|
||||||
uip.transform.localScale = Vector3.one;
|
.ForEach(x => x.transform.localScale = Vector3.one);
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
EditorGUIUtility.labelWidth = labelWidth;
|
EditorGUIUtility.labelWidth = labelWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_SerializedObject.ApplyModifiedProperties();
|
s_SerializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
|
private void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false)
|
||||||
{
|
{
|
||||||
if (!p || ignoreCurrent && target == p) return;
|
if (!p || (ignoreCurrent && target == p)) return;
|
||||||
|
|
||||||
var cr = p.canvasRenderer;
|
var cr = p.canvasRenderer;
|
||||||
DestroyImmediate(p);
|
DestroyImmediate(p);
|
||||||
DestroyImmediate(cr);
|
DestroyImmediate(cr);
|
||||||
|
|
||||||
#if UNITY_2021_2_OR_NEWER
|
|
||||||
var stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
|
|
||||||
#elif UNITY_2018_3_OR_NEWER
|
|
||||||
var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
|
|
||||||
#endif
|
|
||||||
#if UNITY_2018_3_OR_NEWER
|
#if UNITY_2018_3_OR_NEWER
|
||||||
|
var stage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||||
if (stage != null && stage.scene.isLoaded)
|
if (stage != null && stage.scene.isLoaded)
|
||||||
{
|
{
|
||||||
#if UNITY_2020_1_OR_NEWER
|
#if UNITY_2020_1_OR_NEWER
|
||||||
string prefabAssetPath = stage.assetPath;
|
string prefabAssetPath = stage.assetPath;
|
||||||
#else
|
#else
|
||||||
string prefabAssetPath = stage.prefabAssetPath;
|
var prefabAssetPath = stage.prefabAssetPath;
|
||||||
#endif
|
#endif
|
||||||
PrefabUtility.SaveAsPrefabAsset(stage.prefabContentsRoot, prefabAssetPath);
|
PrefabUtility.SaveAsPrefabAsset(stage.prefabContentsRoot, prefabAssetPath);
|
||||||
}
|
}
|
||||||
|
@ -562,7 +586,10 @@ namespace Coffee.UIExtensions
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
showXyz = GUILayout.Toggle(showXyz, s_Content3D, EditorStyles.miniButton, GUILayout.Width(30));
|
showXyz = GUILayout.Toggle(showXyz, s_Content3D, EditorStyles.miniButton, GUILayout.Width(30));
|
||||||
if (EditorGUI.EndChangeCheck() && !showXyz)
|
if (EditorGUI.EndChangeCheck() && !showXyz)
|
||||||
|
{
|
||||||
z.floatValue = y.floatValue = x.floatValue;
|
z.floatValue = y.floatValue = x.floatValue;
|
||||||
|
}
|
||||||
|
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
return showXyz;
|
return showXyz;
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Coffee.UIParticleExtensions
|
||||||
public static Material Add(Material baseMat, Texture texture, int id)
|
public static Material Add(Material baseMat, Texture texture, int id)
|
||||||
{
|
{
|
||||||
MatEntry e;
|
MatEntry e;
|
||||||
for (var i = 0; i < s_Entries.Count; ++i)
|
for (var i = 0; i < s_Entries.Count; i++)
|
||||||
{
|
{
|
||||||
e = s_Entries[i];
|
e = s_Entries[i];
|
||||||
if (e.baseMat != baseMat || e.texture != texture || e.id != id) continue;
|
if (e.baseMat != baseMat || e.texture != texture || e.id != id) continue;
|
||||||
|
@ -18,15 +18,19 @@ namespace Coffee.UIParticleExtensions
|
||||||
return e.customMat;
|
return e.customMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = new MatEntry();
|
e = new MatEntry
|
||||||
e.count = 1;
|
{
|
||||||
e.baseMat = baseMat;
|
count = 1,
|
||||||
e.texture = texture;
|
baseMat = baseMat,
|
||||||
e.id = id;
|
texture = texture,
|
||||||
e.customMat = new Material(baseMat);
|
id = id,
|
||||||
e.customMat.hideFlags = HideFlags.HideAndDontSave;
|
customMat = new Material(baseMat)
|
||||||
if (texture)
|
{
|
||||||
e.customMat.mainTexture = texture;
|
name = $"{baseMat.name}_{id}",
|
||||||
|
hideFlags = HideFlags.HideAndDontSave,
|
||||||
|
mainTexture = texture ? texture : null
|
||||||
|
}
|
||||||
|
};
|
||||||
s_Entries.Add(e);
|
s_Entries.Add(e);
|
||||||
//Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count, baseMat, texture, id);
|
//Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count, baseMat, texture, id);
|
||||||
return e.customMat;
|
return e.customMat;
|
||||||
|
@ -43,7 +47,8 @@ namespace Coffee.UIParticleExtensions
|
||||||
if (--e.count == 0)
|
if (--e.count == 0)
|
||||||
{
|
{
|
||||||
//Debug.LogFormat(">>>> ModifiedMaterial.Remove -> count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
|
//Debug.LogFormat(">>>> ModifiedMaterial.Remove -> count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
|
||||||
DestroyImmediate(e.customMat);
|
Misc.DestroyImmediate(e.customMat);
|
||||||
|
e.customMat = null;
|
||||||
e.baseMat = null;
|
e.baseMat = null;
|
||||||
e.texture = null;
|
e.texture = null;
|
||||||
s_Entries.RemoveAt(i);
|
s_Entries.RemoveAt(i);
|
||||||
|
@ -53,22 +58,13 @@ namespace Coffee.UIParticleExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DestroyImmediate(Object obj)
|
|
||||||
{
|
|
||||||
if (!obj) return;
|
|
||||||
if (Application.isEditor)
|
|
||||||
Object.DestroyImmediate(obj);
|
|
||||||
else
|
|
||||||
Object.Destroy(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MatEntry
|
private class MatEntry
|
||||||
{
|
{
|
||||||
public Material baseMat;
|
public Material baseMat;
|
||||||
public Material customMat;
|
|
||||||
public int count;
|
public int count;
|
||||||
public Texture texture;
|
public Material customMat;
|
||||||
public int id;
|
public int id;
|
||||||
|
public Texture texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define SERIALIZE_FIELD_MASKABLE
|
#define SERIALIZE_FIELD_MASKABLE
|
||||||
#endif
|
#endif
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Coffee.UIParticleExtensions;
|
using Coffee.UIParticleExtensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -28,16 +27,19 @@ namespace Coffee.UIExtensions
|
||||||
Auto,
|
Auto,
|
||||||
Primary,
|
Primary,
|
||||||
PrimarySimulator,
|
PrimarySimulator,
|
||||||
Replica,
|
Replica
|
||||||
}
|
}
|
||||||
|
|
||||||
[HideInInspector][SerializeField] internal bool m_IsTrail = false;
|
[HideInInspector]
|
||||||
|
[SerializeField]
|
||||||
|
internal bool m_IsTrail;
|
||||||
|
|
||||||
[Tooltip("Particle effect scale")]
|
[Tooltip("Particle effect scale")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
|
private Vector3 m_Scale3D = new Vector3(10, 10, 10);
|
||||||
|
|
||||||
[Tooltip("Animatable material properties. If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
[Tooltip("Animatable material properties.\n" +
|
||||||
|
"If you want to change the material properties of the ParticleSystem in Animation, enable it.")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
|
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
|
||||||
|
|
||||||
|
@ -45,40 +47,49 @@ namespace Coffee.UIExtensions
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
||||||
|
|
||||||
[Tooltip("Mesh sharing.None: disable mesh sharing.\nAuto: automatically select Primary/Replica.\nPrimary: provides particle simulation results to the same group.\nPrimary Simulator: Primary, but do not render the particle (simulation only).\nReplica: render simulation results provided by the primary.")]
|
[Tooltip("Mesh sharing.\n" +
|
||||||
|
"None: disable mesh sharing.\n" +
|
||||||
|
"Auto: automatically select Primary/Replica.\n" +
|
||||||
|
"Primary: provides particle simulation results to the same group.\n" +
|
||||||
|
"Primary Simulator: Primary, but do not render the particle (simulation only).\n" +
|
||||||
|
"Replica: render simulation results provided by the primary.")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private MeshSharing m_MeshSharing = MeshSharing.None;
|
private MeshSharing m_MeshSharing = MeshSharing.None;
|
||||||
|
|
||||||
[Tooltip("Mesh sharing group ID. If non-zero is specified, particle simulation results are shared within the group.")]
|
[Tooltip("Mesh sharing group ID.\n" +
|
||||||
|
"If non-zero is specified, particle simulation results are shared within the group.")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private int m_GroupId = 0;
|
private int m_GroupId;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private int m_GroupMaxId = 0;
|
private int m_GroupMaxId;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("The particles will be emitted at the ParticleSystem position.\nMove the UIParticle/ParticleSystem to move the particle.")]
|
[Tooltip("Particle position mode.\n" +
|
||||||
|
"Absolute Mode: The particles will be emitted from the ParticleSystem position.\n" +
|
||||||
|
" Move the UIParticle or ParticleSystem to move the particle.\n" +
|
||||||
|
"Relative Mode: The particles will be emitted from the scaled ParticleSystem position.\n" +
|
||||||
|
" Move the UIParticle to move the particle.")]
|
||||||
private bool m_AbsoluteMode = false;
|
private bool m_AbsoluteMode = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This field uses the inverted value as "AutoScaling".
|
/// This field uses the inverted value as "AutoScaling".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeField]
|
|
||||||
[FormerlySerializedAs("m_IgnoreParent")]
|
[FormerlySerializedAs("m_IgnoreParent")]
|
||||||
private bool m_IgnoreCanvasScaler = false;
|
[SerializeField]
|
||||||
|
private bool m_IgnoreCanvasScaler;
|
||||||
private List<UIParticleRenderer> m_Renderers = new List<UIParticleRenderer>();
|
|
||||||
|
|
||||||
#if !SERIALIZE_FIELD_MASKABLE
|
#if !SERIALIZE_FIELD_MASKABLE
|
||||||
[SerializeField] private bool m_Maskable = true;
|
[SerializeField]
|
||||||
|
private bool m_Maskable = true;
|
||||||
#endif
|
#endif
|
||||||
|
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
|
||||||
private DrivenRectTransformTracker _tracker;
|
|
||||||
private Camera _orthoCamera;
|
|
||||||
private int _groupId;
|
private int _groupId;
|
||||||
|
private Camera _orthoCamera;
|
||||||
|
private DrivenRectTransformTracker _tracker;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should this graphic be considered a target for raycasting?
|
/// Should this graphic be considered a target for ray-casting?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool raycastTarget
|
public override bool raycastTarget
|
||||||
{
|
{
|
||||||
|
@ -87,7 +98,8 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mesh sharing.None: disable mesh sharing.
|
/// Mesh sharing.
|
||||||
|
/// None: disable mesh sharing.
|
||||||
/// Auto: automatically select Primary/Replica.
|
/// Auto: automatically select Primary/Replica.
|
||||||
/// Primary: provides particle simulation results to the same group.
|
/// Primary: provides particle simulation results to the same group.
|
||||||
/// Primary Simulator: Primary, but do not render the particle (simulation only).
|
/// Primary Simulator: Primary, but do not render the particle (simulation only).
|
||||||
|
@ -100,7 +112,8 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mesh sharing group ID. If non-zero is specified, particle simulation results are shared within the group.
|
/// Mesh sharing group ID.
|
||||||
|
/// If non-zero is specified, particle simulation results are shared within the group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int groupId
|
public int groupId
|
||||||
{
|
{
|
||||||
|
@ -110,7 +123,9 @@ namespace Coffee.UIExtensions
|
||||||
if (m_GroupId == value) return;
|
if (m_GroupId == value) return;
|
||||||
m_GroupId = value;
|
m_GroupId = value;
|
||||||
if (m_GroupId != m_GroupMaxId)
|
if (m_GroupId != m_GroupMaxId)
|
||||||
|
{
|
||||||
ResetGroupId();
|
ResetGroupId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +141,11 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Absolute particle position mode.
|
/// Particle position mode.
|
||||||
/// The particles will be emitted at the ParticleSystem position.
|
/// Absolute Mode: The particles will be emitted from the ParticleSystem position.
|
||||||
/// Move the UIParticle/ParticleSystem to move the particle.
|
/// Move the UIParticle or ParticleSystem to move the particle.
|
||||||
|
/// Relative Mode: The particles will be emitted from the scaled ParticleSystem position.
|
||||||
|
/// Move the UIParticle to move the particle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool absoluteMode
|
public bool absoluteMode
|
||||||
{
|
{
|
||||||
|
@ -136,6 +153,11 @@ namespace Coffee.UIExtensions
|
||||||
set { m_AbsoluteMode = value; }
|
set { m_AbsoluteMode = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transform.lossyScale (=world scale) is automatically set to (1, 1, 1).
|
||||||
|
/// It prevents the root-Canvas scale from affecting the hierarchy-scaled ParticleSystem.
|
||||||
|
/// Note: This option works in reverse of ’IgnoreCanvasScaler’ option in v3.x.
|
||||||
|
/// </summary>
|
||||||
public bool autoScaling
|
public bool autoScaling
|
||||||
{
|
{
|
||||||
get { return !m_IgnoreCanvasScaler; }
|
get { return !m_IgnoreCanvasScaler; }
|
||||||
|
@ -154,17 +176,33 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
internal bool isPrimary
|
internal bool isPrimary
|
||||||
{
|
{
|
||||||
get { return m_MeshSharing == MeshSharing.Primary || m_MeshSharing == MeshSharing.PrimarySimulator; }
|
get
|
||||||
|
{
|
||||||
|
return m_MeshSharing == MeshSharing.Primary
|
||||||
|
|| m_MeshSharing == MeshSharing.PrimarySimulator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool canSimulate
|
internal bool canSimulate
|
||||||
{
|
{
|
||||||
get { return m_MeshSharing == MeshSharing.None || m_MeshSharing == MeshSharing.Auto || m_MeshSharing == MeshSharing.Primary || m_MeshSharing == MeshSharing.PrimarySimulator; }
|
get
|
||||||
|
{
|
||||||
|
return m_MeshSharing == MeshSharing.None
|
||||||
|
|| m_MeshSharing == MeshSharing.Auto
|
||||||
|
|| m_MeshSharing == MeshSharing.Primary
|
||||||
|
|| m_MeshSharing == MeshSharing.PrimarySimulator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool canRender
|
internal bool canRender
|
||||||
{
|
{
|
||||||
get { return m_MeshSharing == MeshSharing.None || m_MeshSharing == MeshSharing.Auto || m_MeshSharing == MeshSharing.Primary || m_MeshSharing == MeshSharing.Replica; }
|
get
|
||||||
|
{
|
||||||
|
return m_MeshSharing == MeshSharing.None
|
||||||
|
|| m_MeshSharing == MeshSharing.Auto
|
||||||
|
|| m_MeshSharing == MeshSharing.Primary
|
||||||
|
|| m_MeshSharing == MeshSharing.Replica;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -197,12 +235,12 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
for (var i = 0; i < m_Renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (!m_Renderers[i] || !m_Renderers[i].material) continue;
|
var r = _renderers[i];
|
||||||
yield return m_Renderers[i].material;
|
if (!r || !r.material) continue;
|
||||||
|
yield return r.material;
|
||||||
}
|
}
|
||||||
yield break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,10 +252,60 @@ namespace Coffee.UIExtensions
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Paused.
|
/// Paused.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool isPaused { get; internal set; }
|
public bool isPaused { get; private set; }
|
||||||
|
|
||||||
public Vector3 parentScale { get; private set; }
|
public Vector3 parentScale { get; private set; }
|
||||||
|
|
||||||
|
protected override void OnEnable()
|
||||||
|
{
|
||||||
|
#if !SERIALIZE_FIELD_MASKABLE
|
||||||
|
maskable = m_Maskable;
|
||||||
|
#endif
|
||||||
|
ResetGroupId();
|
||||||
|
UpdateTracker();
|
||||||
|
UIParticleUpdater.Register(this);
|
||||||
|
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||||
|
|
||||||
|
if (0 < particles.Count)
|
||||||
|
{
|
||||||
|
RefreshParticles(particles);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RefreshParticles();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This function is called when the behaviour becomes disabled.
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnDisable()
|
||||||
|
{
|
||||||
|
UpdateTracker();
|
||||||
|
UIParticleUpdater.Unregister(this);
|
||||||
|
_renderers.ForEach(r => r.Reset());
|
||||||
|
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||||
|
|
||||||
|
base.OnDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback for when properties have been changed by animation.
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnDidApplyAnimationProperties()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
protected override void OnValidate()
|
||||||
|
{
|
||||||
|
base.OnValidate();
|
||||||
|
UpdateTracker();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public void Play()
|
public void Play()
|
||||||
{
|
{
|
||||||
particles.Exec(p => p.Simulate(0, false, true));
|
particles.Exec(p => p.Simulate(0, false, true));
|
||||||
|
@ -240,7 +328,7 @@ namespace Coffee.UIExtensions
|
||||||
particles.Exec(p => p.Stop());
|
particles.Exec(p => p.Stop());
|
||||||
isPaused = true;
|
isPaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartEmission()
|
public void StartEmission()
|
||||||
{
|
{
|
||||||
particles.Exec(p =>
|
particles.Exec(p =>
|
||||||
|
@ -249,7 +337,7 @@ namespace Coffee.UIExtensions
|
||||||
emission.enabled = true;
|
emission.enabled = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopEmission()
|
public void StopEmission()
|
||||||
{
|
{
|
||||||
particles.Exec(p =>
|
particles.Exec(p =>
|
||||||
|
@ -278,14 +366,10 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
var go = child.gameObject;
|
var go = child.gameObject;
|
||||||
go.SetActive(false);
|
go.SetActive(false);
|
||||||
if (!destroyOldParticles) continue;
|
if (destroyOldParticles)
|
||||||
|
{
|
||||||
#if UNITY_EDITOR
|
Misc.Destroy(go);
|
||||||
if (!Application.isPlaying)
|
}
|
||||||
DestroyImmediate(go);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
Destroy(go);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tr = instance.transform;
|
var tr = instance.transform;
|
||||||
|
@ -313,11 +397,14 @@ namespace Coffee.UIExtensions
|
||||||
root.GetComponentsInChildren(particles);
|
root.GetComponentsInChildren(particles);
|
||||||
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>() != this);
|
particles.RemoveAll(x => x.GetComponentInParent<UIParticle>() != this);
|
||||||
|
|
||||||
foreach (var ps in particles)
|
for (var i = 0; i < particles.Count; i++)
|
||||||
{
|
{
|
||||||
|
var ps = particles[i];
|
||||||
var tsa = ps.textureSheetAnimation;
|
var tsa = ps.textureSheetAnimation;
|
||||||
if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
|
if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
|
||||||
|
{
|
||||||
tsa.uvChannelMask = UVChannelFlags.UV0;
|
tsa.uvChannelMask = UVChannelFlags.UV0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshParticles(particles);
|
RefreshParticles(particles);
|
||||||
|
@ -326,30 +413,31 @@ namespace Coffee.UIExtensions
|
||||||
public void RefreshParticles(List<ParticleSystem> particles)
|
public void RefreshParticles(List<ParticleSystem> particles)
|
||||||
{
|
{
|
||||||
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
||||||
m_Renderers.Clear();
|
_renderers.Clear();
|
||||||
foreach (Transform child in transform)
|
foreach (Transform child in transform)
|
||||||
{
|
{
|
||||||
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
|
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
|
||||||
|
|
||||||
if (uiParticleRenderer != null)
|
if (uiParticleRenderer != null)
|
||||||
{
|
{
|
||||||
m_Renderers.Add(uiParticleRenderer);
|
_renderers.Add(uiParticleRenderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < m_Renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
m_Renderers[i].Reset(i);
|
_renderers[i].Reset(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
var j = 0;
|
var j = 0;
|
||||||
for (var i = 0; i < particles.Count; i++)
|
for (var i = 0; i < particles.Count; i++)
|
||||||
{
|
{
|
||||||
if (!particles[i]) continue;
|
var ps = particles[i];
|
||||||
GetRenderer(j++).Set(this, particles[i], false);
|
if (!ps) continue;
|
||||||
if (particles[i].trails.enabled)
|
GetRenderer(j++).Set(this, ps, false);
|
||||||
|
if (ps.trails.enabled)
|
||||||
{
|
{
|
||||||
GetRenderer(j++).Set(this, particles[i], true);
|
GetRenderer(j++).Set(this, ps, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,9 +458,10 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
if (!isActiveAndEnabled) return;
|
if (!isActiveAndEnabled) return;
|
||||||
|
|
||||||
foreach (var rend in m_Renderers)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (!rend)
|
var r = _renderers[i];
|
||||||
|
if (!r)
|
||||||
{
|
{
|
||||||
RefreshParticles(particles);
|
RefreshParticles(particles);
|
||||||
break;
|
break;
|
||||||
|
@ -380,67 +469,29 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
var bakeCamera = GetBakeCamera();
|
var bakeCamera = GetBakeCamera();
|
||||||
for (var i = 0; i < m_Renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (!m_Renderers[i]) continue;
|
var r = _renderers[i];
|
||||||
m_Renderers[i].UpdateMesh(bakeCamera);
|
if (!r) continue;
|
||||||
|
r.UpdateMesh(bakeCamera);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateParticleCount()
|
internal void UpdateParticleCount()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < m_Renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (!m_Renderers[i]) continue;
|
var r = _renderers[i];
|
||||||
m_Renderers[i].UpdateParticleCount();
|
if (!r) continue;
|
||||||
|
r.UpdateParticleCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnEnable()
|
|
||||||
{
|
|
||||||
#if !SERIALIZE_FIELD_MASKABLE
|
|
||||||
maskable = m_Maskable;
|
|
||||||
#endif
|
|
||||||
ResetGroupId();
|
|
||||||
UpdateTracker();
|
|
||||||
UIParticleUpdater.Register(this);
|
|
||||||
RegisterDirtyMaterialCallback(UpdateRendererMaterial);
|
|
||||||
|
|
||||||
if (0 < particles.Count)
|
|
||||||
{
|
|
||||||
RefreshParticles(particles);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RefreshParticles();
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnEnable();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ResetGroupId()
|
internal void ResetGroupId()
|
||||||
{
|
{
|
||||||
if (m_GroupId == m_GroupMaxId)
|
_groupId = m_GroupId == m_GroupMaxId
|
||||||
{
|
? m_GroupId
|
||||||
_groupId = m_GroupId;
|
: Random.Range(m_GroupId, m_GroupMaxId + 1);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_groupId = Random.Range(m_GroupId, m_GroupMaxId + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This function is called when the behaviour becomes disabled.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnDisable()
|
|
||||||
{
|
|
||||||
UpdateTracker();
|
|
||||||
UIParticleUpdater.Unregister(this);
|
|
||||||
m_Renderers.ForEach(r => r.Reset());
|
|
||||||
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
|
||||||
|
|
||||||
base.OnDisable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateMaterial()
|
protected override void UpdateMaterial()
|
||||||
|
@ -454,43 +505,42 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Callback for when properties have been changed by animation.
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnDidApplyAnimationProperties()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateRendererMaterial()
|
private void UpdateRendererMaterial()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < m_Renderers.Count; i++)
|
for (var i = 0; i < _renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (!m_Renderers[i]) continue;
|
var r = _renderers[i];
|
||||||
m_Renderers[i].maskable = maskable;
|
if (!r) continue;
|
||||||
m_Renderers[i].SetMaterialDirty();
|
r.maskable = maskable;
|
||||||
|
r.SetMaterialDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal UIParticleRenderer GetRenderer(int index)
|
internal UIParticleRenderer GetRenderer(int index)
|
||||||
{
|
{
|
||||||
if (m_Renderers.Count <= index)
|
if (_renderers.Count <= index)
|
||||||
{
|
{
|
||||||
m_Renderers.Add(UIParticleRenderer.AddRenderer(this, index));
|
_renderers.Add(UIParticleRenderer.AddRenderer(this, index));
|
||||||
}
|
}
|
||||||
if (!m_Renderers[index])
|
|
||||||
|
if (!_renderers[index])
|
||||||
{
|
{
|
||||||
m_Renderers[index] = UIParticleRenderer.AddRenderer(this, index);
|
_renderers[index] = UIParticleRenderer.AddRenderer(this, index);
|
||||||
}
|
}
|
||||||
return m_Renderers[index];
|
|
||||||
|
return _renderers[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Camera GetBakeCamera()
|
private Camera GetBakeCamera()
|
||||||
{
|
{
|
||||||
if (!canvas) return Camera.main;
|
if (!canvas) return Camera.main;
|
||||||
|
|
||||||
// World camera.
|
// Render mode is not ScreenSpaceOverlay, use world camera.
|
||||||
var root = canvas.rootCanvas;
|
var root = canvas.rootCanvas;
|
||||||
if (root.renderMode != RenderMode.ScreenSpaceOverlay) return root.worldCamera ? root.worldCamera : Camera.main;
|
if (root.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||||
|
{
|
||||||
|
return root.worldCamera ? root.worldCamera : Camera.main;
|
||||||
|
}
|
||||||
|
|
||||||
// Create ortho-camera.
|
// Create ortho-camera.
|
||||||
if (!_orthoCamera)
|
if (!_orthoCamera)
|
||||||
|
@ -498,10 +548,7 @@ namespace Coffee.UIExtensions
|
||||||
_orthoCamera = GetComponentInChildren<Camera>();
|
_orthoCamera = GetComponentInChildren<Camera>();
|
||||||
if (!_orthoCamera)
|
if (!_orthoCamera)
|
||||||
{
|
{
|
||||||
var go = new GameObject("UIParticleOverlayCamera")
|
var go = new GameObject("UIParticleOverlayCamera") { hideFlags = HideFlags.DontSave };
|
||||||
{
|
|
||||||
hideFlags = HideFlags.DontSave,
|
|
||||||
};
|
|
||||||
go.SetActive(false);
|
go.SetActive(false);
|
||||||
go.transform.SetParent(transform, false);
|
go.transform.SetParent(transform, false);
|
||||||
_orthoCamera = go.AddComponent<Camera>();
|
_orthoCamera = go.AddComponent<Camera>();
|
||||||
|
@ -509,7 +556,7 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
var size = ((RectTransform)root.transform).rect.size;
|
var size = ((RectTransform)root.transform).rect.size;
|
||||||
_orthoCamera.orthographicSize = Mathf.Max(size.x, size.y) * root.scaleFactor;
|
_orthoCamera.orthographicSize = Mathf.Max(size.x, size.y) * root.scaleFactor;
|
||||||
_orthoCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
_orthoCamera.transform.SetPositionAndRotation(new Vector3(0, 0, -1000), Quaternion.identity);
|
||||||
|
@ -530,13 +577,5 @@ namespace Coffee.UIExtensions
|
||||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
protected override void OnValidate()
|
|
||||||
{
|
|
||||||
base.OnValidate();
|
|
||||||
UpdateTracker();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
using UnityEngine;
|
using System;
|
||||||
using Coffee.UIParticleExtensions;
|
using Coffee.UIParticleExtensions;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
|
@ -12,13 +12,13 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
Linear,
|
Linear,
|
||||||
Smooth,
|
Smooth,
|
||||||
Sphere,
|
Sphere
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UpdateMode
|
public enum UpdateMode
|
||||||
{
|
{
|
||||||
Normal,
|
Normal,
|
||||||
UnscaledTime,
|
UnscaledTime
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
@ -30,7 +30,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
[Range(0f, 0.95f)]
|
[Range(0f, 0.95f)]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float m_DelayRate = 0;
|
private float m_DelayRate;
|
||||||
|
|
||||||
[Range(0.001f, 100f)]
|
[Range(0.001f, 100f)]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
@ -45,84 +45,51 @@ namespace Coffee.UIExtensions
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private UnityEvent m_OnAttracted;
|
private UnityEvent m_OnAttracted;
|
||||||
|
|
||||||
|
private UIParticle _uiParticle;
|
||||||
|
|
||||||
public float destinationRadius
|
public float destinationRadius
|
||||||
{
|
{
|
||||||
get
|
get { return m_DestinationRadius; }
|
||||||
{
|
set { m_DestinationRadius = Mathf.Clamp(value, 0.1f, 10f); }
|
||||||
return m_DestinationRadius;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_DestinationRadius = Mathf.Clamp(value, 0.1f, 10f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float delay
|
public float delay
|
||||||
{
|
{
|
||||||
get
|
get { return m_DelayRate; }
|
||||||
{
|
set { m_DelayRate = value; }
|
||||||
return m_DelayRate;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_DelayRate = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float maxSpeed
|
public float maxSpeed
|
||||||
{
|
{
|
||||||
get
|
get { return m_MaxSpeed; }
|
||||||
{
|
set { m_MaxSpeed = value; }
|
||||||
return m_MaxSpeed;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_MaxSpeed = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Movement movement
|
public Movement movement
|
||||||
{
|
{
|
||||||
get
|
get { return m_Movement; }
|
||||||
{
|
set { m_Movement = value; }
|
||||||
return m_Movement;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_Movement = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UpdateMode updateMode
|
public UpdateMode updateMode
|
||||||
{
|
{
|
||||||
get
|
get { return m_UpdateMode; }
|
||||||
{
|
set { m_UpdateMode = value; }
|
||||||
return m_UpdateMode;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_UpdateMode = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnityEvent onAttracted
|
public UnityEvent onAttracted
|
||||||
{
|
{
|
||||||
get
|
get { return m_OnAttracted; }
|
||||||
{
|
set { m_OnAttracted = value; }
|
||||||
return m_OnAttracted;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_OnAttracted = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public new ParticleSystem particleSystem
|
||||||
|
#else
|
||||||
public ParticleSystem particleSystem
|
public ParticleSystem particleSystem
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
get
|
get { return m_ParticleSystem; }
|
||||||
{
|
|
||||||
return m_ParticleSystem;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
m_ParticleSystem = value;
|
m_ParticleSystem = value;
|
||||||
|
@ -130,8 +97,6 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UIParticle _uiParticle;
|
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
ApplyParticleSystem();
|
ApplyParticleSystem();
|
||||||
|
@ -207,7 +172,7 @@ namespace Coffee.UIExtensions
|
||||||
var psPos = m_ParticleSystem.transform.position;
|
var psPos = m_ParticleSystem.transform.position;
|
||||||
var attractorPos = transform.position;
|
var attractorPos = transform.position;
|
||||||
var dstPos = attractorPos;
|
var dstPos = attractorPos;
|
||||||
var isLocalSpace = m_ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local;
|
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
|
||||||
|
|
||||||
if (isLocalSpace)
|
if (isLocalSpace)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +216,7 @@ namespace Coffee.UIExtensions
|
||||||
speed *= 60 * Time.unscaledDeltaTime;
|
speed *= 60 * Time.unscaledDeltaTime;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_Movement)
|
switch (m_Movement)
|
||||||
{
|
{
|
||||||
case Movement.Linear:
|
case Movement.Linear:
|
||||||
|
@ -278,6 +244,7 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
Debug.LogError("No particle system attached to particle attractor script", this);
|
Debug.LogError("No particle system attached to particle attractor script", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,4 +255,4 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using UnityEngine;
|
using System;
|
||||||
using UnityEngine.UI;
|
using System.Collections.Generic;
|
||||||
using Coffee.UIParticleExtensions;
|
using Coffee.UIParticleExtensions;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngine.Profiling;
|
using UnityEngine.Profiling;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
using System.Collections.Generic;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
|
@ -13,41 +14,34 @@ namespace Coffee.UIExtensions
|
||||||
[AddComponentMenu("")]
|
[AddComponentMenu("")]
|
||||||
internal class UIParticleRenderer : MaskableGraphic
|
internal class UIParticleRenderer : MaskableGraphic
|
||||||
{
|
{
|
||||||
private static readonly CombineInstance[] s_CombineInstances = new CombineInstance[] { new CombineInstance() };
|
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
|
||||||
private static readonly List<Material> s_Materials = new List<Material>(2);
|
private static readonly List<Material> s_Materials = new List<Material>(2);
|
||||||
private static MaterialPropertyBlock s_Mpb;
|
private static MaterialPropertyBlock s_Mpb;
|
||||||
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
|
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
|
||||||
private static readonly Vector3[] s_Corners = new Vector3[4];
|
private static readonly Vector3[] s_Corners = new Vector3[4];
|
||||||
|
private Material _currentMaterialForRendering;
|
||||||
private ParticleSystemRenderer _renderer;
|
private bool _delay;
|
||||||
private ParticleSystem _particleSystem;
|
|
||||||
private int _prevParticleCount = 0;
|
|
||||||
private UIParticle _parent;
|
|
||||||
private int _index;
|
private int _index;
|
||||||
private bool _isTrail;
|
private bool _isTrail;
|
||||||
private Material _modifiedMaterial;
|
|
||||||
private Vector3 _prevScale;
|
|
||||||
private Vector3 _prevPsPos;
|
|
||||||
private Vector2Int _prevScreenSize;
|
|
||||||
private bool _delay = false;
|
|
||||||
private bool _prewarm = false;
|
|
||||||
private Material _currentMaterialForRendering;
|
|
||||||
private Bounds _lastBounds;
|
private Bounds _lastBounds;
|
||||||
|
private Material _modifiedMaterial;
|
||||||
|
private UIParticle _parent;
|
||||||
|
private ParticleSystem _particleSystem;
|
||||||
|
private int _prevParticleCount;
|
||||||
|
private Vector3 _prevPsPos;
|
||||||
|
private Vector3 _prevScale;
|
||||||
|
private Vector2Int _prevScreenSize;
|
||||||
|
private bool _prewarm;
|
||||||
|
private ParticleSystemRenderer _renderer;
|
||||||
|
|
||||||
public override Texture mainTexture
|
public override Texture mainTexture
|
||||||
{
|
{
|
||||||
get
|
get { return _isTrail ? null : _particleSystem.GetTextureForSprite(); }
|
||||||
{
|
|
||||||
return _isTrail ? null : _particleSystem.GetTextureForSprite();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool raycastTarget
|
public override bool raycastTarget
|
||||||
{
|
{
|
||||||
get
|
get { return false; }
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rect rootCanvasRect
|
private Rect rootCanvasRect
|
||||||
|
@ -62,32 +56,103 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
|
var worldToLocalMatrix = canvas.rootCanvas.transform.worldToLocalMatrix;
|
||||||
for (var i = 0; i < 4; ++i)
|
for (var i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
s_Corners[i] = worldToLocalMatrix.MultiplyPoint(s_Corners[i]);
|
s_Corners[i] = worldToLocalMatrix.MultiplyPoint(s_Corners[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var corner1 = (Vector2) s_Corners[0];
|
|
||||||
var corner2 = (Vector2) s_Corners[0];
|
var corner1 = (Vector2)s_Corners[0];
|
||||||
|
var corner2 = (Vector2)s_Corners[0];
|
||||||
for (var i = 1; i < 4; ++i)
|
for (var i = 1; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if (s_Corners[i].x < corner1.x)
|
if (s_Corners[i].x < corner1.x)
|
||||||
|
{
|
||||||
corner1.x = s_Corners[i].x;
|
corner1.x = s_Corners[i].x;
|
||||||
|
}
|
||||||
else if (s_Corners[i].x > corner2.x)
|
else if (s_Corners[i].x > corner2.x)
|
||||||
|
{
|
||||||
corner2.x = s_Corners[i].x;
|
corner2.x = s_Corners[i].x;
|
||||||
|
}
|
||||||
|
|
||||||
if (s_Corners[i].y < corner1.y)
|
if (s_Corners[i].y < corner1.y)
|
||||||
|
{
|
||||||
corner1.y = s_Corners[i].y;
|
corner1.y = s_Corners[i].y;
|
||||||
|
}
|
||||||
else if (s_Corners[i].y > corner2.y)
|
else if (s_Corners[i].y > corner2.y)
|
||||||
|
{
|
||||||
corner2.y = s_Corners[i].y;
|
corner2.y = s_Corners[i].y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Rect(corner1, corner2 - corner1);
|
return new Rect(corner1, corner2 - corner1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Reset(int index = -1)
|
||||||
|
{
|
||||||
|
if (_renderer)
|
||||||
|
{
|
||||||
|
_renderer.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parent = null;
|
||||||
|
_particleSystem = null;
|
||||||
|
_renderer = null;
|
||||||
|
_prevParticleCount = 0;
|
||||||
|
if (0 <= index)
|
||||||
|
{
|
||||||
|
_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
//_emitter = null;
|
||||||
|
if (this && isActiveAndEnabled)
|
||||||
|
{
|
||||||
|
material = null;
|
||||||
|
workerMesh.Clear();
|
||||||
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
|
_lastBounds = new Bounds();
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModifiedMaterial.Remove(_modifiedMaterial);
|
||||||
|
_modifiedMaterial = null;
|
||||||
|
_currentMaterialForRendering = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnEnable()
|
||||||
|
{
|
||||||
|
base.OnEnable();
|
||||||
|
|
||||||
|
if (!s_CombineInstances[0].mesh)
|
||||||
|
{
|
||||||
|
s_CombineInstances[0].mesh = new Mesh
|
||||||
|
{
|
||||||
|
name = "[UIParticleRenderer] Combine Instance Mesh",
|
||||||
|
hideFlags = HideFlags.HideAndDontSave
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentMaterialForRendering = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDisable()
|
||||||
|
{
|
||||||
|
base.OnDisable();
|
||||||
|
|
||||||
|
ModifiedMaterial.Remove(_modifiedMaterial);
|
||||||
|
_modifiedMaterial = null;
|
||||||
|
_currentMaterialForRendering = null;
|
||||||
|
}
|
||||||
|
|
||||||
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
public static UIParticleRenderer AddRenderer(UIParticle parent, int index)
|
||||||
{
|
{
|
||||||
// Create renderer object.
|
// Create renderer object.
|
||||||
var go = new GameObject("UIParticleRenderer", typeof(UIParticleRenderer))
|
var go = new GameObject("UIParticleRenderer", typeof(UIParticleRenderer))
|
||||||
{
|
{
|
||||||
hideFlags = HideFlags.DontSave,
|
hideFlags = HideFlags.DontSave,
|
||||||
layer = parent.gameObject.layer,
|
layer = parent.gameObject.layer
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set parent.
|
// Set parent.
|
||||||
|
@ -139,45 +204,14 @@ namespace Coffee.UIExtensions
|
||||||
return modifiedMaterial;
|
return modifiedMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset(int index = -1)
|
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail)
|
||||||
{
|
|
||||||
if (_renderer)
|
|
||||||
{
|
|
||||||
_renderer.enabled = true;
|
|
||||||
}
|
|
||||||
_parent = null;
|
|
||||||
_particleSystem = null;
|
|
||||||
_renderer = null;
|
|
||||||
_prevParticleCount = 0;
|
|
||||||
if (0 <= index)
|
|
||||||
{
|
|
||||||
_index = index;
|
|
||||||
}
|
|
||||||
//_emitter = null;
|
|
||||||
if (this && isActiveAndEnabled)
|
|
||||||
{
|
|
||||||
material = null;
|
|
||||||
workerMesh.Clear();
|
|
||||||
canvasRenderer.SetMesh(workerMesh);
|
|
||||||
_lastBounds = new Bounds();
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ModifiedMaterial.Remove(_modifiedMaterial);
|
|
||||||
_modifiedMaterial = null;
|
|
||||||
_currentMaterialForRendering = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Set(UIParticle parent, ParticleSystem particleSystem, bool isTrail)
|
|
||||||
{
|
{
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
maskable = parent.maskable;
|
maskable = parent.maskable;
|
||||||
|
|
||||||
gameObject.layer = parent.gameObject.layer;
|
gameObject.layer = parent.gameObject.layer;
|
||||||
|
|
||||||
_particleSystem = particleSystem;
|
_particleSystem = ps;
|
||||||
_prewarm = _particleSystem.main.prewarm;
|
_prewarm = _particleSystem.main.prewarm;
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
@ -191,7 +225,7 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
|
_renderer = ps.GetComponent<ParticleSystemRenderer>();
|
||||||
_renderer.enabled = false;
|
_renderer.enabled = false;
|
||||||
|
|
||||||
//_emitter = emitter;
|
//_emitter = emitter;
|
||||||
|
@ -202,9 +236,11 @@ namespace Coffee.UIExtensions
|
||||||
s_Materials.Clear();
|
s_Materials.Clear();
|
||||||
|
|
||||||
// Support sprite.
|
// Support sprite.
|
||||||
var tsa = particleSystem.textureSheetAnimation;
|
var tsa = ps.textureSheetAnimation;
|
||||||
if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
|
if (tsa.mode == ParticleSystemAnimationMode.Sprites && tsa.uvChannelMask == 0)
|
||||||
|
{
|
||||||
tsa.uvChannelMask = UVChannelFlags.UV0;
|
tsa.uvChannelMask = UVChannelFlags.UV0;
|
||||||
|
}
|
||||||
|
|
||||||
_prevScale = GetWorldScale();
|
_prevScale = GetWorldScale();
|
||||||
_prevPsPos = _particleSystem.transform.position;
|
_prevPsPos = _particleSystem.transform.position;
|
||||||
|
@ -221,15 +257,17 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
// No particle to render: Clear mesh.
|
// No particle to render: Clear mesh.
|
||||||
if (
|
if (
|
||||||
!isActiveAndEnabled || !_particleSystem || !_parent || !canvasRenderer || !canvas || !bakeCamera
|
!isActiveAndEnabled || !_particleSystem || !_parent
|
||||||
|
|| !canvasRenderer || !canvas || !bakeCamera
|
||||||
|| _parent.meshSharing == UIParticle.MeshSharing.Replica
|
|| _parent.meshSharing == UIParticle.MeshSharing.Replica
|
||||||
|| !transform.lossyScale.GetScaled(_parent.scale3D).IsVisible() // Scale is not visible.
|
|| !transform.lossyScale.GetScaled(_parent.scale3D).IsVisible() // Scale is not visible.
|
||||||
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|
||||||
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
|
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
|
||||||
#if UNITY_2018_3_OR_NEWER
|
#if UNITY_2018_3_OR_NEWER
|
||||||
|| canvasRenderer.GetInheritedAlpha() < 0.01f // #102: Do not bake particle system to mesh when the alpha is zero.
|
|| canvasRenderer.GetInheritedAlpha() <
|
||||||
|
0.01f // #102: Do not bake particle system to mesh when the alpha is zero.
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
|
Profiler.BeginSample("[UIParticleRenderer] Clear Mesh");
|
||||||
workerMesh.Clear();
|
workerMesh.Clear();
|
||||||
|
@ -265,15 +303,20 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the ParticleSystem simulation is complete, stop it.
|
// When the ParticleSystem simulation is complete, stop it.
|
||||||
if (!main.loop && main.duration <= _particleSystem.time && (_particleSystem.IsAlive() || _particleSystem.particleCount == 0))
|
if (!main.loop
|
||||||
|
&& main.duration <= _particleSystem.time
|
||||||
|
&& (_particleSystem.IsAlive() || _particleSystem.particleCount == 0)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
_particleSystem.Stop(false);
|
_particleSystem.Stop(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_prevScale = scale;
|
_prevScale = scale;
|
||||||
_prevPsPos = psPos;
|
_prevPsPos = psPos;
|
||||||
_delay = false;
|
_delay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
// Bake mesh.
|
// Bake mesh.
|
||||||
|
@ -295,7 +338,7 @@ namespace Coffee.UIExtensions
|
||||||
if (65535 <= s_CombineInstances[0].mesh.vertexCount)
|
if (65535 <= s_CombineInstances[0].mesh.vertexCount)
|
||||||
{
|
{
|
||||||
s_CombineInstances[0].mesh.Clear(false);
|
s_CombineInstances[0].mesh.Clear(false);
|
||||||
UnityEngine.Debug.LogErrorFormat(this,
|
Debug.LogErrorFormat(this,
|
||||||
"Too many vertices to render. index={0}, isTrail={1}, vertexCount={2}(>=65535)",
|
"Too many vertices to render. index={0}, isTrail={1}, vertexCount={2}(>=65535)",
|
||||||
_index,
|
_index,
|
||||||
_isTrail,
|
_isTrail,
|
||||||
|
@ -303,6 +346,7 @@ namespace Coffee.UIExtensions
|
||||||
);
|
);
|
||||||
s_CombineInstances[0].mesh.Clear(false);
|
s_CombineInstances[0].mesh.Clear(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
// Combine mesh to transform. ([ParticleSystem local ->] world -> renderer local)
|
// Combine mesh to transform. ([ParticleSystem local ->] world -> renderer local)
|
||||||
|
@ -311,13 +355,19 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
if (_parent.absoluteMode)
|
if (_parent.absoluteMode)
|
||||||
{
|
{
|
||||||
s_CombineInstances[0].transform = canvasRenderer.transform.worldToLocalMatrix * GetWorldMatrix(psPos, scale);
|
s_CombineInstances[0].transform =
|
||||||
|
canvasRenderer.transform.worldToLocalMatrix
|
||||||
|
* GetWorldMatrix(psPos, scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var diff = _particleSystem.transform.position - _parent.transform.position;
|
var diff = _particleSystem.transform.position - _parent.transform.position;
|
||||||
s_CombineInstances[0].transform = canvasRenderer.transform.worldToLocalMatrix * Matrix4x4.Translate(diff.GetScaled(scale - Vector3.one)) * GetWorldMatrix(psPos, scale);
|
s_CombineInstances[0].transform =
|
||||||
|
canvasRenderer.transform.worldToLocalMatrix
|
||||||
|
* Matrix4x4.Translate(diff.GetScaled(scale - Vector3.one))
|
||||||
|
* GetWorldMatrix(psPos, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
workerMesh.CombineMeshes(s_CombineInstances, true, true);
|
workerMesh.CombineMeshes(s_CombineInstances, true, true);
|
||||||
|
|
||||||
workerMesh.RecalculateBounds();
|
workerMesh.RecalculateBounds();
|
||||||
|
@ -331,6 +381,7 @@ namespace Coffee.UIExtensions
|
||||||
workerMesh.bounds = bounds;
|
workerMesh.bounds = bounds;
|
||||||
_lastBounds = bounds;
|
_lastBounds = bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,7 +394,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
// Set mesh to the CanvasRenderer.
|
// Set mesh to the CanvasRenderer.
|
||||||
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
|
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
|
||||||
for (int i = 0; i < s_Renderers.Count; i++)
|
for (var i = 0; i < s_Renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (s_Renderers[i] == this) continue;
|
if (s_Renderers[i] == this) continue;
|
||||||
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
|
||||||
|
@ -354,6 +405,7 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
workerMesh.Clear();
|
workerMesh.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasRenderer.SetMesh(workerMesh);
|
canvasRenderer.SetMesh(workerMesh);
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
|
@ -366,7 +418,8 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
_currentMaterialForRendering = materialForRendering;
|
_currentMaterialForRendering = materialForRendering;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < s_Renderers.Count; i++)
|
|
||||||
|
for (var i = 0; i < s_Renderers.Count; i++)
|
||||||
{
|
{
|
||||||
if (s_Renderers[i] == this) continue;
|
if (s_Renderers[i] == this) continue;
|
||||||
|
|
||||||
|
@ -374,6 +427,7 @@ namespace Coffee.UIExtensions
|
||||||
s_Renderers[i].canvasRenderer.SetMaterial(_currentMaterialForRendering, 0);
|
s_Renderers[i].canvasRenderer.SetMaterial(_currentMaterialForRendering, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
s_Renderers.Clear();
|
s_Renderers.Clear();
|
||||||
|
@ -385,30 +439,6 @@ namespace Coffee.UIExtensions
|
||||||
_prevParticleCount = _particleSystem.particleCount;
|
_prevParticleCount = _particleSystem.particleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnEnable()
|
|
||||||
{
|
|
||||||
base.OnEnable();
|
|
||||||
|
|
||||||
if (!s_CombineInstances[0].mesh)
|
|
||||||
{
|
|
||||||
s_CombineInstances[0].mesh = new Mesh()
|
|
||||||
{
|
|
||||||
name = "[UIParticleRenderer] Combine Instance Mesh",
|
|
||||||
hideFlags = HideFlags.HideAndDontSave,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_currentMaterialForRendering = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDisable()
|
|
||||||
{
|
|
||||||
base.OnDisable();
|
|
||||||
|
|
||||||
ModifiedMaterial.Remove(_modifiedMaterial);
|
|
||||||
_modifiedMaterial = null;
|
|
||||||
_currentMaterialForRendering = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -418,7 +448,9 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
public override void Cull(Rect clipRect, bool validRect)
|
public override void Cull(Rect clipRect, bool validRect)
|
||||||
{
|
{
|
||||||
var cull = _lastBounds.extents == Vector3.zero || !validRect || !clipRect.Overlaps(rootCanvasRect, true);
|
var cull = _lastBounds.extents == Vector3.zero
|
||||||
|
|| !validRect
|
||||||
|
|| !clipRect.Overlaps(rootCanvasRect, true);
|
||||||
if (canvasRenderer.cull == cull) return;
|
if (canvasRenderer.cull == cull) return;
|
||||||
|
|
||||||
canvasRenderer.cull = cull;
|
canvasRenderer.cull = cull;
|
||||||
|
@ -450,8 +482,8 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
case ParticleSystemSimulationSpace.World:
|
case ParticleSystemSimulationSpace.World:
|
||||||
return Matrix4x4.Translate(psPos)
|
return Matrix4x4.Translate(psPos)
|
||||||
* Matrix4x4.Scale(scale)
|
* Matrix4x4.Scale(scale)
|
||||||
* Matrix4x4.Translate(-psPos);
|
* Matrix4x4.Translate(-psPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -460,17 +492,17 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
case ParticleSystemSimulationSpace.Local:
|
case ParticleSystemSimulationSpace.Local:
|
||||||
return Matrix4x4.Translate(psPos)
|
return Matrix4x4.Translate(psPos)
|
||||||
* Matrix4x4.Scale(scale);
|
* Matrix4x4.Scale(scale);
|
||||||
case ParticleSystemSimulationSpace.World:
|
case ParticleSystemSimulationSpace.World:
|
||||||
return Matrix4x4.Scale(scale);
|
return Matrix4x4.Scale(scale);
|
||||||
case ParticleSystemSimulationSpace.Custom:
|
case ParticleSystemSimulationSpace.Custom:
|
||||||
return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale))
|
return Matrix4x4.Translate(_particleSystem.main.customSimulationSpace.position.GetScaled(scale))
|
||||||
//* Matrix4x4.Translate(wpos)
|
//* Matrix4x4.Translate(wpos)
|
||||||
* Matrix4x4.Scale(scale)
|
* Matrix4x4.Scale(scale)
|
||||||
//* Matrix4x4.Translate(-wpos)
|
//* Matrix4x4.Translate(-wpos)
|
||||||
;
|
;
|
||||||
default:
|
default:
|
||||||
throw new System.NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +514,9 @@ namespace Coffee.UIExtensions
|
||||||
private void ResolveResolutionChange(Vector3 psPos, Vector3 scale)
|
private void ResolveResolutionChange(Vector3 psPos, Vector3 scale)
|
||||||
{
|
{
|
||||||
var screenSize = new Vector2Int(Screen.width, Screen.height);
|
var screenSize = new Vector2Int(Screen.width, Screen.height);
|
||||||
//if ((_prevScreenSize != screenSize || _prevScale != scale) && _particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World && _parent.uiScaling)
|
var isWorldSpace = _particleSystem.IsWorldSpace();
|
||||||
if ((_prevScreenSize != screenSize || _prevScale != scale) && _particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World)
|
var resolutionChanged = _prevScreenSize != screenSize || _prevScale != scale;
|
||||||
|
if (resolutionChanged && isWorldSpace)
|
||||||
{
|
{
|
||||||
// Update particle array size and get particles.
|
// Update particle array size and get particles.
|
||||||
var size = _particleSystem.particleCount;
|
var size = _particleSystem.particleCount;
|
||||||
|
@ -492,13 +525,17 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
// Resolusion resolver:
|
// Resolusion resolver:
|
||||||
// (psPos / scale) / (prevPsPos / prevScale) -> psPos * scale.inv * prevPsPos.inv * prevScale
|
// (psPos / scale) / (prevPsPos / prevScale) -> psPos * scale.inv * prevPsPos.inv * prevScale
|
||||||
var modifier = psPos.GetScaled(scale.Inverse(), _prevPsPos.Inverse(), _prevScale);
|
var modifier = psPos.GetScaled(
|
||||||
|
scale.Inverse(),
|
||||||
|
_prevPsPos.Inverse(),
|
||||||
|
_prevScale);
|
||||||
for (var i = 0; i < size; i++)
|
for (var i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
var particle = particles[i];
|
var particle = particles[i];
|
||||||
particle.position = particle.position.GetScaled(modifier);
|
particle.position = particle.position.GetScaled(modifier);
|
||||||
particles[i] = particle;
|
particles[i] = particle;
|
||||||
}
|
}
|
||||||
|
|
||||||
_particleSystem.SetParticles(particles, size);
|
_particleSystem.SetParticles(particles, size);
|
||||||
|
|
||||||
// Delay: Do not progress in the frame where the resolution has been changed.
|
// Delay: Do not progress in the frame where the resolution has been changed.
|
||||||
|
@ -506,6 +543,7 @@ namespace Coffee.UIExtensions
|
||||||
_prevScale = scale;
|
_prevScale = scale;
|
||||||
_prevPsPos = psPos;
|
_prevPsPos = psPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
_prevScreenSize = screenSize;
|
_prevScreenSize = screenSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,13 +586,14 @@ namespace Coffee.UIExtensions
|
||||||
var psTransform = _particleSystem.transform;
|
var psTransform = _particleSystem.transform;
|
||||||
var originWorldPosition = psTransform.position;
|
var originWorldPosition = psTransform.position;
|
||||||
var originWorldRotation = psTransform.rotation;
|
var originWorldRotation = psTransform.rotation;
|
||||||
|
|
||||||
var emission = _particleSystem.emission;
|
var emission = _particleSystem.emission;
|
||||||
var rateOverDistance = emission.enabled && 0 < emission.rateOverDistance.constant && 0 < emission.rateOverDistanceMultiplier;
|
var rateOverDistance = emission.enabled
|
||||||
|
&& 0 < emission.rateOverDistance.constant
|
||||||
|
&& 0 < emission.rateOverDistanceMultiplier;
|
||||||
if (rateOverDistance)
|
if (rateOverDistance)
|
||||||
{
|
{
|
||||||
// (For rate-over-distance emission,) Move to previous scaled position, simulate (delta = 0).
|
// (For rate-over-distance emission,) Move to previous scaled position, simulate (delta = 0).
|
||||||
Vector3 prevScaledPos = _prevPsPos.GetScaled(_prevScale.Inverse());
|
var prevScaledPos = _prevPsPos.GetScaled(_prevScale.Inverse());
|
||||||
psTransform.SetPositionAndRotation(prevScaledPos, originWorldRotation);
|
psTransform.SetPositionAndRotation(prevScaledPos, originWorldRotation);
|
||||||
_particleSystem.Simulate(0, false, false, false);
|
_particleSystem.Simulate(0, false, false, false);
|
||||||
}
|
}
|
||||||
|
@ -570,7 +609,8 @@ namespace Coffee.UIExtensions
|
||||||
private void SimulateForEditor(Vector3 diffPos, Vector3 scale)
|
private void SimulateForEditor(Vector3 diffPos, Vector3 scale)
|
||||||
{
|
{
|
||||||
// Extra world simulation.
|
// Extra world simulation.
|
||||||
if (_particleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World && 0 < Vector3.SqrMagnitude(diffPos))
|
var isWorldSpace = _particleSystem.IsWorldSpace();
|
||||||
|
if (isWorldSpace && 0 < Vector3.SqrMagnitude(diffPos))
|
||||||
{
|
{
|
||||||
Profiler.BeginSample("[UIParticle] Bake Mesh > Extra world simulation");
|
Profiler.BeginSample("[UIParticle] Bake Mesh > Extra world simulation");
|
||||||
diffPos.x *= 1f - 1f / Mathf.Max(0.001f, scale.x);
|
diffPos.x *= 1f - 1f / Mathf.Max(0.001f, scale.x);
|
||||||
|
@ -598,7 +638,9 @@ namespace Coffee.UIExtensions
|
||||||
if (_parent.m_AnimatableProperties.Length == 0) return;
|
if (_parent.m_AnimatableProperties.Length == 0) return;
|
||||||
|
|
||||||
if (s_Mpb == null)
|
if (s_Mpb == null)
|
||||||
|
{
|
||||||
s_Mpb = new MaterialPropertyBlock();
|
s_Mpb = new MaterialPropertyBlock();
|
||||||
|
}
|
||||||
|
|
||||||
_renderer.GetPropertyBlock(s_Mpb);
|
_renderer.GetPropertyBlock(s_Mpb);
|
||||||
if (s_Mpb.isEmpty) return;
|
if (s_Mpb.isEmpty) return;
|
||||||
|
@ -606,8 +648,9 @@ namespace Coffee.UIExtensions
|
||||||
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
|
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
|
||||||
if (!_modifiedMaterial) return;
|
if (!_modifiedMaterial) return;
|
||||||
|
|
||||||
foreach (var ap in _parent.m_AnimatableProperties)
|
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
|
||||||
{
|
{
|
||||||
|
var ap = _parent.m_AnimatableProperties[i];
|
||||||
ap.UpdateMaterialProperties(_modifiedMaterial, s_Mpb);
|
ap.UpdateMaterialProperties(_modifiedMaterial, s_Mpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
internal static class UIParticleUpdater
|
internal static class UIParticleUpdater
|
||||||
{
|
{
|
||||||
static readonly List<UIParticle> s_ActiveParticles = new List<UIParticle>();
|
private static readonly List<UIParticle> s_ActiveParticles = new List<UIParticle>();
|
||||||
static readonly List<UIParticleAttractor> s_ActiveAttractors = new List<UIParticleAttractor>();
|
private static readonly List<UIParticleAttractor> s_ActiveAttractors = new List<UIParticleAttractor>();
|
||||||
static readonly HashSet<int> s_UpdatedGroupIds = new HashSet<int>();
|
private static readonly HashSet<int> s_UpdatedGroupIds = new HashSet<int>();
|
||||||
private static int frameCount = 0;
|
private static int s_FrameCount;
|
||||||
|
|
||||||
public static int uiParticleCount
|
public static int uiParticleCount
|
||||||
{
|
{
|
||||||
get
|
get { return s_ActiveParticles.Count; }
|
||||||
{
|
|
||||||
return s_ActiveParticles.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Register(UIParticle particle)
|
public static void Register(UIParticle particle)
|
||||||
|
@ -43,7 +41,7 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[UnityEditor.InitializeOnLoadMethod]
|
[InitializeOnLoadMethod]
|
||||||
#endif
|
#endif
|
||||||
[RuntimeInitializeOnLoadMethod]
|
[RuntimeInitializeOnLoadMethod]
|
||||||
private static void InitializeOnLoad()
|
private static void InitializeOnLoad()
|
||||||
|
@ -55,8 +53,8 @@ namespace Coffee.UIExtensions
|
||||||
private static void Refresh()
|
private static void Refresh()
|
||||||
{
|
{
|
||||||
// Do not allow it to be called in the same frame.
|
// Do not allow it to be called in the same frame.
|
||||||
if (frameCount == Time.frameCount) return;
|
if (s_FrameCount == Time.frameCount) return;
|
||||||
frameCount = Time.frameCount;
|
s_FrameCount = Time.frameCount;
|
||||||
|
|
||||||
// Simulate -> Primary
|
// Simulate -> Primary
|
||||||
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
for (var i = 0; i < s_ActiveParticles.Count; i++)
|
||||||
|
@ -129,6 +127,7 @@ namespace Coffee.UIExtensions
|
||||||
if (uip.isPrimary) return uip;
|
if (uip.isPrimary) return uip;
|
||||||
if (!primary && uip.canSimulate) primary = uip;
|
if (!primary && uip.canSimulate) primary = uip;
|
||||||
}
|
}
|
||||||
|
|
||||||
return primary;
|
return primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,11 @@ namespace Coffee.UIParticleExtensions
|
||||||
internal static class SpriteExtensions
|
internal static class SpriteExtensions
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
private static Type tSpriteEditorExtension =
|
private static readonly Type s_SpriteEditorExtensionType =
|
||||||
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
|
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
|
||||||
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
|
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
|
||||||
|
|
||||||
private static MethodInfo miGetActiveAtlasTexture = tSpriteEditorExtension
|
private static readonly MethodInfo s_GetActiveAtlasTextureMethodInfo = s_SpriteEditorExtensionType
|
||||||
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
|
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
|
||||||
public static Texture2D GetActualTexture(this Sprite self)
|
public static Texture2D GetActualTexture(this Sprite self)
|
||||||
|
@ -58,8 +58,10 @@ namespace Coffee.UIParticleExtensions
|
||||||
if (!self) return null;
|
if (!self) return null;
|
||||||
|
|
||||||
if (Application.isPlaying) return self.texture;
|
if (Application.isPlaying) return self.texture;
|
||||||
var ret = miGetActiveAtlasTexture.Invoke(null, new[] { self }) as Texture2D;
|
var ret = s_GetActiveAtlasTextureMethodInfo.Invoke(null, new object[] { self }) as Texture2D;
|
||||||
return ret ? ret : self.texture;
|
return ret
|
||||||
|
? ret
|
||||||
|
: self.texture;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
internal static Texture2D GetActualTexture(this Sprite self)
|
internal static Texture2D GetActualTexture(this Sprite self)
|
||||||
|
@ -77,12 +79,14 @@ namespace Coffee.UIParticleExtensions
|
||||||
{
|
{
|
||||||
if (s_TmpParticles.Length < size)
|
if (s_TmpParticles.Length < size)
|
||||||
{
|
{
|
||||||
while(s_TmpParticles.Length < size)
|
while (s_TmpParticles.Length < size)
|
||||||
{
|
{
|
||||||
size = Mathf.NextPowerOfTwo(size);
|
size = Mathf.NextPowerOfTwo(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_TmpParticles = new ParticleSystem.Particle[size];
|
s_TmpParticles = new ParticleSystem.Particle[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
return s_TmpParticles;
|
return s_TmpParticles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,47 +106,69 @@ namespace Coffee.UIParticleExtensions
|
||||||
var main = self.main;
|
var main = self.main;
|
||||||
var space = main.simulationSpace;
|
var space = main.simulationSpace;
|
||||||
if (space == ParticleSystemSimulationSpace.Custom && !main.customSimulationSpace)
|
if (space == ParticleSystemSimulationSpace.Custom && !main.customSimulationSpace)
|
||||||
|
{
|
||||||
space = ParticleSystemSimulationSpace.Local;
|
space = ParticleSystemSimulationSpace.Local;
|
||||||
|
}
|
||||||
|
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsLocalSpace(this ParticleSystem self)
|
||||||
|
{
|
||||||
|
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.Local;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsWorldSpace(this ParticleSystem self)
|
||||||
|
{
|
||||||
|
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.World;
|
||||||
|
}
|
||||||
|
|
||||||
public static void SortForRendering(this List<ParticleSystem> self, Transform transform, bool sortByMaterial)
|
public static void SortForRendering(this List<ParticleSystem> self, Transform transform, bool sortByMaterial)
|
||||||
{
|
{
|
||||||
self.Sort((a, b) =>
|
self.Sort((a, b) =>
|
||||||
{
|
{
|
||||||
var tr = transform;
|
|
||||||
var aRenderer = a.GetComponent<ParticleSystemRenderer>();
|
var aRenderer = a.GetComponent<ParticleSystemRenderer>();
|
||||||
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
|
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
|
||||||
|
|
||||||
// Render queue: ascending
|
// Render queue: ascending
|
||||||
var aMat = aRenderer.sharedMaterial ?? aRenderer.trailMaterial;
|
var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
|
||||||
var bMat = bRenderer.sharedMaterial ?? bRenderer.trailMaterial;
|
var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
|
||||||
if (!aMat && !bMat) return 0;
|
if (!aMat && !bMat) return 0;
|
||||||
if (!aMat) return -1;
|
if (!aMat) return -1;
|
||||||
if (!bMat) return 1;
|
if (!bMat) return 1;
|
||||||
|
|
||||||
if (sortByMaterial)
|
if (sortByMaterial)
|
||||||
|
{
|
||||||
return aMat.GetInstanceID() - bMat.GetInstanceID();
|
return aMat.GetInstanceID() - bMat.GetInstanceID();
|
||||||
|
}
|
||||||
|
|
||||||
if (aMat.renderQueue != bMat.renderQueue)
|
if (aMat.renderQueue != bMat.renderQueue)
|
||||||
|
{
|
||||||
return aMat.renderQueue - bMat.renderQueue;
|
return aMat.renderQueue - bMat.renderQueue;
|
||||||
|
}
|
||||||
|
|
||||||
// Sorting layer: ascending
|
// Sorting layer: ascending
|
||||||
if (aRenderer.sortingLayerID != bRenderer.sortingLayerID)
|
if (aRenderer.sortingLayerID != bRenderer.sortingLayerID)
|
||||||
return SortingLayer.GetLayerValueFromID(aRenderer.sortingLayerID) - SortingLayer.GetLayerValueFromID(bRenderer.sortingLayerID);
|
{
|
||||||
|
return SortingLayer.GetLayerValueFromID(aRenderer.sortingLayerID) -
|
||||||
|
SortingLayer.GetLayerValueFromID(bRenderer.sortingLayerID);
|
||||||
|
}
|
||||||
|
|
||||||
// Sorting order: ascending
|
// Sorting order: ascending
|
||||||
if (aRenderer.sortingOrder != bRenderer.sortingOrder)
|
if (aRenderer.sortingOrder != bRenderer.sortingOrder)
|
||||||
|
{
|
||||||
return aRenderer.sortingOrder - bRenderer.sortingOrder;
|
return aRenderer.sortingOrder - bRenderer.sortingOrder;
|
||||||
|
}
|
||||||
|
|
||||||
// Z position & sortingFudge: descending
|
// Z position & sortingFudge: descending
|
||||||
var aTransform = a.transform;
|
var aTransform = a.transform;
|
||||||
var bTransform = b.transform;
|
var bTransform = b.transform;
|
||||||
var aPos = tr.InverseTransformPoint(aTransform.position).z + aRenderer.sortingFudge;
|
var aPos = transform.InverseTransformPoint(aTransform.position).z + aRenderer.sortingFudge;
|
||||||
var bPos = tr.InverseTransformPoint(bTransform.position).z + bRenderer.sortingFudge;
|
var bPos = transform.InverseTransformPoint(bTransform.position).z + bRenderer.sortingFudge;
|
||||||
if (!Mathf.Approximately(aPos, bPos))
|
if (!Mathf.Approximately(aPos, bPos))
|
||||||
|
{
|
||||||
return (int)Mathf.Sign(bPos - aPos);
|
return (int)Mathf.Sign(bPos - aPos);
|
||||||
|
}
|
||||||
|
|
||||||
return (int)Mathf.Sign(GetIndex(self, a) - GetIndex(self, b));
|
return (int)Mathf.Sign(GetIndex(self, a) - GetIndex(self, b));
|
||||||
});
|
});
|
||||||
|
@ -152,7 +178,10 @@ namespace Coffee.UIParticleExtensions
|
||||||
{
|
{
|
||||||
for (var i = 0; i < list.Count; i++)
|
for (var i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
if (list[i].GetInstanceID() == ps.GetInstanceID()) return i;
|
if (list[i].GetInstanceID() == ps.GetInstanceID())
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -183,4 +212,37 @@ namespace Coffee.UIParticleExtensions
|
||||||
self.ForEach(action);
|
self.ForEach(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static class Misc
|
||||||
|
{
|
||||||
|
public static void Destroy(Object obj)
|
||||||
|
{
|
||||||
|
if (!obj) return;
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!Application.isPlaying)
|
||||||
|
{
|
||||||
|
Object.DestroyImmediate(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Object.Destroy(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DestroyImmediate(Object obj)
|
||||||
|
{
|
||||||
|
if (!obj) return;
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (Application.isEditor)
|
||||||
|
{
|
||||||
|
Object.DestroyImmediate(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Object.Destroy(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue