Aimbot-PPO/Aimbot-PPO-MultiScene/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs
Koha9 2d404cfdf2 Aimbot Enviroment very first
Basic environment include Multi scene, Reward Change, Visible chart, etc....
2022-09-05 20:46:08 +09:00

641 lines
24 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEngine;
namespace XCharts.Runtime
{
[System.Serializable]
public class VisualMapRange : ChildComponent
{
[SerializeField] private double m_Min;
[SerializeField] private double m_Max;
[SerializeField] private string m_Label;
[SerializeField] private Color32 m_Color;
/// <summary>
/// 范围最小值
/// </summary>
public double min { get { return m_Min; } set { m_Min = value; } }
/// <summary>
/// 范围最大值
/// </summary>
public double max { get { return m_Max; } set { m_Max = value; } }
/// <summary>
/// 文字描述
/// </summary>
public string label { get { return m_Label; } set { m_Label = value; } }
/// <summary>
/// 颜色
/// </summary>
public Color32 color { get { return m_Color; } set { m_Color = value; } }
public bool Contains(double value, double minMaxRange)
{
if (m_Min == 0 && m_Max == 0) return false;
var cmin = System.Math.Abs(m_Min) < 1 ? minMaxRange * m_Min : m_Min;
var cmax = System.Math.Abs(m_Max) < 1 ? minMaxRange * m_Max : m_Max;
return value >= cmin && value < cmax;
}
}
/// <summary>
/// VisualMap component. Mapping data to visual elements such as colors.
/// |视觉映射组件。用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。
/// </summary>
[System.Serializable]
[ComponentHandler(typeof(VisualMapHandler), true)]
public class VisualMap : MainComponent
{
/// <summary>
/// 类型。分为连续型和分段型。
/// </summary>
public enum Type
{
/// <summary>
/// 连续型。
/// </summary>
Continuous,
/// <summary>
/// 分段型。
/// </summary>
Piecewise
}
/// <summary>
/// 选择模式
/// </summary>
public enum SelectedMode
{
/// <summary>
/// 多选。
/// </summary>
Multiple,
/// <summary>
/// 单选。
/// </summary>
Single
}
[SerializeField] private bool m_Show = true;
[SerializeField] private bool m_ShowUI = false;
[SerializeField] private Type m_Type = Type.Continuous;
[SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple;
[SerializeField] private int m_SerieIndex = 0;
[SerializeField] private double m_Min = 0;
[SerializeField] private double m_Max = 100;
[SerializeField] private double[] m_Range = new double[2] { 0, 100 };
[SerializeField] private string[] m_Text = new string[2] { "", "" };
[SerializeField] private float[] m_TextGap = new float[2] { 10f, 10f };
[SerializeField] private int m_SplitNumber = 5;
[SerializeField] private bool m_Calculable = false;
[SerializeField] private bool m_Realtime = true;
[SerializeField] private float m_ItemWidth = 20f;
[SerializeField] private float m_ItemHeight = 140f;
[SerializeField] private float m_ItemGap = 10f;
[SerializeField] private float m_BorderWidth = 0;
[SerializeField] private int m_Dimension = -1;
[SerializeField] private bool m_HoverLink = true;
[SerializeField] private bool m_AutoMinMax = true;
[SerializeField] private Orient m_Orient = Orient.Horizonal;
[SerializeField] private Location m_Location = Location.defaultLeft;
[SerializeField] private bool m_WorkOnLine = true;
[SerializeField] private bool m_WorkOnArea = false;
[SerializeField] private List<VisualMapRange> m_OutOfRange = new List<VisualMapRange>() { new VisualMapRange() { color = Color.gray } };
[SerializeField] private List<VisualMapRange> m_InRange = new List<VisualMapRange>();
public VisualMapContext context = new VisualMapContext();
/// <summary>
/// Whether to enable components.
/// |组件是否生效。
/// </summary>
public bool show
{
get { return m_Show; }
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
}
/// <summary>
/// Whether to display components. If set to false, it will not show up, but the data mapping function still exists.
/// |是否显示组件。如果设置为 false不会显示但是数据映射的功能还存在。
/// </summary>
public bool showUI
{
get { return m_ShowUI; }
set { if (PropertyUtil.SetStruct(ref m_ShowUI, value)) SetVerticesDirty(); }
}
/// <summary>
/// the type of visualmap component.
/// |组件类型。
/// </summary>
public Type type
{
get { return m_Type; }
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); }
}
/// <summary>
/// the selected mode for Piecewise visualMap.
/// |选择模式。
/// </summary>
public SelectedMode selectedMode
{
get { return m_SelectedMode; }
set { if (PropertyUtil.SetStruct(ref m_SelectedMode, value)) SetVerticesDirty(); }
}
/// <summary>
/// the serie index of visualMap.
/// |影响的serie索引。
/// </summary>
public int serieIndex
{
get { return m_SerieIndex; }
set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); }
}
/// <summary>
/// The minimum allowed. 'min' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
/// |
/// 允许的最小值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。
/// </summary>
public double min
{
get { return m_Min; }
set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetVerticesDirty(); }
}
/// <summary>
/// The maximum allowed. 'max' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
/// |
/// 允许的最大值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
/// </summary>
public double max
{
get { return m_Max; }
set { m_Max = (value < min ? min + 1 : value); SetVerticesDirty(); }
}
/// <summary>
/// Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max].
/// |
/// 指定手柄对应数值的位置。range 应在[min,max]范围内。
/// </summary>
public double[] range { get { return m_Range; } }
/// <summary>
/// Text on both ends.
/// |两端的文本,如 ['High', 'Low']。
/// </summary>
public string[] text { get { return m_Text; } }
/// <summary>
/// The distance between the two text bodies.
/// |两端文字主体之间的距离单位为px。
/// </summary>
public float[] textGap { get { return m_TextGap; } }
/// <summary>
/// For continuous data, it is automatically evenly divided into several segments
/// and automatically matches the size of inRange color list when the default is 0.
/// |
/// 对于连续型数据自动平均切分成几段默认为0时自动匹配inRange颜色列表大小。
/// </summary>
/// <value></value>
public int splitNumber
{
get { return m_SplitNumber; }
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetVerticesDirty(); }
}
/// <summary>
/// Whether the handle used for dragging is displayed (the handle can be dragged to adjust the selected range).
/// |
/// 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。
/// </summary>
public bool calculable
{
get { return m_Calculable; }
set { if (PropertyUtil.SetStruct(ref m_Calculable, value)) SetVerticesDirty(); }
}
/// <summary>
/// Whether to update in real time while dragging.
/// |
/// 拖拽时,是否实时更新。
/// </summary>
public bool realtime
{
get { return m_Realtime; }
set { if (PropertyUtil.SetStruct(ref m_Realtime, value)) SetVerticesDirty(); }
}
/// <summary>
/// The width of the figure, that is, the width of the color bar.
/// |
/// 图形的宽度,即颜色条的宽度。
/// </summary>
public float itemWidth
{
get { return m_ItemWidth; }
set { if (PropertyUtil.SetStruct(ref m_ItemWidth, value)) SetVerticesDirty(); }
}
/// <summary>
/// The height of the figure, that is, the height of the color bar.
/// |
/// 图形的高度,即颜色条的高度。
/// </summary>
public float itemHeight
{
get { return m_ItemHeight; }
set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetVerticesDirty(); }
}
/// <summary>
/// 每个图元之间的间隔距离。
/// </summary>
public float itemGap
{
get { return m_ItemGap; }
set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetVerticesDirty(); }
}
/// <summary>
/// Border line width.
/// |
/// 边框线宽单位px。
/// </summary>
public float borderWidth
{
get { return m_BorderWidth; }
set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); }
}
/// <summary>
/// Specifies "which dimension" of the data to map to the visual element. "Data" is series.data.
/// |Starting at 1, the default is 0 to take the last dimension in data.
/// |
/// 指定用数据的『哪个维度』,映射到视觉元素上。『数据』即 series.data。从1开始默认为0取 data 中最后一个维度。
/// </summary>
public int dimension
{
get { return m_Dimension; }
set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); }
}
/// <summary>
/// When the hoverLink function is turned on, when the mouse hovers over the visualMap component,
/// the corresponding value of the mouse position is highlighted in the corresponding graphic element in the diagram.
/// |Conversely, when the mouse hovers over a graphic element in a diagram,
/// the corresponding value of the visualMap component is triangulated in the corresponding position.
/// |
/// 打开 hoverLink 功能时,鼠标悬浮到 visualMap 组件上时,鼠标位置对应的数值 在 图表中对应的图形元素,会高亮。
/// 反之,鼠标悬浮到图表中的图形元素上时,在 visualMap 组件的相应位置会有三角提示其所对应的数值。
/// </summary>
/// <value></value>
public bool hoverLink
{
get { return m_HoverLink; }
set { if (PropertyUtil.SetStruct(ref m_HoverLink, value)) SetVerticesDirty(); }
}
/// <summary>
/// Automatically set min, Max value
/// 自动设置minmax的值
/// </summary>
public bool autoMinMax
{
get { return m_AutoMinMax; }
set { if (PropertyUtil.SetStruct(ref m_AutoMinMax, value)) SetVerticesDirty(); }
}
/// <summary>
/// Specify whether the layout of component is horizontal or vertical.
/// |
/// 布局方式是横还是竖。
/// </summary>
public Orient orient
{
get { return m_Orient; }
set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetVerticesDirty(); }
}
/// <summary>
/// The location of component.
/// |组件显示的位置。
/// </summary>
public Location location
{
get { return m_Location; }
set { if (PropertyUtil.SetClass(ref m_Location, value)) SetVerticesDirty(); }
}
/// <summary>
/// Whether the visualmap is work on linestyle of linechart.
/// |组件是否对LineChart的LineStyle有效。
/// </summary>
public bool workOnLine
{
get { return m_WorkOnLine; }
set { if (PropertyUtil.SetStruct(ref m_WorkOnLine, value)) SetVerticesDirty(); }
}
/// <summary>
/// Whether the visualmap is work on areaStyle of linechart.
/// |组件是否对LineChart的AreaStyle有效。
/// </summary>
public bool workOnArea
{
get { return m_WorkOnArea; }
set { if (PropertyUtil.SetStruct(ref m_WorkOnArea, value)) SetVerticesDirty(); }
}
/// <summary>
/// Defines a visual color outside of the selected range.
/// |定义 在选中范围外 的视觉颜色。
/// </summary>
public List<VisualMapRange> outOfRange
{
get { return m_OutOfRange; }
set { if (value != null) { m_OutOfRange = value; SetVerticesDirty(); } }
}
/// <summary>
/// 分段式每一段的相关配置。
/// </summary>
public List<VisualMapRange> inRange
{
get { return m_InRange; }
set { if (value != null) { m_InRange = value; SetVerticesDirty(); } }
}
public override bool vertsDirty { get { return m_VertsDirty || location.anyDirty; } }
public override void ClearVerticesDirty()
{
base.ClearVerticesDirty();
location.ClearVerticesDirty();
}
public override void ClearComponentDirty()
{
base.ClearComponentDirty();
location.ClearComponentDirty();
}
public double rangeMin
{
get
{
if (m_Range[0] < min || m_Range[0] > max) return min;
else return m_Range[0];
}
set
{
if (value >= min && value <= m_Range[1]) m_Range[0] = value;
}
}
public double rangeMax
{
get
{
if (m_Range[1] >= m_Range[0] && m_Range[1] < max) return m_Range[1];
else return max;
}
set
{
if (value >= m_Range[0] && value <= max) m_Range[1] = value;
}
}
public float runtimeRangeMinHeight { get { return (float) ((rangeMin - min) / (max - min) * itemHeight); } }
public float runtimeRangeMaxHeight { get { return (float) ((rangeMax - min) / (max - min) * itemHeight); } }
public void AddColors(List<Color32> colors)
{
m_InRange.Clear();
foreach (var color in colors)
{
m_InRange.Add(new VisualMapRange()
{
color = color
});
}
}
public void AddColors(List<string> colors)
{
m_InRange.Clear();
foreach (var str in colors)
{
m_InRange.Add(new VisualMapRange()
{
color = ThemeStyle.GetColor(str)
});
}
}
public Color32 GetColor(double value)
{
int index = GetIndex(value);
if (index == -1)
{
if (m_OutOfRange.Count > 0)
return m_OutOfRange[0].color;
else
return ChartConst.clearColor32;
}
if (m_Type == VisualMap.Type.Piecewise)
{
return m_InRange[index].color;
}
else
{
int splitNumber = m_InRange.Count;
var diff = (m_Max - m_Min) / (splitNumber - 1);
var nowMin = m_Min + index * diff;
var rate = (value - nowMin) / diff;
if (index == splitNumber - 1)
return m_InRange[index].color;
else
return Color32.Lerp(m_InRange[index].color, m_InRange[index + 1].color, (float) rate);
}
}
private bool IsNeedPieceColor(double value, out int index)
{
bool flag = false;
index = -1;
for (int i = 0; i < m_InRange.Count; i++)
{
var range = m_InRange[i];
if (range.min != 0 || range.max != 0)
{
flag = true;
if (range.Contains(value, max - min))
{
index = i;
return true;
}
}
}
return flag;
}
private Color32 GetPiecesColor(double value)
{
foreach (var piece in m_InRange)
{
if (piece.Contains(value, max - min))
{
return piece.color;
}
}
if (m_OutOfRange.Count > 0)
return m_OutOfRange[0].color;
else
return ChartConst.clearColor32;
}
public int GetIndex(double value)
{
int splitNumber = m_InRange.Count;
if (splitNumber <= 0)
return -1;
var index = -1;
if (IsNeedPieceColor(value, out index))
{
return index;
}
value = MathUtil.Clamp(value, m_Min, m_Max);
var diff = (m_Max - m_Min) / (splitNumber - 1);
for (int i = 0; i < splitNumber; i++)
{
if (value <= m_Min + (i + 1) * diff)
{
index = i;
break;
}
}
return index;
}
public bool IsPiecewise()
{
return m_Type == VisualMap.Type.Piecewise;
}
public bool IsInSelectedValue(double value)
{
if (context.pointerIndex < 0)
return true;
else
return context.pointerIndex == GetIndex(value);
}
public double GetValue(Vector3 pos, Rect chartRect)
{
var vertical = orient == Orient.Vertical;
var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
var pos1 = centerPos + (vertical ? Vector3.down : Vector3.left) * itemHeight / 2;
var pos2 = centerPos + (vertical ? Vector3.up : Vector3.right) * itemHeight / 2;
if (vertical)
{
if (pos.y < pos1.y)
return min;
else if (pos.y > pos2.y)
return max;
else
return min + (pos.y - pos1.y) / (pos2.y - pos1.y) * (max - min);
}
else
{
if (pos.x < pos1.x)
return min;
else if (pos.x > pos2.x)
return max;
else
return min + (pos.x - pos1.x) / (pos2.x - pos1.x) * (max - min);
}
}
public bool IsInRect(Vector3 local, Rect chartRect, float triangleLen = 20)
{
var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
var diff = calculable ? triangleLen : 0;
if (local.x >= centerPos.x - itemWidth / 2 - diff &&
local.x <= centerPos.x + itemWidth / 2 + diff &&
local.y >= centerPos.y - itemHeight / 2 - diff &&
local.y <= centerPos.y + itemHeight / 2 + diff)
{
return true;
}
else
{
return false;
}
}
public bool IsInRangeRect(Vector3 local, Rect chartRect)
{
var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
if (orient == Orient.Vertical)
{
var pos1 = centerPos + Vector3.down * itemHeight / 2;
return local.x >= centerPos.x - itemWidth / 2 &&
local.x <= centerPos.x + itemWidth / 2 &&
local.y >= pos1.y + runtimeRangeMinHeight &&
local.y <= pos1.y + runtimeRangeMaxHeight;
}
else
{
var pos1 = centerPos + Vector3.left * itemHeight / 2;
return local.x >= pos1.x + runtimeRangeMinHeight &&
local.x <= pos1.x + runtimeRangeMaxHeight &&
local.y >= centerPos.y - itemWidth / 2 &&
local.y <= centerPos.y + itemWidth / 2;
}
}
public bool IsInRangeMinRect(Vector3 local, Rect chartRect, float triangleLen)
{
var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
if (orient == Orient.Vertical)
{
var radius = triangleLen / 2;
var pos1 = centerPos + Vector3.down * itemHeight / 2;
var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMinHeight - radius);
return local.x >= cpos.x - radius &&
local.x <= cpos.x + radius &&
local.y >= cpos.y - radius &&
local.y <= cpos.y + radius;
}
else
{
var radius = triangleLen / 2;
var pos1 = centerPos + Vector3.left * itemHeight / 2;
var cpos = new Vector3(pos1.x + runtimeRangeMinHeight, pos1.y + itemWidth / 2 + radius);
return local.x >= cpos.x - radius &&
local.x <= cpos.x + radius &&
local.y >= cpos.y - radius &&
local.y <= cpos.y + radius;
}
}
public bool IsInRangeMaxRect(Vector3 local, Rect chartRect, float triangleLen)
{
var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height);
if (orient == Orient.Vertical)
{
var radius = triangleLen / 2;
var pos1 = centerPos + Vector3.down * itemHeight / 2;
var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMaxHeight + radius);
return local.x >= cpos.x - radius &&
local.x <= cpos.x + radius &&
local.y >= cpos.y - radius &&
local.y <= cpos.y + radius;
}
else
{
var radius = triangleLen / 2;
var pos1 = centerPos + Vector3.left * itemHeight / 2;
var cpos = new Vector3(pos1.x + runtimeRangeMaxHeight + radius, pos1.y + itemWidth / 2 + radius);
return local.x >= cpos.x - radius &&
local.x <= cpos.x + radius &&
local.y >= cpos.y - radius &&
local.y <= cpos.y + radius;
}
}
}
}