Creating Plug-ins: FAQ

This is a FAQ page about creating plug-ins using C#.
The content of this FAQ is based on the inquiries we have received from our users and the responses we have received from our development team.


About Creating Plug-ins

How do I create a plug-in?

Please refer to the How to Use Plug-ins section.

Can I choose which editor to launch when editing a C# program from the Event Editor?

You can use a different editor by specifying an association for the sln file other than Visual Studio.


Event Related

Is there a method equivalent to the "Display Conversation" or "Display Message" panel?

"Conversation" can be achieved with the following method. The position of the window (top, middle, bottom) changes when the 0's are set to 1, 2, 3, etc.

mapScene.ShowDialogue(msg, 0, MenuControllerBase.WindowTypes.DIALOGUE,
new AbstractRenderObject.GameContent.DialogueCharacterProperty()
new AbstractRenderObject.GameContent.DialogueCharacterProperty(), mapChr.guId);

The DialogueCharacterProperty() parameter can be used to assign a graphic of the speaking cast, but the parameters are generally linked to what can be specified in the panel.

 

"Message" is the following method. As with conversation, the second parameter, 0, specifies the window position.

mapScene.ShowMessage(stringAttr.value, 0, MenuControllerBase.WindowTypes.MESSAGE, mapChr.guId);
 

In addition, the "ticker" will be the following method.

mapScene.ShowTelop(msg, 0, MenuControllerBase.WindowTypes.TELOP, new AbstractRenderObject.GameContent.TelopProperty(), mapChr.guId);

 

ShowDialogue and ShowMessage return an ad hoc id in the return value, so you can use this to execute
mapScene.IsQueuedDialogue(id)
and
mapScene.IsQueuedMessage(id)
to see if the displayed conversation or message is still being displayed (not closed).

Can I close a conversational message or dialog?

This is not possible at the Ver. 1.9 stage.

Which method corresponds to the "Display String as Image on Screen" panel?

You can use
Graphics.DrawString (with borders)
or
Graphics.DrawStringSoloColor (without borders).

At this time (ver. 1.9), we do not release methods for text decoration by formatting.
(If you need formatted text decoration, please wait for the release of SpriteManager.)

Which method corresponds to the "Change Rendering Settings" panel?

Please use the following:

var render = catalog.getItemFromName<Yukar.Common.Rom.RenderSettings>("Rendering Setting Name");
mapScene.mapDrawer.setRenderSettings(render);

Which methods correspond to the "Change Event Motion" and "Change Cast Motion" panels?

Please use one of the following two options.

mapChr.playMotion("MotionName") 
mapScene.hero.playMotion(("MotionName", 0.2f, true, lockMotion))

lockMotion = Whether to prevent disarming by walking, etc. / locked by true, false for no locking.

Which method corresponds to "Apply Blend Shapes to Player"?

To assign a key and apply it, please use the following.

mapScene.hero.getModelInstance().setMorphBlend("KeyName", 0.5f);

To assign a clip and apply it, please use the following.
The parameters are the target, the clip name, the interpolation time, and whether to reset other blendshapes.

ScriptRunner.AddBlendShapeTask(mapScene.hero, "ClipName", 4, false);

Is there a way to obtain the end of the motion?

Please use the sample code by binding it to an event.
MotionUtil.cs

GetMotionLoopCount to obtain the number of motion loops.
In the case of a one-shot, the motion can be considered complete if it is 1.

PlayMotionImmediately starts motion playback without blending.
Use this when the normal motion playback panel is too much of a distraction from the blending.


Resources

Can I toggle stamp subgraphics on and off?

Please use the following.

mapChr.SetSubGraphicOpacity 

Can I toggle stamp subgraphic "Apply Position Only" on/off?

Subgraphic positions are interpreted in mapChr.DisplayObjects as a matrix get function for updating the coordinates of each display object, so they cannot be changed dynamically.
It can be obtained using the following.

  ((Yukar.Common.Resource.GfxResourceBase)mapChr.getGraphic()).SubGraphics[SubgraphicNumber].useTranslateOnly
 

