Modding Code Examples: Difference between revisions
imported>AvoidBored No edit summary |
m (1 revision imported) |
(No difference)
|
Latest revision as of 01:27, 14 April 2025
Some useful code snippets for Modders attempting to do common tasks.
Adding a Custom Window[edit]
To add a custom window, you can create a custom class inspired by `WindowFavorites.cs`. Once you have your class ready, you can create a new window like so by copying the Favorites window and removing the attached WindowFavorites component, replacing it with your own.
Let's say we want to add a new window for religions :
<syntaxhighlight lang="csharp" line="1"> var canvasWindows = GameObject.Find("/Canvas/CanvasWindows"); var favWindow = GameObject.Find("/Canvas/CanvasWindows/WindowFavorites");
// clone the favorite window var religionWindow = Instantiate(favWindow); religionWindow.gameObject.name = "WindowReligion"; // remove the WindowFavorites class/component from your new window Destroy(religionWindow.gameObject.GetComponent<WindowFavorites>()); // attach your own WindowReligion class/component here religionWindow.gameObject.AddComponent<WindowReligion>(); // set the screen_id of the window, so you can open it from a button religionWindow.gameObject.GetComponent<ScrollWindow>().screen_id = "religion"; // add the window to the canvas windows group religionWindow.gameObject.transform.parent = canvasWindows.transform; // add the window id to the scrollwindows group, so you can open it from a button ScrollWindow.allWindows.Add("religion", religionWindow.GetComponent<ScrollWindow>());
// change the window title var religionTitle = GameObject.Find("/Canvas/CanvasWindows/WindowReligion/Background/Title"); Destroy(religionTitle.gameObject.GetComponent<LocalizedText>()); religionTitle.gameObject.GetComponent<Text>().text = "Religion"; </syntaxhighlight>
Now you should be able to open this window from anywhere with ScrollWindow.allWindows['religion'].clickShow();
How to load sprites from a picture file[edit]
To import and use your own pictures, you can use ToolBox.loadSprite to load directly and conveniently, or this version with options for resizing and repositioning
<syntaxhighlight lang="csharp" line="1"> Sprite LoadSprite(string path, int resizeX, int resizeY, float offsetx, float offsety) {
if (string.IsNullOrEmpty(path)) return null;
if (!File.Exists(path)) return null;
byte[] data = File.ReadAllBytes(path); Texture2D texture2D = new Texture2D(1, 1); texture2D.anisoLevel = 0; texture2D.LoadImage(data); texture2D.filterMode = FilterMode.Point; TextureScale.Point(texture2D, resizeX, resizeY); return Sprite.Create(texture2D, new Rect(0f, 0f, (float)texture2D.width, (float)texture2D.height), new Vector2(offsetx, offsety), 1f);
} </syntaxhighlight>
After this you can load images using their file path. As an example, you could make a new folder in the game's "WorldBox_Data" folder and name it images, put a picture into that folder and load it like this:
<syntaxhighlight lang="csharp" line="1"> Toolbox.LoadSprite(Directory.GetCurrentDirectory() + "\\WorldBox_Data//images//filename.png", 30, 30, 0.5f, 0f); </syntaxhighlight>
How to add sprites to a window[edit]
To attach custom sprites to a window, we can do so by using the following helper method :
<syntaxhighlight lang="csharp" line="1"> void addSprite(string SpritePath, Vector3 position) {
var gameObject = new GameObject (); var rectTransform = gameObject.AddComponent<RectTransform>(); gameObject.AddComponent<CanvasRenderer>(); // requirement for Image var imageRenderer = gameObject.AddComponent<Image>(); var sprite = Resources.Load<Sprite> (SpritePath); // load the sprite imageRenderer.sprite = sprite; gameObject.transform.SetParent (transformContent); // attach to content window gameObject.transform.localScale = Vector3.one; // scale of the image reset to 1 rectTransform.anchoredPosition3D = position; // pos based on content window rectTransform.sizeDelta = new Vector2(20, 20); // size of the image
} </syntaxhighlight>
And then you can add the 4 sprites from the example image like so :
<syntaxhighlight lang="csharp" line="1"> addSprite("ui/Icons/iconDwarf", new Vector3( 0, -20, 0)); addSprite("ui/Icons/iconHumans", new Vector3( 80, -20, 0)); addSprite("ui/Icons/iconOrcs", new Vector3(-80, -20, 0)); addSprite("ui/Icons/iconElves", new Vector3( 0, -200, 0)); </syntaxhighlight>
The positions in this case are based on the top/middle position ( pivot point is 0.5, 0
). So 0,0
is basically right above the dwarf, just below the Favorites title. In the case of the orc, we want him in the far left corner - that's -80
on the x axis. The Human in the far right corner is 80
on the x axis.
And finally to have the elf in the bottom area, we position him at -200
on the y axis.
You could also play around by changing the pivot points of the container to e.g. 0,0
, and then all items would be added from the top left corner.
How to group a list of objects into a circle[edit]
This example is for moving Actors into position
<syntaxhighlight lang="csharp" line="1"> void moveFormationCircle(Vector3 centerPosition, List<Actor> formation, int radius) {
if (formation == null) return;
float num = 6.28318548f / (float)formation.Count; for (int i = 0; i < formation.Count; i++) { float f = (float)i * num; Vector3 newPosition = centerPosition + new Vector3(Mathf.Cos(f), 0f, Mathf.Sin(f)) * (float)radius; formation[i].cancelEverything(); formation[i].moveTo(MapBox.instance.GetTile((int)newPosition.x, (int)newPosition.y)); }
} </syntaxhighlight>
In this, I use the circle to find tiles for the army to walk towards. Adapting this for another use should only require changing the type used in the list and a way to use the new positions