MD Package Technical & APi Documentation
MD_MeshEditorRuntime
Namespace: MDPackage
Essential component for general mesh vertex editing at runtime (Non-VR). Required component: MD_MeshProEditor.
Read more here (Online documentation slide)

There are two modes of editing MeshProEditor objects at runtime: Axis & Non-Axis mode.
Axis mode allows you to select/deselect specific points and use the Axis handle to move up/down/right/left/forward/backward in a world space.
This option is great for precise mesh editing at runtime. This option works only for PCs with mouse.
Non-Axis mode allows you to drag/drop/pull/push specific points in a world space. Works for any platform (PC, Mobile).

The input is not handled by default, as the Unity Engine has many options for handling input and controls in general.
MD-Package components that contain some input features consist of 'Input Hookup' properties that handle the input in a generic way.
You can set these properties from your own input system. The component will display more information about the input setup, so please follow up on this information.
You can find all the input-hookup properties below.
Public Methods
// Axis editor mode

// Axis method - switch editor target for mesh editing at runtime
public void AXIS_SwitchTarget(MD_MeshProEditor target)
// Axis method - undo selection
public void AXIS_Undo()
// Create an axis handle automatically - this will create a default axis handle for axis-editor
public void AXIS_CreateAxisHandleAutomatically()

// Non-Axis editor mode

// Switch current control mode by index [0-Grab/Drop,1-Push,2-Pull]
public void NON_AXIS_SwitchControlMode(int index)
Public Fields and Properties
// Input Hookups

// Use this input hookup for cursor/touch world screen position
public Vector3 InputHook_CursorScreenPosition { get; set; }
// Use this input hookup for generic button down - for vertex selection button [eg. Input.GetKey(KeyCode.Mouse0)]
public bool InputHook_GenericButtonDown { get; set; }
// Use this input hookup for vertex selection add in the Axis Editor only
public bool InputHook_AxisEditorAddPointsToSelection { get; set; }
// Use this input hookup for vertex selection remove in the Axis Editor only
public bool InputHook_AxisEditorRemovePointsFromSelection { get; set; }
// Use this input hookup for mouse position delta in the Axis Editor only
public Vector2 InputHook_AxisEditorMousePositionDelta { get; set; }

// General fields

public Camera mainCameraCache;
public bool isAxisEditor = false;

// ----- Non-Axis mesh editor

public VertexControlMode nonAxis_vertexControlMode = VertexControlMode.GrabDropVertex;

public bool nonAxis_isMobileFocused = false;

// Axis lock
public bool nonAxis_lockAxisX = false;
public bool nonAxis_lockAxisY = false;

// Cursor
public bool nonAxis_cursorIsOrigin = true;
public bool nonAxis_handleCursor = true;
public bool nonAxis_lockAndHideCursor = true;

// Appearance
public bool nonAxis_switchAppearance = true;
public Color nonAxis_switchAppearanceToColor = Color.green;
public bool nonAxis_switchAppearanceUseMaterial = false;
public Material nonAxis_switchAppearanceMaterialTarget;

// Pull-Push Settings
public float nonAxis_pullPushVertexSpeed = 0.15f;
public float nonAxis_maxMinPullPushDistance = Mathf.Infinity;
public bool nonAxis_continuousPullPushDetection = false;
public PullPushType nonAxis_pullPushType = PullPushType.Directional;

// Conditions
public bool nonAxis_allowSpecificPoints = false;
public string nonAxis_allowedPointsTag;

// Raycast
public bool nonAxis_allowBackfaces = true;
public LayerMask nonAxis_allowedLayerMask = -1;
public float nonAxis_raycastDistance = 1000.0f;
public float nonAxis_raycastRadius = 0.25f;

// DEBUG
public bool nonAxis_enableGizmos = true;

// ----- Axis mesh editor

public GameObject axis_axisObject;

public bool axis_inLocalSpace = false;
public float axis_manipulationSpeed = 16.0f;
public Color axis_selectedPointColor = Color.green;
public Color axis_selectionGridColor = Color.black;

public AxisMoveAxisTo axis_movePointsToAxis;
Examples
The following paragraphs contain MeshEditorRuntime used in a practical example with Unity's legacy Input System.
Create a mesh editor runtime via script and edit specific mesh with MeshProEditor.
using UnityEngine;
using MDPackage;

public class SampleScript : MonoBehaviour
{
private MD_MeshEditorRuntime runtimeEditor;

// Cache camera!
 [SerializeField] private Camera mainCamera;
 [SerializeField] private bool useNonAxisEditor = true;
// Assign a gameObject with MD_MeshProEditor - simply add a component to this object in the editor, or even at runtime!
 [SerializeField] private MD_MeshProEditor targetMesh;
// Setup legacy input
 [SerializeField] private KeyCode inputVertexSelection = KeyCode.Mouse0;
 [SerializeField] private KeyCode inputVertexAdd = KeyCode.LeftShift;
 [SerializeField] private KeyCode inputVertexRemove = KeyCode.LeftAlt;

private void Start()
 {
  if(targetMesh == null)
  {
   enabled = false;
   Debug.LogError("targetMesh is null!");
   return;
  }
  
  // Prepare target mesh - generate points in the MeshProEditor
  if (targetMesh.HasGeneratedVerticePoints == false)
   targetMesh.MPE_CreatePointsEditor();
  targetMesh.meshAnimationMode = true;

  // Create a brand new MeshEditorRuntime
  runtimeEditor = gameObject.AddComponent<MD_MeshEditorRuntime>();
  if(mainCamera != null)
   runtimeEditor.mainCameraCache = mainCamera;
  runtimeEditor.isAxisEditor = !useNonAxisEditor;
  // Setup axis editor if enabled
  if(runtimeEditor.isAxisEditor)
  {
   // Create the axis handle automatically from the template
   runtimeEditor.AXIS_CreateAxisHandleAutomatically();
   // Set the target to our MeshProEditor reference
   runtimeEditor.AXIS_SwitchTarget(targetMesh);
  }
 }

// Custom legacy-input handling (Modify this for your input system)
private void Update()
 {
  // Hence the InputHook properties - these properties correspond to the specific actions and are required in order to manually control mesh vertices
  // MD Package actually contains an example content where you can find samples on these input hookups. Please have a look at the 'MD_Examples_InputWrapper_MeshEditorRuntime'.
  
  if (runtimeEditor.isAxisEditor)
   runtimeEditor.InputHook_CursorScreenPosition = Input.mousePosition;
  else
  {
   if (runtimeEditor.nonAxis_isMobileFocused && Input.touchCount > 0)
    runtimeEditor.InputHook_CursorScreenPosition = Input.GetTouch(0).position;
   else
    runtimeEditor.InputHook_CursorScreenPosition = Input.mousePosition;
  }

  if (runtimeEditor.nonAxis_isMobileFocused && Input.touchCount > 0)
   runtimeEditor.InputHook_GenericButtonDown = Input.GetTouch(0).phase == TouchPhase.Began;
  else
   runtimeEditor.InputHook_GenericButtonDown = Input.GetKey(inputVertexSelection);

  runtimeEditor.InputHook_AxisEditorAddPointsToSelection = Input.GetKey(inputVertexAdd);
  runtimeEditor.InputHook_AxisEditorRemovePointsFromSelection = Input.GetKey(inputVertexRemove);
  runtimeEditor.InputHook_AxisEditorMousePositionDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
 }
}