Files
DuckovMods/CharacterPreview/ControlModelMove.cs

274 lines
9.2 KiB
C#
Raw Permalink Normal View History

2025-11-18 18:45:14 +08:00
using System;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace CharacterPreview
{
public class ControlModelMove : MonoBehaviour, IDragHandler,IPointerDownHandler,IPointerEnterHandler,IPointerExitHandler
{
private RectTransform rectTransform;
private Transform canvasRectTransform; //由滑动器自己创建的
private Vector2 lastMousePosition;
private Image image;
private TMP_Text text;
private Button editButton;
private TMP_Text editButtonText;
public bool firstClick=true;
public float Speed => ModBehaviour.config.data.editSpeed;
//防止鼠标在范围外捕获消息
private bool canEdit = false;
private void Awake()
{
}
private void Start()
2025-11-18 18:45:14 +08:00
{
SetRectTransform();
SetText();
SetColor();
if(ModBehaviour.config.data.showSetEditButton)
SetEditButton();
firstClick = ModBehaviour.config.data.tip;
if (!firstClick)
{
HideTip();
}
}
private void OnDestroy()
{
if (canvasRectTransform)
{
Destroy(canvasRectTransform.gameObject);
}
}
void Update()
{
if (!canEdit)
return;
var scroll = Input.GetAxis("Mouse ScrollWheel");
if (scroll != 0)
{
if (Input.GetMouseButton(1))
{
ModBehaviour.modelMove.RotateAroundCameraZ(Speed * scroll * 8);
}
else if(Input.GetKey(KeyCode.LeftShift))
{
ModBehaviour.modelMove.Scale(Speed*scroll/4f);
}
else
{
ModBehaviour.modelMove.Move(new Vector3(0, 0, Speed * scroll * 2));
}
}
if (Input.GetMouseButtonDown(2))
{
if (Input.GetKey(KeyCode.LeftControl))
{
ModBehaviour.modelMove.RefreshPosition();
}
else
{
ModBehaviour.modelMove.LookAtCamera();
}
}
}
public void SetColor()
{
var color = new Color(0.9f, 0.8f, 0.3f, 0.1f);
image = gameObject.GetComponent<Image>();
if (!image)
{
image = gameObject.AddComponent<Image>();
}
image.color = color;
}
public void SetText()
{
text=gameObject.GetComponentInChildren<TMP_Text>();
if (!text)
{
var textChilde = new GameObject("Text");
textChilde.transform.SetParent(gameObject.transform);
var rect = textChilde.AddComponent<RectTransform>();
text= textChilde.AddComponent<TextMeshProUGUI>();
rect.anchorMax = Vector2.one;
rect.anchorMin = Vector2.zero;
rect.offsetMin = Vector2.zero;
rect.offsetMax = Vector2.zero;
}
text.fontSize = 24;
text.alignment=TextAlignmentOptions.Center;
text.text = "在此区域可以编辑模型状态(点击区域关闭提示)\n" +
"通过鼠标左键拖动修改角色的上下左右位置\n" +
"通过鼠标滚轮修改角色的z轴位置\n" +
"通过鼠标右键控制角色旋转\n" +
"按住右键的情况下滚动滚轮可让角色转圈\n" +
"按住shift滚动滚轮可缩放角色\n" +
"点按鼠标中键可让角色朝向摄像头\n" +
"按住ctrl并点击中键则恢复默认位置";
}
public void SetRectTransform()
{
if (!rectTransform)
{
rectTransform = GetComponent<RectTransform>();
}
if (!rectTransform)
{
rectTransform = gameObject.AddComponent<RectTransform>();
}
if (!rectTransform.parent)
2025-11-18 18:45:14 +08:00
{
var defaultCanvas = new GameObject("ControlModelMoveCanvas");
defaultCanvas.layer = LayerMask.NameToLayer("UI");
var canvas = defaultCanvas.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = -100;
var canvasScaler = defaultCanvas.AddComponent<CanvasScaler>();
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(1600, 900);
canvasScaler.matchWidthOrHeight = 1f;
defaultCanvas.AddComponent<GraphicRaycaster>();
canvasRectTransform = defaultCanvas.GetComponent<RectTransform>();
canvasRectTransform.SetParent(null, false);
canvasRectTransform.SetAsFirstSibling();
2025-11-18 18:45:14 +08:00
rectTransform.SetParent(defaultCanvas.transform);
}
rectTransform.SetAsFirstSibling();
rectTransform.anchorMax = Vector2.one;
rectTransform.anchorMin = new Vector2(0.5f, 0);
rectTransform.offsetMax = Vector2.zero;
rectTransform.offsetMin = Vector2.zero;
}
public void SetEditButton()
{
if (!editButton)
{
var buttonObj = new GameObject("EditButton");
buttonObj.transform.SetParent(transform, false);
var buttonRect= buttonObj.AddComponent<RectTransform>();
buttonRect.anchorMax=Vector2.right;
buttonRect.anchorMin=Vector2.right;
buttonRect.pivot = Vector2.right;
buttonRect.sizeDelta=new Vector2(80f,30f);
buttonRect.anchoredPosition = new Vector2(-80, 5);
2025-11-18 18:45:14 +08:00
var button = buttonObj.AddComponent<Button>();
var buttonImage = buttonObj.AddComponent<Image>();
buttonImage.color = Color.green;
button.image = buttonImage;
var textObj=new GameObject("Text");
var txtRect = textObj.AddComponent<RectTransform>();
txtRect.SetParent(buttonRect);
txtRect.anchorMax=Vector2.one;
txtRect.anchorMin=Vector2.zero;
txtRect.offsetMax=Vector2.zero;
txtRect.offsetMin=Vector2.zero;
var tmpText = txtRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = "关闭编辑";
tmpText.color = Color.white;
tmpText.alignment = TextAlignmentOptions.Center;
tmpText.fontSize = 14;
tmpText.raycastTarget = false; // 文本RaycastTarget通常为false除非文本本身需要互动
button.AddComponent<HideSelfOnLeisure>();
editButton = button;
editButtonText = tmpText;
}
editButton.onClick.RemoveAllListeners();
editButton.onClick.AddListener(OnEditButton);
RefreshEditButton();
}
public void HideTip()
{
var oldColor = Color.black;
oldColor.a = 0.01f;
image.color = oldColor;
text.text = "";
}
public void RefreshEditButton()
{
if (editButton)
{
editButton.image.color = ModBehaviour.config.data.canEdit ? Color.green : Color.red;
editButtonText.text = ModBehaviour.config.data.canEdit ? "关闭编辑" : "开启编辑";
}
}
public void OnDrag(PointerEventData eventData)
{
var shift = eventData.position - lastMousePosition;
if (ModBehaviour.modelMove)
{
if (Input.GetMouseButton(0))
{
ModBehaviour.modelMove.Move(shift * Speed / 750);
}
else if (Input.GetMouseButton(1))
{
ModBehaviour.modelMove.Rotate(shift * Speed * 2);
}
}
lastMousePosition=eventData.position;
}
public void OnPointerDown(PointerEventData eventData)
{
lastMousePosition=eventData.position;
if (firstClick)
{
HideTip();
firstClick=false;
ModBehaviour.config.data.tip = firstClick;
}
}
public void OnPointerEnter(PointerEventData eventData)
{
canEdit = true;
}
public void OnPointerExit(PointerEventData eventData)
{
canEdit = false;
}
public void OnEditButton()
{
ModBehaviour.config.data.canEdit = !ModBehaviour.config.data.canEdit;
RefreshEditButton();
}
}
}