Jump to content

Editor and thumbnail questions


linuxgurugamer

Recommended Posts

Hi,

first, thanks to all who've answered my questions in the past.

Now, two new ones:

1. Is it possible to know if a currently loaded craft in the editor has been changed since it was loaded or last saved?

2. I'm currently using the CraftThumbnail.TakeSnapshot function to get a square picture of a ship. The problem is that it only has the ability to take a square picture, and I'd like to somehow be able to take a rectangular picture (ie: 16:10). Is there any way to do this?

Thanks in advance

LGG

Just answered my first question:

GameEvents.onEditorShipModified.Add(onCraftChange);

private void onCraftChange(ShipConstruct craft) {}

and this for when a ship is loaded:

GameEvents.onEditorLoad

Now I need to figure out how to know when a ship was saved. Answers would be welcome (if I don't get it first)

Edited by linuxgurugamer
Link to comment
Share on other sites

Hmm, I don't know if it would work in the editor, but there is a way to create a new camera and place the camera output into a texture which can have a separate width/height which, I think, can then be exported similar to the taking of a screenshot.

I would look into how that plugin (oh what's the name of it... crud, my brain isn't cooperating... that mod which created those blueprint-like images of your craft...) did it and take inspiration from that. It was able to automatically detect the cubic dimensions of the craft and alter the size of the view area and, ultimately, the size of the exported image based on the vessel's dimensions and keep track of changes to the craft while the viewing area was visible.

I suspect that the VesselView plugin, for in-flight and, with JSI, MFD-style views of the craft in wire-frame, could provide some tips on such things, but again I don't know if it would function quite right in the editor.

Everything else you're looking for is likely already in an event that's fired. The plugin that allows you to keep a history of your craft's saves (again, I'm blanking on the details) surely needed to get a hold of craft saving times to do its thing.

Edited by Gaalidas
Link to comment
Share on other sites

Everything else you're looking for is likely already in an event that's fired. The plugin that allows you to keep a history of your craft's saves (again, I'm blanking on the details) surely needed to get a hold of craft saving times to do its thing.

You're thinking of CraftHistory, and I've already looked at that, I'm also contacting SpaceTiger about it. Unfortunately, he overloads the "save" button, and if I do that, our mods will conflict with each other.

I don't understand why there is GameEvent.onEditorLoad and not something similar for saving.

LGG

Link to comment
Share on other sites

You're thinking of CraftHistory, and I've already looked at that, I'm also contacting SpaceTiger about it. Unfortunately, he overloads the "save" button, and if I do that, our mods will conflict with each other.

Only because he does not call the original method and instead overwrites what's already there. There are a number of ways around it. The easiest one is just to use a lower level callback directly:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class CraftHistoryButtonCallbackLowLevel : MonoBehaviour
{
private void Start()
{
EditorLogic.fetch.loadBtn.AddValueChangedDelegate(OnLoadButtonClicked);
EditorLogic.fetch.saveBtn.AddValueChangedDelegate(OnSaveButtonClicked);
}

private void OnSaveButtonClicked(IUIObject uiObject)
{
print("Save button was clicked");
}

private void OnLoadButtonClicked(IUIObject uiObject)
{
print("Load button was clicked");
}
}

Another is to do something similar to him, but store the details of the target method and call it yourself. I've built in a delay here so that his addon runs first (if installed), and then any changes he's made are captured for reuse:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class CraftHistoryButtonCallback : MonoBehaviour
{
private IEnumerator Start()
{
yield return new WaitForEndOfFrame();

gameObject.AddComponent<EditorHooks>().OnEditorSave += OnShipSaved;
}

private void OnShipSaved()
{
print("Callback for OnShipSaved received");
}
}


public class EditorHooks : MonoBehaviour
{
public event Callback OnEditorSave = delegate { };

private MonoBehaviour _originalSaveScript;
private string _originalSaveMethodName;


private void Awake()
{
var logic = EditorLogic.fetch;

_originalSaveMethodName = logic.saveBtn.methodToInvoke;
_originalSaveScript = logic.saveBtn.scriptWithMethodToInvoke;

logic.saveBtn.scriptWithMethodToInvoke = this;
logic.saveBtn.methodToInvoke = "HookedEditorSave";
}


private void HookedEditorSave()
{
OnEditorSave();

// disabled because CraftHistory has overloaded "saveCraft" method and Unity complains
//_originalSaveScript.SendMessage(_originalSaveMethodName, SendMessageOptions.RequireReceiver);

// because we don't know whether the target method is potentially static, public etc ... we do know we're looking
// for one that takes no arguments
var methodInfo = _originalSaveScript.GetType()
.GetMethod(_originalSaveMethodName,
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null, new Type[] {}, null);

if (methodInfo == null)
{
Debug.LogWarning("Did not find a method called " + _originalSaveMethodName + " on " +
_originalSaveScript.GetType().FullName);
}
else
{
methodInfo.Invoke(_originalSaveScript, new object[] {});
}
}
}

Link to comment
Share on other sites

Only because he does not call the original method and instead overwrites what's already there. There are a number of ways around it. The easiest one is just to use a lower level callback directly:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class CraftHistoryButtonCallbackLowLevel : MonoBehaviour
{
private void Start()
{
EditorLogic.fetch.loadBtn.AddValueChangedDelegate(OnLoadButtonClicked);
EditorLogic.fetch.saveBtn.AddValueChangedDelegate(OnSaveButtonClicked);
}

private void OnSaveButtonClicked(IUIObject uiObject)
{
print("Save button was clicked");
}

private void OnLoadButtonClicked(IUIObject uiObject)
{
print("Load button was clicked");
}
}

Another is to do something similar to him, but store the details of the target method and call it yourself. I've built in a delay here so that his addon runs first (if installed), and then any changes he's made are captured for reuse:

[KSPAddon(KSPAddon.Startup.EditorAny, false)]
public class CraftHistoryButtonCallback : MonoBehaviour
{
private IEnumerator Start()
{
yield return new WaitForEndOfFrame();

gameObject.AddComponent<EditorHooks>().OnEditorSave += OnShipSaved;
}

private void OnShipSaved()
{
print("Callback for OnShipSaved received");
}
}


public class EditorHooks : MonoBehaviour
{
public event Callback OnEditorSave = delegate { };

private MonoBehaviour _originalSaveScript;
private string _originalSaveMethodName;


private void Awake()
{
var logic = EditorLogic.fetch;

_originalSaveMethodName = logic.saveBtn.methodToInvoke;
_originalSaveScript = logic.saveBtn.scriptWithMethodToInvoke;

logic.saveBtn.scriptWithMethodToInvoke = this;
logic.saveBtn.methodToInvoke = "HookedEditorSave";
}


private void HookedEditorSave()
{
OnEditorSave();

// disabled because CraftHistory has overloaded "saveCraft" method and Unity complains
//_originalSaveScript.SendMessage(_originalSaveMethodName, SendMessageOptions.RequireReceiver);

// because we don't know whether the target method is potentially static, public etc ... we do know we're looking
// for one that takes no arguments
var methodInfo = _originalSaveScript.GetType()
.GetMethod(_originalSaveMethodName,
BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null, new Type[] {}, null);

if (methodInfo == null)
{
Debug.LogWarning("Did not find a method called " + _originalSaveMethodName + " on " +
_originalSaveScript.GetType().FullName);
}
else
{
methodInfo.Invoke(_originalSaveScript, new object[] {});
}
}
}

Thanks.

Your ideas (especially the first one) are great. This is getting much deeper into Unity than I have ever gone, will be a big help for me when I need it.

Thanks alot

LGG

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...