Files
Tomicz Engineering LLC deea7d2a56 Replace reflection with version-gated conditional compilation.
Addresses review feedback on the Unity 6.5 GetInstanceID migration:

- UnityObjectIdCompatExtensions: drop the reflective method lookup in
  favor of a simple #if UNITY_6000_5_OR_NEWER / #else split calling
  GetEntityId() or GetInstanceID() directly. Also wrap the class in
  the MCPForUnity.Runtime.Helpers namespace.
- UnityTypeConverters: remove the reflective EntityIdToObject probe and
  call EditorUtility.EntityIdToObject(EntityId) directly under the same
  version gate. Serialize entityID as EntityId.ToULong() rather than
  ToString(), since Unity's docs explicitly warn that the textual form
  is not a stable serialization contract.
- Drop #pragma warning disable 0619 from 22 files that no longer make
  any direct calls to obsolete APIs. The remaining 7 files still need
  it (FindObjectsOfType, InstanceIDToObject fallback) and are left as-is
  — those deprecations are out of scope for this PR.
- Add the MCPForUnity.Runtime.Helpers using to every file that calls
  GetInstanceIDCompat() now that the extension method lives in a
  namespace.
2026-04-11 22:55:45 +02:00

65 lines
2.9 KiB
C#

#nullable disable
using MCPForUnity.Editor.Helpers;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEngine;
using MCPForUnity.Runtime.Helpers;
namespace MCPForUnity.Editor.Tools.GameObjects
{
internal static class GameObjectLookAt
{
/// <summary>
/// Rotates a GameObject to face a world position or another GameObject.
/// Parameters:
/// target - The GO to rotate (name/path/instanceID)
/// look_at_target - World position [x,y,z] or GO reference (name/path/instanceID) to look at
/// look_at_up - Optional up vector [x,y,z], defaults to Vector3.up
/// </summary>
internal static object Handle(JObject @params, JToken targetToken, string searchMethod)
{
GameObject targetGo = ManageGameObjectCommon.FindObjectInternal(targetToken, searchMethod);
if (targetGo == null)
{
return new ErrorResponse($"Target GameObject ('{targetToken}') not found using method '{searchMethod ?? "default"}'.");
}
JToken lookAtToken = @params["look_at_target"] ?? @params["lookAtTarget"];
if (lookAtToken == null)
{
return new ErrorResponse("'look_at_target' parameter is required for 'look_at' action. Provide a world position [x,y,z] or a GameObject name/path/ID.");
}
// Try parsing as a position vector first
Vector3? lookAtPos = VectorParsing.ParseVector3(lookAtToken);
if (!lookAtPos.HasValue)
{
// Not a vector — treat as a GO reference, using the same search method as for the main target
GameObject lookAtGo = ManageGameObjectCommon.FindObjectInternal(lookAtToken, searchMethod);
if (lookAtGo == null)
{
return new ErrorResponse($"look_at_target '{lookAtToken}' could not be resolved as a position [x,y,z] or found as a GameObject.");
}
lookAtPos = lookAtGo.transform.position;
}
Vector3 upVector = VectorParsing.ParseVector3OrDefault(@params["look_at_up"] ?? @params["lookAtUp"], Vector3.up);
Undo.RecordObject(targetGo.transform, $"LookAt {targetGo.name}");
targetGo.transform.LookAt(lookAtPos.Value, upVector);
var euler = targetGo.transform.rotation.eulerAngles;
return new SuccessResponse(
$"'{targetGo.name}' now looking at ({lookAtPos.Value.x:F2}, {lookAtPos.Value.y:F2}, {lookAtPos.Value.z:F2}).",
new
{
name = targetGo.name,
instanceID = targetGo.GetInstanceIDCompat(),
rotation = new[] { euler.x, euler.y, euler.z },
lookAtPosition = new[] { lookAtPos.Value.x, lookAtPos.Value.y, lookAtPos.Value.z },
}
);
}
}
}