Changes are not recommended, as they will directly rewrite the resource.

Can I specify the relative position XYZ, relative angle XYZ, and scale XYZ of the stamp's subgraphics?

The following pos, rot, and scale manage these information.

((Yukar.Common.Resource.GfxResourceBase)mapChr.getGraphic()).SubGraphics[SubgraphicNumber] 
 

Changes are not recommended, as they will directly rewrite the resource.

Is it possible to toggle on/off the "Use" of the local light linkage in the subgraphic of the stamp?

The following useLight manages the on/off information.

((Yukar.Common.Resource.GfxResourceBase)mapChr.getGraphic()).SubGraphics[SubgraphicNumber] 
 

Changes are not recommended, as they will directly rewrite the resource.

Can I assign a motion for a slice animation and then render it in 2D? How can I display a 2D image as is instead of a billboard display?

This can be done by the following way.

var spIndex = 10; // Sprite Number
           var guid = new Guid("c15f94b6-d4a0-46c4-bc43-2db2f64471ac"); // GUID for slice animation
           var zoom = 100;
           var x = 640;
           var y = 360;
           mapScene.spManager.ShowPicture(spIndex, guid, zoom, zoom,
               Microsoft.Xna.Framework.Color.White, new Yukar.Common.Rom.Script.StringAttr("walk"), x, y);

The GUID of the slice animation can be obtained by right-clicking on the Resources screen > Copy GUID.
Unlike Graphics.drawImage, this can be executed only once and will continue to be displayed thereafter.
It can be moved with "mapScene.spManager.Move" and removed with "mapScene.spManager.Hide".
This is the class used in the "Display Image" event panel.


Map Related

Is there a method, like in the Map Editor, for an object to be bordered when the cursor is hovered over it on a map?

This feature is not available in the engine because it uses an editor-specific rendering path (pickup buffer).

Is there any way to obtain the coordinates specified in the Map Settings palette > Basic tab > "Camera Tracking Range"?

Please use the following.

mapScene.map.mapCameraRange 

if(mapScene.map.mapCameraRange == Rectangle.Empty) is true, it is unset (unrestricted).

Can I change the "Skybox Model" and "Environment Map" in the "Background" section of the Map Settings Palette > Rendering Settings tab?

Set the model GUID in
mapScene.mapDrawer.renderSettings.skyModel
and then after setting the environment map texture GUID in
mapScene.mapDrawer.renderSettings.reflection
execute
mapScene.mapDrawer.setRenderSettings(mapScene.mapDrawer.renderSettings);


Map Battle

Is there a code to change the Category (ally, enemy, both, none) of a cast?

The following code can be used to obtain the cast type of mapChr.

var type = mapChr.rom?.CastType ?? Yukar.Common.Rom.CastType.ALLY;

Refer Collision Detection between Cast Members and Events to make a determination.

Is it possible to change the color and size of the damage indicator displayed during map battles?

It is possible with the following code.

           var viewer = mapScene.fieldBattleViewer;
           viewer.zoomedScale = 2.0f; // Scale at just the right time to come out
           viewer.damageScale = 1.0f; // Eventual scale
           viewer.zoomTime = 0.1f; // Time to reach eventual scale
           viewer.drawTime = 1.0f; // Time until damage disappears
           viewer.damageColor = Microsoft.Xna.Framework.Color.White; // Damage color
           viewer.criticalDamageColor = Microsoft.Xna.Framework.Color.Red; // Critical damage color
           viewer.criticalDamageColor = Microsoft.Xna.Framework.Color.Red; // Critical damage color

You can also create your own damage rendering process using the attached script.
ChangeFieldBattleViewer.cs

Is there a way to generate critical damage during map battles?

Since the judgment is made randomly based on the critical rate, it cannot simply be determined to occur.
It would be a good idea to use state changes to temporarily increase or decrease the critical rate.

Is it possible to specify how long it takes for a damaged cast to change color and then return to normal during map battles?

