You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何抛出带UnityEngine.Object上下文的异常?

How to Throw a C# Exception with Unity Object Context (For Console Highlighting)

Great question! I’ve run into this exact scenario before, and there’s a clean way to achieve what you’re asking—combining C# exception behavior (terminating execution, catchability) with Unity’s console context highlighting, without duplicate logs.

Here’s a step-by-step solution:

1. Create a Custom Exception Class

First, define a custom exception that stores your Unity object context. This lets you carry the context alongside the exception message and inner exceptions:

using System;
using UnityEngine;

public class UnityContextException : Exception
{
    // Store the Unity object to highlight in the Hierarchy
    public Object Context { get; }

    // Basic constructor
    public UnityContextException(string message, Object context) : base(message)
    {
        Context = context;
    }

    // Constructor with inner exception support
    public UnityContextException(string message, Exception innerException, Object context) : base(message, innerException)
    {
        Context = context;
    }
}

2. Build a Global Exception Handler

Next, create a script that intercepts Unity’s log output to avoid duplicate entries, while ensuring your context-rich error gets displayed properly. Attach this to a persistent GameObject (like a GameManager set to DontDestroyOnLoad) so it works across all scenes:

using UnityEngine;

public class ExceptionContextLogger : MonoBehaviour
{
    // Flag to track when we've thrown our custom exception
    private static bool _isContextExceptionPending;

    private void OnEnable()
    {
        // Subscribe to Unity's log callback
        Application.logMessageReceivedThreaded += HandleLogEvent;
    }

    private void OnDisable()
    {
        // Unsubscribe to prevent memory leaks
        Application.logMessageReceivedThreaded -= HandleLogEvent;
    }

    private void HandleLogEvent(string logString, string stackTrace, LogType logType, ref bool cancel)
    {
        // Cancel the default exception log if it's our custom context exception
        if (logType == LogType.Exception && _isContextExceptionPending && logString.Contains(nameof(UnityContextException)))
        {
            cancel = true;
            _isContextExceptionPending = false; // Reset the flag
        }
    }

    // Static method to throw your context-aware exception
    public static void Throw(string message, Object context)
    {
        // Print the error with Unity context (enables Hierarchy highlighting)
        Debug.LogError(message, context);
        // Flag that we're about to throw our custom exception
        _isContextExceptionPending = true;
        // Throw the exception to halt execution
        throw new UnityContextException(message, context);
    }

    // Overload for exceptions with inner causes
    public static void Throw(string message, Exception innerException, Object context)
    {
        Debug.LogError($"{message}\nInner Exception: {innerException.Message}", context);
        _isContextExceptionPending = true;
        throw new UnityContextException(message, innerException, context);
    }
}

3. Use the Context-Aware Throw

Now you can throw exceptions that behave like regular C# exceptions, but add Unity’s console highlighting, with just one line of code:

// Example: Throw an error linked to a GameObject
ExceptionContextLogger.Throw("Failed to initialize player controller!", playerControllerGameObject);

Key Benefits:

  • No duplicate logs: The handler cancels Unity’s default exception output, leaving only your context-rich Debug.LogError entry.
  • Hierarchy highlighting: Clicking the console error will automatically select the linked Unity object in the Hierarchy.
  • Full exception behavior: The exception will terminate execution, can be caught with try/catch, and preserves stack trace information.

Catching the Custom Exception

You can catch this exception just like any other C# exception, and even access the stored context:

try
{
    ExceptionContextLogger.Throw("Test error", someGameObject);
}
catch (UnityContextException ex)
{
    Debug.LogWarning($"Caught error: {ex.Message}\nAffected Object: {ex.Context.name}");
}

内容的提问来源于stack exchange,提问作者E. Zacarias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:20:55