2015-12-24 5 views
1

Previous thread, в случае y'all любопытно.C# - Four Dragon Fallout4 - обходит необработанные исключения?

Фоновая информация: Four Dragon - это оболочка C# для Fallout 4, позволяющая использовать скрипты C# для изменения игры, а также использование скриптового языка Papyrus (Skyrim и Fallout 4) в том же скрипте C#. Потенциал! ВОЗМОЖНОСТИ!

Я придумал скрипт, который управляет функциями Papyrus и SetMotionType, которые используются для замораживания объекта в игре. Благодаря Metro Smurf сценарий гораздо проще читать.



Однако, существует довольно ... Откровенная проблема. Сценарий регистрируется для ключей F6 и F7, но когда F6 нажата и вызывается функция GetPlayerGrabbedRef(), когда игрок не захватил ссылку (подвижный внутриигровой объект), выводится следующее исключение, вызывая игру чтобы быстро выйти:

FATAL ERROR Unhandled exception while executing FyTyTest.FreezeObject Void OnStaticTick()

Теперь, я сделал некоторое чтение о том, как обрабатывать необработанных исключений, что позволяет программе (игры Fallout 4 в данном случае), чтобы продолжить работу, не закрывая через try и catch функций, но я не имел никакого успеха; исключение все еще происходит, заставляя игру выйти, когда нажата кнопка «ОК».

Увы, различные файлы .log, которые выведены, не показывают проблем; это как если бы все функционировало правильно.

Вот последнее воплощение сценария:

using System; 
using System.Collections.Generic; 
using Fallout; 

public class FreezeObject : ScriptObject 
{ 
public FreezeObject() { } 

bool bGotObject = false; 
ObjectReference ItemReference; 
ObjectReference EmptyReference; 
int itemValue; 


public override void OnStaticTick() 
{ 
    base.OnStaticTick(); 

    bool isF6 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F6); 
    bool isF7 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F7); 

    if(isF6) 
    { 
     try 
     { 
      ItemReference = Game.GetPlayerGrabbedRef(); 
      itemValue = ItemReference.GetGoldValue(); 
      if(ItemReference = EmptyReference) 
      { 
       // nothing else to do if we have a null reference 
       return; 
      } 
     } 

     catch 
     { 
      ItemReference = EmptyReference; 
      itemValue = -1; 
      return; 
     } 

    if (itemValue > -1) 
    { 
     bGotObject = true; 
    } 
      // nothing else to do; the next block is for F7 
    return; 
    } 

    if(isF7 && bGotObject && ItemReference != EmptyReference && itemValue > -1) 
    { 
     ItemReference.SetMotionType(2, true); 
     bGotObject = false; 
    } 
} 
} 

Так да. Как мне заставить остановить необработанное исключение из-за срыва игры? Или это просто невозможно?



Edit: По предложению Кори, я поставил try...catch функции вокруг всех функций-у кода на ... Нет кости; исключение все еще появляется, закрывая игру после закрытия сообщения об исключении.

Вот новый сценарий:

using System; 
using System.Collections.Generic; 
using Fallout; 

public class FreezeObject : ScriptObject 
{ 
public FreezeObject() { } 
bool bGotObject = false; 
ObjectReference ItemReference; 
ObjectReference EmptyReference; 
int itemValue; 


public override void OnStaticTick() 
{try 
{ 

    base.OnStaticTick(); 

    bool isF6 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F6); 
    bool isF7 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F7); 

    if(isF6) 
    { 
     ItemReference = Game.GetPlayerGrabbedRef(); 
     itemValue = ItemReference.GetGoldValue(); 
     if(ItemReference == EmptyReference) 
     { 
      // nothing else to do if we have a null reference 
      return; 
     } 

    if (itemValue > -1) 
    { 
     bGotObject = true; 
    } 
      // nothing else to do; the next block is for F7 
    return; 
    } 

    if(isF7 && bGotObject && ItemReference != EmptyReference && itemValue > -1) 
    { 
     ItemReference.SetMotionType(2, true); 
     bGotObject = false; 
    } 
    } 
catch 
{ 
} 
} 
} 
+2

Вы пробовали обернуть весь контент метода OnStaticTick в 'try ... catch' вместо одной его части? Сообщение об исключении не дает много информации о том, что на самом деле произошло. – Corey

+0

Да, ошибка в значительной степени бесполезна, но это все, что дается. Я не пробовал поместить все это в вещь «попробовать». Я полагаю, что он должен идти после 'public override void OnStaticTick()', а не раньше? – MajinCry

+0

Положите 'try' Непосредственно внутри первой фигурной скобки, улов до последней скобки. Разумеется, с их собственными наборами. – Corey

ответ

0

Четыре дракона проводит свой собственный AppDomain с целью загрузки и выполнения пользовательских скриптов. У меня не было много возможностей работать с пользовательскими хостами, поэтому я не знаю точно, но я считаю, что хосты имеют некоторый контроль над поведением обработки исключений. Предполагая, что я прав, я бы предположил, что это причина ваших странных проблем с обработкой исключений.

Лучше всего решить фактическую причину исключений. В вашем коде вы проверяете нулевую ссылку после того, как вы уже пытались получить доступ к методу объекта. Вы можете попробовать это:

if(isF6) 
{ 
    ItemReference = Game.GetPlayerGrabbedRef(); 
    if(ItemReference != null && ItemReference.HandleExists()) 
    { 
     itemValue = ItemReference.GetFormID(); 
     if (itemValue != 0) 
     { 
      bGotObject = true; 
     } 
    } 

    // nothing else to do; the next block is for F7 
    return; 
} 

Я изменил свой GetGoldValue() вызов GetFormID() так как вы используете его, чтобы установить, действительно ли у вас есть действующий ObjectReference.

Если у вас все еще есть проблемы, я попытаюсь сохранить идентификатор формы и использовать Game.GetForm(formid), чтобы повторно найти ссылку на объект в блоке F7. Вы полагаетесь на предположение, что ссылка на объект остается действительной между вызовами OnStaticTick, что может и не быть так. (все еще выкапывая реализацию Four Dragon, поэтому я все еще не уверен)

Редактировать: Disregard - ссылки на объекты, по-видимому, остаются действительными между событиями.

Смежные вопросы