You can still obtain the information by using the following.

mapChr.rom.InvincibleTime 

However, the change is not recommended because it would directly modify the Database.


Game Definition

Is it possible to obtain/change the ON/OFF of "Basic Operation" and "Tank Controls" in Rules and Operations?

You can switch using the following.

GameMain.instance.data.start.controlMode = Yukar.Common.Rom.GameSettings.ControlMode.NORMAL;
GameMain.instance.data.start.controlMode = Yukar.Common.Rom.GameSettings.ControlMode.RESIDENT_EVIL_LIKE;

Can I obtain/change the "Talking Detection Scale" in Rules and Operations?

The scale itself can be obtained with GameMain.instance.catalog.getGameSettings().TalkColliderScale.
However, changes are not recommended since they directly edit the value of the Game Definition.
It is not recommended to change the values for GameSettings in general, as any changes will be retained even after the test play is completed.

Is it possible to obtain/change the ON/OFF of "Disable Camera Operation" in Rules and Operations?

It can be obtained and changed using the following.

mapScene.mapFixCamera

In addition, individual enable/disable for each camera operation can be obtained and changed by using the following.

owner.data.start.camLockX
owner.data.start.camLockY
owner.data.start.camLockZoom
owner.data.start.camLockReset

Is it possible to turn on/off "Terrains" and "Objects" in Rules & Operations>Camera Distance Auto Adjustment?

You can use the following to obtain the states of each.

catalog.getGameSettings().CameraAvoidObjects
catalog.getGameSettings().CameraAvoidTerrain

However, changes are not recommended since they directly edit the value of the Game Definition.

Is it possible to obtain/change the ON/OFF of "Get Behind Player Automatically" in Rules and Operations?

It is possible to obtain information using the following.
GameMain.instance.catalog.getGameSettings().isTpsMode
However, changes are not recommended since they directly edit the value of the Game Definition.

Is it possible to change the coefficients for movement and camera operation listed in the Game Controller and Mouse section of the Rules and Operations>Key/Button Assignments?

Not possible. Please use the Game Definition settings as they are.

Can I change the "Standard Turning Speed" in Rules & Operations > Movement (Inertia)?

It is possible to obtain the speed using the following.

GameMain.instance.catalog.getGameSettings().DefaultRotateSpeed 

However, changes are not recommended since they directly edit the value of the Game Definition.

Is it possible to change the "Sensitivity" of "Mouse Up/Down" etc. in Game Definition > Rules and Operations > Adjustment Elements for Device Input Values?

Cannot be done.
Instead, create your own process to rotate the camera according to the value of Input.GetAxis() and change the rotation speed accordingly.

How do I display the version, creator, etc. of a project setting in the title?

It is possible to obtain information using the following.

catalog.getGameSettings().meta.buildVer 

The information can then be displayed on the layout by storing it in a variable as shown below.

GameMain.instance.data.system.SetVariable("VariableName", catalog.getGameSettings().meta.buildVer.ToString(), Guid.Empty, false);

However, running C# on the default title screen is not possible as of Ver 1.9.
Therefore, the title screen should be skipped in the Game Definition and used with the in-game title screen in the event.

Is it possible to obtain the ON/OFF judgement for "Auto Run" on the Config screen?

A sample code is attached.
ConfigGetter.cs

It can be obtained by executing the C# method "GetAutoDash" after assigning it.


Is there any way to specify the friction between the "terrain" and the "player" or "cast"?

Please use the following.

MapCharacter.getRigidBody().setFriction(FrictionValue)

However, since MapCharacter controls friction accordingly, it may become invalid at a moment's notice.

Can I change the transparency of the player and cast?

The following method can be used.

mapChr.setOpacityMultiplier(0.5f); // Fully transparent at Transparency 0f

I have tried mapScene.hero.setOpacityMultiplier(Value) to make the player transparent, but it seems to have no effect.

Regarding setOpacityMultiplier, the player is constantly monitoring and applying transparency changes due to state changes, so any changes will be overwritten.
Try setting every frame with AfterDraw().

