using UnityEngine;
using cakeslice;

public class MoxingControl : MonoBehaviour
{
private Transform selectedPart = null;
private Outline outline = null;
private GameObject axis;
private Vector3 axisOffset = Vector3.zero;
private Vector3 mouseOffset = Vector3.zero;
private bool isControlEnabled = false;
private Color selectedColor = Color.yellow;
private Animator animator;
private bool animatorEnabled = true;

public GameObject axisPrefab;

private void Start()
{
axis = Instantiate(axisPrefab, Vector3.zero, Quaternion.identity);
axis.SetActive(false);
}

private void Update()
{
animator = GetComponent<Animator>();
if (!isControlEnabled)
return;

if (Input.GetMouseButtonDown(0))
{
Transform clickedPart = GetClickedPart(transform);
if (clickedPart != null)
{
if (selectedPart != null)
{
Destroy(outline);
}

selectedPart = clickedPart;
outline = selectedPart.gameObject.AddComponent<Outline>();
//outline.OutlineColor = selectedColor;
//outline.OutlineWidth = 2;

Vector3 axisPosition = selectedPart.position + new Vector3(0f, 0.15f, 0f);
axis.SetActive(true);
axis.transform.SetParent(selectedPart);
axis.transform.position = axisPosition;
axisOffset = axis.transform.position - selectedPart.position;
mouseOffset = selectedPart.position - Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
else if (IsAxisClicked())
{
mouseOffset = axis.transform.position - Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
else
{
if (selectedPart != null)
{
//Destroy(outline);
//selectedPart = null;
//axis.SetActive(false);
}
}
}

if (Input.GetMouseButton(0) && selectedPart != null)
{
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = axisOffset.z;
Vector3 worldMousePosition = Camera.main.ScreenToWorldPoint(mousePosition) + mouseOffset;
Vector3 localPosition = axis.transform.InverseTransformPoint(worldMousePosition) - axisOffset;

float xOffset = Mathf.Round(localPosition.x * 1000) / 1000f;
float yOffset = Mathf.Round(localPosition.y * 1000) / 1000f;
float zOffset = Mathf.Round(localPosition.z * 1000) / 1000f;

selectedPart.position += new Vector3(xOffset, yOffset, zOffset);
}

if (selectedPart != null)
{
Vector3 axisPosition = selectedPart.position + new Vector3(0f, 0.15f, 0f);
axis.transform.position = axisPosition + axisOffset;
}
}

private bool IsDescendant(Transform child, Transform parent)
{
foreach (Transform t in parent)
{
if (t == child)
return true;
if (IsDescendant(child, t))
return true;
}
return false;
}

private bool IsAxisClicked()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.transform == axis.transform)
{
return true;
}
}
return false;
}

private Transform GetClickedPart(Transform parent)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Transform clickedPart = hit.transform;
if (IsDescendant(clickedPart, parent))
{
return clickedPart;
}
}
return null;
}

public void ToggleControlEnabled()
{
isControlEnabled = !isControlEnabled;
animator.enabled = !animator.enabled;
if (!isControlEnabled && selectedPart != null)
{
//Destroy(outline);
//selectedPart = null;
//axis.SetActive(false);
}
}
}修改功能：首先将鼠标点击的精度提高为小数点后四位，然后分别将做表面模型的x、y、z三个轴声明一下，通过点击三个坐标轴进行三个方向的鼠标点击拖拽移动（鼠标拖拽多远，模型跟随移动多远）