mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-12 00:58:16 +00:00
提交FairyGUI
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eed3a919a48726c46a61e180a615ef7d
|
||||
folderAsset: yes
|
||||
timeCreated: 1460480287
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,110 @@
|
||||
using UnityEngine;
|
||||
using NativeBlendMode = UnityEngine.Rendering.BlendMode;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/*关于BlendMode.Off, 这种模式相当于Blend Off指令的效果。当然,在着色器里使用Blend Off指令可以获得更高的效率,
|
||||
但因为Image着色器本身就有多个关键字,复制一个这样的着色器代价太大,所有为了节省Shader数量便增加了这样一种模式,也是可以接受的。
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum BlendMode
|
||||
{
|
||||
Normal,
|
||||
None,
|
||||
Add,
|
||||
Multiply,
|
||||
Screen,
|
||||
Erase,
|
||||
Mask,
|
||||
Below,
|
||||
Off,
|
||||
One_OneMinusSrcAlpha,
|
||||
Custom1,
|
||||
Custom2,
|
||||
Custom3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BlendModeUtils
|
||||
{
|
||||
public class BlendFactor
|
||||
{
|
||||
public NativeBlendMode srcFactor;
|
||||
public NativeBlendMode dstFactor;
|
||||
public bool pma;
|
||||
|
||||
public BlendFactor(NativeBlendMode srcFactor, NativeBlendMode dstFactor, bool pma = false)
|
||||
{
|
||||
this.srcFactor = srcFactor;
|
||||
this.dstFactor = dstFactor;
|
||||
this.pma = pma;
|
||||
}
|
||||
}
|
||||
|
||||
//Source指的是被计算的颜色,Destination是已经在屏幕上的颜色。
|
||||
//混合结果=Source * factor1 + Destination * factor2
|
||||
public static BlendFactor[] Factors = new BlendFactor[] {
|
||||
//Normal
|
||||
new BlendFactor(NativeBlendMode.SrcAlpha, NativeBlendMode.OneMinusSrcAlpha),
|
||||
//None
|
||||
new BlendFactor(NativeBlendMode.One, NativeBlendMode.One),
|
||||
//Add
|
||||
new BlendFactor(NativeBlendMode.SrcAlpha, NativeBlendMode.One),
|
||||
//Multiply
|
||||
new BlendFactor(NativeBlendMode.DstColor, NativeBlendMode.OneMinusSrcAlpha, true),
|
||||
//Screen
|
||||
new BlendFactor(NativeBlendMode.One, NativeBlendMode.OneMinusSrcColor, true),
|
||||
//Erase
|
||||
new BlendFactor(NativeBlendMode.Zero, NativeBlendMode.OneMinusSrcAlpha),
|
||||
//Mask
|
||||
new BlendFactor(NativeBlendMode.Zero, NativeBlendMode.SrcAlpha),
|
||||
//Below
|
||||
new BlendFactor(NativeBlendMode.OneMinusDstAlpha, NativeBlendMode.DstAlpha),
|
||||
//Off
|
||||
new BlendFactor(NativeBlendMode.One, NativeBlendMode.Zero),
|
||||
//One_OneMinusSrcAlpha
|
||||
new BlendFactor(NativeBlendMode.One, NativeBlendMode.OneMinusSrcAlpha),
|
||||
//Custom1
|
||||
new BlendFactor(NativeBlendMode.SrcAlpha, NativeBlendMode.OneMinusSrcAlpha),
|
||||
//Custom2
|
||||
new BlendFactor(NativeBlendMode.SrcAlpha, NativeBlendMode.OneMinusSrcAlpha),
|
||||
//Custom3
|
||||
new BlendFactor(NativeBlendMode.SrcAlpha, NativeBlendMode.OneMinusSrcAlpha)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="mat"></param>
|
||||
/// <param name="blendMode"></param>
|
||||
public static void Apply(Material mat, BlendMode blendMode)
|
||||
{
|
||||
BlendFactor bf = Factors[(int)blendMode];
|
||||
mat.SetFloat(ShaderConfig.ID_BlendSrcFactor, (float)bf.srcFactor);
|
||||
mat.SetFloat(ShaderConfig.ID_BlendDstFactor, (float)bf.dstFactor);
|
||||
|
||||
if (bf.pma)
|
||||
mat.SetFloat(ShaderConfig.ID_ColorOption, 1);
|
||||
else
|
||||
mat.SetFloat(ShaderConfig.ID_ColorOption, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="blendMode"></param>
|
||||
/// <param name="srcFactor"></param>
|
||||
/// <param name="dstFactor"></param>
|
||||
public static void Override(BlendMode blendMode, NativeBlendMode srcFactor, NativeBlendMode dstFactor)
|
||||
{
|
||||
BlendFactor bf = Factors[(int)blendMode];
|
||||
bf.srcFactor = srcFactor;
|
||||
bf.dstFactor = dstFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce4df113fe8d9994c83e22680544ccdb
|
||||
timeCreated: 1464679834
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,202 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CaptureCamera : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public Transform cachedTransform;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
public Camera cachedCamera;
|
||||
|
||||
[System.NonSerialized]
|
||||
static CaptureCamera _main;
|
||||
|
||||
[System.NonSerialized]
|
||||
static int _layer = -1;
|
||||
static int _hiddenLayer = -1;
|
||||
|
||||
public const string Name = "Capture Camera";
|
||||
public const string LayerName = "VUI";
|
||||
public const string HiddenLayerName = "Hidden VUI";
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
cachedCamera = this.GetComponent<Camera>();
|
||||
cachedTransform = this.gameObject.transform;
|
||||
|
||||
if (this.gameObject.name == Name)
|
||||
_main = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void CheckMain()
|
||||
{
|
||||
if (_main != null && _main.cachedCamera != null)
|
||||
return;
|
||||
|
||||
GameObject go = GameObject.Find(Name);
|
||||
if (go != null)
|
||||
{
|
||||
_main = go.GetComponent<CaptureCamera>();
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject cameraObject = new GameObject(Name);
|
||||
Camera camera = cameraObject.AddComponent<Camera>();
|
||||
camera.depth = 0;
|
||||
camera.cullingMask = 1 << layer;
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = Color.clear;
|
||||
camera.orthographic = true;
|
||||
camera.orthographicSize = 5;
|
||||
camera.nearClipPlane = -30;
|
||||
camera.farClipPlane = 30;
|
||||
camera.enabled = false;
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
camera.stereoTargetEye = StereoTargetEyeMask.None;
|
||||
#endif
|
||||
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
camera.allowHDR = false;
|
||||
camera.allowMSAA = false;
|
||||
#endif
|
||||
cameraObject.AddComponent<CaptureCamera>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int layer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_layer == -1)
|
||||
{
|
||||
_layer = LayerMask.NameToLayer(LayerName);
|
||||
if (_layer == -1)
|
||||
{
|
||||
_layer = 30;
|
||||
Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return _layer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int hiddenLayer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hiddenLayer == -1)
|
||||
{
|
||||
_hiddenLayer = LayerMask.NameToLayer(HiddenLayerName);
|
||||
if (_hiddenLayer == -1)
|
||||
{
|
||||
Debug.LogWarning("Please define two layers named '" + CaptureCamera.LayerName + "' and '" + CaptureCamera.HiddenLayerName + "'");
|
||||
_hiddenLayer = 31;
|
||||
}
|
||||
}
|
||||
|
||||
return _hiddenLayer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <param name="stencilSupport"></param>
|
||||
/// <returns></returns>
|
||||
public static RenderTexture CreateRenderTexture(int width, int height, bool stencilSupport)
|
||||
{
|
||||
RenderTexture texture = new RenderTexture(width, height, stencilSupport ? 24 : 0, RenderTextureFormat.ARGB32);
|
||||
texture.antiAliasing = 1;
|
||||
texture.filterMode = FilterMode.Bilinear;
|
||||
texture.anisoLevel = 0;
|
||||
texture.useMipMap = false;
|
||||
texture.wrapMode = TextureWrapMode.Clamp;
|
||||
texture.hideFlags = DisplayObject.hideFlags;
|
||||
return texture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="contentHeight"></param>
|
||||
/// <param name="offset"></param>
|
||||
public static void Capture(DisplayObject target, RenderTexture texture, float contentHeight, Vector2 offset)
|
||||
{
|
||||
CheckMain();
|
||||
|
||||
Matrix4x4 matrix = target.cachedTransform.localToWorldMatrix;
|
||||
float scaleX = new Vector4(matrix.m00, matrix.m10, matrix.m20, matrix.m30).magnitude;
|
||||
float scaleY = new Vector4(matrix.m01, matrix.m11, matrix.m21, matrix.m31).magnitude;
|
||||
|
||||
Vector3 forward;
|
||||
forward.x = matrix.m02;
|
||||
forward.y = matrix.m12;
|
||||
forward.z = matrix.m22;
|
||||
|
||||
Vector3 upwards;
|
||||
upwards.x = matrix.m01;
|
||||
upwards.y = matrix.m11;
|
||||
upwards.z = matrix.m21;
|
||||
|
||||
float halfHeight = contentHeight * 0.5f;
|
||||
|
||||
Camera camera = _main.cachedCamera;
|
||||
camera.targetTexture = texture;
|
||||
float aspect = (float)texture.width / texture.height;
|
||||
camera.aspect = aspect * scaleX / scaleY;
|
||||
camera.orthographicSize = halfHeight * scaleY;
|
||||
_main.cachedTransform.localPosition = target.cachedTransform.TransformPoint(halfHeight * aspect - offset.x, -halfHeight + offset.y, 0);
|
||||
if (forward != Vector3.zero)
|
||||
_main.cachedTransform.localRotation = Quaternion.LookRotation(forward, upwards);
|
||||
|
||||
int oldLayer = 0;
|
||||
|
||||
if (target.graphics != null)
|
||||
{
|
||||
oldLayer = target.graphics.gameObject.layer;
|
||||
target.graphics.gameObject.layer = CaptureCamera.layer;
|
||||
}
|
||||
|
||||
if (target is Container)
|
||||
{
|
||||
oldLayer = ((Container)target).numChildren > 0 ? ((Container)target).GetChildAt(0).layer : CaptureCamera.hiddenLayer;
|
||||
((Container)target).SetChildrenLayer(CaptureCamera.layer);
|
||||
}
|
||||
|
||||
RenderTexture old = RenderTexture.active;
|
||||
RenderTexture.active = texture;
|
||||
GL.Clear(true, true, Color.clear);
|
||||
camera.Render();
|
||||
RenderTexture.active = old;
|
||||
|
||||
if (target.graphics != null)
|
||||
target.graphics.gameObject.layer = oldLayer;
|
||||
|
||||
if (target is Container)
|
||||
((Container)target).SetChildrenLayer(oldLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d207151359c99fb448f4b3380bf41b0f
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1124
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Container.cs
Normal file
1124
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Container.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 531f2c788ec31e7459700f6811410a6f
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24d09ba8cf3faa74f8dcd1c86ad38588
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,393 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
/// GoWrapper is class for wrapping common gameobject into UI display list.
|
||||
/// </summary>
|
||||
public class GoWrapper : DisplayObject
|
||||
{
|
||||
[Obsolete("No need to manually set this flag anymore, coz it will be handled automatically.")]
|
||||
public bool supportStencil;
|
||||
|
||||
public event Action<UpdateContext> onUpdate;
|
||||
public Action<Dictionary<Material, Material>> customCloneMaterials;
|
||||
public Action customRecoverMaterials;
|
||||
|
||||
protected GameObject _wrapTarget;
|
||||
protected List<RendererInfo> _renderers;
|
||||
protected Dictionary<Material, Material> _materialsBackup;
|
||||
protected Canvas _canvas;
|
||||
protected bool _cloneMaterial;
|
||||
protected bool _shouldCloneMaterial;
|
||||
|
||||
protected struct RendererInfo
|
||||
{
|
||||
public Renderer renderer;
|
||||
public Material[] materials;
|
||||
public int sortingOrder;
|
||||
}
|
||||
|
||||
// protected static List<Transform> helperTransformList = new List<Transform>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public GoWrapper()
|
||||
{
|
||||
// _flags |= Flags.SkipBatching;
|
||||
|
||||
_renderers = new List<RendererInfo>();
|
||||
_materialsBackup = new Dictionary<Material, Material>();
|
||||
|
||||
CreateGameObject("GoWrapper");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="go">包装对象。</param>
|
||||
public GoWrapper(GameObject go) : this()
|
||||
{
|
||||
SetWrapTarget(go, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置包装对象。注意如果原来有包装对象,设置新的包装对象后,原来的包装对象只会被删除引用,但不会被销毁。
|
||||
/// 对象包含的所有材质不会被复制,如果材质已经是公用的,这可能影响到其他对象。如果希望自动复制,改为使用SetWrapTarget(target, true)设置。
|
||||
/// </summary>
|
||||
public GameObject wrapTarget
|
||||
{
|
||||
get { return _wrapTarget; }
|
||||
set { SetWrapTarget(value, false); }
|
||||
}
|
||||
|
||||
[Obsolete("setWrapTarget is deprecated. Use SetWrapTarget instead.")]
|
||||
public void setWrapTarget(GameObject target, bool cloneMaterial)
|
||||
{
|
||||
SetWrapTarget(target, cloneMaterial);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置包装对象。注意如果原来有包装对象,设置新的包装对象后,原来的包装对象只会被删除引用,但不会被销毁。
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="cloneMaterial">如果true,则复制材质,否则直接使用sharedMaterial。</param>
|
||||
public void SetWrapTarget(GameObject target, bool cloneMaterial)
|
||||
{
|
||||
// set Flags.SkipBatching only target not null
|
||||
if (target == null) _flags &= ~Flags.SkipBatching;
|
||||
else _flags |= Flags.SkipBatching;
|
||||
InvalidateBatchingState();
|
||||
|
||||
RecoverMaterials();
|
||||
|
||||
_cloneMaterial = cloneMaterial;
|
||||
if (_wrapTarget != null)
|
||||
_wrapTarget.transform.SetParent(null, false);
|
||||
|
||||
_canvas = null;
|
||||
_wrapTarget = target;
|
||||
_shouldCloneMaterial = false;
|
||||
_renderers.Clear();
|
||||
|
||||
if (_wrapTarget != null)
|
||||
{
|
||||
_wrapTarget.transform.SetParent(this.cachedTransform, false);
|
||||
_canvas = _wrapTarget.GetComponent<Canvas>();
|
||||
if (_canvas != null)
|
||||
{
|
||||
_canvas.renderMode = RenderMode.WorldSpace;
|
||||
_canvas.worldCamera = StageCamera.main;
|
||||
_canvas.overrideSorting = true;
|
||||
|
||||
RectTransform rt = _canvas.GetComponent<RectTransform>();
|
||||
rt.pivot = new Vector2(0, 1);
|
||||
rt.position = new Vector3(0, 0, 0);
|
||||
this.SetSize(rt.rect.width, rt.rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
CacheRenderers();
|
||||
this.SetSize(0, 0);
|
||||
}
|
||||
|
||||
SetGoLayers(this.layer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GoWrapper will cache all renderers of your gameobject on constructor.
|
||||
/// If your gameobject change laterly, call this function to update the cache.
|
||||
/// GoWrapper会在构造函数里查询你的gameobject所有的Renderer并保存。如果你的gameobject
|
||||
/// 后续发生了改变,调用这个函数通知GoWrapper重新查询和保存。
|
||||
/// </summary>
|
||||
public void CacheRenderers()
|
||||
{
|
||||
if (_canvas != null)
|
||||
return;
|
||||
|
||||
RecoverMaterials();
|
||||
_renderers.Clear();
|
||||
|
||||
var items = ListPool<Renderer>.Get();
|
||||
_wrapTarget.GetComponentsInChildren(true, items);
|
||||
|
||||
int cnt = items.Count;
|
||||
_renderers.Capacity = cnt;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
Renderer r = items[i];
|
||||
Material[] mats = r.sharedMaterials;
|
||||
RendererInfo ri = new RendererInfo()
|
||||
{
|
||||
renderer = r,
|
||||
materials = mats,
|
||||
sortingOrder = r.sortingOrder
|
||||
};
|
||||
_renderers.Add(ri);
|
||||
|
||||
if (!_cloneMaterial && mats != null
|
||||
&& ((r is SkinnedMeshRenderer) || (r is MeshRenderer)))
|
||||
{
|
||||
int mcnt = mats.Length;
|
||||
for (int j = 0; j < mcnt; j++)
|
||||
{
|
||||
Material mat = mats[j];
|
||||
if (mat != null && mat.renderQueue != 3000) //Set the object rendering in Transparent Queue as UI objects
|
||||
mat.renderQueue = 3000;
|
||||
}
|
||||
}
|
||||
}
|
||||
ListPool<Renderer>.Release(items);
|
||||
_renderers.Sort((RendererInfo c1, RendererInfo c2) => { return c1.sortingOrder - c2.sortingOrder; });
|
||||
|
||||
_shouldCloneMaterial = _cloneMaterial;
|
||||
}
|
||||
|
||||
void CloneMaterials()
|
||||
{
|
||||
_shouldCloneMaterial = false;
|
||||
|
||||
int cnt = _renderers.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
RendererInfo ri = _renderers[i];
|
||||
Material[] mats = ri.materials;
|
||||
if (mats == null)
|
||||
continue;
|
||||
|
||||
bool shouldSetRQ = (ri.renderer is SkinnedMeshRenderer) || (ri.renderer is MeshRenderer);
|
||||
|
||||
int mcnt = mats.Length;
|
||||
for (int j = 0; j < mcnt; j++)
|
||||
{
|
||||
Material mat = mats[j];
|
||||
if (mat == null)
|
||||
continue;
|
||||
|
||||
//确保相同的材质不会复制两次
|
||||
Material newMat;
|
||||
if (!_materialsBackup.TryGetValue(mat, out newMat))
|
||||
{
|
||||
newMat = new Material(mat);
|
||||
_materialsBackup[mat] = newMat;
|
||||
}
|
||||
|
||||
mats[j] = newMat;
|
||||
|
||||
if (shouldSetRQ && mat.renderQueue != 3000) //Set the object rendering in Transparent Queue as UI objects
|
||||
newMat.renderQueue = 3000;
|
||||
}
|
||||
|
||||
if (customCloneMaterials != null)
|
||||
customCloneMaterials.Invoke(_materialsBackup);
|
||||
else if (ri.renderer != null)
|
||||
ri.renderer.sharedMaterials = mats;
|
||||
}
|
||||
}
|
||||
|
||||
void RecoverMaterials()
|
||||
{
|
||||
if (_materialsBackup.Count == 0)
|
||||
return;
|
||||
|
||||
int cnt = _renderers.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
RendererInfo ri = _renderers[i];
|
||||
if (ri.renderer == null)
|
||||
continue;
|
||||
|
||||
Material[] mats = ri.materials;
|
||||
if (mats == null)
|
||||
continue;
|
||||
|
||||
int mcnt = mats.Length;
|
||||
for (int j = 0; j < mcnt; j++)
|
||||
{
|
||||
Material mat = mats[j];
|
||||
|
||||
foreach (KeyValuePair<Material, Material> kv in _materialsBackup)
|
||||
{
|
||||
if (kv.Value == mat)
|
||||
mats[j] = kv.Key;
|
||||
}
|
||||
}
|
||||
|
||||
if (customRecoverMaterials != null)
|
||||
customRecoverMaterials.Invoke();
|
||||
else
|
||||
ri.renderer.sharedMaterials = mats;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<Material, Material> kv in _materialsBackup)
|
||||
Material.DestroyImmediate(kv.Value);
|
||||
|
||||
_materialsBackup.Clear();
|
||||
}
|
||||
|
||||
public override int renderingOrder
|
||||
{
|
||||
get { return base.renderingOrder; }
|
||||
set
|
||||
{
|
||||
base.renderingOrder = value;
|
||||
|
||||
if (_canvas != null)
|
||||
_canvas.sortingOrder = value;
|
||||
else
|
||||
{
|
||||
int cnt = _renderers.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
RendererInfo ri = _renderers[i];
|
||||
if (ri.renderer != null)
|
||||
{
|
||||
if (i != 0 && _renderers[i].sortingOrder != _renderers[i - 1].sortingOrder)
|
||||
value = UpdateContext.current.renderingOrder++;
|
||||
ri.renderer.sortingOrder = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override protected bool SetLayer(int value, bool fromParent)
|
||||
{
|
||||
if (base.SetLayer(value, fromParent))
|
||||
{
|
||||
SetGoLayers(value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void SetGoLayers(int layer)
|
||||
{
|
||||
if (_wrapTarget == null)
|
||||
return;
|
||||
|
||||
var helperTransformList = ListPool<Transform>.Get();
|
||||
_wrapTarget.GetComponentsInChildren(true, helperTransformList);
|
||||
int cnt = helperTransformList.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
helperTransformList[i].gameObject.layer = layer;
|
||||
}
|
||||
ListPool<Transform>.Release(helperTransformList);
|
||||
// helperTransformList.Clear();
|
||||
}
|
||||
|
||||
override public void Update(UpdateContext context)
|
||||
{
|
||||
if (onUpdate != null)
|
||||
onUpdate(context);
|
||||
|
||||
if (_shouldCloneMaterial)
|
||||
CloneMaterials();
|
||||
|
||||
ApplyClipping(context);
|
||||
|
||||
base.Update(context);
|
||||
}
|
||||
|
||||
private List<Material> helperMaterials = new List<Material>();
|
||||
|
||||
virtual protected void ApplyClipping(UpdateContext context)
|
||||
{
|
||||
#if UNITY_2018_2_OR_NEWER
|
||||
int cnt = _renderers.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
Renderer renderer = _renderers[i].renderer;
|
||||
if (renderer == null)
|
||||
continue;
|
||||
|
||||
if (customCloneMaterials != null)
|
||||
helperMaterials.AddRange(_materialsBackup.Values);
|
||||
else
|
||||
renderer.GetSharedMaterials(helperMaterials);
|
||||
|
||||
int cnt2 = helperMaterials.Count;
|
||||
for (int j = 0; j < cnt2; j++)
|
||||
{
|
||||
Material mat = helperMaterials[j];
|
||||
if (mat != null)
|
||||
context.ApplyClippingProperties(mat, false);
|
||||
}
|
||||
|
||||
helperMaterials.Clear();
|
||||
}
|
||||
#else
|
||||
int cnt = _renderers.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
Material[] mats = _renderers[i].materials;
|
||||
if (mats == null)
|
||||
continue;
|
||||
|
||||
int cnt2 = mats.Length;
|
||||
for (int j = 0; j < cnt2; j++)
|
||||
{
|
||||
Material mat = mats[j];
|
||||
if (mat != null)
|
||||
context.ApplyClippingProperties(mat, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if ((_flags & Flags.Disposed) != 0)
|
||||
return;
|
||||
|
||||
if (_wrapTarget != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(_wrapTarget);
|
||||
_wrapTarget = null;
|
||||
|
||||
if (_materialsBackup.Count > 0)
|
||||
{
|
||||
//如果有备份,说明材质是复制出来的,应该删除
|
||||
foreach (KeyValuePair<Material, Material> kv in _materialsBackup)
|
||||
Material.DestroyImmediate(kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
_renderers = null;
|
||||
_materialsBackup = null;
|
||||
_canvas = null;
|
||||
customCloneMaterials = null;
|
||||
customRecoverMaterials = null;
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 796d0bdebe7368c47adfdf04a1abdfc6
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 736ceb6630254bd42b41568b387cbcbe
|
||||
folderAsset: yes
|
||||
timeCreated: 1461773297
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ColliderHitTest : IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Collider collider;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
virtual public bool HitTest(Rect contentRect, Vector2 localPoint)
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (!HitTestContext.GetRaycastHitFromCache(HitTestContext.camera, out hit))
|
||||
return false;
|
||||
|
||||
if (hit.collider != collider)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffed53edbd969f3439a942ca847cd43d
|
||||
timeCreated: 1461773299
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class HitTestContext
|
||||
{
|
||||
//set before hit test
|
||||
public static Vector3 screenPoint;
|
||||
public static Vector3 worldPoint;
|
||||
public static Vector3 direction;
|
||||
public static bool forTouch;
|
||||
public static Camera camera;
|
||||
|
||||
public static int layerMask = -1;
|
||||
public static float maxDistance = Mathf.Infinity;
|
||||
|
||||
public static Camera cachedMainCamera;
|
||||
|
||||
static Dictionary<Camera, RaycastHit?> raycastHits = new Dictionary<Camera, RaycastHit?>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="camera"></param>
|
||||
/// <param name="hit"></param>
|
||||
/// <returns></returns>
|
||||
public static bool GetRaycastHitFromCache(Camera camera, out RaycastHit hit)
|
||||
{
|
||||
RaycastHit? hitRef;
|
||||
if (!raycastHits.TryGetValue(camera, out hitRef))
|
||||
{
|
||||
Ray ray = camera.ScreenPointToRay(screenPoint);
|
||||
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
|
||||
{
|
||||
raycastHits[camera] = hit;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
raycastHits[camera] = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (hitRef == null)
|
||||
{
|
||||
hit = new RaycastHit();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hit = (RaycastHit)hitRef;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="camera"></param>
|
||||
/// <param name="hit"></param>
|
||||
public static void CacheRaycastHit(Camera camera, ref RaycastHit hit)
|
||||
{
|
||||
raycastHits[camera] = hit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void ClearRaycastHitCache()
|
||||
{
|
||||
raycastHits.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19869d6307205b84a81aef6031ba1f33
|
||||
timeCreated: 1461750571
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum HitTestMode
|
||||
{
|
||||
Default,
|
||||
Raycast
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
bool HitTest(Rect contentRect, Vector2 localPoint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bbadf82645501c41957c257ab020708
|
||||
timeCreated: 1461853133
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MeshColliderHitTest : ColliderHitTest
|
||||
{
|
||||
public Vector2 lastHit;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="collider"></param>
|
||||
public MeshColliderHitTest(MeshCollider collider)
|
||||
{
|
||||
this.collider = collider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
override public bool HitTest(Rect contentRect, Vector2 localPoint)
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (!HitTestContext.GetRaycastHitFromCache(HitTestContext.camera, out hit))
|
||||
return false;
|
||||
|
||||
if (hit.collider != collider)
|
||||
return false;
|
||||
|
||||
lastHit = new Vector2(hit.textureCoord.x * contentRect.width, (1 - hit.textureCoord.y) * contentRect.height);
|
||||
HitTestContext.direction = Vector3.back;
|
||||
HitTestContext.worldPoint = StageCamera.main.ScreenToWorldPoint(new Vector2(lastHit.x, Screen.height - lastHit.y));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d0a2fa0c7008814795dc7f5f3bd4b19
|
||||
timeCreated: 1461750571
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using FairyGUI.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PixelHitTestData
|
||||
{
|
||||
public int pixelWidth;
|
||||
public float scale;
|
||||
public byte[] pixels;
|
||||
public int pixelsLength;
|
||||
public int pixelsOffset;
|
||||
|
||||
public void Load(ByteBuffer ba)
|
||||
{
|
||||
ba.ReadInt();
|
||||
pixelWidth = ba.ReadInt();
|
||||
scale = 1.0f / ba.ReadByte();
|
||||
pixels = ba.buffer;
|
||||
pixelsLength = ba.ReadInt();
|
||||
pixelsOffset = ba.position;
|
||||
ba.Skip(pixelsLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PixelHitTest : IHitTest
|
||||
{
|
||||
public int offsetX;
|
||||
public int offsetY;
|
||||
public float sourceWidth;
|
||||
public float sourceHeight;
|
||||
|
||||
PixelHitTestData _data;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="offsetX"></param>
|
||||
/// <param name="offsetY"></param>
|
||||
public PixelHitTest(PixelHitTestData data, int offsetX, int offsetY, float sourceWidth, float sourceHeight)
|
||||
{
|
||||
_data = data;
|
||||
this.offsetX = offsetX;
|
||||
this.offsetY = offsetY;
|
||||
this.sourceWidth = sourceWidth;
|
||||
this.sourceHeight = sourceHeight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
public bool HitTest(Rect contentRect, Vector2 localPoint)
|
||||
{
|
||||
if (!contentRect.Contains(localPoint))
|
||||
return false;
|
||||
|
||||
int x = Mathf.FloorToInt((localPoint.x * sourceWidth / contentRect.width - offsetX) * _data.scale);
|
||||
int y = Mathf.FloorToInt((localPoint.y * sourceHeight / contentRect.height - offsetY) * _data.scale);
|
||||
if (x < 0 || y < 0 || x >= _data.pixelWidth)
|
||||
return false;
|
||||
|
||||
int pos = y * _data.pixelWidth + x;
|
||||
int pos2 = pos / 8;
|
||||
int pos3 = pos % 8;
|
||||
|
||||
if (pos2 >= 0 && pos2 < _data.pixelsLength)
|
||||
return ((_data.pixels[_data.pixelsOffset + pos2] >> pos3) & 0x1) > 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98cb65df7f5853c4b8e3719a28d4d81f
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RectHitTest : IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect rect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
public bool HitTest(Rect contentRect, Vector2 localPoint)
|
||||
{
|
||||
return rect.Contains(localPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92768f03d9b8dea47b1649613c4d0de7
|
||||
timeCreated: 1474896442
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ShapeHitTest : IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DisplayObject shape;
|
||||
|
||||
public ShapeHitTest(DisplayObject obj)
|
||||
{
|
||||
shape = obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="contentRect"></param>
|
||||
/// <param name="localPoint"></param>
|
||||
/// <returns></returns>
|
||||
public bool HitTest(Rect contentRect, Vector2 localPoint)
|
||||
{
|
||||
if (shape.graphics == null)
|
||||
return false;
|
||||
|
||||
if (shape.parent != null)
|
||||
{
|
||||
localPoint = shape.parent.TransformPoint(localPoint, shape);
|
||||
contentRect.size = shape.size;
|
||||
}
|
||||
|
||||
IHitTest ht = shape.graphics.meshFactory as IHitTest;
|
||||
if (ht == null)
|
||||
return false;
|
||||
|
||||
return ht.HitTest(contentRect, localPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cd85528f2766431cafc5282f956c060
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
436
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Image.cs
Normal file
436
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Image.cs
Normal file
@@ -0,0 +1,436 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Image : DisplayObject, IMeshFactory
|
||||
{
|
||||
protected Rect? _scale9Grid;
|
||||
protected bool _scaleByTile;
|
||||
protected Vector2 _textureScale;
|
||||
protected int _tileGridIndice;
|
||||
protected FillMesh _fillMesh;
|
||||
|
||||
public Image() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
public Image(NTexture texture)
|
||||
: base()
|
||||
{
|
||||
_flags |= Flags.TouchDisabled;
|
||||
|
||||
CreateGameObject("Image");
|
||||
graphics = new NGraphics(gameObject);
|
||||
graphics.shader = ShaderConfig.imageShader;
|
||||
graphics.meshFactory = this;
|
||||
|
||||
_textureScale = Vector2.one;
|
||||
|
||||
if (texture != null)
|
||||
UpdateTexture(texture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public NTexture texture
|
||||
{
|
||||
get { return graphics.texture; }
|
||||
set
|
||||
{
|
||||
UpdateTexture(value);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 textureScale
|
||||
{
|
||||
get { return _textureScale; }
|
||||
set
|
||||
{
|
||||
_textureScale = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color color
|
||||
{
|
||||
get
|
||||
{
|
||||
return graphics.color;
|
||||
}
|
||||
set
|
||||
{
|
||||
graphics.color = value;
|
||||
graphics.Tint();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public FillMethod fillMethod
|
||||
{
|
||||
get { return _fillMesh != null ? _fillMesh.method : FillMethod.None; }
|
||||
set
|
||||
{
|
||||
if (_fillMesh == null)
|
||||
{
|
||||
if (value == FillMethod.None)
|
||||
return;
|
||||
|
||||
_fillMesh = new FillMesh();
|
||||
}
|
||||
if (_fillMesh.method != value)
|
||||
{
|
||||
_fillMesh.method = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int fillOrigin
|
||||
{
|
||||
get { return _fillMesh != null ? _fillMesh.origin : 0; }
|
||||
set
|
||||
{
|
||||
if (_fillMesh == null)
|
||||
_fillMesh = new FillMesh();
|
||||
|
||||
if (_fillMesh.origin != value)
|
||||
{
|
||||
_fillMesh.origin = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool fillClockwise
|
||||
{
|
||||
get { return _fillMesh != null ? _fillMesh.clockwise : true; }
|
||||
set
|
||||
{
|
||||
if (_fillMesh == null)
|
||||
_fillMesh = new FillMesh();
|
||||
|
||||
if (_fillMesh.clockwise != value)
|
||||
{
|
||||
_fillMesh.clockwise = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float fillAmount
|
||||
{
|
||||
get { return _fillMesh != null ? _fillMesh.amount : 0; }
|
||||
set
|
||||
{
|
||||
if (_fillMesh == null)
|
||||
_fillMesh = new FillMesh();
|
||||
|
||||
if (_fillMesh.amount != value)
|
||||
{
|
||||
_fillMesh.amount = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect? scale9Grid
|
||||
{
|
||||
get { return _scale9Grid; }
|
||||
set
|
||||
{
|
||||
if (_scale9Grid != value)
|
||||
{
|
||||
_scale9Grid = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool scaleByTile
|
||||
{
|
||||
get { return _scaleByTile; }
|
||||
set
|
||||
{
|
||||
if (_scaleByTile != value)
|
||||
{
|
||||
_scaleByTile = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int tileGridIndice
|
||||
{
|
||||
get { return _tileGridIndice; }
|
||||
set
|
||||
{
|
||||
if (_tileGridIndice != value)
|
||||
{
|
||||
_tileGridIndice = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetNativeSize()
|
||||
{
|
||||
if (graphics.texture != null)
|
||||
SetSize(graphics.texture.width, graphics.texture.height);
|
||||
else
|
||||
SetSize(0, 0);
|
||||
}
|
||||
|
||||
virtual protected void UpdateTexture(NTexture value)
|
||||
{
|
||||
if (value == graphics.texture)
|
||||
return;
|
||||
|
||||
graphics.texture = value;
|
||||
_textureScale = Vector2.one;
|
||||
if (_contentRect.width == 0)
|
||||
SetNativeSize();
|
||||
InvalidateBatchingState();
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
if (_fillMesh != null && _fillMesh.method != FillMethod.None)
|
||||
{
|
||||
_fillMesh.OnPopulateMesh(vb);
|
||||
}
|
||||
else if (_scaleByTile)
|
||||
{
|
||||
NTexture texture = graphics.texture;
|
||||
if (texture.root == texture
|
||||
&& texture.nativeTexture != null
|
||||
&& texture.nativeTexture.wrapMode == TextureWrapMode.Repeat)
|
||||
{
|
||||
Rect uvRect = vb.uvRect;
|
||||
uvRect.width *= vb.contentRect.width / texture.width * _textureScale.x;
|
||||
uvRect.height *= vb.contentRect.height / texture.height * _textureScale.y;
|
||||
|
||||
vb.AddQuad(vb.contentRect, vb.vertexColor, uvRect);
|
||||
vb.AddTriangles();
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect contentRect = vb.contentRect;
|
||||
contentRect.width *= _textureScale.x;
|
||||
contentRect.height *= _textureScale.y;
|
||||
|
||||
TileFill(vb, contentRect, vb.uvRect, texture.width, texture.height);
|
||||
vb.AddTriangles();
|
||||
}
|
||||
}
|
||||
else if (_scale9Grid != null)
|
||||
{
|
||||
SliceFill(vb);
|
||||
}
|
||||
else
|
||||
graphics.OnPopulateMesh(vb);
|
||||
}
|
||||
|
||||
static int[] TRIANGLES_9_GRID = new int[] {
|
||||
4,0,1,1,5,4,
|
||||
5,1,2,2,6,5,
|
||||
6,2,3,3,7,6,
|
||||
8,4,5,5,9,8,
|
||||
9,5,6,6,10,9,
|
||||
10,6,7,7,11,10,
|
||||
12,8,9,9,13,12,
|
||||
13,9,10,10,14,13,
|
||||
14,10,11,
|
||||
11,15,14
|
||||
};
|
||||
|
||||
static int[] gridTileIndice = new int[] { -1, 0, -1, 2, 4, 3, -1, 1, -1 };
|
||||
static float[] gridX = new float[4];
|
||||
static float[] gridY = new float[4];
|
||||
static float[] gridTexX = new float[4];
|
||||
static float[] gridTexY = new float[4];
|
||||
|
||||
public void SliceFill(VertexBuffer vb)
|
||||
{
|
||||
NTexture texture = graphics.texture;
|
||||
Rect gridRect = (Rect)_scale9Grid;
|
||||
Rect contentRect = vb.contentRect;
|
||||
contentRect.width *= _textureScale.x;
|
||||
contentRect.height *= _textureScale.y;
|
||||
Rect uvRect = vb.uvRect;
|
||||
|
||||
float sourceW = texture.width;
|
||||
float sourceH = texture.height;
|
||||
|
||||
if (graphics.flip != FlipType.None)
|
||||
{
|
||||
if (graphics.flip == FlipType.Horizontal || graphics.flip == FlipType.Both)
|
||||
{
|
||||
gridRect.x = sourceW - gridRect.xMax;
|
||||
gridRect.xMax = gridRect.x + gridRect.width;
|
||||
}
|
||||
|
||||
if (graphics.flip == FlipType.Vertical || graphics.flip == FlipType.Both)
|
||||
{
|
||||
gridRect.y = sourceH - gridRect.yMax;
|
||||
gridRect.yMax = gridRect.y + gridRect.height;
|
||||
}
|
||||
}
|
||||
|
||||
float sx = uvRect.width / sourceW;
|
||||
float sy = uvRect.height / sourceH;
|
||||
float xMax = uvRect.xMax;
|
||||
float yMax = uvRect.yMax;
|
||||
float xMax2 = gridRect.xMax;
|
||||
float yMax2 = gridRect.yMax;
|
||||
|
||||
gridTexX[0] = uvRect.x;
|
||||
gridTexX[1] = uvRect.x + gridRect.x * sx;
|
||||
gridTexX[2] = uvRect.x + xMax2 * sx;
|
||||
gridTexX[3] = xMax;
|
||||
gridTexY[0] = yMax;
|
||||
gridTexY[1] = yMax - gridRect.y * sy;
|
||||
gridTexY[2] = yMax - yMax2 * sy;
|
||||
gridTexY[3] = uvRect.y;
|
||||
|
||||
if (contentRect.width >= (sourceW - gridRect.width))
|
||||
{
|
||||
gridX[1] = gridRect.x;
|
||||
gridX[2] = contentRect.width - (sourceW - xMax2);
|
||||
gridX[3] = contentRect.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = gridRect.x / (sourceW - xMax2);
|
||||
tmp = contentRect.width * tmp / (1 + tmp);
|
||||
gridX[1] = tmp;
|
||||
gridX[2] = tmp;
|
||||
gridX[3] = contentRect.width;
|
||||
}
|
||||
|
||||
if (contentRect.height >= (sourceH - gridRect.height))
|
||||
{
|
||||
gridY[1] = gridRect.y;
|
||||
gridY[2] = contentRect.height - (sourceH - yMax2);
|
||||
gridY[3] = contentRect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = gridRect.y / (sourceH - yMax2);
|
||||
tmp = contentRect.height * tmp / (1 + tmp);
|
||||
gridY[1] = tmp;
|
||||
gridY[2] = tmp;
|
||||
gridY[3] = contentRect.height;
|
||||
}
|
||||
|
||||
if (_tileGridIndice == 0)
|
||||
{
|
||||
for (int cy = 0; cy < 4; cy++)
|
||||
{
|
||||
for (int cx = 0; cx < 4; cx++)
|
||||
vb.AddVert(new Vector2(gridX[cx] / _textureScale.x, gridY[cy] / _textureScale.y), vb.vertexColor, new Vector2(gridTexX[cx], gridTexY[cy]));
|
||||
}
|
||||
vb.AddTriangles(TRIANGLES_9_GRID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect drawRect;
|
||||
Rect texRect;
|
||||
int row, col;
|
||||
int part;
|
||||
|
||||
for (int pi = 0; pi < 9; pi++)
|
||||
{
|
||||
col = pi % 3;
|
||||
row = pi / 3;
|
||||
part = gridTileIndice[pi];
|
||||
drawRect = Rect.MinMaxRect(gridX[col], gridY[row], gridX[col + 1], gridY[row + 1]);
|
||||
texRect = Rect.MinMaxRect(gridTexX[col], gridTexY[row + 1], gridTexX[col + 1], gridTexY[row]);
|
||||
|
||||
if (part != -1 && (_tileGridIndice & (1 << part)) != 0)
|
||||
{
|
||||
TileFill(vb, drawRect, texRect,
|
||||
(part == 0 || part == 1 || part == 4) ? gridRect.width : drawRect.width,
|
||||
(part == 2 || part == 3 || part == 4) ? gridRect.height : drawRect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawRect.x /= _textureScale.x;
|
||||
drawRect.y /= _textureScale.y;
|
||||
drawRect.width /= _textureScale.x;
|
||||
drawRect.height /= _textureScale.y;
|
||||
|
||||
vb.AddQuad(drawRect, vb.vertexColor, texRect);
|
||||
}
|
||||
}
|
||||
|
||||
vb.AddTriangles();
|
||||
}
|
||||
}
|
||||
|
||||
void TileFill(VertexBuffer vb, Rect contentRect, Rect uvRect, float sourceW, float sourceH)
|
||||
{
|
||||
int hc = Mathf.CeilToInt(contentRect.width / sourceW);
|
||||
int vc = Mathf.CeilToInt(contentRect.height / sourceH);
|
||||
float tailWidth = contentRect.width - (hc - 1) * sourceW;
|
||||
float tailHeight = contentRect.height - (vc - 1) * sourceH;
|
||||
float xMax = uvRect.xMax;
|
||||
float yMax = uvRect.yMax;
|
||||
|
||||
for (int i = 0; i < hc; i++)
|
||||
{
|
||||
for (int j = 0; j < vc; j++)
|
||||
{
|
||||
Rect uvTmp = uvRect;
|
||||
if (i == hc - 1)
|
||||
uvTmp.xMax = Mathf.Lerp(uvRect.x, xMax, tailWidth / sourceW);
|
||||
if (j == vc - 1)
|
||||
uvTmp.yMin = Mathf.Lerp(uvRect.y, yMax, 1 - tailHeight / sourceH);
|
||||
|
||||
Rect drawRect = new Rect(contentRect.x + i * sourceW, contentRect.y + j * sourceH,
|
||||
i == (hc - 1) ? tailWidth : sourceW, j == (vc - 1) ? tailHeight : sourceH);
|
||||
|
||||
drawRect.x /= _textureScale.x;
|
||||
drawRect.y /= _textureScale.y;
|
||||
drawRect.width /= _textureScale.x;
|
||||
drawRect.height /= _textureScale.y;
|
||||
|
||||
vb.AddQuad(drawRect, vb.vertexColor, uvTmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 948ec8822e3c52942bc6e7f6265b264c
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,243 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
[Flags]
|
||||
public enum MaterialFlags
|
||||
{
|
||||
Clipped = 1,
|
||||
SoftClipped = 2,
|
||||
StencilTest = 4,
|
||||
AlphaMask = 8,
|
||||
Grayed = 16,
|
||||
ColorFilter = 32
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Every texture-shader combination has a MaterialManager.
|
||||
/// </summary>
|
||||
public class MaterialManager
|
||||
{
|
||||
public event Action<Material> onCreateNewMaterial;
|
||||
|
||||
public bool firstMaterialInFrame;
|
||||
|
||||
NTexture _texture;
|
||||
Shader _shader;
|
||||
List<string> _addKeywords;
|
||||
Dictionary<int, List<MaterialRef>> _materials;
|
||||
bool _combineTexture;
|
||||
|
||||
class MaterialRef
|
||||
{
|
||||
public Material material;
|
||||
public int frame;
|
||||
public BlendMode blendMode;
|
||||
public uint group;
|
||||
}
|
||||
|
||||
const int internalKeywordsCount = 6;
|
||||
static string[] internalKeywords = new[] { "CLIPPED", "SOFT_CLIPPED", null, "ALPHA_MASK", "GRAYED", "COLOR_FILTER" };
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="shader"></param>
|
||||
internal MaterialManager(NTexture texture, Shader shader)
|
||||
{
|
||||
_texture = texture;
|
||||
_shader = shader;
|
||||
_materials = new Dictionary<int, List<MaterialRef>>();
|
||||
_combineTexture = texture.alphaTexture != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="keywords"></param>
|
||||
/// <returns></returns>
|
||||
public int GetFlagsByKeywords(IList<string> keywords)
|
||||
{
|
||||
if (_addKeywords == null)
|
||||
_addKeywords = new List<string>();
|
||||
|
||||
int flags = 0;
|
||||
for (int i = 0; i < keywords.Count; i++)
|
||||
{
|
||||
string s = keywords[i];
|
||||
if (string.IsNullOrEmpty(s))
|
||||
continue;
|
||||
int j = _addKeywords.IndexOf(s);
|
||||
if (j == -1)
|
||||
{
|
||||
j = _addKeywords.Count;
|
||||
_addKeywords.Add(s);
|
||||
}
|
||||
flags += (1 << (j + internalKeywordsCount));
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="flags"></param>
|
||||
/// <param name="blendMode"></param>
|
||||
/// <param name="group"></param>
|
||||
/// <returns></returns>
|
||||
public Material GetMaterial(int flags, BlendMode blendMode, uint group)
|
||||
{
|
||||
if (blendMode != BlendMode.Normal && BlendModeUtils.Factors[(int)blendMode].pma)
|
||||
flags |= (int)MaterialFlags.ColorFilter;
|
||||
|
||||
List<MaterialRef> items;
|
||||
if (!_materials.TryGetValue(flags, out items))
|
||||
{
|
||||
items = new List<MaterialRef>();
|
||||
_materials[flags] = items;
|
||||
}
|
||||
|
||||
int frameId = Time.frameCount;
|
||||
int cnt = items.Count;
|
||||
MaterialRef result = null;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
MaterialRef item = items[i];
|
||||
|
||||
if (item.group == group && item.blendMode == blendMode)
|
||||
{
|
||||
if (item.frame != frameId)
|
||||
{
|
||||
firstMaterialInFrame = true;
|
||||
item.frame = frameId;
|
||||
}
|
||||
else
|
||||
firstMaterialInFrame = false;
|
||||
|
||||
if (_combineTexture)
|
||||
item.material.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
|
||||
|
||||
return item.material;
|
||||
}
|
||||
else if (result == null && (item.frame > frameId || item.frame < frameId - 1)) //collect materials if it is unused in last frame
|
||||
result = item;
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
result = new MaterialRef() { material = CreateMaterial(flags) };
|
||||
items.Add(result);
|
||||
}
|
||||
else if (_combineTexture)
|
||||
result.material.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
|
||||
|
||||
if (result.blendMode != blendMode)
|
||||
{
|
||||
BlendModeUtils.Apply(result.material, blendMode);
|
||||
result.blendMode = blendMode;
|
||||
}
|
||||
|
||||
result.group = group;
|
||||
result.frame = frameId;
|
||||
firstMaterialInFrame = true;
|
||||
return result.material;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Material CreateMaterial(int flags)
|
||||
{
|
||||
Material mat = new Material(_shader);
|
||||
|
||||
mat.mainTexture = _texture.nativeTexture;
|
||||
if (_texture.alphaTexture != null)
|
||||
{
|
||||
mat.EnableKeyword("COMBINED");
|
||||
mat.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
|
||||
}
|
||||
|
||||
for (int i = 0; i < internalKeywordsCount; i++)
|
||||
{
|
||||
if ((flags & (1 << i)) != 0)
|
||||
{
|
||||
string s = internalKeywords[i];
|
||||
if (s != null)
|
||||
mat.EnableKeyword(s);
|
||||
}
|
||||
}
|
||||
if (_addKeywords != null)
|
||||
{
|
||||
int keywordCnt = _addKeywords.Count;
|
||||
for (int i = 0; i < keywordCnt; i++)
|
||||
{
|
||||
if ((flags & (1 << (i + internalKeywordsCount))) != 0)
|
||||
mat.EnableKeyword(_addKeywords[i]);
|
||||
}
|
||||
}
|
||||
|
||||
mat.hideFlags = DisplayObject.hideFlags;
|
||||
if (onCreateNewMaterial != null)
|
||||
onCreateNewMaterial(mat);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void DestroyMaterials()
|
||||
{
|
||||
var iter = _materials.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
List<MaterialRef> items = iter.Current.Value;
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
int cnt = items.Count;
|
||||
for (int j = 0; j < cnt; j++)
|
||||
Object.Destroy(items[j].material);
|
||||
}
|
||||
else
|
||||
{
|
||||
int cnt = items.Count;
|
||||
for (int j = 0; j < cnt; j++)
|
||||
Object.DestroyImmediate(items[j].material);
|
||||
}
|
||||
items.Clear();
|
||||
}
|
||||
iter.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void RefreshMaterials()
|
||||
{
|
||||
_combineTexture = _texture.alphaTexture != null;
|
||||
var iter = _materials.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
{
|
||||
List<MaterialRef> items = iter.Current.Value;
|
||||
int cnt = items.Count;
|
||||
for (int j = 0; j < cnt; j++)
|
||||
{
|
||||
Material mat = items[j].material;
|
||||
mat.mainTexture = _texture.nativeTexture;
|
||||
if (_combineTexture)
|
||||
{
|
||||
mat.EnableKeyword("COMBINED");
|
||||
mat.SetTexture(ShaderConfig.ID_AlphaTex, _texture.alphaTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7223c4628e56c1e448c70e10168f5fa1
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fca659474d209d94fbded309f407995c
|
||||
folderAsset: yes
|
||||
timeCreated: 1545987172
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,75 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CompositeMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<IMeshFactory> elements;
|
||||
|
||||
/// <summary>
|
||||
/// If it is -1, means all elements are active, otherwise, only the specific element is active
|
||||
/// </summary>
|
||||
public int activeIndex;
|
||||
|
||||
public CompositeMesh()
|
||||
{
|
||||
elements = new List<IMeshFactory>();
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
int cnt = elements.Count;
|
||||
if (cnt == 1)
|
||||
elements[0].OnPopulateMesh(vb);
|
||||
else
|
||||
{
|
||||
VertexBuffer vb2 = VertexBuffer.Begin(vb);
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
if (activeIndex == -1 || i == activeIndex)
|
||||
{
|
||||
vb2.Clear();
|
||||
elements[i].OnPopulateMesh(vb2);
|
||||
vb.Append(vb2);
|
||||
}
|
||||
}
|
||||
|
||||
vb2.End();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
if (!contentRect.Contains(point))
|
||||
return false;
|
||||
|
||||
bool flag = false;
|
||||
int cnt = elements.Count;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
if (activeIndex == -1 || i == activeIndex)
|
||||
{
|
||||
IHitTest ht = elements[i] as IHitTest;
|
||||
if (ht != null)
|
||||
{
|
||||
if (ht.HitTest(contentRect, point))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba3d921c1f6e95f4e9105f45fd67bda5
|
||||
timeCreated: 1546159121
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,200 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EllipseMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect? drawRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 lineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? centerColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? fillColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float startDegree;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float endDegreee;
|
||||
|
||||
static int[] SECTOR_CENTER_TRIANGLES = new int[] {
|
||||
0, 4, 1,
|
||||
0, 3, 4,
|
||||
0, 2, 3,
|
||||
0, 8, 5,
|
||||
0, 7, 8,
|
||||
0, 6, 7,
|
||||
6, 5, 2,
|
||||
2, 1, 6
|
||||
};
|
||||
|
||||
public EllipseMesh()
|
||||
{
|
||||
lineColor = Color.black;
|
||||
startDegree = 0;
|
||||
endDegreee = 360;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect;
|
||||
Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
|
||||
|
||||
float sectionStart = Mathf.Clamp(startDegree, 0, 360);
|
||||
float sectionEnd = Mathf.Clamp(endDegreee, 0, 360);
|
||||
bool clipped = sectionStart > 0 || sectionEnd < 360;
|
||||
sectionStart = sectionStart * Mathf.Deg2Rad;
|
||||
sectionEnd = sectionEnd * Mathf.Deg2Rad;
|
||||
Color32 centerColor2 = centerColor == null ? color : (Color32)centerColor;
|
||||
|
||||
float radiusX = rect.width / 2;
|
||||
float radiusY = rect.height / 2;
|
||||
int sides = Mathf.CeilToInt(Mathf.PI * (radiusX + radiusY) / 4);
|
||||
sides = Mathf.Clamp(sides, 40, 800);
|
||||
float angleDelta = 2 * Mathf.PI / sides;
|
||||
float angle = 0;
|
||||
float lineAngle = 0;
|
||||
|
||||
if (lineWidth > 0 && clipped)
|
||||
{
|
||||
lineAngle = lineWidth / Mathf.Max(radiusX, radiusY);
|
||||
sectionStart += lineAngle;
|
||||
sectionEnd -= lineAngle;
|
||||
}
|
||||
|
||||
int vpos = vb.currentVertCount;
|
||||
float centerX = rect.x + radiusX;
|
||||
float centerY = rect.y + radiusY;
|
||||
vb.AddVert(new Vector3(centerX, centerY, 0), centerColor2);
|
||||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
if (angle < sectionStart)
|
||||
angle = sectionStart;
|
||||
else if (angle > sectionEnd)
|
||||
angle = sectionEnd;
|
||||
Vector3 vec = new Vector3(Mathf.Cos(angle) * (radiusX - lineWidth) + centerX, Mathf.Sin(angle) * (radiusY - lineWidth) + centerY, 0);
|
||||
vb.AddVert(vec, color);
|
||||
if (lineWidth > 0)
|
||||
{
|
||||
vb.AddVert(vec, lineColor);
|
||||
vb.AddVert(new Vector3(Mathf.Cos(angle) * radiusX + centerX, Mathf.Sin(angle) * radiusY + centerY, 0), lineColor);
|
||||
}
|
||||
angle += angleDelta;
|
||||
}
|
||||
|
||||
if (lineWidth > 0)
|
||||
{
|
||||
int cnt = sides * 3;
|
||||
for (int i = 0; i < cnt; i += 3)
|
||||
{
|
||||
if (i != cnt - 3)
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, i + 4);
|
||||
vb.AddTriangle(i + 5, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, i + 6, i + 5);
|
||||
}
|
||||
else if (!clipped)
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, 1);
|
||||
vb.AddTriangle(2, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, 3, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, i + 1);
|
||||
vb.AddTriangle(i + 2, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, i + 3, i + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
if (i != sides - 1)
|
||||
vb.AddTriangle(0, i + 1, i + 2);
|
||||
else if (!clipped)
|
||||
vb.AddTriangle(0, i + 1, 1);
|
||||
else
|
||||
vb.AddTriangle(0, i + 1, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (lineWidth > 0 && clipped)
|
||||
{
|
||||
//扇形内边缘的线条
|
||||
|
||||
vb.AddVert(new Vector3(radiusX, radiusY, 0), lineColor);
|
||||
float centerRadius = lineWidth * 0.5f;
|
||||
|
||||
sectionStart -= lineAngle;
|
||||
angle = sectionStart + lineAngle * 0.5f + Mathf.PI * 0.5f;
|
||||
vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor);
|
||||
angle -= Mathf.PI;
|
||||
vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor);
|
||||
vb.AddVert(new Vector3(Mathf.Cos(sectionStart) * radiusX + radiusX, Mathf.Sin(sectionStart) * radiusY + radiusY, 0), lineColor);
|
||||
vb.AddVert(vb.GetPosition(vpos + 3), lineColor);
|
||||
|
||||
sectionEnd += lineAngle;
|
||||
angle = sectionEnd - lineAngle * 0.5f + Mathf.PI * 0.5f;
|
||||
vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor);
|
||||
angle -= Mathf.PI;
|
||||
vb.AddVert(new Vector3(Mathf.Cos(angle) * centerRadius + radiusX, Mathf.Sin(angle) * centerRadius + radiusY, 0), lineColor);
|
||||
vb.AddVert(vb.GetPosition(vpos + sides * 3), lineColor);
|
||||
vb.AddVert(new Vector3(Mathf.Cos(sectionEnd) * radiusX + radiusX, Mathf.Sin(sectionEnd) * radiusY + radiusY, 0), lineColor);
|
||||
|
||||
vb.AddTriangles(SECTOR_CENTER_TRIANGLES, sides * 3 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
if (!contentRect.Contains(point))
|
||||
return false;
|
||||
|
||||
float radiusX = contentRect.width * 0.5f;
|
||||
float raduisY = contentRect.height * 0.5f;
|
||||
float xx = point.x - radiusX - contentRect.x;
|
||||
float yy = point.y - raduisY - contentRect.y;
|
||||
if (Mathf.Pow(xx / radiusX, 2) + Mathf.Pow(yy / raduisY, 2) < 1)
|
||||
{
|
||||
if (startDegree != 0 || endDegreee != 360)
|
||||
{
|
||||
float deg = Mathf.Atan2(yy, xx) * Mathf.Rad2Deg;
|
||||
if (deg < 0)
|
||||
deg += 360;
|
||||
return deg >= startDegree && deg <= endDegreee;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ea96854995120948847301fb48d1675
|
||||
timeCreated: 1545987173
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,400 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class FillMesh : IMeshFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public FillMethod method;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int origin;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float amount;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool clockwise;
|
||||
|
||||
public FillMesh()
|
||||
{
|
||||
clockwise = true;
|
||||
amount = 1;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
float amount = Mathf.Clamp01(this.amount);
|
||||
switch (method)
|
||||
{
|
||||
case FillMethod.Horizontal:
|
||||
FillHorizontal(vb, vb.contentRect, origin, amount);
|
||||
break;
|
||||
|
||||
case FillMethod.Vertical:
|
||||
FillVertical(vb, vb.contentRect, origin, amount);
|
||||
break;
|
||||
|
||||
case FillMethod.Radial90:
|
||||
FillRadial90(vb, vb.contentRect, (Origin90)origin, amount, clockwise);
|
||||
break;
|
||||
|
||||
case FillMethod.Radial180:
|
||||
FillRadial180(vb, vb.contentRect, (Origin180)origin, amount, clockwise);
|
||||
break;
|
||||
|
||||
case FillMethod.Radial360:
|
||||
FillRadial360(vb, vb.contentRect, (Origin360)origin, amount, clockwise);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void FillHorizontal(VertexBuffer vb, Rect vertRect, int origin, float amount)
|
||||
{
|
||||
float a = vertRect.width * amount;
|
||||
if ((OriginHorizontal)origin == OriginHorizontal.Right || (OriginVertical)origin == OriginVertical.Bottom)
|
||||
vertRect.x += (vertRect.width - a);
|
||||
vertRect.width = a;
|
||||
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles();
|
||||
}
|
||||
|
||||
static void FillVertical(VertexBuffer vb, Rect vertRect, int origin, float amount)
|
||||
{
|
||||
float a = vertRect.height * amount;
|
||||
if ((OriginHorizontal)origin == OriginHorizontal.Right || (OriginVertical)origin == OriginVertical.Bottom)
|
||||
vertRect.y += (vertRect.height - a);
|
||||
vertRect.height = a;
|
||||
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles();
|
||||
}
|
||||
|
||||
//4 vertex
|
||||
static void FillRadial90(VertexBuffer vb, Rect vertRect, Origin90 origin, float amount, bool clockwise)
|
||||
{
|
||||
bool flipX = origin == Origin90.TopRight || origin == Origin90.BottomRight;
|
||||
bool flipY = origin == Origin90.BottomLeft || origin == Origin90.BottomRight;
|
||||
if (flipX != flipY)
|
||||
clockwise = !clockwise;
|
||||
|
||||
float ratio = clockwise ? amount : (1 - amount);
|
||||
float tan = Mathf.Tan(Mathf.PI * 0.5f * ratio);
|
||||
bool thresold = false;
|
||||
if (ratio != 1)
|
||||
thresold = (vertRect.height / vertRect.width - tan) > 0;
|
||||
if (!clockwise)
|
||||
thresold = !thresold;
|
||||
float x = vertRect.x + (ratio == 0 ? float.MaxValue : (vertRect.height / tan));
|
||||
float y = vertRect.y + (ratio == 1 ? float.MaxValue : (vertRect.width * tan));
|
||||
float x2 = x;
|
||||
float y2 = y;
|
||||
if (flipX)
|
||||
x2 = vertRect.width - x;
|
||||
if (flipY)
|
||||
y2 = vertRect.height - y;
|
||||
float xMin = flipX ? (vertRect.width - vertRect.x) : vertRect.xMin;
|
||||
float yMin = flipY ? (vertRect.height - vertRect.y) : vertRect.yMin;
|
||||
float xMax = flipX ? -vertRect.xMin : vertRect.xMax;
|
||||
float yMax = flipY ? -vertRect.yMin : vertRect.yMax;
|
||||
|
||||
vb.AddVert(new Vector3(xMin, yMin, 0));
|
||||
|
||||
if (clockwise)
|
||||
vb.AddVert(new Vector3(xMax, yMin, 0));
|
||||
|
||||
if (y > vertRect.yMax)
|
||||
{
|
||||
if (thresold)
|
||||
vb.AddVert(new Vector3(x2, yMax, 0));
|
||||
else
|
||||
vb.AddVert(new Vector3(xMax, yMax, 0));
|
||||
}
|
||||
else
|
||||
vb.AddVert(new Vector3(xMax, y2, 0));
|
||||
|
||||
if (x > vertRect.xMax)
|
||||
{
|
||||
if (thresold)
|
||||
vb.AddVert(new Vector3(xMax, y2, 0));
|
||||
else
|
||||
vb.AddVert(new Vector3(xMax, yMax, 0));
|
||||
}
|
||||
else
|
||||
vb.AddVert(new Vector3(x2, yMax, 0));
|
||||
|
||||
if (!clockwise)
|
||||
vb.AddVert(new Vector3(xMin, yMax, 0));
|
||||
|
||||
if (flipX == flipY)
|
||||
{
|
||||
vb.AddTriangle(0, 1, 2);
|
||||
vb.AddTriangle(0, 2, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
vb.AddTriangle(2, 1, 0);
|
||||
vb.AddTriangle(3, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//8 vertex
|
||||
static void FillRadial180(VertexBuffer vb, Rect vertRect, Origin180 origin, float amount, bool clockwise)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case Origin180.Top:
|
||||
if (amount <= 0.5f)
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.TopLeft : Origin90.TopRight, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-4);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.TopRight : Origin90.TopLeft, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
else
|
||||
vertRect.x -= vertRect.width;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Origin180.Bottom:
|
||||
if (amount <= 0.5f)
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.BottomRight : Origin90.BottomLeft, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-4);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.BottomLeft : Origin90.BottomRight, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.x -= vertRect.width;
|
||||
else
|
||||
vertRect.x += vertRect.width;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Origin180.Left:
|
||||
if (amount <= 0.5f)
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.BottomLeft : Origin90.TopLeft, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-4);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.TopLeft : Origin90.BottomLeft, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.y -= vertRect.height;
|
||||
else
|
||||
vertRect.y += vertRect.height;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Origin180.Right:
|
||||
if (amount <= 0.5f)
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.TopRight : Origin90.BottomRight, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-4);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial90(vb, vertRect, clockwise ? Origin90.BottomRight : Origin90.TopRight, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
else
|
||||
vertRect.y -= vertRect.height;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//12 vertex
|
||||
static void FillRadial360(VertexBuffer vb, Rect vertRect, Origin360 origin, float amount, bool clockwise)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case Origin360.Top:
|
||||
if (amount < 0.5f)
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Left : Origin180.Right, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-8);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Right : Origin180.Left, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
else
|
||||
vertRect.x -= vertRect.width;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Origin360.Bottom:
|
||||
if (amount < 0.5f)
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Right : Origin180.Left, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-8);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.width /= 2;
|
||||
if (clockwise)
|
||||
vertRect.x += vertRect.width;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Left : Origin180.Right, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.x -= vertRect.width;
|
||||
else
|
||||
vertRect.x += vertRect.width;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Origin360.Left:
|
||||
if (amount < 0.5f)
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Bottom : Origin180.Top, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-8);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Top : Origin180.Bottom, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.y -= vertRect.height;
|
||||
else
|
||||
vertRect.y += vertRect.height;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
|
||||
case Origin360.Right:
|
||||
if (amount < 0.5f)
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Top : Origin180.Bottom, amount / 0.5f, clockwise);
|
||||
Vector3 vec = vb.GetPosition(-8);
|
||||
vb.AddQuad(new Rect(vec.x, vec.y, 0, 0));
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertRect.height /= 2;
|
||||
if (!clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
|
||||
FillRadial180(vb, vertRect, clockwise ? Origin180.Bottom : Origin180.Top, (amount - 0.5f) / 0.5f, clockwise);
|
||||
|
||||
if (clockwise)
|
||||
vertRect.y += vertRect.height;
|
||||
else
|
||||
vertRect.y -= vertRect.height;
|
||||
vb.AddQuad(vertRect);
|
||||
vb.AddTriangles(-4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b37d56dc1840734a8fdb4971f5bc733
|
||||
timeCreated: 1545987173
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,179 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Inspired by kim ki won (http://mypi.ruliweb.daum.net/mypi.htm?id=newtypekorea)
|
||||
/// </summary>
|
||||
public class LineMesh : IMeshFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public GPath path;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public AnimationCurve lineWidthCurve;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Gradient gradient;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool roundEdge;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float fillStart;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float fillEnd;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float pointDensity;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool repeatFill;
|
||||
|
||||
static List<Vector3> points = new List<Vector3>();
|
||||
static List<float> ts = new List<float>();
|
||||
|
||||
public LineMesh()
|
||||
{
|
||||
path = new GPath();
|
||||
lineWidth = 2;
|
||||
fillStart = 0;
|
||||
fillEnd = 1;
|
||||
pointDensity = 0.1f;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
Vector2 uvMin = vb.uvRect.position;
|
||||
Vector2 uvMax = new Vector2(vb.uvRect.xMax, vb.uvRect.yMax);
|
||||
float uvRatio = path.length / vb.textureSize.x;
|
||||
|
||||
int segCount = path.segmentCount;
|
||||
float t = 0;
|
||||
float lw = lineWidth;
|
||||
float u;
|
||||
for (int si = 0; si < segCount; si++)
|
||||
{
|
||||
float ratio = path.GetSegmentLength(si) / path.length;
|
||||
float t0 = Mathf.Clamp(fillStart - t, 0, ratio) / ratio;
|
||||
float t1 = Mathf.Clamp(fillEnd - t, 0, ratio) / ratio;
|
||||
if (t0 >= t1)
|
||||
{
|
||||
t += ratio;
|
||||
continue;
|
||||
}
|
||||
|
||||
points.Clear();
|
||||
ts.Clear();
|
||||
path.GetPointsInSegment(si, t0, t1, points, ts, pointDensity);
|
||||
int cnt = points.Count;
|
||||
|
||||
Color c0 = vb.vertexColor;
|
||||
Color c1 = vb.vertexColor;
|
||||
if (gradient != null)
|
||||
c0 = gradient.Evaluate(t);
|
||||
if (lineWidthCurve != null)
|
||||
lw = lineWidthCurve.Evaluate(t);
|
||||
|
||||
if (roundEdge && si == 0 && t0 == 0)
|
||||
DrawRoundEdge(vb, points[0], points[1], lw, c0, uvMin);
|
||||
|
||||
int vertCount = vb.currentVertCount;
|
||||
for (int i = 1; i < cnt; i++)
|
||||
{
|
||||
Vector3 p0 = points[i - 1];
|
||||
Vector3 p1 = points[i];
|
||||
int k = vertCount + (i - 1) * 2;
|
||||
float tc = t + ratio * ts[i];
|
||||
|
||||
Vector3 lineVector = p1 - p0;
|
||||
Vector3 widthVector = Vector3.Cross(lineVector, new Vector3(0, 0, 1));
|
||||
widthVector.Normalize();
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
if (repeatFill)
|
||||
u = tc * uvRatio * uvMax.x;
|
||||
else
|
||||
u = Mathf.Lerp(uvMin.x, uvMax.x, t + ratio * ts[i - 1]);
|
||||
vb.AddVert(p0 - widthVector * lw * 0.5f, c0, new Vector2(u, uvMax.y));
|
||||
vb.AddVert(p0 + widthVector * lw * 0.5f, c0, new Vector2(u, uvMin.y));
|
||||
|
||||
if (si != 0) //joint
|
||||
{
|
||||
vb.AddTriangle(k - 2, k - 1, k + 1);
|
||||
vb.AddTriangle(k - 2, k + 1, k);
|
||||
}
|
||||
}
|
||||
if (gradient != null)
|
||||
c1 = gradient.Evaluate(tc);
|
||||
|
||||
if (lineWidthCurve != null)
|
||||
lw = lineWidthCurve.Evaluate(tc);
|
||||
|
||||
if (repeatFill)
|
||||
u = tc * uvRatio * uvMax.x;
|
||||
else
|
||||
u = Mathf.Lerp(uvMin.x, uvMax.x, tc);
|
||||
vb.AddVert(p1 - widthVector * lw * 0.5f, c1, new Vector2(u, uvMax.y));
|
||||
vb.AddVert(p1 + widthVector * lw * 0.5f, c1, new Vector2(u, uvMin.y));
|
||||
|
||||
vb.AddTriangle(k, k + 1, k + 3);
|
||||
vb.AddTriangle(k, k + 3, k + 2);
|
||||
}
|
||||
|
||||
if (roundEdge && si == segCount - 1 && t1 == 1)
|
||||
DrawRoundEdge(vb, points[cnt - 1], points[cnt - 2], lw, c1, uvMax);
|
||||
|
||||
t += ratio;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRoundEdge(VertexBuffer vb, Vector2 p0, Vector2 p1, float lw, Color32 color, Vector2 uv)
|
||||
{
|
||||
Vector2 widthVector = Vector3.Cross(p0 - p1, new Vector3(0, 0, 1));
|
||||
widthVector.Normalize();
|
||||
widthVector = widthVector * lw / 2f;
|
||||
Vector2 lineVector = (p0 - p1).normalized * lw / 2f;
|
||||
|
||||
int sides = Mathf.CeilToInt(Mathf.PI * lw / 2);
|
||||
if (sides < 6)
|
||||
sides = 6;
|
||||
int current = vb.currentVertCount;
|
||||
float angleUnit = Mathf.PI / (sides - 1);
|
||||
|
||||
vb.AddVert(p0, color, uv);
|
||||
vb.AddVert(p0 + widthVector, color, uv);
|
||||
|
||||
for (int n = 0; n < sides; n++)
|
||||
{
|
||||
vb.AddVert(p0 + Mathf.Cos(angleUnit * n) * widthVector + Mathf.Sin(angleUnit * n) * lineVector, color, uv);
|
||||
vb.AddTriangle(current, current + 1 + n, current + 2 + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d1935a924fabf74a92c72b22a042279
|
||||
timeCreated: 1546519483
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IMeshFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vb"></param>
|
||||
void OnPopulateMesh(VertexBuffer vb);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 274275eaa3fbbc94697cbe90a0fb52f1
|
||||
timeCreated: 1545987172
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PlaneMesh : IMeshFactory
|
||||
{
|
||||
public int gridSize = 30;
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
float w = vb.contentRect.width;
|
||||
float h = vb.contentRect.height;
|
||||
float xMax = vb.contentRect.xMax;
|
||||
float yMax = vb.contentRect.yMax;
|
||||
int hc = (int)Mathf.Min(Mathf.CeilToInt(w / gridSize), 9);
|
||||
int vc = (int)Mathf.Min(Mathf.CeilToInt(h / gridSize), 9);
|
||||
int eachPartX = Mathf.FloorToInt(w / hc);
|
||||
int eachPartY = Mathf.FloorToInt(h / vc);
|
||||
float x, y;
|
||||
for (int i = 0; i <= vc; i++)
|
||||
{
|
||||
if (i == vc)
|
||||
y = yMax;
|
||||
else
|
||||
y = vb.contentRect.y + i * eachPartY;
|
||||
for (int j = 0; j <= hc; j++)
|
||||
{
|
||||
if (j == hc)
|
||||
x = xMax;
|
||||
else
|
||||
x = vb.contentRect.x + j * eachPartX;
|
||||
vb.AddVert(new Vector3(x, y, 0));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < vc; i++)
|
||||
{
|
||||
int k = i * (hc + 1);
|
||||
for (int j = 1; j <= hc; j++)
|
||||
{
|
||||
int m = k + j;
|
||||
vb.AddTriangle(m - 1, m, m + hc);
|
||||
vb.AddTriangle(m, m + hc + 1, m + hc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 121b756a7a8240c49b63fa9de560691a
|
||||
timeCreated: 1547970144
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,291 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PolygonMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
/// points must be in clockwise order, and must start from bottom-left if stretchUV is set.
|
||||
/// </summary>
|
||||
public readonly List<Vector2> points;
|
||||
|
||||
/// <summary>
|
||||
/// if you dont want to provide uv, leave it empty.
|
||||
/// </summary>
|
||||
public readonly List<Vector2> texcoords;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 lineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? fillColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32[] colors;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool usePercentPositions;
|
||||
|
||||
static List<int> sRestIndices = new List<int>();
|
||||
|
||||
public PolygonMesh()
|
||||
{
|
||||
points = new List<Vector2>();
|
||||
texcoords = new List<Vector2>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
public void Add(Vector2 point)
|
||||
{
|
||||
points.Add(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
/// <param name="texcoord"></param>
|
||||
public void Add(Vector2 point, Vector2 texcoord)
|
||||
{
|
||||
points.Add(point);
|
||||
texcoords.Add(texcoord);
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
int numVertices = points.Count;
|
||||
if (numVertices < 3)
|
||||
return;
|
||||
|
||||
int restIndexPos, numRestIndices;
|
||||
Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
|
||||
|
||||
float w = vb.contentRect.width;
|
||||
float h = vb.contentRect.height;
|
||||
bool useTexcoords = texcoords.Count >= numVertices;
|
||||
bool fullUV = true;
|
||||
for (int i = 0; i < numVertices; i++)
|
||||
{
|
||||
Vector3 vec = new Vector3(points[i].x, points[i].y, 0);
|
||||
if (usePercentPositions)
|
||||
{
|
||||
vec.x *= w;
|
||||
vec.y *= h;
|
||||
}
|
||||
if (useTexcoords)
|
||||
{
|
||||
Vector2 uv = texcoords[i];
|
||||
if (uv.x != 0 && uv.x != 1 || uv.y != 0 && uv.y != 1)
|
||||
fullUV = false;
|
||||
uv.x = Mathf.Lerp(vb.uvRect.x, vb.uvRect.xMax, uv.x);
|
||||
uv.y = Mathf.Lerp(vb.uvRect.y, vb.uvRect.yMax, uv.y);
|
||||
vb.AddVert(vec, color, uv);
|
||||
}
|
||||
else
|
||||
vb.AddVert(vec, color);
|
||||
}
|
||||
|
||||
if (useTexcoords && fullUV && numVertices == 4)
|
||||
vb._isArbitraryQuad = true;
|
||||
|
||||
// Algorithm "Ear clipping method" described here:
|
||||
// -> https://en.wikipedia.org/wiki/Polygon_triangulation
|
||||
//
|
||||
// Implementation inspired by:
|
||||
// -> http://polyk.ivank.net
|
||||
// -> Starling
|
||||
|
||||
sRestIndices.Clear();
|
||||
for (int i = 0; i < numVertices; ++i)
|
||||
sRestIndices.Add(i);
|
||||
|
||||
restIndexPos = 0;
|
||||
numRestIndices = numVertices;
|
||||
|
||||
Vector2 a, b, c, p;
|
||||
int otherIndex;
|
||||
bool earFound;
|
||||
int i0, i1, i2;
|
||||
|
||||
while (numRestIndices > 3)
|
||||
{
|
||||
earFound = false;
|
||||
i0 = sRestIndices[restIndexPos % numRestIndices];
|
||||
i1 = sRestIndices[(restIndexPos + 1) % numRestIndices];
|
||||
i2 = sRestIndices[(restIndexPos + 2) % numRestIndices];
|
||||
|
||||
a = points[i0];
|
||||
b = points[i1];
|
||||
c = points[i2];
|
||||
|
||||
if ((a.y - b.y) * (c.x - b.x) + (b.x - a.x) * (c.y - b.y) >= 0)
|
||||
{
|
||||
earFound = true;
|
||||
for (int i = 3; i < numRestIndices; ++i)
|
||||
{
|
||||
otherIndex = sRestIndices[(restIndexPos + i) % numRestIndices];
|
||||
p = points[otherIndex];
|
||||
|
||||
if (IsPointInTriangle(ref p, ref a, ref b, ref c))
|
||||
{
|
||||
earFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (earFound)
|
||||
{
|
||||
vb.AddTriangle(i0, i1, i2);
|
||||
sRestIndices.RemoveAt((restIndexPos + 1) % numRestIndices);
|
||||
|
||||
numRestIndices--;
|
||||
restIndexPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
restIndexPos++;
|
||||
if (restIndexPos == numRestIndices) break; // no more ears
|
||||
}
|
||||
}
|
||||
vb.AddTriangle(sRestIndices[0], sRestIndices[1], sRestIndices[2]);
|
||||
|
||||
if (colors != null)
|
||||
vb.RepeatColors(colors, 0, vb.currentVertCount);
|
||||
|
||||
if (lineWidth > 0)
|
||||
DrawOutline(vb);
|
||||
}
|
||||
|
||||
void DrawOutline(VertexBuffer vb)
|
||||
{
|
||||
int numVertices = points.Count;
|
||||
int start = vb.currentVertCount - numVertices;
|
||||
int k = vb.currentVertCount;
|
||||
for (int i = 0; i < numVertices; i++)
|
||||
{
|
||||
Vector3 p0 = vb.vertices[start + i];
|
||||
p0.y = -p0.y;
|
||||
Vector3 p1;
|
||||
if (i < numVertices - 1)
|
||||
p1 = vb.vertices[start + i + 1];
|
||||
else
|
||||
p1 = vb.vertices[start];
|
||||
p1.y = -p1.y;
|
||||
|
||||
Vector3 lineVector = p1 - p0;
|
||||
Vector3 widthVector = Vector3.Cross(lineVector, new Vector3(0, 0, 1));
|
||||
widthVector.Normalize();
|
||||
|
||||
vb.AddVert(p0 - widthVector * lineWidth * 0.5f, lineColor);
|
||||
vb.AddVert(p0 + widthVector * lineWidth * 0.5f, lineColor);
|
||||
vb.AddVert(p1 - widthVector * lineWidth * 0.5f, lineColor);
|
||||
vb.AddVert(p1 + widthVector * lineWidth * 0.5f, lineColor);
|
||||
|
||||
k += 4;
|
||||
vb.AddTriangle(k - 4, k - 3, k - 1);
|
||||
vb.AddTriangle(k - 4, k - 1, k - 2);
|
||||
|
||||
//joint
|
||||
if (i != 0)
|
||||
{
|
||||
vb.AddTriangle(k - 6, k - 5, k - 3);
|
||||
vb.AddTriangle(k - 6, k - 3, k - 4);
|
||||
}
|
||||
if (i == numVertices - 1)
|
||||
{
|
||||
start += numVertices;
|
||||
vb.AddTriangle(k - 2, k - 1, start + 1);
|
||||
vb.AddTriangle(k - 2, start + 1, start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPointInTriangle(ref Vector2 p, ref Vector2 a, ref Vector2 b, ref Vector2 c)
|
||||
{
|
||||
// From Starling
|
||||
// This algorithm is described well in this article:
|
||||
// http://www.blackpawn.com/texts/pointinpoly/default.html
|
||||
|
||||
float v0x = c.x - a.x;
|
||||
float v0y = c.y - a.y;
|
||||
float v1x = b.x - a.x;
|
||||
float v1y = b.y - a.y;
|
||||
float v2x = p.x - a.x;
|
||||
float v2y = p.y - a.y;
|
||||
|
||||
float dot00 = v0x * v0x + v0y * v0y;
|
||||
float dot01 = v0x * v1x + v0y * v1y;
|
||||
float dot02 = v0x * v2x + v0y * v2y;
|
||||
float dot11 = v1x * v1x + v1y * v1y;
|
||||
float dot12 = v1x * v2x + v1y * v2y;
|
||||
|
||||
float invDen = 1.0f / (dot00 * dot11 - dot01 * dot01);
|
||||
float u = (dot11 * dot02 - dot01 * dot12) * invDen;
|
||||
float v = (dot00 * dot12 - dot01 * dot02) * invDen;
|
||||
|
||||
return (u >= 0) && (v >= 0) && (u + v < 1);
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
if (!contentRect.Contains(point))
|
||||
return false;
|
||||
|
||||
// Algorithm & implementation thankfully taken from:
|
||||
// -> http://alienryderflex.com/polygon/
|
||||
// inspired by Starling
|
||||
int len = points.Count;
|
||||
int i;
|
||||
int j = len - 1;
|
||||
bool oddNodes = false;
|
||||
float w = contentRect.width;
|
||||
float h = contentRect.height;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
float ix = points[i].x;
|
||||
float iy = points[i].y;
|
||||
float jx = points[j].x;
|
||||
float jy = points[j].y;
|
||||
if (usePercentPositions)
|
||||
{
|
||||
ix *= w;
|
||||
iy *= h;
|
||||
ix *= w;
|
||||
iy *= h;
|
||||
}
|
||||
|
||||
if ((iy < point.y && jy >= point.y || jy < point.y && iy >= point.y) && (ix <= point.x || jx <= point.x))
|
||||
{
|
||||
if (ix + (point.y - iy) / (jy - iy) * (jx - ix) < point.x)
|
||||
oddNodes = !oddNodes;
|
||||
}
|
||||
|
||||
j = i;
|
||||
}
|
||||
|
||||
return oddNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db020628cd79e714fbafdbaaa2cc355f
|
||||
timeCreated: 1545987173
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RectMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect? drawRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 lineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? fillColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32[] colors;
|
||||
|
||||
public RectMesh()
|
||||
{
|
||||
lineColor = Color.black;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect;
|
||||
Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
|
||||
if (lineWidth == 0)
|
||||
{
|
||||
if (color.a != 0)//optimized
|
||||
vb.AddQuad(rect, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect part;
|
||||
|
||||
//left,right
|
||||
part = new Rect(rect.x, rect.y, lineWidth, rect.height);
|
||||
vb.AddQuad(part, lineColor);
|
||||
part = new Rect(rect.xMax - lineWidth, rect.y, lineWidth, rect.height);
|
||||
vb.AddQuad(part, lineColor);
|
||||
|
||||
//top, bottom
|
||||
part = new Rect(rect.x + lineWidth, rect.y, rect.width - lineWidth * 2, lineWidth);
|
||||
vb.AddQuad(part, lineColor);
|
||||
part = new Rect(rect.x + lineWidth, rect.yMax - lineWidth, rect.width - lineWidth * 2, lineWidth);
|
||||
vb.AddQuad(part, lineColor);
|
||||
|
||||
//middle
|
||||
if (color.a != 0)//optimized
|
||||
{
|
||||
part = Rect.MinMaxRect(rect.x + lineWidth, rect.y + lineWidth, rect.xMax - lineWidth, rect.yMax - lineWidth);
|
||||
if (part.width > 0 && part.height > 0)
|
||||
vb.AddQuad(part, color);
|
||||
}
|
||||
}
|
||||
|
||||
if (colors != null)
|
||||
vb.RepeatColors(colors, 0, vb.currentVertCount);
|
||||
|
||||
vb.AddTriangles();
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
return contentRect.Contains(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13a3a9d0d365d834696112114d7bf951
|
||||
timeCreated: 1545987172
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RegularPolygonMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect? drawRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int sides;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 lineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? centerColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? fillColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float[] distances;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float rotation;
|
||||
|
||||
public RegularPolygonMesh()
|
||||
{
|
||||
sides = 3;
|
||||
lineColor = Color.black;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
if (distances != null && distances.Length < sides)
|
||||
{
|
||||
Debug.LogError("distances.Length<sides");
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect;
|
||||
Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
|
||||
|
||||
float angleDelta = 2 * Mathf.PI / sides;
|
||||
float angle = rotation * Mathf.Deg2Rad;
|
||||
float radius = Mathf.Min(rect.width / 2, rect.height / 2);
|
||||
|
||||
float centerX = radius + rect.x;
|
||||
float centerY = radius + rect.y;
|
||||
vb.AddVert(new Vector3(centerX, centerY, 0), centerColor == null ? color : (Color32)centerColor);
|
||||
for (int i = 0; i < sides; i++)
|
||||
{
|
||||
float r = radius;
|
||||
if (distances != null)
|
||||
r *= distances[i];
|
||||
float xv = Mathf.Cos(angle) * (r - lineWidth);
|
||||
float yv = Mathf.Sin(angle) * (r - lineWidth);
|
||||
Vector3 vec = new Vector3(xv + centerX, yv + centerY, 0);
|
||||
vb.AddVert(vec, color);
|
||||
if (lineWidth > 0)
|
||||
{
|
||||
vb.AddVert(vec, lineColor);
|
||||
|
||||
xv = Mathf.Cos(angle) * r + centerX;
|
||||
yv = Mathf.Sin(angle) * r + centerY;
|
||||
vb.AddVert(new Vector3(xv, yv, 0), lineColor);
|
||||
}
|
||||
angle += angleDelta;
|
||||
}
|
||||
|
||||
if (lineWidth > 0)
|
||||
{
|
||||
int tmp = sides * 3;
|
||||
for (int i = 0; i < tmp; i += 3)
|
||||
{
|
||||
if (i != tmp - 3)
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, i + 4);
|
||||
vb.AddTriangle(i + 5, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, i + 6, i + 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, 1);
|
||||
vb.AddTriangle(2, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, 3, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < sides; i++)
|
||||
vb.AddTriangle(0, i + 1, (i == sides - 1) ? 1 : i + 2);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
if (drawRect != null)
|
||||
return ((Rect)drawRect).Contains(point);
|
||||
else
|
||||
return contentRect.Contains(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4084bdb2f1738340a28ab5699977f3b
|
||||
timeCreated: 1545987173
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,177 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
public class RoundedRectMesh : IMeshFactory, IHitTest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect? drawRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 lineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32? fillColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float topLeftRadius;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float topRightRadius;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float bottomLeftRadius;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float bottomRightRadius;
|
||||
|
||||
public RoundedRectMesh()
|
||||
{
|
||||
lineColor = Color.black;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
Rect rect = drawRect != null ? (Rect)drawRect : vb.contentRect;
|
||||
Color32 color = fillColor != null ? (Color32)fillColor : vb.vertexColor;
|
||||
|
||||
float radiusX = rect.width / 2;
|
||||
float radiusY = rect.height / 2;
|
||||
float cornerMaxRadius = Mathf.Min(radiusX, radiusY);
|
||||
float centerX = radiusX + rect.x;
|
||||
float centerY = radiusY + rect.y;
|
||||
|
||||
vb.AddVert(new Vector3(centerX, centerY, 0), color);
|
||||
|
||||
int cnt = vb.currentVertCount;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float radius = 0;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
radius = bottomRightRadius;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
radius = bottomLeftRadius;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
radius = topLeftRadius;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
radius = topRightRadius;
|
||||
break;
|
||||
}
|
||||
radius = Mathf.Min(cornerMaxRadius, radius);
|
||||
|
||||
float offsetX = rect.x;
|
||||
float offsetY = rect.y;
|
||||
|
||||
if (i == 0 || i == 3)
|
||||
offsetX = rect.xMax - radius * 2;
|
||||
if (i == 0 || i == 1)
|
||||
offsetY = rect.yMax - radius * 2;
|
||||
|
||||
if (radius != 0)
|
||||
{
|
||||
int partNumSides = Mathf.Max(1, Mathf.CeilToInt(Mathf.PI * radius / 8)) + 1;
|
||||
float angleDelta = Mathf.PI / 2 / partNumSides;
|
||||
float angle = Mathf.PI / 2 * i;
|
||||
float startAngle = angle;
|
||||
|
||||
for (int j = 1; j <= partNumSides; j++)
|
||||
{
|
||||
if (j == partNumSides) //消除精度误差带来的不对齐
|
||||
angle = startAngle + Mathf.PI / 2;
|
||||
Vector3 v1 = new Vector3(offsetX + Mathf.Cos(angle) * (radius - lineWidth) + radius,
|
||||
offsetY + Mathf.Sin(angle) * (radius - lineWidth) + radius, 0);
|
||||
vb.AddVert(v1, color);
|
||||
if (lineWidth != 0)
|
||||
{
|
||||
vb.AddVert(v1, lineColor);
|
||||
vb.AddVert(new Vector3(offsetX + Mathf.Cos(angle) * radius + radius,
|
||||
offsetY + Mathf.Sin(angle) * radius + radius, 0), lineColor);
|
||||
}
|
||||
angle += angleDelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 v1 = new Vector3(offsetX, offsetY, 0);
|
||||
if (lineWidth != 0)
|
||||
{
|
||||
if (i == 0 || i == 3)
|
||||
offsetX -= lineWidth;
|
||||
else
|
||||
offsetX += lineWidth;
|
||||
if (i == 0 || i == 1)
|
||||
offsetY -= lineWidth;
|
||||
else
|
||||
offsetY += lineWidth;
|
||||
Vector3 v2 = new Vector3(offsetX, offsetY, 0);
|
||||
vb.AddVert(v2, color);
|
||||
vb.AddVert(v2, lineColor);
|
||||
vb.AddVert(v1, lineColor);
|
||||
}
|
||||
else
|
||||
vb.AddVert(v1, color);
|
||||
}
|
||||
}
|
||||
cnt = vb.currentVertCount - cnt;
|
||||
|
||||
if (lineWidth > 0)
|
||||
{
|
||||
for (int i = 0; i < cnt; i += 3)
|
||||
{
|
||||
if (i != cnt - 3)
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, i + 4);
|
||||
vb.AddTriangle(i + 5, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, i + 6, i + 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
vb.AddTriangle(0, i + 1, 1);
|
||||
vb.AddTriangle(2, i + 2, i + 3);
|
||||
vb.AddTriangle(i + 3, 3, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
vb.AddTriangle(0, i + 1, (i == cnt - 1) ? 1 : i + 2);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HitTest(Rect contentRect, Vector2 point)
|
||||
{
|
||||
if (drawRect != null)
|
||||
return ((Rect)drawRect).Contains(point);
|
||||
else
|
||||
return contentRect.Contains(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f910c4392a714c41b421c296621562b
|
||||
timeCreated: 1545987172
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,90 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class StraightLineMesh : IMeshFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color color;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector3 origin;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector3 end;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lineWidth;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool repeatFill;
|
||||
|
||||
public StraightLineMesh()
|
||||
{
|
||||
color = Color.black;
|
||||
lineWidth = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lineWidth"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="repeatFill"></param>
|
||||
public StraightLineMesh(float lineWidth, Color color, bool repeatFill)
|
||||
{
|
||||
this.lineWidth = lineWidth;
|
||||
this.color = color;
|
||||
this.repeatFill = repeatFill;
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
if (origin == end)
|
||||
return;
|
||||
|
||||
float length = Vector2.Distance(origin, end);
|
||||
Vector3 lineVector = end - origin;
|
||||
Vector3 widthVector = Vector3.Cross(lineVector, new Vector3(0, 0, 1));
|
||||
widthVector.Normalize();
|
||||
|
||||
Vector3 v0, v1, v2, v3;
|
||||
|
||||
if (repeatFill)
|
||||
{
|
||||
float ratio = length / vb.textureSize.x;
|
||||
v0 = VertexBuffer.NormalizedUV[0];
|
||||
v1 = VertexBuffer.NormalizedUV[1];
|
||||
v2 = new Vector2(ratio, 1);
|
||||
v3 = new Vector2(ratio, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
v0 = new Vector2(vb.uvRect.xMin, vb.uvRect.yMin);
|
||||
v1 = new Vector2(vb.uvRect.xMin, vb.uvRect.yMax);
|
||||
v2 = new Vector2(vb.uvRect.xMax, vb.uvRect.yMax);
|
||||
v3 = new Vector2(vb.uvRect.xMax, vb.uvRect.yMin);
|
||||
}
|
||||
|
||||
vb.AddVert(origin - widthVector * lineWidth * 0.5f, color, v0);
|
||||
vb.AddVert(origin + widthVector * lineWidth * 0.5f, color, v1);
|
||||
vb.AddVert(end + widthVector * lineWidth * 0.5f, color, v2);
|
||||
vb.AddVert(end - widthVector * lineWidth * 0.5f, color, v3);
|
||||
|
||||
vb.AddTriangles();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27b002bc89d804a7b8058b9d16d5c506
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,441 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public sealed class VertexBuffer
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect contentRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect uvRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32 vertexColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector2 textureSize;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<Vector3> vertices;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<Color32> colors;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<Vector2> uvs;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<Vector2> uvs2;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public readonly List<int> triangles;
|
||||
|
||||
static public Vector2[] NormalizedUV = new Vector2[] {
|
||||
new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) };
|
||||
|
||||
static public Vector2[] NormalizedPosition = new Vector2[] {
|
||||
new Vector2(0, 1), new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1) };
|
||||
|
||||
internal bool _alphaInVertexColor;
|
||||
internal bool _isArbitraryQuad;
|
||||
|
||||
static Stack<VertexBuffer> _pool = new Stack<VertexBuffer>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static VertexBuffer Begin()
|
||||
{
|
||||
if (_pool.Count > 0)
|
||||
{
|
||||
VertexBuffer inst = _pool.Pop();
|
||||
inst.Clear();
|
||||
return inst;
|
||||
}
|
||||
else
|
||||
return new VertexBuffer();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public static VertexBuffer Begin(VertexBuffer source)
|
||||
{
|
||||
VertexBuffer vb = Begin();
|
||||
vb.contentRect = source.contentRect;
|
||||
vb.uvRect = source.uvRect;
|
||||
vb.vertexColor = source.vertexColor;
|
||||
vb.textureSize = source.textureSize;
|
||||
|
||||
return vb;
|
||||
}
|
||||
|
||||
private VertexBuffer()
|
||||
{
|
||||
vertices = new List<Vector3>();
|
||||
colors = new List<Color32>();
|
||||
uvs = new List<Vector2>();
|
||||
uvs2 = new List<Vector2>();
|
||||
triangles = new List<int>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void End()
|
||||
{
|
||||
_pool.Push(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
vertices.Clear();
|
||||
colors.Clear();
|
||||
uvs.Clear();
|
||||
uvs2.Clear();
|
||||
triangles.Clear();
|
||||
|
||||
_isArbitraryQuad = false;
|
||||
_alphaInVertexColor = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int currentVertCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return vertices.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="position"></param>
|
||||
public void AddVert(Vector3 position)
|
||||
{
|
||||
position.y = -position.y;
|
||||
vertices.Add(position);
|
||||
colors.Add(vertexColor);
|
||||
if (vertexColor.a != 255)
|
||||
_alphaInVertexColor = true;
|
||||
uvs.Add(new Vector2(
|
||||
Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
|
||||
Mathf.Lerp(uvRect.yMax, uvRect.yMin, (-position.y - contentRect.yMin) / contentRect.height)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="position"></param>
|
||||
/// <param name="color"></param>
|
||||
public void AddVert(Vector3 position, Color32 color)
|
||||
{
|
||||
position.y = -position.y;
|
||||
vertices.Add(position);
|
||||
colors.Add(color);
|
||||
if (color.a != 255)
|
||||
_alphaInVertexColor = true;
|
||||
uvs.Add(new Vector2(
|
||||
Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
|
||||
Mathf.Lerp(uvRect.yMax, uvRect.yMin, (-position.y - contentRect.yMin) / contentRect.height)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="position"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="uv"></param>
|
||||
public void AddVert(Vector3 position, Color32 color, Vector2 uv)
|
||||
{
|
||||
position.y = -position.y;
|
||||
vertices.Add(position);
|
||||
uvs.Add(new Vector2(uv.x, uv.y));
|
||||
colors.Add(color);
|
||||
if (color.a != 255)
|
||||
_alphaInVertexColor = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// 1---2
|
||||
/// | / |
|
||||
/// 0---3
|
||||
/// </summary>
|
||||
/// <param name="vertRect"></param>
|
||||
public void AddQuad(Rect vertRect)
|
||||
{
|
||||
AddVert(new Vector3(vertRect.xMin, vertRect.yMax, 0f));
|
||||
AddVert(new Vector3(vertRect.xMin, vertRect.yMin, 0f));
|
||||
AddVert(new Vector3(vertRect.xMax, vertRect.yMin, 0f));
|
||||
AddVert(new Vector3(vertRect.xMax, vertRect.yMax, 0f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vertRect"></param>
|
||||
/// <param name="color"></param>
|
||||
public void AddQuad(Rect vertRect, Color32 color)
|
||||
{
|
||||
AddVert(new Vector3(vertRect.xMin, vertRect.yMax, 0f), color);
|
||||
AddVert(new Vector3(vertRect.xMin, vertRect.yMin, 0f), color);
|
||||
AddVert(new Vector3(vertRect.xMax, vertRect.yMin, 0f), color);
|
||||
AddVert(new Vector3(vertRect.xMax, vertRect.yMax, 0f), color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vertRect"></param>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="uvRect"></param>
|
||||
public void AddQuad(Rect vertRect, Color32 color, Rect uvRect)
|
||||
{
|
||||
vertices.Add(new Vector3(vertRect.xMin, -vertRect.yMax, 0f));
|
||||
vertices.Add(new Vector3(vertRect.xMin, -vertRect.yMin, 0f));
|
||||
vertices.Add(new Vector3(vertRect.xMax, -vertRect.yMin, 0f));
|
||||
vertices.Add(new Vector3(vertRect.xMax, -vertRect.yMax, 0f));
|
||||
|
||||
uvs.Add(new Vector2(uvRect.xMin, uvRect.yMin));
|
||||
uvs.Add(new Vector2(uvRect.xMin, uvRect.yMax));
|
||||
uvs.Add(new Vector2(uvRect.xMax, uvRect.yMax));
|
||||
uvs.Add(new Vector2(uvRect.xMax, uvRect.yMin));
|
||||
|
||||
colors.Add(color);
|
||||
colors.Add(color);
|
||||
colors.Add(color);
|
||||
colors.Add(color);
|
||||
|
||||
if (color.a != 255)
|
||||
_alphaInVertexColor = true;
|
||||
}
|
||||
|
||||
static List<Vector4> helperV4List = new List<Vector4>(4) { Vector4.zero, Vector4.zero, Vector4.zero, Vector4.zero };
|
||||
internal List<Vector4> FixUVForArbitraryQuad()
|
||||
{
|
||||
//ref1 http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/
|
||||
//ref2 https://bitlush.com/blog/arbitrary-quadrilaterals-in-opengl-es-2-0
|
||||
|
||||
Vector4 qq = Vector4.one;
|
||||
Vector2 a = vertices[2] - vertices[0];
|
||||
Vector2 b = vertices[1] - vertices[3];
|
||||
Vector2 c = vertices[0] - vertices[3];
|
||||
|
||||
float cross = a.x * b.y - a.y * b.x;
|
||||
if (cross != 0)
|
||||
{
|
||||
float s = (a.x * c.y - a.y * c.x) / cross;
|
||||
if (s > 0 && s < 1)
|
||||
{
|
||||
float t = (b.x * c.y - b.y * c.x) / cross;
|
||||
if (t > 0 && t < 1)
|
||||
{
|
||||
qq.x = 1 / (1 - t);
|
||||
qq.y = 1 / s;
|
||||
qq.z = 1 / t;
|
||||
qq.w = 1 / (1 - s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Vector4 v = uvs[i];
|
||||
float q = qq[i];
|
||||
v.x *= q;
|
||||
v.y *= q;
|
||||
v.w = q;
|
||||
helperV4List[i] = v;
|
||||
}
|
||||
|
||||
return helperV4List;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="startIndex"></param>
|
||||
/// <param name="count"></param>
|
||||
public void RepeatColors(Color32[] value, int startIndex, int count)
|
||||
{
|
||||
int len = Mathf.Min(startIndex + count, vertices.Count);
|
||||
int colorCount = value.Length;
|
||||
int k = 0;
|
||||
for (int i = startIndex; i < len; i++)
|
||||
{
|
||||
Color32 c = value[(k++) % colorCount];
|
||||
colors[i] = c;
|
||||
if (c.a != 255)
|
||||
_alphaInVertexColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="idx0"></param>
|
||||
/// <param name="idx1"></param>
|
||||
/// <param name="idx2"></param>
|
||||
public void AddTriangle(int idx0, int idx1, int idx2)
|
||||
{
|
||||
triangles.Add(idx0);
|
||||
triangles.Add(idx1);
|
||||
triangles.Add(idx2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="idxList"></param>
|
||||
/// <param name="startVertexIndex"></param>
|
||||
public void AddTriangles(int[] idxList, int startVertexIndex = 0)
|
||||
{
|
||||
if (startVertexIndex != 0)
|
||||
{
|
||||
if (startVertexIndex < 0)
|
||||
startVertexIndex = vertices.Count + startVertexIndex;
|
||||
|
||||
int cnt = idxList.Length;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
triangles.Add(idxList[i] + startVertexIndex);
|
||||
}
|
||||
else
|
||||
triangles.AddRange(idxList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="startVertexIndex"></param>
|
||||
public void AddTriangles(int startVertexIndex = 0)
|
||||
{
|
||||
int cnt = vertices.Count;
|
||||
if (startVertexIndex < 0)
|
||||
startVertexIndex = cnt + startVertexIndex;
|
||||
|
||||
for (int i = startVertexIndex; i < cnt; i += 4)
|
||||
{
|
||||
triangles.Add(i);
|
||||
triangles.Add(i + 1);
|
||||
triangles.Add(i + 2);
|
||||
|
||||
triangles.Add(i + 2);
|
||||
triangles.Add(i + 3);
|
||||
triangles.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Vector3 GetPosition(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
index = vertices.Count + index;
|
||||
|
||||
Vector3 vec = vertices[index];
|
||||
vec.y = -vec.y;
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="position"></param>
|
||||
/// <param name="usePercent"></param>
|
||||
/// <returns></returns>
|
||||
public Vector2 GetUVAtPosition(Vector2 position, bool usePercent)
|
||||
{
|
||||
if (usePercent)
|
||||
{
|
||||
return new Vector2(Mathf.Lerp(uvRect.xMin, uvRect.xMax, position.x),
|
||||
Mathf.Lerp(uvRect.yMax, uvRect.yMin, position.y));
|
||||
}
|
||||
else
|
||||
return new Vector2(Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
|
||||
Mathf.Lerp(uvRect.yMax, uvRect.yMin, (position.y - contentRect.yMin) / contentRect.height));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vb"></param>
|
||||
public void Append(VertexBuffer vb)
|
||||
{
|
||||
int len = vertices.Count;
|
||||
vertices.AddRange(vb.vertices);
|
||||
uvs.AddRange(vb.uvs);
|
||||
uvs2.AddRange(vb.uvs2);
|
||||
colors.AddRange(vb.colors);
|
||||
if (len != 0)
|
||||
{
|
||||
int len1 = vb.triangles.Count;
|
||||
for (int i = 0; i < len1; i++)
|
||||
triangles.Add(vb.triangles[i] + len);
|
||||
}
|
||||
else
|
||||
triangles.AddRange(vb.triangles);
|
||||
|
||||
if (vb._alphaInVertexColor)
|
||||
_alphaInVertexColor = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vb"></param>
|
||||
public void Insert(VertexBuffer vb)
|
||||
{
|
||||
vertices.InsertRange(0, vb.vertices);
|
||||
uvs.InsertRange(0, vb.uvs);
|
||||
uvs2.InsertRange(0, vb.uvs2);
|
||||
colors.InsertRange(0, vb.colors);
|
||||
int len = triangles.Count;
|
||||
if (len != 0)
|
||||
{
|
||||
int len1 = vb.vertices.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
triangles[i] += len1;
|
||||
}
|
||||
triangles.InsertRange(0, vb.triangles);
|
||||
|
||||
if (vb._alphaInVertexColor)
|
||||
_alphaInVertexColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d5501e8f84e40e47835611ab3896029
|
||||
timeCreated: 1545987173
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,414 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MovieClip : Image
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Frame
|
||||
{
|
||||
public NTexture texture;
|
||||
public float addDelay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float interval;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool swing;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float repeatDelay;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float timeScale;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to ignore Unity time scale.
|
||||
/// </summary>
|
||||
public bool ignoreEngineTimeScale;
|
||||
|
||||
Frame[] _frames;
|
||||
int _frameCount;
|
||||
int _frame;
|
||||
bool _playing;
|
||||
int _start;
|
||||
int _end;
|
||||
int _times;
|
||||
int _endAt;
|
||||
int _status; //0-none, 1-next loop, 2-ending, 3-ended
|
||||
|
||||
float _frameElapsed; //当前帧延迟
|
||||
bool _reversed;
|
||||
int _repeatedCount;
|
||||
TimerCallback _timerDelegate;
|
||||
|
||||
EventListener _onPlayEnd;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MovieClip()
|
||||
{
|
||||
interval = 0.1f;
|
||||
_playing = true;
|
||||
_timerDelegate = OnTimer;
|
||||
timeScale = 1;
|
||||
ignoreEngineTimeScale = false;
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
onAddedToStage.Add(OnAddedToStage);
|
||||
onRemovedFromStage.Add(OnRemoveFromStage);
|
||||
}
|
||||
|
||||
SetPlaySettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public EventListener onPlayEnd
|
||||
{
|
||||
get { return _onPlayEnd ?? (_onPlayEnd = new EventListener(this, "onPlayEnd")); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Frame[] frames
|
||||
{
|
||||
get
|
||||
{
|
||||
return _frames;
|
||||
}
|
||||
set
|
||||
{
|
||||
_frames = value;
|
||||
_scale9Grid = null;
|
||||
_scaleByTile = false;
|
||||
|
||||
if (_frames == null)
|
||||
{
|
||||
_frameCount = 0;
|
||||
graphics.texture = null;
|
||||
CheckTimer();
|
||||
return;
|
||||
}
|
||||
_frameCount = frames.Length;
|
||||
|
||||
if (_end == -1 || _end > _frameCount - 1)
|
||||
_end = _frameCount - 1;
|
||||
if (_endAt == -1 || _endAt > _frameCount - 1)
|
||||
_endAt = _frameCount - 1;
|
||||
|
||||
if (_frame < 0 || _frame > _frameCount - 1)
|
||||
_frame = _frameCount - 1;
|
||||
|
||||
InvalidateBatchingState();
|
||||
|
||||
_frameElapsed = 0;
|
||||
_repeatedCount = 0;
|
||||
_reversed = false;
|
||||
|
||||
DrawFrame();
|
||||
CheckTimer();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool playing
|
||||
{
|
||||
get { return _playing; }
|
||||
set
|
||||
{
|
||||
if (_playing != value)
|
||||
{
|
||||
_playing = value;
|
||||
CheckTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int frame
|
||||
{
|
||||
get { return _frame; }
|
||||
set
|
||||
{
|
||||
if (_frame != value)
|
||||
{
|
||||
if (_frames != null && value >= _frameCount)
|
||||
value = _frameCount - 1;
|
||||
|
||||
_frame = value;
|
||||
_frameElapsed = 0;
|
||||
DrawFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Rewind()
|
||||
{
|
||||
_frame = 0;
|
||||
_frameElapsed = 0;
|
||||
_reversed = false;
|
||||
_repeatedCount = 0;
|
||||
DrawFrame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="anotherMc"></param>
|
||||
public void SyncStatus(MovieClip anotherMc)
|
||||
{
|
||||
_frame = anotherMc._frame;
|
||||
_frameElapsed = anotherMc._frameElapsed;
|
||||
_reversed = anotherMc._reversed;
|
||||
_repeatedCount = anotherMc._repeatedCount;
|
||||
DrawFrame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
public void Advance(float time)
|
||||
{
|
||||
int beginFrame = _frame;
|
||||
bool beginReversed = _reversed;
|
||||
float backupTime = time;
|
||||
while (true)
|
||||
{
|
||||
float tt = interval + _frames[_frame].addDelay;
|
||||
if (_frame == 0 && _repeatedCount > 0)
|
||||
tt += repeatDelay;
|
||||
if (time < tt)
|
||||
{
|
||||
_frameElapsed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
time -= tt;
|
||||
|
||||
if (swing)
|
||||
{
|
||||
if (_reversed)
|
||||
{
|
||||
_frame--;
|
||||
if (_frame <= 0)
|
||||
{
|
||||
_frame = 0;
|
||||
_repeatedCount++;
|
||||
_reversed = !_reversed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_frame++;
|
||||
if (_frame > _frameCount - 1)
|
||||
{
|
||||
_frame = Mathf.Max(0, _frameCount - 2);
|
||||
_repeatedCount++;
|
||||
_reversed = !_reversed;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_frame++;
|
||||
if (_frame > _frameCount - 1)
|
||||
{
|
||||
_frame = 0;
|
||||
_repeatedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_frame == beginFrame && _reversed == beginReversed) //走了一轮了
|
||||
{
|
||||
float roundTime = backupTime - time; //这就是一轮需要的时间
|
||||
time -= Mathf.FloorToInt(time / roundTime) * roundTime; //跳过
|
||||
}
|
||||
}
|
||||
|
||||
DrawFrame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetPlaySettings()
|
||||
{
|
||||
SetPlaySettings(0, -1, 0, -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从start帧开始,播放到end帧(-1表示结尾),重复times次(0表示无限循环),循环结束后,停止在endAt帧(-1表示参数end)
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="times"></param>
|
||||
/// <param name="endAt"></param>
|
||||
public void SetPlaySettings(int start, int end, int times, int endAt)
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
if (_end == -1 || _end > _frameCount - 1)
|
||||
_end = _frameCount - 1;
|
||||
_times = times;
|
||||
_endAt = endAt;
|
||||
if (_endAt == -1)
|
||||
_endAt = _end;
|
||||
_status = 0;
|
||||
this.frame = start;
|
||||
}
|
||||
|
||||
void OnAddedToStage()
|
||||
{
|
||||
if (_playing && _frameCount > 0)
|
||||
Timers.inst.AddUpdate(_timerDelegate);
|
||||
}
|
||||
|
||||
void OnRemoveFromStage()
|
||||
{
|
||||
Timers.inst.Remove(_timerDelegate);
|
||||
}
|
||||
|
||||
void CheckTimer()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
return;
|
||||
|
||||
if (_playing && _frameCount > 0 && this.stage != null)
|
||||
Timers.inst.AddUpdate(_timerDelegate);
|
||||
else
|
||||
Timers.inst.Remove(_timerDelegate);
|
||||
}
|
||||
|
||||
void OnTimer(object param)
|
||||
{
|
||||
if (!_playing || _frameCount == 0 || _status == 3)
|
||||
return;
|
||||
|
||||
float dt;
|
||||
if (ignoreEngineTimeScale)
|
||||
{
|
||||
dt = Time.unscaledDeltaTime;
|
||||
if (dt > 0.1f)
|
||||
dt = 0.1f;
|
||||
}
|
||||
else
|
||||
dt = Time.deltaTime;
|
||||
if (timeScale != 1)
|
||||
dt *= timeScale;
|
||||
|
||||
_frameElapsed += dt;
|
||||
float tt = interval + _frames[_frame].addDelay;
|
||||
if (_frame == 0 && _repeatedCount > 0)
|
||||
tt += repeatDelay;
|
||||
if (_frameElapsed < tt)
|
||||
return;
|
||||
|
||||
_frameElapsed -= tt;
|
||||
if (_frameElapsed > interval)
|
||||
_frameElapsed = interval;
|
||||
|
||||
if (swing)
|
||||
{
|
||||
if (_reversed)
|
||||
{
|
||||
_frame--;
|
||||
if (_frame <= 0)
|
||||
{
|
||||
_frame = 0;
|
||||
_repeatedCount++;
|
||||
_reversed = !_reversed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_frame++;
|
||||
if (_frame > _frameCount - 1)
|
||||
{
|
||||
_frame = Mathf.Max(0, _frameCount - 2);
|
||||
_repeatedCount++;
|
||||
_reversed = !_reversed;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_frame++;
|
||||
if (_frame > _frameCount - 1)
|
||||
{
|
||||
_frame = 0;
|
||||
_repeatedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_status == 1) //new loop
|
||||
{
|
||||
_frame = _start;
|
||||
_frameElapsed = 0;
|
||||
_status = 0;
|
||||
DrawFrame();
|
||||
}
|
||||
else if (_status == 2) //ending
|
||||
{
|
||||
_frame = _endAt;
|
||||
_frameElapsed = 0;
|
||||
_status = 3; //ended
|
||||
DrawFrame();
|
||||
|
||||
DispatchEvent("onPlayEnd", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawFrame();
|
||||
if (_frame == _end)
|
||||
{
|
||||
if (_times > 0)
|
||||
{
|
||||
_times--;
|
||||
if (_times == 0)
|
||||
_status = 2; //ending
|
||||
else
|
||||
_status = 1; //new loop
|
||||
}
|
||||
else if (_start != 0)
|
||||
_status = 1; //new loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawFrame()
|
||||
{
|
||||
if (_frameCount > 0)
|
||||
{
|
||||
Frame frame = _frames[_frame];
|
||||
graphics.texture = frame.texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ddeeb52259b7ed4e8a604fa8cd47897
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NAudioClip
|
||||
{
|
||||
public static Action<AudioClip> CustomDestroyMethod;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DestroyMethod destroyMethod;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public AudioClip nativeClip;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="audioClip"></param>
|
||||
public NAudioClip(AudioClip audioClip)
|
||||
{
|
||||
nativeClip = audioClip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Unload()
|
||||
{
|
||||
if (nativeClip == null)
|
||||
return;
|
||||
|
||||
if (destroyMethod == DestroyMethod.Unload)
|
||||
Resources.UnloadAsset(nativeClip);
|
||||
else if (destroyMethod == DestroyMethod.Destroy)
|
||||
UnityEngine.Object.DestroyImmediate(nativeClip, true);
|
||||
else if (destroyMethod == DestroyMethod.Custom)
|
||||
{
|
||||
if (CustomDestroyMethod == null)
|
||||
Debug.LogWarning("NAudioClip.CustomDestroyMethod must be set to handle DestroyMethod.Custom");
|
||||
else
|
||||
CustomDestroyMethod(nativeClip);
|
||||
}
|
||||
|
||||
nativeClip = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="audioClip"></param>
|
||||
public void Reload(AudioClip audioClip)
|
||||
{
|
||||
if (nativeClip != null && nativeClip != audioClip)
|
||||
Unload();
|
||||
|
||||
nativeClip = audioClip;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e081bc28928c3474194543c862fadec5
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,842 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using FairyGUI.Utils;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NGraphics : IMeshFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public GameObject gameObject { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MeshFilter meshFilter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MeshRenderer meshRenderer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Mesh mesh { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BlendMode blendMode;
|
||||
|
||||
/// <summary>
|
||||
/// 不参与剪裁
|
||||
/// </summary>
|
||||
public bool dontClip;
|
||||
|
||||
/// <summary>
|
||||
/// 当Mesh更新时触发
|
||||
/// </summary>
|
||||
public event Action meshModifier;
|
||||
|
||||
NTexture _texture;
|
||||
string _shader;
|
||||
Material _material;
|
||||
int _customMatarial; //0-none, 1-common, 2-support internal mask, 128-owns material
|
||||
MaterialManager _manager;
|
||||
string[] _shaderKeywords;
|
||||
int _materialFlags;
|
||||
IMeshFactory _meshFactory;
|
||||
|
||||
float _alpha;
|
||||
Color _color;
|
||||
bool _meshDirty;
|
||||
Rect _contentRect;
|
||||
FlipType _flip;
|
||||
|
||||
public class VertexMatrix
|
||||
{
|
||||
public Vector3 cameraPos;
|
||||
public Matrix4x4 matrix;
|
||||
}
|
||||
VertexMatrix _vertexMatrix;
|
||||
|
||||
bool hasAlphaBackup;
|
||||
List<byte> _alphaBackup; //透明度改变需要通过修改顶点颜色实现,但顶点颜色本身可能就带有透明度,所以这里要有一个备份
|
||||
|
||||
internal int _maskFlag;
|
||||
StencilEraser _stencilEraser;
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
Color32[] _colors;
|
||||
#endif
|
||||
|
||||
MaterialPropertyBlock _propertyBlock;
|
||||
bool _blockUpdated;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
public NGraphics(GameObject gameObject)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
|
||||
_alpha = 1f;
|
||||
_shader = ShaderConfig.imageShader;
|
||||
_color = Color.white;
|
||||
_meshFactory = this;
|
||||
|
||||
meshFilter = gameObject.AddComponent<MeshFilter>();
|
||||
meshRenderer = gameObject.AddComponent<MeshRenderer>();
|
||||
meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
|
||||
meshRenderer.receiveShadows = false;
|
||||
|
||||
mesh = new Mesh();
|
||||
mesh.name = gameObject.name;
|
||||
mesh.MarkDynamic();
|
||||
|
||||
meshFilter.mesh = mesh;
|
||||
|
||||
meshFilter.hideFlags = DisplayObject.hideFlags;
|
||||
meshRenderer.hideFlags = DisplayObject.hideFlags;
|
||||
mesh.hideFlags = DisplayObject.hideFlags;
|
||||
|
||||
Stats.LatestGraphicsCreation++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IMeshFactory meshFactory
|
||||
{
|
||||
get { return _meshFactory; }
|
||||
set
|
||||
{
|
||||
if (_meshFactory != value)
|
||||
{
|
||||
_meshFactory = value;
|
||||
_meshDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public T GetMeshFactory<T>() where T : IMeshFactory, new()
|
||||
{
|
||||
if (!(_meshFactory is T))
|
||||
{
|
||||
_meshFactory = new T();
|
||||
_meshDirty = true;
|
||||
}
|
||||
return (T)_meshFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect contentRect
|
||||
{
|
||||
get { return _contentRect; }
|
||||
set
|
||||
{
|
||||
_contentRect = value;
|
||||
_meshDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public FlipType flip
|
||||
{
|
||||
get { return _flip; }
|
||||
set
|
||||
{
|
||||
if (_flip != value)
|
||||
{
|
||||
_flip = value;
|
||||
_meshDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public NTexture texture
|
||||
{
|
||||
get { return _texture; }
|
||||
set
|
||||
{
|
||||
if (_texture != value)
|
||||
{
|
||||
if (value != null)
|
||||
value.AddRef();
|
||||
if (_texture != null)
|
||||
_texture.ReleaseRef();
|
||||
|
||||
_texture = value;
|
||||
if (_customMatarial != 0 && _material != null)
|
||||
_material.mainTexture = _texture != null ? _texture.nativeTexture : null;
|
||||
_meshDirty = true;
|
||||
UpdateManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string shader
|
||||
{
|
||||
get { return _shader; }
|
||||
set
|
||||
{
|
||||
_shader = value;
|
||||
UpdateManager();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="shader"></param>
|
||||
/// <param name="texture"></param>
|
||||
public void SetShaderAndTexture(string shader, NTexture texture)
|
||||
{
|
||||
_shader = shader;
|
||||
if (_texture != texture)
|
||||
this.texture = texture;
|
||||
else
|
||||
UpdateManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_customMatarial == 0 && _material == null && _manager != null)
|
||||
_material = _manager.GetMaterial(_materialFlags, blendMode, 0);
|
||||
return _material;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((_customMatarial & 128) != 0 && _material != null)
|
||||
Object.DestroyImmediate(_material);
|
||||
|
||||
_material = value;
|
||||
if (_material != null)
|
||||
{
|
||||
_customMatarial = 1;
|
||||
if (_material.HasProperty(ShaderConfig.ID_Stencil) || _material.HasProperty(ShaderConfig.ID_ClipBox))
|
||||
_customMatarial |= 2;
|
||||
|
||||
meshRenderer.sharedMaterial = _material;
|
||||
if (_texture != null)
|
||||
_material.mainTexture = _texture.nativeTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
_customMatarial = 0;
|
||||
meshRenderer.sharedMaterial = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as material property except that ownership is transferred to this object.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetMaterial(Material material)
|
||||
{
|
||||
this.material = material;
|
||||
_customMatarial |= 128;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string[] materialKeywords
|
||||
{
|
||||
get { return _shaderKeywords; }
|
||||
set
|
||||
{
|
||||
_shaderKeywords = value;
|
||||
UpdateMaterialFlags();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="keyword"></param>
|
||||
/// <param name="enabled"></param>
|
||||
public void ToggleKeyword(string keyword, bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
if (_shaderKeywords == null)
|
||||
{
|
||||
_shaderKeywords = new string[] { keyword };
|
||||
UpdateMaterialFlags();
|
||||
}
|
||||
else if (Array.IndexOf(_shaderKeywords, keyword) == -1)
|
||||
{
|
||||
Array.Resize(ref _shaderKeywords, _shaderKeywords.Length + 1);
|
||||
_shaderKeywords[_shaderKeywords.Length - 1] = keyword;
|
||||
UpdateMaterialFlags();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_shaderKeywords != null)
|
||||
{
|
||||
int i = Array.IndexOf(_shaderKeywords, keyword);
|
||||
if (i != -1)
|
||||
{
|
||||
_shaderKeywords[i] = null;
|
||||
UpdateMaterialFlags();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateManager()
|
||||
{
|
||||
if (_texture != null)
|
||||
_manager = _texture.GetMaterialManager(_shader);
|
||||
else
|
||||
_manager = null;
|
||||
UpdateMaterialFlags();
|
||||
}
|
||||
|
||||
void UpdateMaterialFlags()
|
||||
{
|
||||
if (_customMatarial != 0)
|
||||
{
|
||||
if (material != null)
|
||||
material.shaderKeywords = _shaderKeywords;
|
||||
}
|
||||
else if (_shaderKeywords != null && _manager != null)
|
||||
_materialFlags = _manager.GetFlagsByKeywords(_shaderKeywords);
|
||||
else
|
||||
_materialFlags = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool enabled
|
||||
{
|
||||
get { return meshRenderer.enabled; }
|
||||
set { meshRenderer.enabled = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int sortingOrder
|
||||
{
|
||||
get { return meshRenderer.sortingOrder; }
|
||||
set { meshRenderer.sortingOrder = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
internal void _SetStencilEraserOrder(int value)
|
||||
{
|
||||
_stencilEraser.meshRenderer.sortingOrder = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public Color color
|
||||
{
|
||||
get { return _color; }
|
||||
set { _color = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Tint()
|
||||
{
|
||||
if (_meshDirty)
|
||||
return;
|
||||
|
||||
int vertCount = mesh.vertexCount;
|
||||
if (vertCount == 0)
|
||||
return;
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
Color32[] colors = _colors;
|
||||
if (colors == null)
|
||||
colors = mesh.colors32;
|
||||
#else
|
||||
VertexBuffer vb = VertexBuffer.Begin();
|
||||
mesh.GetColors(vb.colors);
|
||||
List<Color32> colors = vb.colors;
|
||||
#endif
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Color32 col = _color;
|
||||
col.a = (byte)(_alpha * (hasAlphaBackup ? _alphaBackup[i] : (byte)255));
|
||||
colors[i] = col;
|
||||
}
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
mesh.colors32 = colors;
|
||||
#else
|
||||
mesh.SetColors(vb.colors);
|
||||
vb.End();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChangeAlpha(float value)
|
||||
{
|
||||
_alpha = value;
|
||||
|
||||
int vertCount = mesh.vertexCount;
|
||||
if (vertCount == 0)
|
||||
return;
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
Color32[] colors = _colors;
|
||||
if (colors == null)
|
||||
colors = mesh.colors32;
|
||||
#else
|
||||
VertexBuffer vb = VertexBuffer.Begin();
|
||||
mesh.GetColors(vb.colors);
|
||||
List<Color32> colors = vb.colors;
|
||||
#endif
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Color32 col = colors[i];
|
||||
col.a = (byte)(_alpha * (hasAlphaBackup ? _alphaBackup[i] : (byte)255));
|
||||
colors[i] = col;
|
||||
}
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
mesh.colors32 = colors;
|
||||
#else
|
||||
mesh.SetColors(vb.colors);
|
||||
vb.End();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public VertexMatrix vertexMatrix
|
||||
{
|
||||
get { return _vertexMatrix; }
|
||||
set
|
||||
{
|
||||
_vertexMatrix = value;
|
||||
_meshDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public MaterialPropertyBlock materialPropertyBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_propertyBlock == null)
|
||||
_propertyBlock = new MaterialPropertyBlock();
|
||||
|
||||
_blockUpdated = true;
|
||||
return _propertyBlock;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void SetMeshDirty()
|
||||
{
|
||||
_meshDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMesh()
|
||||
{
|
||||
if (_meshDirty)
|
||||
{
|
||||
UpdateMeshNow();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (mesh != null)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
Object.Destroy(mesh);
|
||||
else
|
||||
Object.DestroyImmediate(mesh);
|
||||
mesh = null;
|
||||
}
|
||||
if ((_customMatarial & 128) != 0 && _material != null)
|
||||
Object.DestroyImmediate(_material);
|
||||
|
||||
if (_texture != null)
|
||||
{
|
||||
_texture.ReleaseRef();
|
||||
_texture = null;
|
||||
}
|
||||
|
||||
_manager = null;
|
||||
_material = null;
|
||||
meshRenderer = null;
|
||||
meshFilter = null;
|
||||
_stencilEraser = null;
|
||||
meshModifier = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="alpha"></param>
|
||||
/// <param name="grayed"></param>
|
||||
public void Update(UpdateContext context, float alpha, bool grayed)
|
||||
{
|
||||
Stats.GraphicsCount++;
|
||||
|
||||
if (_meshDirty)
|
||||
{
|
||||
_alpha = alpha;
|
||||
UpdateMeshNow();
|
||||
}
|
||||
else if (_alpha != alpha)
|
||||
ChangeAlpha(alpha);
|
||||
|
||||
if (_propertyBlock != null && _blockUpdated)
|
||||
{
|
||||
meshRenderer.SetPropertyBlock(_propertyBlock);
|
||||
_blockUpdated = false;
|
||||
}
|
||||
|
||||
if (_customMatarial != 0)
|
||||
{
|
||||
if ((_customMatarial & 2) != 0 && _material != null)
|
||||
context.ApplyClippingProperties(_material, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_manager != null)
|
||||
{
|
||||
if (_maskFlag == 1)
|
||||
{
|
||||
_material = _manager.GetMaterial((int)MaterialFlags.AlphaMask | _materialFlags, BlendMode.Normal, context.clipInfo.clipId);
|
||||
context.ApplyAlphaMaskProperties(_material, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int matFlags = _materialFlags;
|
||||
if (grayed)
|
||||
matFlags |= (int)MaterialFlags.Grayed;
|
||||
|
||||
if (context.clipped)
|
||||
{
|
||||
if (context.stencilReferenceValue > 0)
|
||||
matFlags |= (int)MaterialFlags.StencilTest;
|
||||
if (context.rectMaskDepth > 0)
|
||||
{
|
||||
if (context.clipInfo.soft)
|
||||
matFlags |= (int)MaterialFlags.SoftClipped;
|
||||
else
|
||||
matFlags |= (int)MaterialFlags.Clipped;
|
||||
}
|
||||
|
||||
_material = _manager.GetMaterial(matFlags, blendMode, context.clipInfo.clipId);
|
||||
if (_manager.firstMaterialInFrame)
|
||||
context.ApplyClippingProperties(_material, true);
|
||||
}
|
||||
else
|
||||
_material = _manager.GetMaterial(matFlags, blendMode, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
_material = null;
|
||||
|
||||
if (!Material.ReferenceEquals(_material, meshRenderer.sharedMaterial))
|
||||
meshRenderer.sharedMaterial = _material;
|
||||
}
|
||||
|
||||
if (_maskFlag != 0)
|
||||
{
|
||||
if (_maskFlag == 1)
|
||||
_maskFlag = 2;
|
||||
else
|
||||
{
|
||||
if (_stencilEraser != null)
|
||||
_stencilEraser.enabled = false;
|
||||
|
||||
_maskFlag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void _PreUpdateMask(UpdateContext context, uint maskId)
|
||||
{
|
||||
//_maskFlag: 0-new mask, 1-active mask, 2-mask complete
|
||||
if (_maskFlag == 0)
|
||||
{
|
||||
if (_stencilEraser == null)
|
||||
{
|
||||
_stencilEraser = new StencilEraser(gameObject.transform);
|
||||
_stencilEraser.meshFilter.mesh = mesh;
|
||||
}
|
||||
else
|
||||
_stencilEraser.enabled = true;
|
||||
}
|
||||
|
||||
_maskFlag = 1;
|
||||
|
||||
if (_manager != null)
|
||||
{
|
||||
//这里使用maskId而不是clipInfo.clipId,是因为遮罩有两个用途,一个是写入遮罩,一个是擦除,两个不能用同一个材质
|
||||
Material mat = _manager.GetMaterial((int)MaterialFlags.AlphaMask | _materialFlags, BlendMode.Normal, maskId);
|
||||
if (!Material.ReferenceEquals(mat, _stencilEraser.meshRenderer.sharedMaterial))
|
||||
_stencilEraser.meshRenderer.sharedMaterial = mat;
|
||||
|
||||
context.ApplyAlphaMaskProperties(mat, true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMeshNow()
|
||||
{
|
||||
_meshDirty = false;
|
||||
|
||||
if (_texture == null || _meshFactory == null)
|
||||
{
|
||||
if (mesh.vertexCount > 0)
|
||||
{
|
||||
mesh.Clear();
|
||||
|
||||
if (meshModifier != null)
|
||||
meshModifier();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VertexBuffer vb = VertexBuffer.Begin();
|
||||
vb.contentRect = _contentRect;
|
||||
vb.uvRect = _texture.uvRect;
|
||||
if (_texture != null)
|
||||
vb.textureSize = new Vector2(_texture.width, _texture.height);
|
||||
else
|
||||
vb.textureSize = new Vector2(0, 0);
|
||||
if (_flip != FlipType.None)
|
||||
{
|
||||
if (_flip == FlipType.Horizontal || _flip == FlipType.Both)
|
||||
{
|
||||
float tmp = vb.uvRect.xMin;
|
||||
vb.uvRect.xMin = vb.uvRect.xMax;
|
||||
vb.uvRect.xMax = tmp;
|
||||
}
|
||||
if (_flip == FlipType.Vertical || _flip == FlipType.Both)
|
||||
{
|
||||
float tmp = vb.uvRect.yMin;
|
||||
vb.uvRect.yMin = vb.uvRect.yMax;
|
||||
vb.uvRect.yMax = tmp;
|
||||
}
|
||||
}
|
||||
vb.vertexColor = _color;
|
||||
_meshFactory.OnPopulateMesh(vb);
|
||||
|
||||
int vertCount = vb.currentVertCount;
|
||||
if (vertCount == 0)
|
||||
{
|
||||
if (mesh.vertexCount > 0)
|
||||
{
|
||||
mesh.Clear();
|
||||
|
||||
if (meshModifier != null)
|
||||
meshModifier();
|
||||
}
|
||||
vb.End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_texture.rotated)
|
||||
{
|
||||
float xMin = _texture.uvRect.xMin;
|
||||
float yMin = _texture.uvRect.yMin;
|
||||
float yMax = _texture.uvRect.yMax;
|
||||
float tmp;
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Vector2 vec = vb.uvs[i];
|
||||
tmp = vec.y;
|
||||
vec.y = yMin + vec.x - xMin;
|
||||
vec.x = xMin + yMax - tmp;
|
||||
vb.uvs[i] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
hasAlphaBackup = vb._alphaInVertexColor;
|
||||
if (hasAlphaBackup)
|
||||
{
|
||||
if (_alphaBackup == null)
|
||||
_alphaBackup = new List<byte>();
|
||||
else
|
||||
_alphaBackup.Clear();
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Color32 col = vb.colors[i];
|
||||
_alphaBackup.Add(col.a);
|
||||
|
||||
col.a = (byte)(col.a * _alpha);
|
||||
vb.colors[i] = col;
|
||||
}
|
||||
}
|
||||
else if (_alpha != 1)
|
||||
{
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Color32 col = vb.colors[i];
|
||||
col.a = (byte)(col.a * _alpha);
|
||||
vb.colors[i] = col;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vertexMatrix != null)
|
||||
{
|
||||
Vector3 camPos = _vertexMatrix.cameraPos;
|
||||
Vector3 center = new Vector3(camPos.x, camPos.y, 0);
|
||||
center -= _vertexMatrix.matrix.MultiplyPoint(center);
|
||||
for (int i = 0; i < vertCount; i++)
|
||||
{
|
||||
Vector3 pt = vb.vertices[i];
|
||||
pt = _vertexMatrix.matrix.MultiplyPoint(pt);
|
||||
pt += center;
|
||||
Vector3 vec = pt - camPos;
|
||||
float lambda = -camPos.z / vec.z;
|
||||
pt.x = camPos.x + lambda * vec.x;
|
||||
pt.y = camPos.y + lambda * vec.y;
|
||||
pt.z = 0;
|
||||
|
||||
vb.vertices[i] = pt;
|
||||
}
|
||||
}
|
||||
|
||||
mesh.Clear();
|
||||
|
||||
#if UNITY_5_2 || UNITY_5_3_OR_NEWER
|
||||
mesh.SetVertices(vb.vertices);
|
||||
if (vb._isArbitraryQuad)
|
||||
mesh.SetUVs(0, vb.FixUVForArbitraryQuad());
|
||||
else
|
||||
mesh.SetUVs(0, vb.uvs);
|
||||
mesh.SetColors(vb.colors);
|
||||
mesh.SetTriangles(vb.triangles, 0);
|
||||
if (vb.uvs2.Count == vb.uvs.Count)
|
||||
mesh.SetUVs(1, vb.uvs2);
|
||||
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
_colors = null;
|
||||
#endif
|
||||
#else
|
||||
Vector3[] vertices = new Vector3[vertCount];
|
||||
Vector2[] uv = new Vector2[vertCount];
|
||||
_colors = new Color32[vertCount];
|
||||
int[] triangles = new int[vb.triangles.Count];
|
||||
|
||||
vb.vertices.CopyTo(vertices);
|
||||
vb.uvs.CopyTo(uv);
|
||||
vb.colors.CopyTo(_colors);
|
||||
vb.triangles.CopyTo(triangles);
|
||||
|
||||
mesh.vertices = vertices;
|
||||
mesh.uv = uv;
|
||||
mesh.triangles = triangles;
|
||||
mesh.colors32 = _colors;
|
||||
|
||||
if(vb.uvs2.Count==uv.Length)
|
||||
{
|
||||
uv = new Vector2[vertCount];
|
||||
vb.uvs2.CopyTo(uv);
|
||||
mesh.uv2 = uv;
|
||||
}
|
||||
#endif
|
||||
vb.End();
|
||||
|
||||
if (meshModifier != null)
|
||||
meshModifier();
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
Rect rect = texture.GetDrawRect(vb.contentRect);
|
||||
|
||||
vb.AddQuad(rect, vb.vertexColor, vb.uvRect);
|
||||
vb.AddTriangles();
|
||||
vb._isArbitraryQuad = _vertexMatrix != null;
|
||||
}
|
||||
|
||||
class StencilEraser
|
||||
{
|
||||
public GameObject gameObject;
|
||||
public MeshFilter meshFilter;
|
||||
public MeshRenderer meshRenderer;
|
||||
|
||||
public StencilEraser(Transform parent)
|
||||
{
|
||||
gameObject = new GameObject("StencilEraser");
|
||||
gameObject.transform.SetParent(parent, false);
|
||||
|
||||
meshFilter = gameObject.AddComponent<MeshFilter>();
|
||||
meshRenderer = gameObject.AddComponent<MeshRenderer>();
|
||||
meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
|
||||
meshRenderer.receiveShadows = false;
|
||||
|
||||
gameObject.layer = parent.gameObject.layer;
|
||||
gameObject.hideFlags = parent.gameObject.hideFlags;
|
||||
meshFilter.hideFlags = parent.gameObject.hideFlags;
|
||||
meshRenderer.hideFlags = parent.gameObject.hideFlags;
|
||||
}
|
||||
|
||||
public bool enabled
|
||||
{
|
||||
get { return meshRenderer.enabled; }
|
||||
set { meshRenderer.enabled = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b84f79fb60acc974cb58c5368b257716
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,515 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum DestroyMethod
|
||||
{
|
||||
Destroy,
|
||||
Unload,
|
||||
None,
|
||||
ReleaseTemp,
|
||||
Custom
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NTexture
|
||||
{
|
||||
/// <summary>
|
||||
/// This event will trigger when a texture is destroying if its destroyMethod is Custom
|
||||
/// </summary>
|
||||
public static event Action<Texture> CustomDestroyMethod;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Rect uvRect;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool rotated;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int refCount;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float lastActive;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public DestroyMethod destroyMethod;
|
||||
|
||||
/// <summary>
|
||||
/// This event will trigger when texture reloaded and size changed.
|
||||
/// </summary>
|
||||
public event Action<NTexture> onSizeChanged;
|
||||
|
||||
/// <summary>
|
||||
/// This event will trigger when ref count is zero.
|
||||
/// </summary>
|
||||
public event Action<NTexture> onRelease;
|
||||
|
||||
private Texture _nativeTexture;
|
||||
private Texture _alphaTexture;
|
||||
|
||||
private Rect _region;
|
||||
private Vector2 _offset;
|
||||
private Vector2 _originalSize;
|
||||
|
||||
private NTexture _root;
|
||||
private Dictionary<string, MaterialManager> _materialManagers;
|
||||
|
||||
internal static Texture2D CreateEmptyTexture()
|
||||
{
|
||||
var emptyTexture = new Texture2D(1, 1, TextureFormat.RGB24, false);
|
||||
emptyTexture.name = "White Texture";
|
||||
emptyTexture.hideFlags = DisplayObject.hideFlags;
|
||||
emptyTexture.SetPixel(0, 0, Color.white);
|
||||
emptyTexture.Apply();
|
||||
return emptyTexture;
|
||||
}
|
||||
|
||||
private static NTexture _empty;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static NTexture Empty
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_empty == null)
|
||||
_empty = new NTexture(CreateEmptyTexture());
|
||||
|
||||
return _empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void DisposeEmpty()
|
||||
{
|
||||
if (_empty != null)
|
||||
{
|
||||
var tmp = _empty;
|
||||
_empty = null;
|
||||
tmp.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
public NTexture(Texture texture) : this(texture, null, 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="xScale"></param>
|
||||
/// <param name="yScale"></param>
|
||||
public NTexture(Texture texture, Texture alphaTexture, float xScale, float yScale)
|
||||
{
|
||||
_root = this;
|
||||
_nativeTexture = texture;
|
||||
_alphaTexture = alphaTexture;
|
||||
uvRect = new Rect(0, 0, xScale, yScale);
|
||||
if (yScale < 0)
|
||||
{
|
||||
uvRect.y = -yScale;
|
||||
uvRect.yMax = 0;
|
||||
}
|
||||
|
||||
if (xScale < 0)
|
||||
{
|
||||
uvRect.x = -xScale;
|
||||
uvRect.xMax = 0;
|
||||
}
|
||||
|
||||
if (_nativeTexture != null)
|
||||
_originalSize = new Vector2(_nativeTexture.width, _nativeTexture.height);
|
||||
_region = new Rect(0, 0, _originalSize.x, _originalSize.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="region"></param>
|
||||
public NTexture(Texture texture, Rect region)
|
||||
{
|
||||
_root = this;
|
||||
_nativeTexture = texture;
|
||||
_region = region;
|
||||
_originalSize = new Vector2(_region.width, _region.height);
|
||||
if (_nativeTexture != null)
|
||||
uvRect = new Rect(region.x / _nativeTexture.width, 1 - region.yMax / _nativeTexture.height,
|
||||
region.width / _nativeTexture.width, region.height / _nativeTexture.height);
|
||||
else
|
||||
uvRect.Set(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="root"></param>
|
||||
/// <param name="region"></param>
|
||||
/// <param name="rotated"></param>
|
||||
public NTexture(NTexture root, Rect region, bool rotated)
|
||||
{
|
||||
_root = root;
|
||||
this.rotated = rotated;
|
||||
region.x += root._region.x;
|
||||
region.y += root._region.y;
|
||||
uvRect = new Rect(region.x * root.uvRect.width / root.width,
|
||||
1 - region.yMax * root.uvRect.height / root.height,
|
||||
region.width * root.uvRect.width / root.width, region.height * root.uvRect.height / root.height);
|
||||
if (rotated)
|
||||
{
|
||||
var tmp = region.width;
|
||||
region.width = region.height;
|
||||
region.height = tmp;
|
||||
|
||||
tmp = uvRect.width;
|
||||
uvRect.width = uvRect.height;
|
||||
uvRect.height = tmp;
|
||||
}
|
||||
|
||||
_region = region;
|
||||
_originalSize = _region.size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="root"></param>
|
||||
/// <param name="region"></param>
|
||||
/// <param name="rotated"></param>
|
||||
/// <param name="originalSize"></param>
|
||||
/// <param name="offset"></param>
|
||||
public NTexture(NTexture root, Rect region, bool rotated, Vector2 originalSize, Vector2 offset)
|
||||
: this(root, region, rotated)
|
||||
{
|
||||
_originalSize = originalSize;
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sprite"></param>
|
||||
public NTexture(Sprite sprite)
|
||||
{
|
||||
var rect = sprite.textureRect;
|
||||
rect.y = sprite.texture.height - rect.yMax;
|
||||
|
||||
_root = this;
|
||||
_nativeTexture = sprite.texture;
|
||||
_region = rect;
|
||||
_originalSize = new Vector2(_region.width, _region.height);
|
||||
uvRect = new Rect(_region.x / _nativeTexture.width, 1 - _region.yMax / _nativeTexture.height,
|
||||
_region.width / _nativeTexture.width, _region.height / _nativeTexture.height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int width => (int)_region.width;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int height => (int)_region.height;
|
||||
|
||||
/// <summary>
|
||||
/// 修改源码,unity里sprite用fgui的图,转换时要用
|
||||
/// </summary>
|
||||
public Rect region => _region;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector2 offset
|
||||
{
|
||||
get => _offset;
|
||||
set => _offset = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector2 originalSize
|
||||
{
|
||||
get => _originalSize;
|
||||
set => _originalSize = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="drawRect"></param>
|
||||
/// <returns></returns>
|
||||
public Rect GetDrawRect(Rect drawRect)
|
||||
{
|
||||
if (_originalSize.x == _region.width && _originalSize.y == _region.height)
|
||||
return drawRect;
|
||||
|
||||
var sx = drawRect.width / _originalSize.x;
|
||||
var sy = drawRect.height / _originalSize.y;
|
||||
return new Rect(_offset.x * sx, _offset.y * sy, _region.width * sx, _region.height * sy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="uv"></param>
|
||||
public void GetUV(Vector2[] uv)
|
||||
{
|
||||
uv[0] = uvRect.position;
|
||||
uv[1] = new Vector2(uvRect.xMin, uvRect.yMax);
|
||||
uv[2] = new Vector2(uvRect.xMax, uvRect.yMax);
|
||||
uv[3] = new Vector2(uvRect.xMax, uvRect.yMin);
|
||||
if (rotated)
|
||||
{
|
||||
var xMin = uvRect.xMin;
|
||||
var yMin = uvRect.yMin;
|
||||
var yMax = uvRect.yMax;
|
||||
|
||||
float tmp;
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
var m = uv[i];
|
||||
tmp = m.y;
|
||||
m.y = yMin + m.x - xMin;
|
||||
m.x = xMin + yMax - tmp;
|
||||
uv[i] = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public NTexture root => _root;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool disposed => _root == null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Texture nativeTexture => _root != null ? _root._nativeTexture : null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Texture alphaTexture => _root != null ? _root._alphaTexture : null;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public MaterialManager GetMaterialManager(string shaderName)
|
||||
{
|
||||
if (_root != this)
|
||||
{
|
||||
if (_root == null)
|
||||
return null;
|
||||
else
|
||||
return _root.GetMaterialManager(shaderName);
|
||||
}
|
||||
|
||||
if (_materialManagers == null)
|
||||
_materialManagers = new Dictionary<string, MaterialManager>();
|
||||
|
||||
MaterialManager mm;
|
||||
if (!_materialManagers.TryGetValue(shaderName, out mm))
|
||||
{
|
||||
mm = new MaterialManager(this, ShaderConfig.GetShader(shaderName));
|
||||
_materialManagers.Add(shaderName, mm);
|
||||
}
|
||||
|
||||
return mm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Unload()
|
||||
{
|
||||
Unload(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Unload(bool destroyMaterials)
|
||||
{
|
||||
if (this == _empty)
|
||||
return;
|
||||
|
||||
if (_root != this)
|
||||
throw new Exception("Unload is not allow to call on none root NTexture.");
|
||||
|
||||
if (_nativeTexture != null)
|
||||
{
|
||||
DestroyTexture();
|
||||
|
||||
if (destroyMaterials)
|
||||
DestroyMaterials();
|
||||
else
|
||||
RefreshMaterials();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="nativeTexture"></param>
|
||||
/// <param name="alphaTexture"></param>
|
||||
public void Reload(Texture nativeTexture, Texture alphaTexture)
|
||||
{
|
||||
if (_root != this)
|
||||
throw new Exception("Reload is not allow to call on none root NTexture.");
|
||||
|
||||
if (_nativeTexture != null && _nativeTexture != nativeTexture)
|
||||
DestroyTexture();
|
||||
|
||||
_nativeTexture = nativeTexture;
|
||||
_alphaTexture = alphaTexture;
|
||||
|
||||
var lastSize = _originalSize;
|
||||
if (_nativeTexture != null)
|
||||
_originalSize = new Vector2(_nativeTexture.width, _nativeTexture.height);
|
||||
else
|
||||
_originalSize = Vector2.zero;
|
||||
_region = new Rect(0, 0, _originalSize.x, _originalSize.y);
|
||||
|
||||
RefreshMaterials();
|
||||
|
||||
if (onSizeChanged != null && lastSize != _originalSize)
|
||||
onSizeChanged(this);
|
||||
}
|
||||
|
||||
private void DestroyTexture()
|
||||
{
|
||||
switch (destroyMethod)
|
||||
{
|
||||
case DestroyMethod.Destroy:
|
||||
Object.DestroyImmediate(_nativeTexture, true);
|
||||
if (_alphaTexture != null)
|
||||
Object.DestroyImmediate(_alphaTexture, true);
|
||||
break;
|
||||
case DestroyMethod.Unload:
|
||||
Resources.UnloadAsset(_nativeTexture);
|
||||
if (_alphaTexture != null)
|
||||
Resources.UnloadAsset(_alphaTexture);
|
||||
break;
|
||||
case DestroyMethod.ReleaseTemp:
|
||||
RenderTexture.ReleaseTemporary((RenderTexture)_nativeTexture);
|
||||
if (_alphaTexture is RenderTexture)
|
||||
RenderTexture.ReleaseTemporary((RenderTexture)_alphaTexture);
|
||||
break;
|
||||
case DestroyMethod.Custom:
|
||||
if (CustomDestroyMethod == null)
|
||||
{
|
||||
Debug.LogWarning("NTexture.CustomDestroyMethod must be set to handle DestroyMethod.Custom");
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomDestroyMethod(_nativeTexture);
|
||||
if (_alphaTexture != null)
|
||||
CustomDestroyMethod(_alphaTexture);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_nativeTexture = null;
|
||||
_alphaTexture = null;
|
||||
}
|
||||
|
||||
private void RefreshMaterials()
|
||||
{
|
||||
if (_materialManagers != null && _materialManagers.Count > 0)
|
||||
{
|
||||
var iter = _materialManagers.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
iter.Current.Value.RefreshMaterials();
|
||||
iter.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyMaterials()
|
||||
{
|
||||
if (_materialManagers != null && _materialManagers.Count > 0)
|
||||
{
|
||||
var iter = _materialManagers.GetEnumerator();
|
||||
while (iter.MoveNext())
|
||||
iter.Current.Value.DestroyMaterials();
|
||||
iter.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRef()
|
||||
{
|
||||
if (_root == null) //disposed
|
||||
return;
|
||||
|
||||
if (_root != this && refCount == 0)
|
||||
_root.AddRef();
|
||||
|
||||
refCount++;
|
||||
}
|
||||
|
||||
public void ReleaseRef()
|
||||
{
|
||||
if (_root == null) //disposed
|
||||
return;
|
||||
|
||||
refCount--;
|
||||
|
||||
if (refCount == 0)
|
||||
{
|
||||
if (_root != this)
|
||||
_root.ReleaseRef();
|
||||
|
||||
if (onRelease != null)
|
||||
onRelease(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (this == _empty)
|
||||
return;
|
||||
|
||||
if (_root == this)
|
||||
Unload(true);
|
||||
_root = null;
|
||||
onSizeChanged = null;
|
||||
onRelease = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdb420f5e4ef87d419c4467d1b8f2ddf
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class ShaderConfig
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public delegate Shader GetFunction(string name);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static GetFunction Get = Shader.Find;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static string imageShader = "FairyGUI/Image";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static string textShader = "FairyGUI/Text";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static string bmFontShader = "FairyGUI/BMFont";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static string TMPFontShader = "FairyGUI/TMP";
|
||||
|
||||
public static int ID_ClipBox;
|
||||
public static int ID_ClipSoftness;
|
||||
public static int ID_AlphaTex;
|
||||
public static int ID_StencilComp;
|
||||
public static int ID_Stencil;
|
||||
public static int ID_StencilOp;
|
||||
public static int ID_StencilReadMask;
|
||||
public static int ID_ColorMask;
|
||||
public static int ID_ColorMatrix;
|
||||
public static int ID_ColorOffset;
|
||||
public static int ID_BlendSrcFactor;
|
||||
public static int ID_BlendDstFactor;
|
||||
public static int ID_ColorOption;
|
||||
|
||||
public static int ID_Stencil2;
|
||||
|
||||
static ShaderConfig()
|
||||
{
|
||||
ID_ClipBox = Shader.PropertyToID("_ClipBox");
|
||||
ID_ClipSoftness = Shader.PropertyToID("_ClipSoftness");
|
||||
ID_AlphaTex = Shader.PropertyToID("_AlphaTex");
|
||||
ID_StencilComp = Shader.PropertyToID("_StencilComp");
|
||||
ID_Stencil = Shader.PropertyToID("_Stencil");
|
||||
ID_StencilOp = Shader.PropertyToID("_StencilOp");
|
||||
ID_StencilReadMask = Shader.PropertyToID("_StencilReadMask");
|
||||
ID_ColorMask = Shader.PropertyToID("_ColorMask");
|
||||
ID_ColorMatrix = Shader.PropertyToID("_ColorMatrix");
|
||||
ID_ColorOffset = Shader.PropertyToID("_ColorOffset");
|
||||
ID_BlendSrcFactor = Shader.PropertyToID("_BlendSrcFactor");
|
||||
ID_BlendDstFactor = Shader.PropertyToID("_BlendDstFactor");
|
||||
ID_ColorOption = Shader.PropertyToID("_ColorOption");
|
||||
|
||||
ID_Stencil2 = Shader.PropertyToID("_StencilRef");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static Shader GetShader(string name)
|
||||
{
|
||||
Shader shader = Get(name);
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogWarning("FairyGUI: shader not found: " + name);
|
||||
shader = Shader.Find("UI/Default");
|
||||
}
|
||||
shader.hideFlags = DisplayObject.hideFlags;
|
||||
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4eae4be32683c04a96ac1c4cd1834ab
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
250
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Shape.cs
Normal file
250
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Shape.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Shape : DisplayObject
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Shape()
|
||||
{
|
||||
CreateGameObject("Shape");
|
||||
graphics = new NGraphics(gameObject);
|
||||
graphics.texture = NTexture.Empty;
|
||||
graphics.meshFactory = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color color
|
||||
{
|
||||
get
|
||||
{
|
||||
return graphics.color;
|
||||
}
|
||||
set
|
||||
{
|
||||
graphics.color = value;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="lineColor"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
public void DrawRect(float lineSize, Color lineColor, Color fillColor)
|
||||
{
|
||||
RectMesh mesh = graphics.GetMeshFactory<RectMesh>();
|
||||
mesh.lineWidth = lineSize;
|
||||
mesh.lineColor = lineColor;
|
||||
mesh.fillColor = null;
|
||||
mesh.colors = null;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="colors"></param>
|
||||
public void DrawRect(float lineSize, Color32[] colors)
|
||||
{
|
||||
RectMesh mesh = graphics.GetMeshFactory<RectMesh>();
|
||||
mesh.lineWidth = lineSize;
|
||||
mesh.colors = colors;
|
||||
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="lineColor"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
/// <param name="topLeftRadius"></param>
|
||||
/// <param name="topRightRadius"></param>
|
||||
/// <param name="bottomLeftRadius"></param>
|
||||
/// <param name="bottomRightRadius"></param>
|
||||
public void DrawRoundRect(float lineSize, Color lineColor, Color fillColor,
|
||||
float topLeftRadius, float topRightRadius, float bottomLeftRadius, float bottomRightRadius)
|
||||
{
|
||||
RoundedRectMesh mesh = graphics.GetMeshFactory<RoundedRectMesh>();
|
||||
mesh.lineWidth = lineSize;
|
||||
mesh.lineColor = lineColor;
|
||||
mesh.fillColor = null;
|
||||
mesh.topLeftRadius = topLeftRadius;
|
||||
mesh.topRightRadius = topRightRadius;
|
||||
mesh.bottomLeftRadius = bottomLeftRadius;
|
||||
mesh.bottomRightRadius = bottomRightRadius;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fillColor"></param>
|
||||
public void DrawEllipse(Color fillColor)
|
||||
{
|
||||
EllipseMesh mesh = graphics.GetMeshFactory<EllipseMesh>();
|
||||
mesh.lineWidth = 0;
|
||||
mesh.startDegree = 0;
|
||||
mesh.endDegreee = 360;
|
||||
mesh.fillColor = null;
|
||||
mesh.centerColor = null;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="centerColor"></param>
|
||||
/// <param name="lineColor"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
/// <param name="startDegree"></param>
|
||||
/// <param name="endDegree"></param>
|
||||
public void DrawEllipse(float lineSize, Color centerColor, Color lineColor, Color fillColor, float startDegree, float endDegree)
|
||||
{
|
||||
EllipseMesh mesh = graphics.GetMeshFactory<EllipseMesh>();
|
||||
mesh.lineWidth = lineSize;
|
||||
if (centerColor.Equals(fillColor))
|
||||
mesh.centerColor = null;
|
||||
else
|
||||
mesh.centerColor = centerColor;
|
||||
mesh.lineColor = lineColor;
|
||||
mesh.fillColor = null;
|
||||
mesh.startDegree = startDegree;
|
||||
mesh.endDegreee = endDegree;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="points"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
public void DrawPolygon(IList<Vector2> points, Color fillColor)
|
||||
{
|
||||
PolygonMesh mesh = graphics.GetMeshFactory<PolygonMesh>();
|
||||
mesh.points.Clear();
|
||||
mesh.points.AddRange(points);
|
||||
mesh.fillColor = null;
|
||||
mesh.colors = null;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="points"></param>
|
||||
/// <param name="colors"></param>
|
||||
public void DrawPolygon(IList<Vector2> points, Color32[] colors)
|
||||
{
|
||||
PolygonMesh mesh = graphics.GetMeshFactory<PolygonMesh>();
|
||||
mesh.points.Clear();
|
||||
mesh.points.AddRange(points);
|
||||
mesh.fillColor = null;
|
||||
mesh.colors = colors;
|
||||
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="points"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="lineColor"></param>
|
||||
public void DrawPolygon(IList<Vector2> points, Color fillColor, float lineSize, Color lineColor)
|
||||
{
|
||||
PolygonMesh mesh = graphics.GetMeshFactory<PolygonMesh>();
|
||||
mesh.points.Clear();
|
||||
mesh.points.AddRange(points);
|
||||
mesh.fillColor = null;
|
||||
mesh.lineWidth = lineSize;
|
||||
mesh.lineColor = lineColor;
|
||||
mesh.colors = null;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sides"></param>
|
||||
/// <param name="lineSize"></param>
|
||||
/// <param name="centerColor"></param>
|
||||
/// <param name="lineColor"></param>
|
||||
/// <param name="fillColor"></param>
|
||||
/// <param name="rotation"></param>
|
||||
/// <param name="distances"></param>
|
||||
public void DrawRegularPolygon(int sides, float lineSize, Color centerColor, Color lineColor, Color fillColor, float rotation, float[] distances)
|
||||
{
|
||||
RegularPolygonMesh mesh = graphics.GetMeshFactory<RegularPolygonMesh>();
|
||||
mesh.sides = sides;
|
||||
mesh.lineWidth = lineSize;
|
||||
mesh.centerColor = centerColor;
|
||||
mesh.lineColor = lineColor;
|
||||
mesh.fillColor = null;
|
||||
mesh.rotation = rotation;
|
||||
mesh.distances = distances;
|
||||
|
||||
graphics.color = fillColor;
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
graphics.meshFactory = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool isEmpty
|
||||
{
|
||||
get { return graphics.meshFactory == null; }
|
||||
}
|
||||
|
||||
protected override DisplayObject HitTest()
|
||||
{
|
||||
if (graphics.meshFactory == null)
|
||||
return null;
|
||||
|
||||
Vector2 localPoint = WorldToLocal(HitTestContext.worldPoint, HitTestContext.direction);
|
||||
|
||||
IHitTest ht = graphics.meshFactory as IHitTest;
|
||||
if (ht != null)
|
||||
return ht.HitTest(_contentRect, localPoint) ? this : null;
|
||||
else if (_contentRect.Contains(localPoint))
|
||||
return this;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbcf11c269a33474aa9adaafd9867711
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1768
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Stage.cs
Normal file
1768
JNFrame2/Assets/Plugins/FairyGUI/Runtime/Scripts/Core/Stage.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6650441f8140eae4c896682b7fd5b3e6
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Stage Camera is an orthographic camera for UI rendering.
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("FairyGUI/UI Camera")]
|
||||
public class StageCamera : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool constantSize = true;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public float unitsPerPixel = 0.02f;
|
||||
|
||||
[NonSerialized]
|
||||
public Transform cachedTransform;
|
||||
[NonSerialized]
|
||||
public Camera cachedCamera;
|
||||
|
||||
[NonSerialized]
|
||||
int screenWidth;
|
||||
[NonSerialized]
|
||||
int screenHeight;
|
||||
[NonSerialized]
|
||||
bool isMain;
|
||||
[NonSerialized]
|
||||
Display _display;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public static Camera main;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public static int screenSizeVer = 1;
|
||||
|
||||
public const string Name = "Stage Camera";
|
||||
public const string LayerName = "UI";
|
||||
|
||||
public static float DefaultCameraSize = 5;
|
||||
public static float DefaultUnitsPerPixel = 0.02f;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
cachedTransform = this.transform;
|
||||
cachedCamera = this.GetComponent<Camera>();
|
||||
if (this.gameObject.name == Name)
|
||||
{
|
||||
main = cachedCamera;
|
||||
isMain = true;
|
||||
}
|
||||
|
||||
if (Display.displays.Length > 1 && cachedCamera.targetDisplay != 0 && cachedCamera.targetDisplay < Display.displays.Length)
|
||||
_display = Display.displays[cachedCamera.targetDisplay];
|
||||
|
||||
if (_display == null)
|
||||
OnScreenSizeChanged(Screen.width, Screen.height);
|
||||
else
|
||||
OnScreenSizeChanged(_display.renderingWidth, _display.renderingHeight);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_display == null)
|
||||
{
|
||||
if (screenWidth != Screen.width || screenHeight != Screen.height)
|
||||
OnScreenSizeChanged(Screen.width, Screen.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (screenWidth != _display.renderingWidth || screenHeight != _display.renderingHeight)
|
||||
OnScreenSizeChanged(_display.renderingWidth, _display.renderingHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void OnScreenSizeChanged(int newWidth, int newHeight)
|
||||
{
|
||||
if (newWidth == 0 || newHeight == 0)
|
||||
return;
|
||||
|
||||
screenWidth = newWidth;
|
||||
screenHeight = newHeight;
|
||||
|
||||
if (constantSize)
|
||||
{
|
||||
cachedCamera.orthographicSize = DefaultCameraSize;
|
||||
unitsPerPixel = cachedCamera.orthographicSize * 2 / screenHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
unitsPerPixel = DefaultUnitsPerPixel;
|
||||
cachedCamera.orthographicSize = screenHeight / 2 * unitsPerPixel;
|
||||
}
|
||||
cachedTransform.localPosition = new Vector3(cachedCamera.orthographicSize * screenWidth / screenHeight, -cachedCamera.orthographicSize);
|
||||
|
||||
if (isMain)
|
||||
{
|
||||
screenSizeVer++;
|
||||
if (Application.isPlaying)
|
||||
Stage.inst.HandleScreenSizeChanged(screenWidth, screenHeight, unitsPerPixel);
|
||||
else
|
||||
{
|
||||
UIContentScaler scaler = GameObject.FindObjectOfType<UIContentScaler>();
|
||||
if (scaler != null)
|
||||
scaler.ApplyChange();
|
||||
else
|
||||
UIContentScaler.scaleFactor = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnRenderObject()
|
||||
{
|
||||
//Update和OnGUI在EditMode的调用都不那么及时,OnRenderObject则比较频繁,可以保证界面及时刷新。所以使用OnRenderObject
|
||||
if (isMain && !Application.isPlaying)
|
||||
{
|
||||
EMRenderSupport.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyModifiedProperties()
|
||||
{
|
||||
screenWidth = 0; //force OnScreenSizeChanged called in next update
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if there is a stage camera in the scene. If none, create one.
|
||||
/// </summary>
|
||||
public static void CheckMainCamera()
|
||||
{
|
||||
if (GameObject.Find(Name) == null)
|
||||
{
|
||||
int layer = LayerMask.NameToLayer(LayerName);
|
||||
CreateCamera(Name, 1 << layer);
|
||||
}
|
||||
|
||||
HitTestContext.cachedMainCamera = Camera.main;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static void CheckCaptureCamera()
|
||||
{
|
||||
if (GameObject.Find(Name) == null)
|
||||
{
|
||||
int layer = LayerMask.NameToLayer(LayerName);
|
||||
CreateCamera(Name, 1 << layer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cullingMask"></param>
|
||||
/// <returns></returns>
|
||||
public static Camera CreateCamera(string name, int cullingMask)
|
||||
{
|
||||
GameObject cameraObject = new GameObject(name);
|
||||
Camera camera = cameraObject.AddComponent<Camera>();
|
||||
camera.depth = 1;
|
||||
camera.cullingMask = cullingMask;
|
||||
camera.clearFlags = CameraClearFlags.Depth;
|
||||
camera.orthographic = true;
|
||||
camera.orthographicSize = DefaultCameraSize;
|
||||
camera.nearClipPlane = -30;
|
||||
camera.farClipPlane = 30;
|
||||
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
camera.stereoTargetEye = StereoTargetEyeMask.None;
|
||||
#endif
|
||||
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
camera.allowHDR = false;
|
||||
camera.allowMSAA = false;
|
||||
#endif
|
||||
cameraObject.AddComponent<StageCamera>();
|
||||
|
||||
return camera;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 367e80e3fa958344491a9a196a902b72
|
||||
timeCreated: 1460480287
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class StageEngine : MonoBehaviour
|
||||
{
|
||||
public int ObjectsOnStage;
|
||||
public int GraphicsOnStage;
|
||||
|
||||
public static bool beingQuit;
|
||||
|
||||
void Start()
|
||||
{
|
||||
useGUILayout = false;
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
Stage.inst.InternalUpdate();
|
||||
|
||||
ObjectsOnStage = Stats.ObjectCount;
|
||||
GraphicsOnStage = Stats.GraphicsCount;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
Stage.inst.HandleGUIEvents(Event.current);
|
||||
}
|
||||
|
||||
#if !UNITY_5_4_OR_NEWER
|
||||
void OnLevelWasLoaded()
|
||||
{
|
||||
StageCamera.CheckMainCamera();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
if (Application.isEditor)
|
||||
{
|
||||
beingQuit = true;
|
||||
UIPackage.RemoveAllPackages();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0922848d650639f479e29635982d4a4c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 100
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Stats
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int ObjectCount;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int GraphicsCount;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int LatestObjectCreation;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static int LatestGraphicsCreation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: baddfd53a8a771f4eaa567ee3eb2ccc0
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6a329985f59cbd4ba1618ac71c89d7d
|
||||
folderAsset: yes
|
||||
timeCreated: 1460480287
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all kind of fonts.
|
||||
/// </summary>
|
||||
public class BaseFont
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this font object.
|
||||
/// </summary>
|
||||
public string name;
|
||||
|
||||
/// <summary>
|
||||
/// The texture of this font object.
|
||||
/// </summary>
|
||||
public NTexture mainTexture;
|
||||
|
||||
/// <summary>
|
||||
/// Can this font be tinted? Will be true for dynamic font and fonts generated by BMFont.
|
||||
/// </summary>
|
||||
public bool canTint;
|
||||
|
||||
/// <summary>
|
||||
/// If true, it will use extra vertices to enhance bold effect
|
||||
/// </summary>
|
||||
public bool customBold;
|
||||
|
||||
/// <summary>
|
||||
/// If true, it will use extra vertices to enhance bold effect ONLY when it is in italic style.
|
||||
/// </summary>
|
||||
public bool customBoldAndItalic;
|
||||
|
||||
/// <summary>
|
||||
/// If true, it will use extra vertices(4 direction) to enhance outline effect
|
||||
/// </summary>
|
||||
public bool customOutline;
|
||||
|
||||
/// <summary>
|
||||
/// The shader for this font object.
|
||||
/// </summary>
|
||||
public string shader;
|
||||
|
||||
/// <summary>
|
||||
/// Keep text crisp.
|
||||
/// </summary>
|
||||
public bool keepCrisp;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int version;
|
||||
|
||||
protected internal static bool textRebuildFlag;
|
||||
|
||||
protected const float SupScale = 0.58f;
|
||||
protected const float SupOffset = 0.33f;
|
||||
|
||||
virtual public void UpdateGraphics(NGraphics graphics)
|
||||
{
|
||||
}
|
||||
|
||||
virtual public void SetFormat(TextFormat format, float fontSizeScale)
|
||||
{
|
||||
}
|
||||
|
||||
virtual public void PrepareCharacters(string text)
|
||||
{
|
||||
}
|
||||
|
||||
virtual public bool GetGlyph(char ch, out float width, out float height, out float baseline)
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
baseline = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual public int DrawGlyph(float x, float y,
|
||||
List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual public int DrawLine(float x, float y, float width, int fontSize, int type,
|
||||
List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual public bool HasCharacter(char ch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual public int GetLineHeight(int size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 242acb07eafac7a43a60dc4107fbd6b4
|
||||
timeCreated: 1460480287
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,177 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BitmapFont : BaseFont
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BMGlyph
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
public int advance;
|
||||
public int lineHeight;
|
||||
public Vector2[] uv = new Vector2[4];
|
||||
public int channel;//0-n/a, 1-r,2-g,3-b,4-alpha
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int size;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool resizable;
|
||||
|
||||
/// <summary>
|
||||
/// Font generated by BMFont use channels.
|
||||
/// </summary>
|
||||
public bool hasChannel;
|
||||
|
||||
protected Dictionary<int, BMGlyph> _dict;
|
||||
protected BMGlyph _glyph;
|
||||
float _scale;
|
||||
|
||||
public BitmapFont()
|
||||
{
|
||||
this.canTint = true;
|
||||
this.hasChannel = false;
|
||||
this.customOutline = true;
|
||||
this.shader = ShaderConfig.bmFontShader;
|
||||
|
||||
_dict = new Dictionary<int, BMGlyph>();
|
||||
_scale = 1;
|
||||
}
|
||||
|
||||
public void AddChar(char ch, BMGlyph glyph)
|
||||
{
|
||||
_dict[ch] = glyph;
|
||||
}
|
||||
|
||||
override public void SetFormat(TextFormat format, float fontSizeScale)
|
||||
{
|
||||
if (resizable)
|
||||
_scale = (float)format.size / size * fontSizeScale;
|
||||
else
|
||||
_scale = fontSizeScale;
|
||||
|
||||
if (canTint)
|
||||
format.FillVertexColors(vertexColors);
|
||||
}
|
||||
|
||||
override public bool GetGlyph(char ch, out float width, out float height, out float baseline)
|
||||
{
|
||||
if (ch == ' ')
|
||||
{
|
||||
width = Mathf.RoundToInt(size * _scale / 2);
|
||||
height = Mathf.RoundToInt(size * _scale);
|
||||
baseline = height;
|
||||
_glyph = null;
|
||||
return true;
|
||||
}
|
||||
else if (_dict.TryGetValue((int)ch, out _glyph))
|
||||
{
|
||||
width = Mathf.RoundToInt(_glyph.advance * _scale);
|
||||
height = Mathf.RoundToInt(_glyph.lineHeight * _scale);
|
||||
baseline = height;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
baseline = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Vector3 bottomLeft;
|
||||
static Vector3 topLeft;
|
||||
static Vector3 topRight;
|
||||
static Vector3 bottomRight;
|
||||
|
||||
static Color32[] vertexColors = new Color32[4];
|
||||
|
||||
override public int DrawGlyph(float x, float y,
|
||||
List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
|
||||
{
|
||||
if (_glyph == null) //space
|
||||
return 0;
|
||||
|
||||
topLeft.x = x + _glyph.x * _scale;
|
||||
topLeft.y = y + (_glyph.lineHeight - _glyph.y) * _scale;
|
||||
bottomRight.x = x + (_glyph.x + _glyph.width) * _scale;
|
||||
bottomRight.y = topLeft.y - _glyph.height * _scale;
|
||||
|
||||
topRight.x = bottomRight.x;
|
||||
topRight.y = topLeft.y;
|
||||
bottomLeft.x = topLeft.x;
|
||||
bottomLeft.y = bottomRight.y;
|
||||
|
||||
vertList.Add(bottomLeft);
|
||||
vertList.Add(topLeft);
|
||||
vertList.Add(topRight);
|
||||
vertList.Add(bottomRight);
|
||||
|
||||
uvList.AddRange(_glyph.uv);
|
||||
|
||||
if (hasChannel)
|
||||
{
|
||||
Vector2 channel = new Vector2(_glyph.channel, 0);
|
||||
uv2List.Add(channel);
|
||||
uv2List.Add(channel);
|
||||
uv2List.Add(channel);
|
||||
uv2List.Add(channel);
|
||||
}
|
||||
|
||||
if (canTint)
|
||||
{
|
||||
colList.Add(vertexColors[0]);
|
||||
colList.Add(vertexColors[1]);
|
||||
colList.Add(vertexColors[2]);
|
||||
colList.Add(vertexColors[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
colList.Add(Color.white);
|
||||
colList.Add(Color.white);
|
||||
colList.Add(Color.white);
|
||||
colList.Add(Color.white);
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
override public bool HasCharacter(char ch)
|
||||
{
|
||||
return ch == ' ' || _dict.ContainsKey((int)ch);
|
||||
}
|
||||
|
||||
override public int GetLineHeight(int size)
|
||||
{
|
||||
if (_dict.Count > 0)
|
||||
{
|
||||
using (var et = _dict.GetEnumerator())
|
||||
{
|
||||
et.MoveNext();
|
||||
if (resizable)
|
||||
return Mathf.RoundToInt((float)et.Current.Value.lineHeight * size / this.size);
|
||||
else
|
||||
return et.Current.Value.lineHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1441c09e3389a046827b23ee409a37a
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class DynamicFont : BaseFont
|
||||
{
|
||||
Font _font;
|
||||
int _size;
|
||||
float _ascent;
|
||||
float _lineHeight;
|
||||
float _scale;
|
||||
TextFormat _format;
|
||||
FontStyle _style;
|
||||
bool _boldVertice;
|
||||
CharacterInfo _char;
|
||||
CharacterInfo _lineChar;
|
||||
bool _gotLineChar;
|
||||
|
||||
public DynamicFont()
|
||||
{
|
||||
this.canTint = true;
|
||||
this.keepCrisp = true;
|
||||
this.customOutline = true;
|
||||
this.shader = ShaderConfig.textShader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="font"></param>
|
||||
/// <returns></returns>
|
||||
public DynamicFont(string name, Font font) : this()
|
||||
{
|
||||
this.name = name;
|
||||
this.nativeFont = font;
|
||||
}
|
||||
|
||||
override public void Dispose()
|
||||
{
|
||||
Font.textureRebuilt -= textureRebuildCallback;
|
||||
}
|
||||
|
||||
public Font nativeFont
|
||||
{
|
||||
get { return _font; }
|
||||
set
|
||||
{
|
||||
if (_font != null)
|
||||
Font.textureRebuilt -= textureRebuildCallback;
|
||||
|
||||
_font = value;
|
||||
Font.textureRebuilt += textureRebuildCallback;
|
||||
_font.hideFlags = DisplayObject.hideFlags;
|
||||
_font.material.hideFlags = DisplayObject.hideFlags;
|
||||
_font.material.mainTexture.hideFlags = DisplayObject.hideFlags;
|
||||
|
||||
if (mainTexture != null)
|
||||
mainTexture.Dispose();
|
||||
mainTexture = new NTexture(_font.material.mainTexture);
|
||||
mainTexture.destroyMethod = DestroyMethod.None;
|
||||
|
||||
// _ascent = _font.ascent;
|
||||
// _lineHeight = _font.lineHeight;
|
||||
_ascent = _font.fontSize;
|
||||
_lineHeight = _font.fontSize * 1.25f;
|
||||
}
|
||||
}
|
||||
|
||||
override public void SetFormat(TextFormat format, float fontSizeScale)
|
||||
{
|
||||
_format = format;
|
||||
float size = format.size * fontSizeScale;
|
||||
if (keepCrisp)
|
||||
size *= UIContentScaler.scaleFactor;
|
||||
if (_format.specialStyle == TextFormat.SpecialStyle.Subscript || _format.specialStyle == TextFormat.SpecialStyle.Superscript)
|
||||
size *= SupScale;
|
||||
_size = Mathf.FloorToInt(size);
|
||||
if (_size == 0)
|
||||
_size = 1;
|
||||
_scale = (float)_size / _font.fontSize;
|
||||
|
||||
if (format.bold && !customBold)
|
||||
{
|
||||
if (format.italic)
|
||||
{
|
||||
if (customBoldAndItalic)
|
||||
_style = FontStyle.Italic;
|
||||
else
|
||||
_style = FontStyle.BoldAndItalic;
|
||||
}
|
||||
else
|
||||
_style = FontStyle.Bold;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (format.italic)
|
||||
_style = FontStyle.Italic;
|
||||
else
|
||||
_style = FontStyle.Normal;
|
||||
}
|
||||
|
||||
_boldVertice = format.bold && (customBold || (format.italic && customBoldAndItalic));
|
||||
format.FillVertexColors(vertexColors);
|
||||
}
|
||||
|
||||
override public void PrepareCharacters(string text)
|
||||
{
|
||||
_font.RequestCharactersInTexture(text, _size, _style);
|
||||
}
|
||||
|
||||
override public bool GetGlyph(char ch, out float width, out float height, out float baseline)
|
||||
{
|
||||
if (!_font.GetCharacterInfo(ch, out _char, _size, _style))
|
||||
{
|
||||
if (ch == ' ')
|
||||
{
|
||||
//space may not be prepared, try again
|
||||
_font.RequestCharactersInTexture(" ", _size, _style);
|
||||
_font.GetCharacterInfo(ch, out _char, _size, _style);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = height = baseline = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
width = _char.advance;
|
||||
height = _lineHeight * _scale;
|
||||
baseline = _ascent * _scale;
|
||||
if (_boldVertice)
|
||||
width++;
|
||||
|
||||
if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
|
||||
{
|
||||
height /= SupScale;
|
||||
baseline /= SupScale;
|
||||
}
|
||||
else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
|
||||
{
|
||||
height = height / SupScale + baseline * SupOffset;
|
||||
baseline *= (SupOffset + 1 / SupScale);
|
||||
}
|
||||
|
||||
height = Mathf.RoundToInt(height);
|
||||
baseline = Mathf.RoundToInt(baseline);
|
||||
|
||||
if (keepCrisp)
|
||||
{
|
||||
width /= UIContentScaler.scaleFactor;
|
||||
height /= UIContentScaler.scaleFactor;
|
||||
baseline /= UIContentScaler.scaleFactor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Vector3 bottomLeft;
|
||||
static Vector3 topLeft;
|
||||
static Vector3 topRight;
|
||||
static Vector3 bottomRight;
|
||||
|
||||
static Vector2 uvBottomLeft;
|
||||
static Vector2 uvTopLeft;
|
||||
static Vector2 uvTopRight;
|
||||
static Vector2 uvBottomRight;
|
||||
|
||||
static Color32[] vertexColors = new Color32[4];
|
||||
|
||||
static Vector3[] BOLD_OFFSET = new Vector3[]
|
||||
{
|
||||
new Vector3(-0.5f, 0f, 0f),
|
||||
new Vector3(0.5f, 0f, 0f),
|
||||
new Vector3(0f, -0.5f, 0f),
|
||||
new Vector3(0f, 0.5f, 0f)
|
||||
};
|
||||
|
||||
override public int DrawGlyph(float x, float y,
|
||||
List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
|
||||
{
|
||||
topLeft.x = _char.minX;
|
||||
topLeft.y = _char.maxY;
|
||||
bottomRight.x = _char.maxX;
|
||||
if (_char.glyphWidth == 0) //zero width, space etc
|
||||
bottomRight.x = topLeft.x + _size / 2;
|
||||
bottomRight.y = _char.minY;
|
||||
|
||||
if (keepCrisp)
|
||||
{
|
||||
topLeft /= UIContentScaler.scaleFactor;
|
||||
bottomRight /= UIContentScaler.scaleFactor;
|
||||
}
|
||||
|
||||
if (_format.specialStyle == TextFormat.SpecialStyle.Subscript)
|
||||
y = y - Mathf.RoundToInt(_ascent * _scale * SupOffset);
|
||||
else if (_format.specialStyle == TextFormat.SpecialStyle.Superscript)
|
||||
y = y + Mathf.RoundToInt(_ascent * _scale * (1 / SupScale - 1 + SupOffset));
|
||||
|
||||
topLeft.x += x;
|
||||
topLeft.y += y;
|
||||
bottomRight.x += x;
|
||||
bottomRight.y += y;
|
||||
|
||||
topRight.x = bottomRight.x;
|
||||
topRight.y = topLeft.y;
|
||||
bottomLeft.x = topLeft.x;
|
||||
bottomLeft.y = bottomRight.y;
|
||||
|
||||
vertList.Add(bottomLeft);
|
||||
vertList.Add(topLeft);
|
||||
vertList.Add(topRight);
|
||||
vertList.Add(bottomRight);
|
||||
|
||||
uvBottomLeft = _char.uvBottomLeft;
|
||||
uvTopLeft = _char.uvTopLeft;
|
||||
uvTopRight = _char.uvTopRight;
|
||||
uvBottomRight = _char.uvBottomRight;
|
||||
|
||||
uvList.Add(uvBottomLeft);
|
||||
uvList.Add(uvTopLeft);
|
||||
uvList.Add(uvTopRight);
|
||||
uvList.Add(uvBottomRight);
|
||||
|
||||
colList.Add(vertexColors[0]);
|
||||
colList.Add(vertexColors[1]);
|
||||
colList.Add(vertexColors[2]);
|
||||
colList.Add(vertexColors[3]);
|
||||
|
||||
if (_boldVertice)
|
||||
{
|
||||
for (int b = 0; b < 4; b++)
|
||||
{
|
||||
Vector3 boldOffset = BOLD_OFFSET[b];
|
||||
|
||||
vertList.Add(bottomLeft + boldOffset);
|
||||
vertList.Add(topLeft + boldOffset);
|
||||
vertList.Add(topRight + boldOffset);
|
||||
vertList.Add(bottomRight + boldOffset);
|
||||
|
||||
uvList.Add(uvBottomLeft);
|
||||
uvList.Add(uvTopLeft);
|
||||
uvList.Add(uvTopRight);
|
||||
uvList.Add(uvBottomRight);
|
||||
|
||||
colList.Add(vertexColors[0]);
|
||||
colList.Add(vertexColors[1]);
|
||||
colList.Add(vertexColors[2]);
|
||||
colList.Add(vertexColors[3]);
|
||||
}
|
||||
|
||||
return 20;
|
||||
}
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
override public int DrawLine(float x, float y, float width, int fontSize, int type,
|
||||
List<Vector3> vertList, List<Vector2> uvList, List<Vector2> uv2List, List<Color32> colList)
|
||||
{
|
||||
if (!_gotLineChar)
|
||||
{
|
||||
_gotLineChar = true;
|
||||
_font.RequestCharactersInTexture("_", 50, FontStyle.Normal);
|
||||
_font.GetCharacterInfo('_', out _lineChar, 50, FontStyle.Normal);
|
||||
}
|
||||
|
||||
float thickness;
|
||||
float offset;
|
||||
|
||||
thickness = Mathf.Max(1, fontSize / 16f); //guest underline size
|
||||
if (type == 0)
|
||||
offset = Mathf.RoundToInt(_lineChar.minY * (float)fontSize / 50 + thickness);
|
||||
else
|
||||
offset = Mathf.RoundToInt(_ascent * 0.4f * fontSize / _font.fontSize);
|
||||
if (thickness < 1)
|
||||
thickness = 1;
|
||||
|
||||
topLeft.x = x;
|
||||
topLeft.y = y + offset;
|
||||
bottomRight.x = x + width;
|
||||
bottomRight.y = topLeft.y - thickness;
|
||||
|
||||
topRight.x = bottomRight.x;
|
||||
topRight.y = topLeft.y;
|
||||
bottomLeft.x = topLeft.x;
|
||||
bottomLeft.y = bottomRight.y;
|
||||
|
||||
vertList.Add(bottomLeft);
|
||||
vertList.Add(topLeft);
|
||||
vertList.Add(topRight);
|
||||
vertList.Add(bottomRight);
|
||||
|
||||
uvBottomLeft = _lineChar.uvBottomLeft;
|
||||
uvTopLeft = _lineChar.uvTopLeft;
|
||||
uvTopRight = _lineChar.uvTopRight;
|
||||
uvBottomRight = _lineChar.uvBottomRight;
|
||||
|
||||
//取中点的UV
|
||||
Vector2 u0;
|
||||
if (_lineChar.uvBottomLeft.x != _lineChar.uvBottomRight.x)
|
||||
u0.x = (_lineChar.uvBottomLeft.x + _lineChar.uvBottomRight.x) * 0.5f;
|
||||
else
|
||||
u0.x = (_lineChar.uvBottomLeft.x + _lineChar.uvTopLeft.x) * 0.5f;
|
||||
|
||||
if (_lineChar.uvBottomLeft.y != _lineChar.uvTopLeft.y)
|
||||
u0.y = (_lineChar.uvBottomLeft.y + _lineChar.uvTopLeft.y) * 0.5f;
|
||||
else
|
||||
u0.y = (_lineChar.uvBottomLeft.y + _lineChar.uvBottomRight.y) * 0.5f;
|
||||
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
|
||||
colList.Add(vertexColors[0]);
|
||||
colList.Add(vertexColors[1]);
|
||||
colList.Add(vertexColors[2]);
|
||||
colList.Add(vertexColors[3]);
|
||||
|
||||
if (_boldVertice)
|
||||
{
|
||||
for (int b = 0; b < 4; b++)
|
||||
{
|
||||
Vector3 boldOffset = BOLD_OFFSET[b];
|
||||
|
||||
vertList.Add(bottomLeft + boldOffset);
|
||||
vertList.Add(topLeft + boldOffset);
|
||||
vertList.Add(topRight + boldOffset);
|
||||
vertList.Add(bottomRight + boldOffset);
|
||||
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
uvList.Add(u0);
|
||||
|
||||
colList.Add(vertexColors[0]);
|
||||
colList.Add(vertexColors[1]);
|
||||
colList.Add(vertexColors[2]);
|
||||
colList.Add(vertexColors[3]);
|
||||
}
|
||||
|
||||
return 20;
|
||||
}
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
override public bool HasCharacter(char ch)
|
||||
{
|
||||
return _font.HasCharacter(ch);
|
||||
}
|
||||
|
||||
override public int GetLineHeight(int size)
|
||||
{
|
||||
return Mathf.RoundToInt(_lineHeight * size / _font.fontSize);
|
||||
}
|
||||
|
||||
void textureRebuildCallback(Font targetFont)
|
||||
{
|
||||
if (_font != targetFont)
|
||||
return;
|
||||
|
||||
if (mainTexture == null || !Application.isPlaying)
|
||||
{
|
||||
mainTexture = new NTexture(_font.material.mainTexture);
|
||||
mainTexture.destroyMethod = DestroyMethod.None;
|
||||
}
|
||||
else
|
||||
mainTexture.Reload(_font.material.mainTexture, null);
|
||||
|
||||
_gotLineChar = false;
|
||||
|
||||
textRebuildFlag = true;
|
||||
version++;
|
||||
|
||||
//Debug.Log("Font texture rebuild: " + name + "," + mainTexture.width + "," + mainTexture.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37b73f8527098974cb0ccf518ff95351
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class Emoji
|
||||
{
|
||||
/// <summary>
|
||||
/// 代表图片资源url。
|
||||
/// </summary>
|
||||
public string url;
|
||||
|
||||
/// <summary>
|
||||
/// 图片宽度。不设置(0)则表示使用原始宽度。
|
||||
/// </summary>
|
||||
public int width;
|
||||
|
||||
/// <summary>
|
||||
/// 图片高度。不设置(0)则表示使用原始高度。
|
||||
/// </summary>
|
||||
public int height;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
public Emoji(string url, int width, int height)
|
||||
{
|
||||
this.url = url;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
public Emoji(string url)
|
||||
{
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3859ae9020061394cadacd1624e04ed9
|
||||
timeCreated: 1475139464
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class FontManager
|
||||
{
|
||||
public static Dictionary<string, BaseFont> sFontFactory = new Dictionary<string, BaseFont>();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
/// <param name="alias"></param>
|
||||
static public void RegisterFont(BaseFont font, string alias = null)
|
||||
{
|
||||
sFontFactory[font.name] = font;
|
||||
if (alias != null)
|
||||
sFontFactory[alias] = font;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="font"></param>
|
||||
static public void UnregisterFont(BaseFont font)
|
||||
{
|
||||
List<string> toDelete = new List<string>();
|
||||
foreach (KeyValuePair<string, BaseFont> kv in sFontFactory)
|
||||
{
|
||||
if (kv.Value == font)
|
||||
toDelete.Add(kv.Key);
|
||||
}
|
||||
|
||||
foreach (string key in toDelete)
|
||||
sFontFactory.Remove(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
static public BaseFont GetFont(string name)
|
||||
{
|
||||
BaseFont font;
|
||||
if (name.StartsWith(UIPackage.URL_PREFIX))
|
||||
{
|
||||
font = UIPackage.GetItemAssetByURL(name) as BaseFont;
|
||||
if (font != null)
|
||||
return font;
|
||||
}
|
||||
|
||||
if (sFontFactory.TryGetValue(name, out font))
|
||||
return font;
|
||||
|
||||
object asset = Resources.Load(name);
|
||||
if (asset == null)
|
||||
asset = Resources.Load("Fonts/" + name);
|
||||
|
||||
//Try to use new API in Uinty5 to load
|
||||
if (asset == null)
|
||||
{
|
||||
if (name.IndexOf(",") != -1)
|
||||
{
|
||||
string[] arr = name.Split(',');
|
||||
int cnt = arr.Length;
|
||||
for (int i = 0; i < cnt; i++)
|
||||
arr[i] = arr[i].Trim();
|
||||
asset = Font.CreateDynamicFontFromOSFont(arr, 16);
|
||||
}
|
||||
else
|
||||
asset = Font.CreateDynamicFontFromOSFont(name, 16);
|
||||
}
|
||||
|
||||
if (asset == null)
|
||||
return Fallback(name);
|
||||
|
||||
if (asset is Font)
|
||||
{
|
||||
font = new DynamicFont();
|
||||
font.name = name;
|
||||
sFontFactory.Add(name, font);
|
||||
|
||||
((DynamicFont)font).nativeFont = (Font)asset;
|
||||
}
|
||||
#if FAIRYGUI_TMPRO
|
||||
else if (asset is TMPro.TMP_FontAsset)
|
||||
{
|
||||
font = new TMPFont();
|
||||
font.name = name;
|
||||
sFontFactory.Add(name, font);
|
||||
((TMPFont)font).fontAsset = (TMPro.TMP_FontAsset)asset;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (asset.GetType().Name.Contains("TMP_FontAsset"))
|
||||
Debug.LogWarning("To enable TextMeshPro support, add script define symbol: FAIRYGUI_TMPRO");
|
||||
|
||||
return Fallback(name);
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static BaseFont Fallback(string name)
|
||||
{
|
||||
if (name != UIConfig.defaultFont)
|
||||
{
|
||||
BaseFont ff;
|
||||
if (sFontFactory.TryGetValue(UIConfig.defaultFont, out ff))
|
||||
{
|
||||
sFontFactory[name] = ff;
|
||||
return ff;
|
||||
}
|
||||
}
|
||||
|
||||
Font asset = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
|
||||
if (asset == null)
|
||||
throw new Exception("Failed to load font '" + name + "'");
|
||||
|
||||
BaseFont font = new DynamicFont();
|
||||
font.name = name;
|
||||
((DynamicFont)font).nativeFont = asset;
|
||||
|
||||
sFontFactory.Add(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
static public void Clear()
|
||||
{
|
||||
foreach (KeyValuePair<string, BaseFont> kv in sFontFactory)
|
||||
kv.Value.Dispose();
|
||||
|
||||
sFontFactory.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5084c28e388b94a4fa4e2a80485296b3
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于文本输入的键盘接口
|
||||
/// </summary>
|
||||
public interface IKeyboard
|
||||
{
|
||||
/// <summary>
|
||||
/// 键盘已收回,输入已完成
|
||||
/// </summary>
|
||||
bool done { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否支持在光标处输入。如果为true,GetInput返回的是在当前光标处需要插入的文本,如果为false,GetInput返回的是整个文本。
|
||||
/// </summary>
|
||||
bool supportsCaret { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户输入的文本。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetInput();
|
||||
|
||||
/// <summary>
|
||||
/// 打开键盘
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="autocorrection"></param>
|
||||
/// <param name="multiline"></param>
|
||||
/// <param name="secure"></param>
|
||||
/// <param name="alert"></param>
|
||||
/// <param name="textPlaceholder"></param>
|
||||
/// <param name="keyboardType"></param>
|
||||
/// <param name="hideInput"></param>
|
||||
void Open(string text, bool autocorrection, bool multiline, bool secure, bool alert, string textPlaceholder, int keyboardType, bool hideInput);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭键盘
|
||||
/// </summary>
|
||||
void Close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e3b9d951c903b049b8495c2d16f67fe
|
||||
timeCreated: 1460480287
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87f693de944eb7d4ab4ccb9b65af352a
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,701 @@
|
||||
/********************************************************************
|
||||
Copyright (c) 2018, Tadpole Studio
|
||||
All rights reserved
|
||||
|
||||
文件名称: RTL.cs
|
||||
说 明: RTL字符转换
|
||||
|
||||
版 本: 1.00
|
||||
时 间: 2018/2/24 9:02:12
|
||||
作 者: AQ QQ:355010366
|
||||
概 述: 新建
|
||||
|
||||
*********************************************************************/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
public class RTLSupport
|
||||
{
|
||||
internal enum CharState
|
||||
{
|
||||
isolated,
|
||||
final,
|
||||
lead,
|
||||
middle,
|
||||
}
|
||||
|
||||
// Bidirectional Character Types
|
||||
public enum DirectionType
|
||||
{
|
||||
UNKNOW = 0,
|
||||
LTR,
|
||||
RTL,
|
||||
NEUTRAL,
|
||||
}
|
||||
|
||||
#if RTL_TEXT_SUPPORT
|
||||
public static DirectionType BaseDirection = DirectionType.RTL; // 主体语言是否是RTL的语言
|
||||
#else
|
||||
public static DirectionType BaseDirection = DirectionType.UNKNOW;
|
||||
#endif
|
||||
private static bool isCharsInitialized = false;
|
||||
private static Dictionary<int, char[]> mapping = new Dictionary<int, char[]>();
|
||||
|
||||
private static List<char> listFinal = new List<char>();
|
||||
private static List<string> listRep = new List<string>();
|
||||
private static StringBuilder sbRep = new StringBuilder();
|
||||
private static StringBuilder sbN = new StringBuilder();
|
||||
private static StringBuilder sbFinal = new StringBuilder();
|
||||
private static StringBuilder sbReverse = new StringBuilder();
|
||||
|
||||
public static bool IsArabicLetter(char ch)
|
||||
{
|
||||
if (ch >= 0x600 && ch <= 0x6ff)
|
||||
{
|
||||
if ((ch >= 0x660 && ch <= 0x66D) || (ch >= 0x6f0 && ch <= 0x6f9)) // 标准阿拉伯语数字和东阿拉伯语数字 [2019/3/1/ 17:45:18 by aq_1000]
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (ch >= 0x750 && ch <= 0x77f)
|
||||
return true;
|
||||
else if (ch >= 0xfb50 && ch <= 0xfc3f)
|
||||
return true;
|
||||
else if (ch >= 0xfe70 && ch <= 0xfefc)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string ConvertNumber(string strNumber)
|
||||
{
|
||||
sbRep.Length = 0;
|
||||
foreach (char ch in strNumber)
|
||||
{
|
||||
int un = ch;
|
||||
if (un == 0x66c || ch == ',') // 去掉逗号
|
||||
continue;
|
||||
else if (un == 0x660 || un == 0x6f0)
|
||||
sbRep.Append('0');
|
||||
else if (un == 0x661 || un == 0x6f1)
|
||||
sbRep.Append('1');
|
||||
else if (un == 0x662 || un == 0x6f2)
|
||||
sbRep.Append('2');
|
||||
else if (un == 0x663 || un == 0x6f3)
|
||||
sbRep.Append('3');
|
||||
else if (un == 0x664 || un == 0x6f4)
|
||||
sbRep.Append('4');
|
||||
else if (un == 0x665 || un == 0x6f5)
|
||||
sbRep.Append('5');
|
||||
else if (un == 0x666 || un == 0x6f6)
|
||||
sbRep.Append('6');
|
||||
else if (un == 0x667 || un == 0x6f7)
|
||||
sbRep.Append('7');
|
||||
else if (un == 0x668 || un == 0x6f8)
|
||||
sbRep.Append('8');
|
||||
else if (un == 0x669 || un == 0x6f9)
|
||||
sbRep.Append('9');
|
||||
else
|
||||
sbRep.Append(ch);
|
||||
}
|
||||
return sbRep.ToString();
|
||||
}
|
||||
|
||||
public static bool ContainsArabicLetters(string text)
|
||||
{
|
||||
foreach (char character in text)
|
||||
{
|
||||
if (character >= 0x600 && character <= 0x6ff)
|
||||
return true;
|
||||
|
||||
if (character >= 0x750 && character <= 0x77f)
|
||||
return true;
|
||||
|
||||
if (character >= 0xfb50 && character <= 0xfc3f)
|
||||
return true;
|
||||
|
||||
if (character >= 0xfe70 && character <= 0xfefc)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检测文本主方向
|
||||
public static DirectionType DetectTextDirection(string text)
|
||||
{
|
||||
bool isContainRTL = false;
|
||||
bool isContainLTR = false;
|
||||
foreach (char ch in text)
|
||||
{
|
||||
if (IsArabicLetter(ch))
|
||||
{
|
||||
isContainRTL = true;
|
||||
if (isContainLTR)
|
||||
break;
|
||||
}
|
||||
else if (char.IsLetter(ch))
|
||||
{
|
||||
isContainLTR = true;
|
||||
if (isContainRTL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isContainRTL)
|
||||
return DirectionType.UNKNOW; // 这边unknow暂时代表文本一个RTL字符都没有,无需进行RTL转换
|
||||
else if (!isContainLTR)
|
||||
return DirectionType.RTL;
|
||||
return BaseDirection;
|
||||
}
|
||||
|
||||
private static bool CheckSeparator(char input)
|
||||
{
|
||||
if (!IsArabicLetter(input))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (input == '،') || (input == '?') || (input == '؟');
|
||||
}
|
||||
|
||||
// if ((input != ' ') && (input != '\t') && (input != '!') && (input != '.') &&
|
||||
// (input != '،') && (input != '?') && (input != '؟') &&
|
||||
// !_IsBracket(input) && // 括号也算 [2018/8/1/ 15:12:20 by aq_1000]
|
||||
// !_IsNeutrality(input))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
}
|
||||
|
||||
private static bool CheckSpecific(char input)
|
||||
{
|
||||
int num = input;
|
||||
if ((num != 0x622) && (num != 0x623) && (num != 0x627) && (num != 0x62f) && (num != 0x625) &&
|
||||
(num != 0x630) && (num != 0x631) && (num != 0x632) && (num != 0x698) && (num != 0x648) &&
|
||||
!_CheckSoundmark(input))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool _CheckSoundmark(char ch)
|
||||
{
|
||||
int un = ch;
|
||||
return (un >= 0x610 && un <= 0x61e) || (un >= 0x64b && un <= 0x65f);
|
||||
}
|
||||
|
||||
public static string DoMapping(string input)
|
||||
{
|
||||
if (!isCharsInitialized)
|
||||
{
|
||||
isCharsInitialized = true;
|
||||
InitChars();
|
||||
}
|
||||
|
||||
// 伊斯兰教真主安拉在阿拉伯文里写作الله
|
||||
// 键盘输入时输入 ل (lam) + ل (lam) + ه (ha) 后会自动转换成带记号的符号。 [2018/3/13 20:03:45 --By aq_1000]
|
||||
if (input == "الله")
|
||||
{
|
||||
input = "ﷲ";
|
||||
}
|
||||
|
||||
sbFinal.Length = 0;
|
||||
sbFinal.Append(input);
|
||||
char perChar = '\0';
|
||||
for (int i = 0; i < sbFinal.Length; i++)
|
||||
{
|
||||
if (!mapping.ContainsKey(sbFinal[i]))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((i + 1) == sbFinal.Length)
|
||||
{
|
||||
if (sbFinal.Length == 1)
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
else if (CheckSeparator(perChar) || CheckSpecific(perChar))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.final];
|
||||
}
|
||||
}
|
||||
else if (i == 0)
|
||||
{
|
||||
if (!CheckSeparator(sbFinal[i + 1]))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.lead];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
}
|
||||
else if (CheckSeparator(sbFinal[i + 1]))
|
||||
{
|
||||
if (CheckSeparator(perChar) || CheckSpecific(perChar))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.final];
|
||||
}
|
||||
}
|
||||
else if (CheckSeparator(perChar))
|
||||
{
|
||||
if (CheckSeparator(sbFinal[i + 1]))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.lead];
|
||||
}
|
||||
}
|
||||
else if (CheckSpecific(sbFinal[i + 1]))
|
||||
{
|
||||
if (CheckSeparator(perChar) || CheckSpecific(perChar))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.lead];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.middle];
|
||||
}
|
||||
}
|
||||
else if (CheckSpecific(perChar))
|
||||
{
|
||||
if (CheckSeparator(sbFinal[i + 1]))
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.isolated];
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.lead];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perChar = sbFinal[i];
|
||||
sbFinal[i] = mapping[sbFinal[i]][(int)CharState.middle];
|
||||
}
|
||||
}
|
||||
return sbFinal.ToString();
|
||||
}
|
||||
|
||||
// 主体语言是LTR
|
||||
public static string ConvertLineL(string source)
|
||||
{
|
||||
listFinal.Clear();
|
||||
listRep.Clear();
|
||||
sbRep.Length = 0;
|
||||
sbN.Length = 0;
|
||||
int iReplace = 0;
|
||||
DirectionType ePre = DirectionType.LTR;
|
||||
char nextChar = '\0';
|
||||
for (int j = 0; j < source.Length; j++)
|
||||
{
|
||||
if (j < source.Length - 1)
|
||||
nextChar = source[j + 1];
|
||||
else
|
||||
nextChar = '\0';
|
||||
char item = source[j];
|
||||
DirectionType eCType = _GetDirection(item, nextChar, ePre, DirectionType.LTR);
|
||||
if (eCType == DirectionType.RTL)
|
||||
{
|
||||
if (sbRep.Length == 0)
|
||||
{
|
||||
listFinal.Add('\x00bf');
|
||||
iReplace++;
|
||||
}
|
||||
|
||||
if (sbN.Length > 0)
|
||||
sbRep.Append(sbN.ToString());
|
||||
sbN.Length = 0;
|
||||
sbRep.Append(item);
|
||||
}
|
||||
else if (eCType == DirectionType.LTR)
|
||||
{
|
||||
if (sbRep.Length > 0)
|
||||
{
|
||||
listRep.Add(sbRep.ToString());
|
||||
}
|
||||
sbRep.Length = 0;
|
||||
|
||||
if (sbN.Length > 0)
|
||||
{
|
||||
for (int n = 0; n < sbN.Length; ++n)
|
||||
{
|
||||
listFinal.Add(sbN[n]);
|
||||
}
|
||||
}
|
||||
sbN.Length = 0;
|
||||
|
||||
// item = _ProcessBracket(item); // 文本主方向为LTR的话,括号不需要翻转 [2018/12/20/ 17:03:23 by aq_1000]
|
||||
listFinal.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
sbN.Append(item);
|
||||
}
|
||||
ePre = eCType;
|
||||
}
|
||||
if (sbRep.Length > 0)
|
||||
{
|
||||
listRep.Add(sbRep.ToString());
|
||||
}
|
||||
|
||||
// 一行中都只有中立字符的情况,就直接返回中立字符 [2018/12/6/ 16:34:38 by aq_1000]
|
||||
if (sbN.Length > 0)
|
||||
{
|
||||
for (int n = 0; n < sbN.Length; ++n)
|
||||
{
|
||||
listFinal.Add(sbN[n]);
|
||||
}
|
||||
}
|
||||
|
||||
sbRep.Length = 0;
|
||||
sbN.Length = 0;
|
||||
sbFinal.Length = 0;
|
||||
sbFinal.Append(listFinal.ToArray());
|
||||
for (int m = 0; m < iReplace; m++)
|
||||
{
|
||||
for (int n = 0; n < sbFinal.Length; n++)
|
||||
{
|
||||
if (sbFinal[n] == '\x00bf')
|
||||
{
|
||||
sbRep.Length = 0;
|
||||
sbRep.Append(_Reverse(listRep[0]));
|
||||
listRep.RemoveAt(0);
|
||||
|
||||
// 字符串反向的时候造成末尾空格跑到词首 [2018/4/11 20:04:35 --By aq_1000]
|
||||
sbN.Length = 0;
|
||||
for (int num4 = 0; num4 < sbRep.Length; num4++)
|
||||
{
|
||||
if (!_IsNeutrality(sbRep[num4]))
|
||||
break;
|
||||
sbN.Append(sbRep[num4]);
|
||||
}
|
||||
if (sbN.Length > 0) // 词首空格重新放到词尾
|
||||
{
|
||||
sbRep.Remove(0, sbN.Length);
|
||||
for (int iSpace = sbN.Length - 1; iSpace >= 0; --iSpace) // 空格也要取反
|
||||
{
|
||||
sbRep.Append(sbN[iSpace]);
|
||||
}
|
||||
}
|
||||
|
||||
sbFinal.Replace(sbFinal[n].ToString(), sbRep.ToString(), n, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sbFinal.ToString();
|
||||
}
|
||||
|
||||
// 主体语言是RTL,整个文本就从右往左读,LTR语言就作为嵌入语段处理
|
||||
public static string ConvertLineR(string source)
|
||||
{
|
||||
listFinal.Clear();
|
||||
listRep.Clear();
|
||||
sbRep.Length = 0;
|
||||
sbN.Length = 0;
|
||||
int iReplace = 0;
|
||||
DirectionType ePre = DirectionType.RTL;
|
||||
char nextChar = '\0';
|
||||
for (int j = 0; j < source.Length; j++)
|
||||
{
|
||||
if (j < source.Length - 1)
|
||||
nextChar = source[j + 1];
|
||||
else
|
||||
nextChar = '\0';
|
||||
char item = source[j];
|
||||
DirectionType eCType = _GetDirection(item, nextChar, ePre, DirectionType.RTL);
|
||||
if (eCType == DirectionType.LTR)
|
||||
{
|
||||
if (sbRep.Length == 0)
|
||||
{
|
||||
listFinal.Add('\x00bf');
|
||||
iReplace++;
|
||||
}
|
||||
|
||||
if (sbN.Length > 0)
|
||||
sbRep.Append(sbN.ToString());
|
||||
sbN.Length = 0;
|
||||
sbRep.Append(item);
|
||||
}
|
||||
else if (eCType == DirectionType.RTL)
|
||||
{
|
||||
if (sbRep.Length > 0)
|
||||
{
|
||||
listRep.Add(sbRep.ToString());
|
||||
}
|
||||
sbRep.Length = 0;
|
||||
|
||||
if (sbN.Length > 0)
|
||||
{
|
||||
for (int n = 0; n < sbN.Length; ++n)
|
||||
{
|
||||
listFinal.Add(sbN[n]);
|
||||
}
|
||||
}
|
||||
sbN.Length = 0;
|
||||
|
||||
item = _ProcessBracket(item);
|
||||
listFinal.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
sbN.Append(item);
|
||||
}
|
||||
ePre = eCType;
|
||||
}
|
||||
if (sbRep.Length > 0)
|
||||
{
|
||||
listRep.Add(sbRep.ToString());
|
||||
}
|
||||
|
||||
// 一行中都只有中立字符的情况,就直接返回中立字符 [2018/12/6/ 16:34:38 by aq_1000]
|
||||
if (sbN.Length > 0)
|
||||
{
|
||||
for (int n = 0; n < sbN.Length; ++n)
|
||||
{
|
||||
listFinal.Add(sbN[n]);
|
||||
}
|
||||
}
|
||||
|
||||
sbFinal.Length = 0;
|
||||
sbFinal.Append(listFinal.ToArray());
|
||||
for (int m = 0; m < iReplace; m++)
|
||||
{
|
||||
for (int n = 0; n < sbFinal.Length; n++)
|
||||
{
|
||||
if (sbFinal[n] == '\x00bf')
|
||||
{
|
||||
sbRep.Length = 0;
|
||||
sbRep.Append(_Reverse(listRep[0]));
|
||||
listRep.RemoveAt(0);
|
||||
|
||||
// 字符串反向的时候造成末尾空格跑到词首 [2018/4/11 20:04:35 --By aq_1000]
|
||||
sbN.Length = 0;
|
||||
for (int num4 = 0; num4 < sbRep.Length; num4++)
|
||||
{
|
||||
if (!_IsNeutrality(sbRep[num4]))
|
||||
break;
|
||||
sbN.Append(sbRep[num4]);
|
||||
}
|
||||
if (sbN.Length > 0) // 词首空格重新放到词尾
|
||||
{
|
||||
sbRep.Remove(0, sbN.Length);
|
||||
for (int iSpace = sbN.Length - 1; iSpace >= 0; --iSpace) // 空格也要取反
|
||||
{
|
||||
sbRep.Append(sbN[iSpace]);
|
||||
}
|
||||
}
|
||||
|
||||
sbFinal.Replace(sbFinal[n].ToString(), sbRep.ToString(), n, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sbFinal.ToString();
|
||||
}
|
||||
|
||||
|
||||
private static string _Reverse(string source)
|
||||
{
|
||||
sbReverse.Length = 0;
|
||||
int len = source.Length;
|
||||
int i = len - 1;
|
||||
while (i >= 0)
|
||||
{
|
||||
char ch = source[i];
|
||||
if (ch == '\r' && i != len - 1 && source[i + 1] == '\n')
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char.IsLowSurrogate(ch)) //不要反向高低代理对
|
||||
{
|
||||
sbReverse.Append(source[i - 1]);
|
||||
sbReverse.Append(ch);
|
||||
i--;
|
||||
}
|
||||
else
|
||||
sbReverse.Append(ch);
|
||||
i--;
|
||||
}
|
||||
|
||||
return sbReverse.ToString();
|
||||
}
|
||||
|
||||
private static void InitChars()
|
||||
{
|
||||
// {isolated,final,lead,middle} [2018/11/27 16:04:18 --By aq_1000]
|
||||
mapping.Add(0x621, new char[4] { (char)0xFE80, (char)0xFE8A, (char)0xFE8B, (char)0xFE8C }); // Hamza
|
||||
mapping.Add(0x627, new char[4] { (char)0xFE8D, (char)0xFE8E, (char)0xFE8D, (char)0xFE8E }); // Alef
|
||||
mapping.Add(0x623, new char[4] { (char)0xFE83, (char)0xFE84, (char)0xFE83, (char)0xFE84 }); // AlefHamza
|
||||
mapping.Add(0x624, new char[4] { (char)0xFE85, (char)0xFE85, (char)0xFE85, (char)0xFE85 }); // WawHamza
|
||||
mapping.Add(0x625, new char[4] { (char)0xFE87, (char)0xFE87, (char)0xFE87, (char)0xFE87 }); // AlefMaksoor
|
||||
mapping.Add(0x649, new char[4] { (char)0xFBFC, (char)0xFBFD, (char)0xFBFE, (char)0xFBFF }); // AlefMagsora
|
||||
mapping.Add(0x626, new char[4] { (char)0xFE89, (char)0xFE8A, (char)0xFE8B, (char)0xFE8C }); // HamzaNabera
|
||||
mapping.Add(0x628, new char[4] { (char)0xFE8F, (char)0xFE90, (char)0xFE91, (char)0xFE92 }); // Ba
|
||||
mapping.Add(0x62A, new char[4] { (char)0xFE95, (char)0xFE96, (char)0xFE97, (char)0xFE98 }); // Ta
|
||||
mapping.Add(0x62B, new char[4] { (char)0xFE99, (char)0xFE9A, (char)0xFE9B, (char)0xFE9C }); // Tha2
|
||||
mapping.Add(0x62C, new char[4] { (char)0xFE9D, (char)0xFE9E, (char)0xFE9F, (char)0xFEA0 }); // Jeem
|
||||
mapping.Add(0x62D, new char[4] { (char)0xFEA1, (char)0xFEA2, (char)0xFEA3, (char)0xFEA4 }); // H7aa
|
||||
mapping.Add(0x62E, new char[4] { (char)0xFEA5, (char)0xFEA6, (char)0xFEA7, (char)0xFEA8 }); // Khaa2
|
||||
mapping.Add(0x62F, new char[4] { (char)0xFEA9, (char)0xFEAA, (char)0xFEA9, (char)0xFEAA }); // Dal
|
||||
mapping.Add(0x630, new char[4] { (char)0xFEAB, (char)0xFEAC, (char)0xFEAB, (char)0xFEAC }); // Thal
|
||||
mapping.Add(0x631, new char[4] { (char)0xFEAD, (char)0xFEAE, (char)0xFEAD, (char)0xFEAD }); // Ra2
|
||||
mapping.Add(0x632, new char[4] { (char)0xFEAF, (char)0xFEB0, (char)0xFEAF, (char)0xFEB0 }); // Zeen
|
||||
mapping.Add(0x633, new char[4] { (char)0xFEB1, (char)0xFEB2, (char)0xFEB3, (char)0xFEB4 }); // Seen
|
||||
mapping.Add(0x634, new char[4] { (char)0xFEB5, (char)0xFEB6, (char)0xFEB7, (char)0xFEB8 }); // Sheen
|
||||
mapping.Add(0x635, new char[4] { (char)0xFEB9, (char)0xFEBA, (char)0xFEBB, (char)0xFEBC }); // S9a
|
||||
mapping.Add(0x636, new char[4] { (char)0xFEBD, (char)0xFEBE, (char)0xFEBF, (char)0xFEC0 }); // Dha
|
||||
mapping.Add(0x637, new char[4] { (char)0xFEC1, (char)0xFEC2, (char)0xFEC3, (char)0xFEC4 }); // T6a
|
||||
mapping.Add(0x638, new char[4] { (char)0xFEC5, (char)0xFEC6, (char)0xFEC7, (char)0xFEC8 }); // T6ha
|
||||
mapping.Add(0x639, new char[4] { (char)0xFEC9, (char)0xFECA, (char)0xFECB, (char)0xFECC }); // Ain
|
||||
mapping.Add(0x63A, new char[4] { (char)0xFECD, (char)0xFECE, (char)0xFECF, (char)0xFED0 }); // Gain
|
||||
mapping.Add(0x641, new char[4] { (char)0xFED1, (char)0xFED2, (char)0xFED3, (char)0xFED4 }); // Fa
|
||||
mapping.Add(0x642, new char[4] { (char)0xFED5, (char)0xFED6, (char)0xFED7, (char)0xFED8 }); // Gaf
|
||||
mapping.Add(0x643, new char[4] { (char)0xFED9, (char)0xFEDA, (char)0xFEDB, (char)0xFEDC }); // Kaf
|
||||
mapping.Add(0x644, new char[4] { (char)0xFEDD, (char)0xFEDE, (char)0xFEDF, (char)0xFEE0 }); // Lam
|
||||
mapping.Add(0x645, new char[4] { (char)0xFEE1, (char)0xFEE2, (char)0xFEE3, (char)0xFEE4 }); // Meem
|
||||
mapping.Add(0x646, new char[4] { (char)0xFEE5, (char)0xFEE6, (char)0xFEE7, (char)0xFEE8 }); // Noon
|
||||
mapping.Add(0x647, new char[4] { (char)0xFEE9, (char)0xFEEA, (char)0xFEEB, (char)0xFEEC }); // Ha
|
||||
mapping.Add(0x648, new char[4] { (char)0xFEED, (char)0xFEEE, (char)0xFEED, (char)0xFEEE }); // Waw
|
||||
mapping.Add(0x64A, new char[4] { (char)0xFEF1, (char)0xFEF2, (char)0xFEF3, (char)0xFEF4 }); // Ya
|
||||
mapping.Add(0x622, new char[4] { (char)0xFE81, (char)0xFE81, (char)0xFE81, (char)0xFE81 }); // AlefMad
|
||||
mapping.Add(0x629, new char[4] { (char)0xFE93, (char)0xFE94, (char)0xFE94, (char)0xFE94 }); // TaMarboota // 该字符只会出现在末尾 [2018/4/10 16:04:18 --By aq_1000]
|
||||
mapping.Add(0x67E, new char[4] { (char)0xFB56, (char)0xFB57, (char)0xFB58, (char)0xFB59 }); // PersianPe
|
||||
mapping.Add(0x686, new char[4] { (char)0xFB7A, (char)0xFB7B, (char)0xFB7C, (char)0xFB7D }); // PersianChe
|
||||
mapping.Add(0x698, new char[4] { (char)0xFB8A, (char)0xFB8B, (char)0xFB8A, (char)0xFB8B }); // PersianZe
|
||||
mapping.Add(0x6AF, new char[4] { (char)0xFB92, (char)0xFB93, (char)0xFB94, (char)0xFB95 }); // PersianGaf
|
||||
mapping.Add(0x6A9, new char[4] { (char)0xFB8E, (char)0xFB8F, (char)0xFB90, (char)0xFB91 }); // PersianGaf2
|
||||
|
||||
mapping.Add(0x6BE, new char[4] { (char)0xFEE9, (char)0xFEEA, (char)0xFEEB, (char)0xFEEC });
|
||||
mapping.Add(0x6CC, new char[4] { (char)0xFBFC, (char)0xFBFD, (char)0xFBFE, (char)0xFBFF });
|
||||
}
|
||||
|
||||
// 是否中立方向字符
|
||||
private static bool _IsNeutrality(char uc)
|
||||
{
|
||||
return (uc == ':' || uc == ':' || uc == ' ' || /*uc == '%' ||*/ /*uc == '+' ||*/ /*uc == '-' ||*/ uc == '\n' || uc == '\r' || uc == '\t' || uc == '@' ||
|
||||
(uc >= 0x2600 && uc <= 0x27BF)); // 表情符号
|
||||
}
|
||||
|
||||
// 是否句末标点符号
|
||||
private static bool _IsEndPunctuation(char uc, char nextChar)
|
||||
{
|
||||
if (uc == '.')
|
||||
return _IsNeutrality(nextChar);
|
||||
return (uc == '!' || uc == '!' || uc == '。' || uc == '،' || uc == '?' || uc == '؟');
|
||||
}
|
||||
|
||||
// 判断字符方向
|
||||
private static DirectionType _GetDirection(char uc, char nextChar, DirectionType ePre, DirectionType eBase)
|
||||
{
|
||||
DirectionType eCType = ePre;
|
||||
int uni = uc;
|
||||
|
||||
if (_IsBracket(uc) || _IsEndPunctuation(uc, nextChar))
|
||||
{
|
||||
eCType = eBase; // 括号和句末标点符号,方向根据上个字符为准 [2018/12/26/ 15:56:24 by aq_1000]
|
||||
}
|
||||
else if ((uni >= 0x660) && (uni <= 0x66D))
|
||||
{
|
||||
eCType = DirectionType.LTR;
|
||||
}
|
||||
else if (IsArabicLetter(uc) || uc == '+' /*|| uc == '-'*/ || uc == '%')
|
||||
{
|
||||
eCType = DirectionType.RTL;
|
||||
}
|
||||
else if (uc == '-')
|
||||
{
|
||||
if (char.IsNumber(nextChar))
|
||||
eCType = DirectionType.LTR;
|
||||
else
|
||||
eCType = DirectionType.RTL;
|
||||
}
|
||||
else if (_IsNeutrality(uc)) // 中立方向字符,方向就和上一个字符一样 [2018/3/24 16:03:27 --By aq_1000]
|
||||
{
|
||||
if (ePre == DirectionType.UNKNOW || ePre == DirectionType.NEUTRAL)
|
||||
{
|
||||
if (char.IsNumber(nextChar)) // 数字都是弱LTR方向符,开头中立字符后面紧跟着数字的话,中立字符方向算文本主方向 [IsDigit()只是0-9] [2018/12/20/ 16:32:32 by aq_1000]
|
||||
{
|
||||
eCType = BaseDirection;
|
||||
}
|
||||
else
|
||||
eCType = DirectionType.NEUTRAL;
|
||||
}
|
||||
else
|
||||
eCType = ePre;
|
||||
}
|
||||
else
|
||||
eCType = DirectionType.LTR;
|
||||
|
||||
return eCType;
|
||||
}
|
||||
|
||||
// 是否括号
|
||||
private static bool _IsBracket(char uc)
|
||||
{
|
||||
return (uc == ')' || uc == '(' || uc == ')' || uc == '(' ||
|
||||
uc == ']' || uc == '[' || uc == '】' || uc == '【' ||
|
||||
uc == '}' || uc == '{' ||
|
||||
// uc == '≥' || uc == '≤' || uc == '>' || uc == '<' ||
|
||||
uc == '》' || uc == '《' || uc == '“' || uc == '”' || uc == '"');
|
||||
}
|
||||
|
||||
// 这些配对符,在从右至左排列中应该逆序显示
|
||||
private static char _ProcessBracket(char uc)
|
||||
{
|
||||
if (uc == '[') return ']';
|
||||
else if (uc == ']') return '[';
|
||||
else if (uc == '【') return '】';
|
||||
else if (uc == '】') return '【';
|
||||
else if (uc == '{') return '}';
|
||||
else if (uc == '}') return '{';
|
||||
else if (uc == '(') return ')';
|
||||
else if (uc == ')') return '(';
|
||||
else if (uc == '(') return ')';
|
||||
else if (uc == ')') return '(';
|
||||
else if (uc == '<') return '>';
|
||||
else if (uc == '>') return '<';
|
||||
else if (uc == '《') return '》';
|
||||
else if (uc == '》') return '《';
|
||||
else if (uc == '≤') return '≥';
|
||||
else if (uc == '≥') return '≤';
|
||||
else if (uc == '”') return '“';
|
||||
else if (uc == '”') return '“';
|
||||
else return uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 575b3af943ee8a04bb4d8feb568b1d2e
|
||||
timeCreated: 1521600498
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,216 @@
|
||||
using System.Collections.Generic;
|
||||
using FairyGUI.Utils;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class RichTextField : Container
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IHtmlPageContext htmlPageContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HtmlParseOptions htmlParseOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Dictionary<uint, Emoji> emojies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public TextField textField { get; private set; }
|
||||
|
||||
public RichTextField()
|
||||
{
|
||||
gameObject.name = "RichTextField";
|
||||
this.opaque = true;
|
||||
|
||||
htmlPageContext = HtmlPageContext.inst;
|
||||
htmlParseOptions = new HtmlParseOptions();
|
||||
|
||||
this.textField = new TextField();
|
||||
textField.EnableRichSupport(this);
|
||||
AddChild(textField);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
virtual public string text
|
||||
{
|
||||
get { return textField.text; }
|
||||
set { textField.text = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
virtual public string htmlText
|
||||
{
|
||||
get { return textField.htmlText; }
|
||||
set { textField.htmlText = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
virtual public TextFormat textFormat
|
||||
{
|
||||
get { return textField.textFormat; }
|
||||
set { textField.textFormat = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public HtmlElement GetHtmlElement(string name)
|
||||
{
|
||||
List<HtmlElement> elements = textField.htmlElements;
|
||||
int count = elements.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
HtmlElement element = elements[i];
|
||||
if (name.Equals(element.name, System.StringComparison.OrdinalIgnoreCase))
|
||||
return element;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public HtmlElement GetHtmlElementAt(int index)
|
||||
{
|
||||
return textField.htmlElements[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int htmlElementCount
|
||||
{
|
||||
get { return textField.htmlElements.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="show"></param>
|
||||
public void ShowHtmlObject(int index, bool show)
|
||||
{
|
||||
HtmlElement element = textField.htmlElements[index];
|
||||
if (element.htmlObject != null && element.type != HtmlElementType.Link)
|
||||
{
|
||||
//set hidden flag
|
||||
if (show)
|
||||
element.status &= 253; //~(1<<1)
|
||||
else
|
||||
element.status |= 2;
|
||||
|
||||
if ((element.status & 3) == 0) //not (hidden and clipped)
|
||||
{
|
||||
if ((element.status & 4) == 0) //not added
|
||||
{
|
||||
element.status |= 4;
|
||||
element.htmlObject.Add();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((element.status & 4) != 0) //added
|
||||
{
|
||||
element.status &= 251;
|
||||
element.htmlObject.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnsureSizeCorrect()
|
||||
{
|
||||
textField.EnsureSizeCorrect();
|
||||
}
|
||||
|
||||
override protected void OnSizeChanged()
|
||||
{
|
||||
textField.size = _contentRect.size; //千万不可以调用this.size,后者会触发EnsureSizeCorrect
|
||||
|
||||
base.OnSizeChanged();
|
||||
}
|
||||
|
||||
public override void Update(UpdateContext context)
|
||||
{
|
||||
textField.Redraw();
|
||||
|
||||
base.Update(context);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if ((_flags & Flags.Disposed) != 0)
|
||||
return;
|
||||
|
||||
CleanupObjects();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
internal void CleanupObjects()
|
||||
{
|
||||
List<HtmlElement> elements = textField.htmlElements;
|
||||
int count = elements.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
HtmlElement element = elements[i];
|
||||
if (element.htmlObject != null)
|
||||
{
|
||||
element.htmlObject.Remove();
|
||||
htmlPageContext.FreeObject(element.htmlObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual internal void RefreshObjects()
|
||||
{
|
||||
List<HtmlElement> elements = textField.htmlElements;
|
||||
int count = elements.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
HtmlElement element = elements[i];
|
||||
if (element.htmlObject != null)
|
||||
{
|
||||
if ((element.status & 3) == 0) //not (hidden and clipped)
|
||||
{
|
||||
if ((element.status & 4) == 0) //not added
|
||||
{
|
||||
element.status |= 4;
|
||||
element.htmlObject.Add();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((element.status & 4) != 0) //added
|
||||
{
|
||||
element.status &= 251;
|
||||
element.htmlObject.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87b472f7ce488fa4bbd8942342458ccf
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using FairyGUI.Utils;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class SelectionShape : DisplayObject, IMeshFactory
|
||||
{
|
||||
public readonly List<Rect> rects;
|
||||
|
||||
public SelectionShape()
|
||||
{
|
||||
CreateGameObject("SelectionShape");
|
||||
graphics = new NGraphics(gameObject);
|
||||
graphics.texture = NTexture.Empty;
|
||||
graphics.meshFactory = this;
|
||||
|
||||
rects = new List<Rect>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color color
|
||||
{
|
||||
get
|
||||
{
|
||||
return graphics.color;
|
||||
}
|
||||
set
|
||||
{
|
||||
graphics.color = value;
|
||||
graphics.Tint();
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
int count = rects.Count;
|
||||
if (count > 0)
|
||||
{
|
||||
Rect rect = new Rect();
|
||||
rect = rects[0];
|
||||
Rect tmp;
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
tmp = rects[i];
|
||||
rect = ToolSet.Union(ref rect, ref tmp);
|
||||
}
|
||||
SetSize(rect.xMax, rect.yMax);
|
||||
}
|
||||
else
|
||||
SetSize(0, 0);
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
rects.Clear();
|
||||
graphics.SetMeshDirty();
|
||||
}
|
||||
|
||||
public void OnPopulateMesh(VertexBuffer vb)
|
||||
{
|
||||
int count = rects.Count;
|
||||
if (count == 0 || this.color == Color.clear)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
vb.AddQuad(rects[i]);
|
||||
vb.AddTriangles();
|
||||
}
|
||||
|
||||
protected override DisplayObject HitTest()
|
||||
{
|
||||
Vector2 localPoint = WorldToLocal(HitTestContext.worldPoint, HitTestContext.direction);
|
||||
|
||||
if (_contentRect.Contains(localPoint))
|
||||
{
|
||||
int count = rects.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (rects[i].Contains(localPoint))
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f1920b8ccf9c8b4ca5f2794991735d9
|
||||
timeCreated: 1535374214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8a05d6d82201104cb6b5156ca294f54
|
||||
timeCreated: 1535374215
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,175 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace FairyGUI
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public partial class TextFormat
|
||||
{
|
||||
public enum SpecialStyle
|
||||
{
|
||||
None,
|
||||
Superscript,
|
||||
Subscript
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int size;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string font;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color color;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int lineSpacing;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int letterSpacing;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool bold;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool underline;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool italic;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool strikethrough;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color32[] gradientColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public AlignType align;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public SpecialStyle specialStyle;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public float outline;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color outlineColor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Vector2 shadowOffset;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Color shadowColor;
|
||||
|
||||
public TextFormat()
|
||||
{
|
||||
color = Color.black;
|
||||
size = 12;
|
||||
lineSpacing = 3;
|
||||
outlineColor = shadowColor = Color.black;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetColor(uint value)
|
||||
{
|
||||
uint rr = (value >> 16) & 0x0000ff;
|
||||
uint gg = (value >> 8) & 0x0000ff;
|
||||
uint bb = value & 0x0000ff;
|
||||
float r = rr / 255.0f;
|
||||
float g = gg / 255.0f;
|
||||
float b = bb / 255.0f;
|
||||
color = new Color(r, g, b, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="aFormat"></param>
|
||||
/// <returns></returns>
|
||||
public bool EqualStyle(TextFormat aFormat)
|
||||
{
|
||||
return size == aFormat.size && color == aFormat.color
|
||||
&& bold == aFormat.bold && underline == aFormat.underline
|
||||
&& italic == aFormat.italic
|
||||
&& strikethrough == aFormat.strikethrough
|
||||
&& gradientColor == aFormat.gradientColor
|
||||
&& align == aFormat.align
|
||||
&& specialStyle == aFormat.specialStyle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only base NOT all formats will be copied
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void CopyFrom(TextFormat source)
|
||||
{
|
||||
this.size = source.size;
|
||||
this.font = source.font;
|
||||
this.color = source.color;
|
||||
this.lineSpacing = source.lineSpacing;
|
||||
this.letterSpacing = source.letterSpacing;
|
||||
this.bold = source.bold;
|
||||
this.underline = source.underline;
|
||||
this.italic = source.italic;
|
||||
this.strikethrough = source.strikethrough;
|
||||
if (source.gradientColor != null)
|
||||
{
|
||||
this.gradientColor = new Color32[4];
|
||||
source.gradientColor.CopyTo(this.gradientColor, 0);
|
||||
}
|
||||
else
|
||||
this.gradientColor = null;
|
||||
this.align = source.align;
|
||||
this.specialStyle = source.specialStyle;
|
||||
}
|
||||
|
||||
public void FillVertexColors(Color32[] vertexColors)
|
||||
{
|
||||
if (gradientColor == null)
|
||||
vertexColors[0] = vertexColors[1] = vertexColors[2] = vertexColors[3] = color;
|
||||
else
|
||||
{
|
||||
vertexColors[0] = gradientColor[1];
|
||||
vertexColors[1] = gradientColor[0];
|
||||
vertexColors[2] = gradientColor[2];
|
||||
vertexColors[3] = gradientColor[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecffbe294c108da4ab8a1c573e3d4dfd
|
||||
timeCreated: 1460480288
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user