Is there a code to open/close a free layout with a specified name?

Please use the code below.

// To open
var lyt = catalog.getLayoutProperties().AllLayoutNodes.FirstOrDefault(x => x.Name == "ItemSelect");
if (lyt != null)
{
    GameMain.instance.ShowFreeLayout(lyt.Guid);
}

// To close
var lyt = GameMain.instance.freeLayouts.FirstOrDefault(x => x.LayoutNode.Name == "ItemSelect");
if (lyt != null)
{
    GameMain.instance.HideFreeLayout(lyt.LayoutGuid);
}

Layout

Is it possible to specify the display position of a free layout with a specified name (equivalent to the Special Coordinate Specification Tag "Position[x][y]") or the Special Coordinate Specification Tag "Position[x][y]" from C#?

You can do so as shown below, but since the assignment to positionAnchorTag directly rewrites the Layout Tool's settings (which are then kept as rewritten) and does not take effect until the layout is redisplayed, it is better to use the Position operation.

var lyt = GameMain.instance.freeLayouts.FirstOrDefault(x => x.LayoutNode.Name == "ItemSelect");
if (lyt != null)
{
    var node = lyt.LayoutDrawer.ParseNodes().FirstOrDefault(x => x.MenuItem.name == "Item Details");
 
    node.Position = new Microsoft.Xna.Framework.Vector2(256, 256); // To move directly
 
    node.MenuItem.positionAnchorTag = "Rewrite Special Coordinate Tags";
}

Can I obtain the container management number (index) of a selected container in a layout?

You can access the currently displayed layout by the following ways.

       [BakinFunction(Description = "Obtain the container management number of the selected subcontainer\nSet the action of the subcontainer to "Call Common Event" and call the following method in that event")]
       public int GetIndex()
       {
           // First, obtain the main menu manager
           var lc = mapScene.menuWindow as LayoutMenuController;
           var lm = lc.mainMenu;

           // Track and obtain open layouts derived from the main menu
           // (If it's being called from item select, it should end up in item select.)
           while (lm.NextlayoutManager != null)
               lm = lm.NextlayoutManager;

           // Obtain the currently selected index from the Drawer
           var drawer = lm.LayoutDrawer;
           GameMain.PushLog(DebugDialog.LogEntry.LogType.EVENT, "drawer", drawer.GetSelectIndex().ToString());
           return drawer.GetSelectIndex();
       }

Furthermore, if you wish to force the main menu to close after indexing, you can use the following method.

       [BakinFunction]
       public void CloseMainMenu()
       {
           // First, obtain the main menu manager
           var lc = mapScene.menuWindow as LayoutMenuController;
           var lm = lc.mainMenu;
           lm.HideAll();
       }

Incidentally, to obtain the currently selected index from a free layout, the following is used.

       [BakinFunction]
       public int GetIndexForFreeLayout()
       {
           // First, obtain a free layout manager
           var lm = GameMain.instance.freeLayouts.FirstOrDefault(x => x.LayoutNode.Name == "Name of the Free Layout you want to obtain");
           if (lm == null)
           {
               GameMain.PushLog(DebugDialog.LogEntry.LogType.EVENT, "drawer", "error");
               return -1;
           }

           // Obtain the currently selected index from the Drawer
           var drawer = lm.LayoutDrawer;
           GameMain.PushLog(DebugDialog.LogEntry.LogType.EVENT, "drawer", drawer.GetSelectIndex().ToString());
           return drawer.GetSelectIndex();
       }

Database

Is it possible to retrieve the Management Tags + Notes string entered in the cast database?

This is the case for the field named tags.
You can access it by the following.

catalog.getItemFromName<Yukar.Common.Rom.Cast>("Hero").tags

Is it possible to obtain a list of the skills that the cast learns?

The skills that a cast member learns are in Cast.availableSkills. They can be obtained as follows.

var learnSkills = catalog.getItemFromName<Yukar.Common.Rom.Cast>("Ken").availableSkills;

