モニタ情報取得関連実装。Macで透明時の最大化は画面一杯にリサイズするようにした。
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0db504c44cbc84d95b04bc9f9ffc64e8
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6b189a5b436540cca5208d65b81ad68
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee0fb4e292b3e4dabb07ad7bd5660968
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>19H2</string>
|
||||
<string>20B29</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
@@ -27,19 +27,19 @@
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>12A7403</string>
|
||||
<string>12B45b</string>
|
||||
<key>DTPlatformName</key>
|
||||
<string>macosx</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>10.15.6</string>
|
||||
<string>11.0</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19G68</string>
|
||||
<string>20A2408</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<string>macosx11.0</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1210</string>
|
||||
<string>1220</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>12A7403</string>
|
||||
<string>12B45b</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.11</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
Binary file not shown.
@@ -15,6 +15,24 @@
|
||||
<key>requirement</key>
|
||||
<string>identifier "com.apple.dt.runtime.swiftAppKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
</dict>
|
||||
<key>Frameworks/libswiftCloudKit.dylib</key>
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
<data>
|
||||
gmHZ6EtjZXwLmOROWLvNh5atYzU=
|
||||
</data>
|
||||
<key>requirement</key>
|
||||
<string>identifier "com.apple.dt.runtime.swiftCloudKit" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
</dict>
|
||||
<key>Frameworks/libswiftContacts.dylib</key>
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
<data>
|
||||
zvewrNbJbl2qZ9pt9xS1I5WzYos=
|
||||
</data>
|
||||
<key>requirement</key>
|
||||
<string>identifier "com.apple.dt.runtime.swiftContacts" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
</dict>
|
||||
<key>Frameworks/libswiftCore.dylib</key>
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
@@ -60,6 +78,15 @@
|
||||
<key>requirement</key>
|
||||
<string>identifier "com.apple.dt.runtime.swiftCoreImage" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
</dict>
|
||||
<key>Frameworks/libswiftCoreLocation.dylib</key>
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
<data>
|
||||
LS0s9RQWGhqotiG8hBJ7hQR77Qw=
|
||||
</data>
|
||||
<key>requirement</key>
|
||||
<string>identifier "com.apple.dt.runtime.swiftCoreLocation" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Ryota Sakamoto (Q8T2P8EN2T)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
|
||||
</dict>
|
||||
<key>Frameworks/libswiftDarwin.dylib</key>
|
||||
<dict>
|
||||
<key>cdhash</key>
|
||||
|
||||
@@ -84,6 +84,15 @@ public class UniWinCore : IDisposable
|
||||
[DllImport("LibUniWinC")]
|
||||
public static extern bool GetSize(out float x, out float y);
|
||||
|
||||
[DllImport("LibUniWinC")]
|
||||
public static extern Int32 GetCurrentMonitor();
|
||||
|
||||
[DllImport("LibUniWinC")]
|
||||
public static extern Int32 GetMonitorCount();
|
||||
|
||||
[DllImport("LibUniWinC")]
|
||||
public static extern bool GetMonitorRectangle(Int32 index, out float x, out float y, out float width, out float height);
|
||||
|
||||
[DllImport("LibUniWinC")]
|
||||
public static extern void SetCursorPosition(float x, float y);
|
||||
|
||||
@@ -256,6 +265,7 @@ public class UniWinCore : IDisposable
|
||||
/// ウィンドウを最大化(Macではズーム)する
|
||||
/// 最大化された後にサイズ変更がされることもあり、現状、確実には動作しない可能性があります
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public void SetZoomed(bool isZoomed)
|
||||
{
|
||||
LibUniWinC.SetMaximized(isZoomed);
|
||||
@@ -265,6 +275,7 @@ public class UniWinCore : IDisposable
|
||||
/// ウィンドウが最大化(Macではズーム)されているかを取得
|
||||
/// 最大化された後にサイズ変更がされることもあり、現状、確実には動作しない可能性があります
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public bool GetZoomed()
|
||||
{
|
||||
return LibUniWinC.IsMaximized();
|
||||
@@ -350,7 +361,64 @@ public class UniWinCore : IDisposable
|
||||
ChromakeyColor = color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the monitor index where the window is located
|
||||
/// </summary>
|
||||
/// <returns>Monitor index</returns>
|
||||
public int GetCurrentMonitor()
|
||||
{
|
||||
return LibUniWinC.GetCurrentMonitor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of connected monitors
|
||||
/// </summary>
|
||||
/// <returns>Count</returns>
|
||||
public int GetMonitorCount()
|
||||
{
|
||||
return LibUniWinC.GetMonitorCount();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fit the window to specified monitor
|
||||
/// </summary>
|
||||
/// <param name="monitorIndex"></param>
|
||||
/// <returns></returns>
|
||||
public bool FitToMonitor(int monitorIndex)
|
||||
{
|
||||
float x, y, width, height;
|
||||
if (LibUniWinC.GetMonitorRectangle(monitorIndex, out x, out y, out width, out height))
|
||||
{
|
||||
LibUniWinC.SetPosition(x, y);
|
||||
LibUniWinC.SetSize(width, height);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// モニタ一覧を出力
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public static void DebugMonitorInfo()
|
||||
{
|
||||
int monitors = LibUniWinC.GetMonitorCount();
|
||||
|
||||
int currentMonitorIndex = LibUniWinC.GetCurrentMonitor();
|
||||
|
||||
string message = "Current monitor: " + currentMonitorIndex + "\r\n";
|
||||
|
||||
for (int i = 0; i < monitors; i++)
|
||||
{
|
||||
float x, y, w, h;
|
||||
bool result = LibUniWinC.GetMonitorRectangle(i, out x, out y, out w, out h);
|
||||
message += String.Format(
|
||||
"Monitor {0}: X:{1}, Y:{2} - W:{3}, H:{4}\r\n",
|
||||
i, x, y, w, h
|
||||
);
|
||||
}
|
||||
Debug.Log(message);
|
||||
}
|
||||
|
||||
// Not implemented
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@@ -624,6 +625,7 @@ namespace Kirurobo
|
||||
/// 最大化する
|
||||
/// </summary>
|
||||
/// <param name="zoomed"></param>
|
||||
[Obsolete]
|
||||
private void SetZoomed(bool zoomed)
|
||||
{
|
||||
if (uniWinCore == null) return;
|
||||
@@ -634,7 +636,27 @@ namespace Kirurobo
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 終了時にはウィンドウプロシージャを戻す処理が必要
|
||||
/// 接続されているモニタ数を取得
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetMonitorCount()
|
||||
{
|
||||
if (uniWinCore == null) return 0;
|
||||
return uniWinCore.GetMonitorCount();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接続されているモニタ数を取得
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool FitToMonitor(int monitorIndex)
|
||||
{
|
||||
if (uniWinCore == null) return false;
|
||||
return uniWinCore.FitToMonitor(monitorIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 終了時にはウィンドウ状態を戻す処理が必要
|
||||
/// </summary>
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,11 @@ namespace Kirurobo
|
||||
{
|
||||
private UniWindowController _uniwinc;
|
||||
|
||||
/// <summary>
|
||||
/// ウィンドウが最大化されているときは移動を無効にするか
|
||||
/// </summary>
|
||||
public bool disableOnZoomed = true;
|
||||
|
||||
/// <summary>
|
||||
/// ドラッグ中なら true
|
||||
/// </summary>
|
||||
@@ -26,6 +31,11 @@ namespace Kirurobo
|
||||
}
|
||||
private bool _isDragging = false;
|
||||
|
||||
private bool IsEnabled
|
||||
{
|
||||
get { return enabled && (!disableOnZoomed || !(_uniwinc && _uniwinc.isZoomed)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ドラッグ前には自動ヒットテストが有効だったかを記憶
|
||||
/// </summary>
|
||||
@@ -57,6 +67,11 @@ namespace Kirurobo
|
||||
/// </summary>
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Macだと挙動を変える
|
||||
// 実際はRetinaサポートが有効のときだけだが、
|
||||
// eventData.position の系と、ウィンドウ座標系でスケールが一致しなくなってしまう
|
||||
@@ -103,7 +118,7 @@ namespace Kirurobo
|
||||
if (!_uniwinc || !_isDragging) return;
|
||||
|
||||
// ドラッグでの移動が無効化されていた場合
|
||||
if (!enabled)
|
||||
if (!IsEnabled)
|
||||
{
|
||||
EndDragging();
|
||||
return;
|
||||
|
||||
@@ -38,6 +38,7 @@ GraphicsSettings:
|
||||
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_PreloadedShaders: []
|
||||
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
|
||||
type: 0}
|
||||
|
||||
@@ -119,7 +119,7 @@ PlayerSettings:
|
||||
16:10: 1
|
||||
16:9: 1
|
||||
Others: 1
|
||||
bundleVersion: 0.5.0
|
||||
bundleVersion: 0.6.0
|
||||
preloadedAssets: []
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
|
||||
@@ -273,8 +273,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = F4K53USRZ7;
|
||||
@@ -301,8 +301,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = F4K53USRZ7;
|
||||
|
||||
@@ -85,6 +85,18 @@ UNIWINC_EXPORT BOOL GetSize(Float32* width, Float32* height) {
|
||||
return [LibUniWinC getSizeWithWidth:width height:height];
|
||||
}
|
||||
|
||||
UNIWINC_EXPORT SInt32 GetCurrentMonitor() {
|
||||
return [LibUniWinC getCurrentMonitor];
|
||||
}
|
||||
|
||||
UNIWINC_EXPORT BOOL GetMonitorCount() {
|
||||
return [LibUniWinC getMonitorCount];
|
||||
}
|
||||
|
||||
UNIWINC_EXPORT BOOL GetMonitorRectangle(SInt32 monitorIndex, Float32* x, Float32* y, Float32* width, Float32* height) {
|
||||
return [LibUniWinC getMonitorRectangleWithMonitorIndex:monitorIndex x:x y:y width:width height:height];
|
||||
}
|
||||
|
||||
UNIWINC_EXPORT BOOL SetCursorPosition(Float32 x, Float32 y) {
|
||||
return [LibUniWinC setCursorPositionWithX:x y:y];
|
||||
}
|
||||
|
||||
@@ -106,10 +106,13 @@ public class LibUniWinC : NSObject {
|
||||
/// プライマリーモニターの高さ
|
||||
private static var primaryMonitorHeight: CGFloat = 0
|
||||
|
||||
private static var monitorCount: Int = 0
|
||||
private static var monitorRectangles: [CGRect] = []
|
||||
private static var monitorIndices: [Int] = []
|
||||
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
|
||||
/// 準備完了かどうかを返す
|
||||
/// - Returns: 準備完了ならtrue
|
||||
@objc public static func isActive() -> Bool {
|
||||
@@ -172,8 +175,32 @@ public class LibUniWinC : NSObject {
|
||||
private static func _updateScreenSize() -> Void {
|
||||
// 参考 https://stackoverrun.com/ja/q/1746184
|
||||
primaryMonitorHeight = NSScreen.screens.map {$0.frame.origin.y + $0.frame.height}.max()!
|
||||
|
||||
// モニタの状態も更新
|
||||
_updateMonitorRectangles()
|
||||
}
|
||||
|
||||
private static func _updateMonitorRectangles() -> Void {
|
||||
// モニタ数
|
||||
monitorCount = NSScreen.screens.count
|
||||
|
||||
// 一旦消去
|
||||
monitorRectangles.removeAll()
|
||||
monitorIndices.removeAll()
|
||||
|
||||
// 現在のスクリーン情報を記憶
|
||||
for i in 0..<monitorCount {
|
||||
let screen = NSScreen.screens[i]
|
||||
monitorRectangles.append(screen.visibleFrame)
|
||||
monitorIndices.append(i)
|
||||
}
|
||||
|
||||
// 左上の画面が0、右下が最大となるようソート
|
||||
monitorIndices = monitorIndices.sorted(by: {
|
||||
(monitorRectangles[$0].minX < monitorRectangles[$1].minX)
|
||||
|| (monitorRectangles[$0].minX == monitorRectangles[$1].minX && monitorRectangles[$0].maxY < monitorRectangles[$1].maxY)
|
||||
})
|
||||
}
|
||||
|
||||
/// 初期化処理
|
||||
private static func setup() -> Void {
|
||||
@@ -330,7 +357,16 @@ public class LibUniWinC : NSObject {
|
||||
/// - Parameter isBorderless: trueなら透過ウィンドウにする
|
||||
@objc public static func setBorderless(isBorderless: Bool) -> Void {
|
||||
if let window: NSWindow = targetWindow {
|
||||
_setWindowBorderless(window: window, isBorderless: isBorderless)
|
||||
if (isMaximized()) {
|
||||
//// 最大化状態なら、一度解除して枠を変更して再度最大化
|
||||
//// ↑枠の分の隙間をなくせるかと思ったが、枠なしで最大化しても意味ないようだった
|
||||
//setMaximized(isZoomed: false)
|
||||
_setWindowBorderless(window: window, isBorderless: isBorderless)
|
||||
//setMaximized(isZoomed: true)
|
||||
} else {
|
||||
// 最大化されていなければ、そのままウィンドウ枠を変更
|
||||
_setWindowBorderless(window: window, isBorderless: isBorderless)
|
||||
}
|
||||
}
|
||||
state.isBorderless = isBorderless
|
||||
}
|
||||
@@ -362,11 +398,21 @@ public class LibUniWinC : NSObject {
|
||||
if (targetWindow != nil) {
|
||||
if (state.isTransparent) {
|
||||
// 透過中なら、一度透過解除してから最大化を変更してみる
|
||||
// 最大化前のウィンドウサイズが記憶されるが、透過のままだと挙動が直感に反するため
|
||||
setTransparent(isTransparent: false)
|
||||
if (targetWindow!.isZoomed != isZoomed) {
|
||||
targetWindow!.zoom(nil)
|
||||
}
|
||||
setTransparent(isTransparent: true)
|
||||
if (isZoomed) {
|
||||
// 透明化状態で zoom() をしてもウィンドウ枠の分小さくなってしまっていたため画面サイズにリサイズ
|
||||
let monitorIndex = getCurrentMonitor()
|
||||
let rect = monitorRectangles[monitorIndices[Int(monitorIndex)]]
|
||||
var frame = targetWindow!.frame
|
||||
frame.size.width = CGFloat(rect.width)
|
||||
frame.size.height = CGFloat(rect.height)
|
||||
targetWindow?.setFrame(frame, display: true)
|
||||
}
|
||||
} else {
|
||||
// 透過していない場合の処理
|
||||
if (targetWindow!.isZoomed != isZoomed) {
|
||||
@@ -453,6 +499,81 @@ public class LibUniWinC : NSObject {
|
||||
return true
|
||||
}
|
||||
|
||||
/// 現在有効な画面数を取得
|
||||
/// - Returns: 画面数
|
||||
@objc public static func getCurrentMonitor() -> Int32 {
|
||||
var primaryMonitorIndex: Int = 0
|
||||
|
||||
// ウィンドウ未取得ならプライマリモニタの番号を返す
|
||||
if (targetWindow == nil) {
|
||||
for i in 0..<monitorCount {
|
||||
let screen = NSScreen.screens[monitorIndices[i]]
|
||||
let sf = screen.visibleFrame
|
||||
|
||||
// 原点にあるモニタはプライマリモニタと判定
|
||||
if (sf.minX == 0 && sf.minY == 0) {
|
||||
primaryMonitorIndex = i
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Int32(primaryMonitorIndex)
|
||||
}
|
||||
|
||||
// 現在のウィンドウの中心座標を取得
|
||||
let frame = targetWindow!.frame;
|
||||
let cx: CGFloat = (frame.minX + frame.maxX) / 2.0
|
||||
let cy: CGFloat = (frame.minY + frame.maxY) / 2.0
|
||||
|
||||
for i in 0..<monitorCount {
|
||||
let screen = NSScreen.screens[monitorIndices[i]]
|
||||
let sf = screen.visibleFrame
|
||||
|
||||
// ウィンドウ中心を含む画面があればその画面番号を返す
|
||||
if (sf.minX <= cx && cx <= sf.maxX && sf.minY <= cy && cy <= sf.maxY) {
|
||||
return Int32(i)
|
||||
}
|
||||
|
||||
// 原点にあるモニタはプライマリモニタと判定
|
||||
if (sf.minX == 0 && sf.minY == 0) {
|
||||
primaryMonitorIndex = i
|
||||
}
|
||||
}
|
||||
return Int32(primaryMonitorIndex)
|
||||
}
|
||||
|
||||
/// 現在有効な画面数を取得
|
||||
/// - Returns: 画面数
|
||||
@objc public static func getMonitorCount() -> Int32 {
|
||||
// NOTE: UnityにあるScreenやDisplayとは異なるため、Monitorという言葉にした
|
||||
return Int32(monitorCount)
|
||||
}
|
||||
|
||||
/// 指定した画面の位置、サイズを取得
|
||||
/// - Parameters:
|
||||
/// - monitorIndex: 画面の番号
|
||||
/// - x: X座標
|
||||
/// - y: Y座標
|
||||
/// - width: ウィンドウ幅
|
||||
/// - height: ウィンドウ高さ
|
||||
/// - Returns: 成功すれば true
|
||||
@objc public static func getMonitorRectangle(
|
||||
monitorIndex: Int32,
|
||||
x: UnsafeMutablePointer<Float32>, y: UnsafeMutablePointer<Float32>,
|
||||
width: UnsafeMutablePointer<Float32>, height: UnsafeMutablePointer<Float32>
|
||||
) -> Bool {
|
||||
// 存在しないスクリーン番号ならば false で終了
|
||||
if (monitorIndex < 0 || monitorIndex >= monitorCount || monitorIndex >= NSScreen.screens.count) {
|
||||
return false
|
||||
}
|
||||
|
||||
let frame = NSScreen.screens[monitorIndices[Int(monitorIndex)]].visibleFrame
|
||||
x.pointee = Float32(frame.minX)
|
||||
y.pointee = Float32(frame.minY)
|
||||
width.pointee = Float32(frame.width)
|
||||
height.pointee = Float32(frame.height)
|
||||
return true
|
||||
}
|
||||
|
||||
/// 現在のカーソル座標を取得
|
||||
/// - Parameters:
|
||||
/// - x: X座標
|
||||
|
||||
Reference in New Issue
Block a user