Skills are stored in the form of GUIDs, so Achievement Level and the skills themselves can be obtained by further querying the Catalog as shown below.

if (learnSkills.Count > 0)
{
    var skill = catalog.getItemFromGuid(learnSkills[0].skill) as Yukar.Common.Rom.NSkill;
    GameMain.PushLog(DebugDialog.LogEntry.LogType.EVENT, "C#", "Achievement Levels : " + learnSkills[0].level + " / Skill Name : " + skill.name);
}

A complete list of all skills can be obtained by the following way.

           var allSkills = catalog.getFilteredItemList<Yukar.Common.Rom.NSkill>().Cast<Yukar.Common.Rom.NSkill>();

Is it possible to obtain Money in Possession or dropped items from an enemy cast member currently in battle by using a Common Event?

You can obtain the EXP of the first monster by the following way.

BattleSequenceManagerBase.Get().EnemyViewDataList[0].monster.exp 

You can also obtain the first drop item of the first monster by the following way.

var guid = BattleSequenceManagerBase.Get().EnemyViewDataList[0].monster.dropItems[0].item;
var name = catalog.getItemFromGuid(guid)?.name;

When actually using the EnemyViewDataList or dropItems, check the upper limit by looking at the Count.


Others

Can the background music be crossfaded?

BGM as a system has only one playback line, so it cannot be done with Audio.PlayBGM.

First, use the following method to start playback with zero volume as a sound effect (the loop setting is still reflected in this case).

           var id = Audio.LoadSound(guid);
           Audio.PlaySound(id, 0, 0, 1);

Then use the following to manipulate the volume every frame to bring the volume of the new BGM closer to 1 while bringing the previous BGM closer to 0.

           Audio.SetSEVolume(id, volume);

Can I switch the battle camera during a battle?

You can change it with the following code.

           GameMain.instance.data.system.currentBattleCameraSet = "CameraSetName";

The camera will be reflected at the time of camera switching, but if you want it to be reflected immediately, you can use the following code.

          mapScene.applyCameraToBattle();

Please note, however, that this is only effective from the C# assigned to the battle event.

If I want to display a specific image, how should I write the parameters for Graphics.DrawImage?

First load the texture using the following code in Start(), for example.

           tex = catalog.getItemFromName<Yukar.Common.Resource.Texture>(""TextureResourceName"");
           Graphics.LoadImage(tex);

Then, use the following at the scene you wish to render (Update, AfterDraw, etc.).

           Graphics.DrawImage(tex, x, y);

After use, release the image used when the event is discarded as shown below.

       public override void Destroy()
       {
           Graphics.UnloadImage(tex);
       }

Is it possible to use the event generation mapChr.CreateEvent()? If possible, how should the parameters of the method be specified?

It is available for use.
It can be used like mapChr.CreateEvent(guid, dir);.
mapChr.getDirectionRad() should be passed for dir if you want it to face the same direction as the source.

guid is the GUID of the cast.
It would be better to use catalog.getItemFromName("name of the cast you want to obtain").guId to find it and pass it.
Once a GUID is created for a cast, it does not change. Therefore, it is faster to write down the GUID by outputting a log, etc. and pass it without looking for it in the catalog by new Guid("GUID string").

What value does the getRelativeParam60FPS function in the GameMain class return?

getRelativeParam60FPS is the elapsed time from the previous frame converted to 60FPS.
In other words, this method returns the time taken for one frame (0.016666666 for 60FPS) multiplied by 60.

 

Within the C# script Update(), frameCount++; will add 1 to frameCount, and assuming no processing slowdown, it will be called 60 times per second, increasing by 60 per second.
However, this method will result in the addition of non-"60" values such as "30" or "120" per second when processing is slow or when the refresh rate is higher than 60.

Therefore, instead of frameCount++, frameCount += getRelativeParam60FPS() can be used to ensure that 60 is added per second even if the time taken per update is not 1/60 second.


Front page   New Page list Search Recent changes   Help   RSS of recent changes