All of the machine materials were created by me in Gravit, excluding the teleporters
The material for the conveyor belts was created by me in Gravit
All of the icons like the wire, gear, or even the circuit were created by me in Gravit
The 3D models of the wire, gear, circuit, plate, and any other material or craft-able item were designed by me in inventor then exported to blender for Unity to be able to read it.
This does not include the sphere for liquid materials, that's a basic sphere
The 3D model of the machines were not created by me, that's a basic cube
The 3D model of the conveyor belt was created by me
The money in the particle system effect used by the seller was created by me in Gravit, and the 3D model of the money was made by me in Blender
The UI panels were made by me in Gravit. This includes:
The filled button or backdrops with screws in the corners
Example: Many of the component UI's have this as their back panel
The same image without the screws
Example: The buttons in the pause menu
The indented button or backdrops with screws in the corners
The same image without screws
Example: Buttons in the build selections
The font is not mine
The grass (both the flat world and the tall grass) are not mine
The skybox is not mine. It's the default skybox
The red X used on many of the components UI's to close them is not mine
The mode toggles on the top-bar are not mine
The paint roller cursor is not mine
However, I was the one to color it for the different paint options
None of the sounds are mine
I wanted to start a larger Unity project that deals with crafting, databases, and item identification. A lot of factory simulators looked like they had just that.
Since this was a self-made game, I came into this project knowing that the art would not be top-of-the-line quality. As a way to get around this hurdle while still making a nice looking game, I decided to make the graphics and certain aspects with a creative take on them. For instance, the hydraulic press' graphic is a box full of newspapers, the "press".
Welcome! In this video, we will be going over a game that I developed for four to five months, a factory simulator. I found a few versions of factory simulators on the google play store and was inspired to create one myself. At first, I just wanted a bigger project and more practice dealing with databases. I thought all the crafting recipes could be in a database that the code would process. That's all this game was going to be at first. I knew however, that there would have to be more to it than just that because the recipe would still need inputs and a way to move the outputs. So, I knew there would have to be some machines and maybe a conveyor belt to do this.
Firstly, I started to work on the input machine, which can also be called the delivery system. In unity, I gave the machine a prefab of a simple cube. Nothing fancy, the graphics can be introduced later. I added a new script to the prefab and named in Input. I created some variables and basic functions, then went back to the game to test it. Big mistake. There was a swarm of error messages immediately. You can't have a script named Input, that's supposed to be for actual inputs to the computer. So, I had to rename it.
Once it had a name that didn't upset the compiler, I was able to get to work creating a system to create a material and move it out of the input cube thing. I learned about coroutines and spent hours and hours scrolling through forums to try to understand how to use an IEnumerator. In the end, that was pointless for the actual task, but I did learn a lot and it helped me later on. For the time being, I used a coroutine to move the block out of the cube, updating the position every frame.
I needed a way to activate this and control it though, I needed a UI system for the player to interact with. So, I had to do more research about how to add a 2D UI system to a 3D game. Turns out it was really simple, but it took me an entire day. Then I had to understand how to use a button. That took another day. Then I wanted a pretty font, so I spent another few days learning how to use TextMeshPro. I even created another project just to mess around with buttons and TextMeshPro components.
Now that I understood how to use it, I made the UI for the input. I even made a new script just for the UI of the input machine. This is where I had to make one of the big decisions in this game: how do I want to detect that a player clicked on an object? Should the object detect it and tell all the other scripts "Hey, the player clicked me," or should there be an overseeing entity that sees what the player clicked on and tells that specific object "Pst, the player click on you. What's your data?"? I ended up going with the overseeing entity since only one object would be calculating the raycasting math instead of every machine that will be made in the future. I named this overseeing entity God. God would be in charge of creating and managing everything, and also act as a link for machines to reach other machines. When I made God, it didn't stand for anything. Later on when I made something called the Gatekeeper Of Data, my mother asked if that's what God stood for. It wasn't, it just helped carry data between scenes. But that made me want to give God an acronym, so now God stands for Gameplay Operating Diode or Deity.
I gave God an empty gameobject and made it a prefab, attaching the Input UI interface script to God as well so that God had access to it. The plan was to have God detect the user input, determine which type of machine it was and tell the appropriate interface to pop-up, and give said interface the gameobject of the specific machine that was clicked on so that the interface could display specific information about said machine. Basically, God would act as both the initiator and the middleman for the interaction. I used this process for every machine I made in the future.
Next, I needed to turn the basic materials into something that I called "simple materials". I could have named it better, but that's what I went with. Basically, I needed to turn the initial block of material into a wire, gear, plate, or a liquid form of said material. These simple materials, along with the starting materials, would be used in the crafting recipes. I knew all the machines that made those items would be basically the same, they would just produce a different prefab. But, they would detect things the same way and they would use the same function. So, I made one script that was attached to all of them, a Simple Machine script. Simple machines take the initial material and turn it into one of the four simple materials. I had to detect that what collided with the machine was really a material, then take said material and determine WHAT material it was. There were 5 different material types: Copper, iron, aluminum, diamond, and gold.
I made a new script called CreateObject that I attached to God at first, but would later be attached to an empty gameobject called ObjectHandler. This script would be accessed by inputs and simple machines. Simple machines would call a function called IdentifyMaterial and the script would return a material texture. This material texture held a name, which was the same as the material's gameobject. The simple machines would then take this material and send it into CloneObject(Material m, GameObject blueprint, GameObject Creator). Cloneobject would look at the gameobject of whoever's calling the function and take the name of the gameobject and put it into a switch. So, depending on the name of the machine, it would make a certain prefab. All of these prefabs were being stored in a list that God held, by the way.
It took a lot of effort and a lot of debugging, but eventually, I got this working. I didn't even bother making a crafter yet, I wanted to make a conveyor belt next. So I did. And it was really simple.
...
But I gave it rails. That's almost as bad as making a game where the gametiles are made of hexagons. Ignoring the railing issue, I had to deal with making the object move in the right direction after the conveyor belt was rotated. So, I had a big switch statement for the y rotation of the belt to move the material the right way. Little did I know, there's such a thing called transform.forward. The code for this only took about half a day anyway, and I got it working well enough to move on. Then the railings...
Why did I add railings?
A lot of conveyor belts don't even have rails in real life. My father works at a plant, he's seen real conveyor belts, and they don't have rails! But, I went with the rails anyway. I thought they looked nice and added another layer of depth. So, I had to work on the code to update the railings depending on the position and rotation of other conveyor belts around it. If a conveyor belt next to the current belt and was facing directly into the side of said belt, the rail should disappear, or else the objects will look like they went right through a rail. This one took days to get working, and even then there were cases when my algorithm produced unexpected results. But those cases were rare enough that sometimes I couldn't even replicate them.
I was happy with the conveyor belts, so then I moved on to the craf--
Wait a minute, the conveyor belt is moving the materials just fine! Why am I making the machines manually move the materials? Can't I just toss a conveyor belt into them?
This revelation saved me days of extra debugging. All I had to do was make another prefab for the conveyor belt and turn off its renderers. Forget coroutines, we have conveyor belts!
Now, I think I should also say that I am not going over every detail of what I made. Just the major things. Behind the scenes, I am gradually expanding God more and more. He is in charge of making all these objects and changing modes to be able to rotate, delete, and move machines. I also made a bunch more UI interfaces for everything. I just don't have time to go over it all.
Continuing on with the video...
After the conveyor belt thing, I started to working on the crafters. These guys would be what finally used that database. I did some research on how to make crafting recipe databases and followed along with some tutorials until I came out with something that I could use. First, there's the recipe class, which contains the basic structure of each recipe. Then there's the RecipeDatabase, which holds all the recipes and some functions to quickly access specific recipes. With this made, I was able to make the crafter. It was very similar to the simple machine, except at the end, it didn't ask CreateObject to make the new items, it instantiated them itself. The recipe held a prefab index so that the crafter could get the prefab from God.
All the basic machines are done. The game is finished now, right?
Well, can't I add a pause menu? That won't be too hard.
So I got to work on that.
What about audio?
So I got to work on that.
What about a title screen?
So I got to work on that. Wait, there should be audio on the title screen too. Audio manager should be in both scenes. But I only want it instantiated once. This portion of my journey was a huge hurdle. I spent weeks trying to understand how to carry data over from the title screen to the game screen. Not only that, but I added a save system too. So, I had to make sure I loaded the right data to get the right board setup. I watched some more tutorials, did some more research, and after a while, I did it!
The player can now go from the pause screen to the gameplay, then hit pause and go back to the title screen and load a different game.
Or can they?
Load the game for the first time: Success!
Return to title screen from the game to load a new game: Success!
Return again to load another game: Where did the world go? Oh no, the console's filling up, what happened?!
And this happened consistently. I had no idea why. It took days, maybe even a week of scrolling through forums, reading the scripting API's, testing different options to determine where the issue is, and a lot of discussions with my father (who is a computer scientist, and he was stumped too) until I finally figured it out. God was calling its awake function twice. Which means two Gods were being instantiated? I don't fully understand it to this day, but I made God a singleton and managed to resolve the issue. So, back to testing if it works after multiple loads.
Load the game for the first time: Success!
Return to title screen from the game to load a new game: Success!
Return again to load another game: Success!
Return again to load another game: Success!
Return again to load another game: Great, it looks like it's working!
Wait a few seconds: Wait, why aren't the inputs making anything? Nooo, I thought we were free!
This issue turned out to be much simpler than the other. When you hit pause, it sets the game's timescale to 0. Time stops moving. It's never reset if you go back to the title screen. So everything was working, time just wasn't moving forward. So I had God fix that.
Now! We are done, right?
Well, there is still a lot of refining to do and minor bugs to fix, but the core basics of the game are completed and functional.
Welcome! In this video, we will be going over two features in the game: The teleporters and the pooling system. Though those two features may not seem like they are related at all, they are. The system that I created to manage the connections between teleporter inputs and teleporter outputs was the same basic structure I used to manage my pooling system. I made an index searcher.
What that is, is a list, which for the teleporters was called the BuddyIndexSearcher, which holds two more lists, a list of inputs and a list of outputs. Each teleporter had a BuddySystem attached to their teleporter script, which held the details the BuddyManager needed to access. So, if I wanted to find who the first teleporter input was connected to, I would call BuddyIndexSearcher[0 (This signifies it's the list of inputs) ][0 (This is the index in the list of all inputs) ].GetComponent<Teleporter>().BuddySystem.BuddyPairNumber;
If the teleporter had no buddy, first of all it would have a bool that would show this, IHaveABuddy, but also, the BuddyPairNumber would be null. It's a nullable integer. So there's two checks that can be done to see if a teleporter has a buddy and if all of it's information is synced correctly.
This setup I made to be able to manage the connections between teleporters made it really easy to implement an interface the players could use to modify who's connected with who. And I named the functions practically and helpfully so that when I was debugging or if I ever came back to the code, I could easily understand what was happening. For instance, DisconnectFromPreviousBuddy. That does exactly what it says. It's a long name, but it's descriptive, which is more important than having a short and easy name. This method is used in another method, ChangePairingTo(), where a teleporter has to make that not only itself disconnects from its old buddy, but also make sure the old buddy disconnects from it.
Let's watch this in action:
*teleporter interface stuff*
Now onto the Pooling System, which I named ReuseMaterials at first. This was made to increase performance by lowering the amount of calls made to the instantiate and destroy functions, which are known to be bad for performance if repeatedly called. And I was making hundreds of materials. That's a lot of instantiate calls, and a lot of garbage when they were destroyed.
It took me weeks to be able to implement the pooling system with no errors for the first time. But I used the same idea I used for the teleports: Make an index searcher for the active and inactive lists of gameobjects. There were two index searchers this time, one to see if that pool TYPE existed in the inactive and active lists, and another to find a specific object in the two lists. This time, I gave the first index part of the searchers an actual number to be able to read it easier. For example, I could write PoolIndexSearcher[Inactive][Whatever index].gameObject; That made it a lot easier and while debugging, I wasn't sitting there going "Wait, is 1 inactive or active? I don't know anymore."
Most of the time, for the pooling searchers, I did not know the index I needed for the second index number. That had to be calculated, created, or found. This is why there had to be two searchers. Let's say the ObjectHandler asked the pooler to spawn a new wire. First, the pooler has to check the inactive list to see if a pool of wires even exist. That would be the job of the TagIndexSearcher. If it doesn't exist, is it just because we ran out, or does the active list not have one either? If neither think that pool exists, there's a big problem. So then, it's time to check if the big list of all pool names has that pool tag name. If not, the method returns null to avoid major issues.
If the active list has a wire pool and the inactive list does not, then that just means there aren't enough wires in rotation currently. So, a new wire is instantiated. If the inactive list does contain a wire pool, then the PoolIndexSearcher finds the first one and adds it back to the active list to be sent back into rotation.
A similar thing happens for deactivating objects, but in reverse. Though this time, it also checks to see if the object is null, in case the object was somehow destroyed at the same time the method was called.
Here, you can see the rotation that takes place with a basic material as it's being spawned and deactivated repeatedly:
*show it*
That's the main tasks that the pooler does. In this video, you got to see how the teleporter and the pooling system works. So for now...
Welcome!
In this video, we will be going over the process I went through to refine the game and add the final touches. Firstly, I needed to improve the graphics. So far, the graphics were simple because my focus was on getting the game to work. So, I found a site to be able to create vector art, as I was more familiar and comfortable with vector art than free form. The first component's image that I update was the input, and to make sure that the player would understand that it was supposed to represent something being delivered to them, I took inspiration from Amazon. Then I made the wire drawer. I had no idea what that looked like, and when I looked up "Wire Drawer" online, I got drawers made out of wire. So I made it look like a dresser. Next was the hydraulic press. Again, I didn't know what that looked like and looked up "press". I got the news press. So, I made a box containing the newest releases of a news article I made up. Here you can read it if you'd like. The gear cutter wasn't modeled after anything, it was just a design I came up with to look somewhat like a machine. And the furnace I wanted to have a big, glass side to see the fire inside. And I really liked it.
That gave me the idea of lighting. Imagine if the furnace glowed. Imagine if everything glowed. That would look so cool. So I did some research to figure out how to do it, and learned how emission works in unity. Like an Exit sign, it does not affect objects around it, but it does glow in the dark. That was cool and all, but I wanted a real glow. So I did more research. Eventually, I got everything looking really nice.
However, when I looked at the profiler, I could see that the CPU and GPU were not taking it very well. There were so many objects on screen that were receiving so many different lights. My first idea was to have the conveyor belts have a limit as to how many items can be on them at once. If it exceeded that limit, an error would show up which the player could see and the belt would start deleting objects.
This helped performance a ton.
Still, the lights were causing issues, so I deciding to drop the idea. Instead, I gave only a few objects lights. The furnace kept a light and I made a lamp that had a light. It was sized differently that other components to add some more depth and detail to the game. I made a few more components have more depth as well by learning about and implementing normal maps and height maps.
I also gave the seller a light, but not just any light. A light when something enters its trigger zone. And I wanted money to sort of fly out, like an animation. An animation was unreasonable though. I did some research and learned about particle systems. So, I added one to the seller to have a short burst of money, which glowed, to show the player that the seller is actually selling the item.
After that, I started working on solving some minor bugs and issues, mostly with the splitters and selectors. When I got those working, I played around with them a bit and eventually decided that I wanted to be able to customize the conveyor belts to be able to organize the flow of materials better. So, I added that.
There were a lot more features and small touch ups I made to the game, but not everything can be mentioned. In this video, I went through some of the major things I focused on during the refining stages. So for now,
Goodbye.
Welcome!
In this video we will be going over the different tags that are used in the code and throughout the game.
The first tag we will be going over is the InputObj tag. This tag signifies if a component is an input and it helps speed up the looping process that occurs when trying to find a specific type of machine or component.
The second tag we will be going over is the Machine tag. It is used on every simple machine which includes a wire drawer, a gear cutter, a hydraulic press and a furnace. These machines only produce simple materials and they have the same interface with a different name at the top, so this tag is used to help determine if the interface needs to be brought up when it is clicked on.
The SimpleMaterial tag was created to show the difference between this type of material and that type of material. A wire is a simple material (this is a simple material, that’s a material). This helps many components and machines determine whether or not whatever collided with them is a resource they can use to create their next output. For instance a simple machine uses .CompareTag(“Material”) to see if it can create a simple material out of the input.
The Floor tag is used on blue floors and different floor levels. It is also used on the top of every miscellaneous building materials such as a lamp, wall, floor, or grass. These blocks are not cubes. This block right here is actually six planes put together to look like a block. This plane has a tag of a Floor. The other planes on the sides have a tag of a Wall. This allows the code to know whether or not a player is clicking on the top of the wall or the side of the wall. A wall cannot be attached to the side of another wall. They must be built upwards. They must be built on floors. So this tag helps with the rules used to build and create components.
The next tag is the ConveyorBelt tag. This tag is used mainly inside the conveyor belt. When a conveyor belt is created it needs to set up its rails. So it calls physics.overlapBox and checks if any of the game objects around it have the tag ConveyorBelt. It only cares about game objects that are conveyor belts. So this tag helps speed up the process and reduce the amount of time it takes for a conveyor belt to actually be made or updated.
The Crafter tag is very similar to the InputObj and Machine tag. It is simply used to denote the difference between itself and other types of components.
The Baby tag is used in the simple machine. When a material enters the simple machine it has a tag material. The simple machine uses that material as a blueprint to make its next object. The simple machine deletes or deactivates any other object that touches it. This includes other simple materials. So when a new simple material is created it is immediately destroyed because it entered the trigger zone of the simple machine at the same time it was created. The baby tag is used to bypass that initial frame that the material is created in to let it have a chance of exiting the machine.
The CraftedObject tag is very similar to a simple material. It is just another type of item that is created from a crafter.
The Seller tag is used to signify the difference between a seller and other types of machines and components. At first when I hit the rotate button the seller would not turn green. It had a separate type of material and build compared to everything else. So when the ComponentHandler went through its list of every component it would check if that component had the tag seller, and if it did it would skip over it to avoid creating any errors.
The next two tags have been depreciated from being used in the code. It was going to be used to help with creating the rails on the conveyor belt but I found a more efficient and elegant solution to the issue so those tags are not used anymore; the detectors and the rails.
DarkMatter is all the black stuff around the floor which is land you can buy in the future. It is used to signify the difference between itself and the normal floor.
The World tag is used to signify what game objects are part of the world. This includes the main grass plane and the grass objects on top of the plane.
The Wall tag we already went over when I went over the Floor tag. It is used on the side of all the miscellaneous building materials such as the walls, lamps, new floors, and grass. It helps the code know whether or not the player clicked on the side or the top of a miscellaneous building material.
And the Teleporter tag is used just like the InputObj tag, the Machine tag, and the Crafter tag. It just signifies it’s difference compared to every other component.
Next, we will be going over the layers. The first seven layers are made by Unity by default. You cannot edit them. The eighth layer is used for all objects that are on a floor level that is disabled. This means that the player can click right through them as if they didn’t exist. For example there is no way for me to click the Wire Drawer that is behind the furnace where my mouse is right now. I would just get the furnace. Now I can click on the Wire Drawer or that input because the furnace is on the eighth layer and is ignoring the raycasting math. The ninth layer I created while following a tutorial on PostProcessing and graphics improvement. This layer contains the post processing game object only.
In this video we went over the tags and layers to help you understand the use and the code.
So for now, bye.
Make Input Create objects and push them out
Make simple machines detect items coming in
Check if it’s usable
Delete it
Create the new ‘Modified’ gameObject
Make ConveyorBelts move objects
Tooltips
Get Queue shown on interface
Manage Queue size and stacking capabilities
Update Simple machine interface to be like Crafting interface
Add Splitter Conveyor Belts
UI
Selection Conveyor Belts
UI
Sounds
Background
Title Screen
Conveyor Belt constant loop quiet
Placing sound
Deleting sound
Selecting sound
Button click sound
Mechanical Arm
UI
Expand Craftables
Assets
Recipes
Beta testing
Tutorial
Add PreDelete() to all types
Add PostCreation() to all types
Finalize Pause Screen and add in promised functionalities
Money animation toggle
Mouse Sensitivity
Get the mouse control of the camera fixed
(Dragging is messed up after a rotation)
Brightness?
Finalize Title screen
Instructions
Settings
About
ConveyorBelt Rails still need to be fixed
Build menu not registered as an interface
Destroy can have a delay
Destroy(gameObject, Delay);
Material management
Save and load system
Pausing the game to return to the main menu and load or start a new game would break almost everything
Performance loss w/ constant instantiation and destruction of game-objects
Hopping between "managers" of specific fields such as the "Object Handler," "Component Handler," and "Ground Handler" to get information about everything going on
Deciding how to hide the UI interfaces of each component
Designing the UI in a player-friendly and understandable way
Designing the program for scalability and the ability to add more later
Understanding my own tags and naming systems
"DontDestroyOnLoad();" for certain managers such as the SceneManager, the AudioManager, and the GatekeeperOfData to keep one instance of each no matter what scene is currently active, but making sure to keep the same one and not another copy of said manager
Understanding Singletons and Instances
Making the conveyor belt railings line up nicely and automatically update when a component is place beside it
A lot of C# and Unity API
Hierarchy management
UI in Unity and how to handle it
A lot of the features in Unity
Lighting
Game-objects
The canvas
The physics engine
Ridgidbodies
Colliders
Particle systems
Singletons and Instances
Minor code changes to optimize performance
Instead of:
for(int i = 0; i < A_List.length; i++){ ... }
Do this instead:
int A_ListCount = A_List.length; //Temporary variable
for(int i = 0; i < A_ListCount; i++){ ... }
so that the computer only has to perform A_List.length once
Save and load systems
GitHub
Project management practices
Consistent naming
Good file management
Clean out unnecessary files every so often
Invoke
Coroutines
LINQ
Not good for performance, but sometimes needed
In Unity and many other programming platforms, it's a good practice to split up your code into multiple files. Therefore, sharing the code takes more effort, seeing as there are multiple files. So, this will be split up into the game-play managers and miscellaneous classes. I will only be including the major scripts.
G.O.D. is the over-looker for the game-play scene, detecting user inputs and telling whoever the user clicked on to start up their interfaces. G.O.D. also acts as a source that everything has access to and that components can use to retrieve information about the world, such as the money variable or access to the AudioManager.
1492 lines
Click to expandusing System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Globalization;
using System.Linq;
[RequireComponent(typeof(Teleport))]
[RequireComponent(typeof(SimpleProducerInterface))]
[RequireComponent(typeof(ModeToggles))]
[RequireComponent(typeof(InputBlock))]
[RequireComponent(typeof(CraftingInterface))]
[RequireComponent(typeof(RecipeDatabase))]
[RequireComponent(typeof(ConveyorInterface))]
public class God : MonoBehaviour
{
/*
* Gameplay
* Operating
* Diode
*/
[Range(1f, 6f)]
public float RotationSensitivity = 3f;
[Range(0.01f, 1f)]
public float MoveSensitivity = 0.15f;
[HideInInspector]
public bool Paused = false;
[HideInInspector]
public Texture NullImagePic;
[HideInInspector]
public Transform MouseOver;
private GameObject Save;
[HideInInspector]
public GameObject InputInterface;
[HideInInspector]
public GameObject MachineInterface;
[HideInInspector]
public GameObject BuildSelection;
[HideInInspector]
public GameObject CrafterInterface;
[HideInInspector]
public GameObject CrafterSelection;
[HideInInspector]
public GameObject PauseMenu;
[HideInInspector]
public GameObject Topbar;
[HideInInspector]
public GameObject ConveyorInterface;
[HideInInspector]
public ConveyorInterface ConveyorInterfaceF;
[HideInInspector]
public GameObject SelectorInterface;
[HideInInspector]
public GameObject BuyingLandPrice;
[HideInInspector]
public GameObject LeftSidebar;
[HideInInspector]
public SelectorInterface SelectorInterfaceF;
[HideInInspector]
public InputBlock InputBlock;
[HideInInspector]
public SimpleProducerInterface Machine_Interface;
[HideInInspector]
public CraftingInterface CraftingInterface;
private ModeToggles modeToggles;
[Header("Materials")]
public List<Material> Mats = new List<Material>();
public GameObject Liquid;
public GameObject Plate;
public GameObject Wire;
public GameObject Gear;
[HideInInspector]
public GameObject ObjectHandler;
[HideInInspector]
public GameObject ComponentHandler;
[Header("Prefabs")]
public List<GameObject> Prefabs = new List<GameObject>();
public List<GameObject> RailPrefabs = new List<GameObject>();
public List<Texture> MaterialPics = new List<Texture>();
public Dictionary<string, Color> MatColors;
public Dictionary<string, Texture> Icons;
public Dictionary<string, Texture> ProductIcons;
[HideInInspector]
public GameObject Floor;
[HideInInspector]
public Material Normal;
[HideInInspector]
public Material MoveMode;
public Material NormalMat;
public Material RotateMode;
private bool HaveMovingObjectSelected = false;
private GameObject NewObject;
private bool Creating = false;
private bool WaitForIt = false;
public bool InterfaceOpen = false;
private bool SelectingMaterial = false;
private bool SelectingCraft = false;
[HideInInspector]
public int Money = 175;
[HideInInspector]
public TextMeshProUGUI MONEY;
private int BuyingPrice = 0;
[HideInInspector]
public AudioManager AudioManager;
private bool buildbool = false;
private bool BuyingLandNow = false;
[HideInInspector]
public GameObject GroundHandler;
private Material Buying;
private Material TheVoid;
private Material BoughtLand;
private GameObject Stats;
[HideInInspector]
public bool RunningThroughTutorial = false;
private GameObject TutorialMan;
private GameObject HelpMenu;
[HideInInspector]
public BuddyManager BuddyManager = new BuddyManager();
[HideInInspector]
public GameObject TeleportI;
public GameObject PaintSelection;
[HideInInspector]
public bool TutorialPossible = false;
private Color[] StructureColors = new Color[4]
{
new Color(0.383f, 0.7531f, 1),
new Color(0.035f, 1, 0.035f),
new Color(1, 1, 1),
new Color(1, 0, 0)
};
private Camera MainCamera;
private Transform TheCanvas;
private CreateObject createObject;
public ComponentHandler componentHandler;
#region Singleton
public static God Instance;
public void Awake()
{
Instance = this;
#endregion
MainCamera = Camera.main;
TheCanvas = GameObject.Find("Canvas").transform;
Debug.Log("God woke up");
BuddyManager.Begin();
Normal = Resources.Load("Materials/Floor/Floor") as Material;
MoveMode = Resources.Load("Materials/Floor/FloorMoveMode") as Material;
Buying = Resources.Load("Materials/Floor/BuyLand") as Material;
TheVoid = Resources.Load("Materials/Floor/UnclaimedLand") as Material;
BoughtLand = Resources.Load("Materials/Floor/BoughtLand") as Material;
GroundHandler = GameObject.Find("GroundHandler");
GroundHandler.GetComponent<InfiniteLand>().God = this;
NullImagePic = Resources.Load("Textures/NullImage") as Texture;
ConveyorInterfaceF = transform.GetComponent<ConveyorInterface>();
SelectorInterfaceF = transform.GetComponent<SelectorInterface>();
MatColors = new Dictionary<string, Color>()
{
{"Copper", new Color(0.468f, 0.2768f, 0.1095f)},
{"Gold", new Color(0.645f, 0.645f, 0)},
{"Diamond", new Color(0, 0.5267f, 0.645f)},
{"Iron", new Color(0.1665f, 0.1769f, 0.1792f)},
{"Aluminum", new Color(0.6226f, 0.6226f, 0.6226f)}
};
Icons = new Dictionary<string, Texture>()
{
{"Wire", Resources.Load("Textures/Icons/WireIcon") as Texture},
{"Gear", Resources.Load("Textures/Icons/GearIcon") as Texture},
{"Plate", Resources.Load("Textures/Icons/PlateIcon") as Texture},
{"Liquid", Resources.Load("Textures/Icons/LiquidIcon") as Texture},
{"Basic", Resources.Load("Textures/Icons/RegularMaterial") as Texture}
};
ProductIcons = new Dictionary<string, Texture>()
{
{"Circuit", Resources.Load("Textures/Icons/CircuitIcon") as Texture},
{"Engine", Resources.Load("Textures/Icons/EngineIcon") as Texture},
{"Heater Plate", Resources.Load("Textures/Icons/Heater PlateIcon") as Texture},
{"Cooler Plate", Resources.Load("Textures/Icons/Cooler PlateIcon") as Texture},
{"Light Bulb", Resources.Load("Textures/Icons/Light BulbIcon") as Texture}
};
InputBlock = transform.GetComponent<InputBlock>();
modeToggles = transform.GetComponent<ModeToggles>();
Machine_Interface = transform.GetComponent<SimpleProducerInterface>();
CraftingInterface = transform.GetComponent<CraftingInterface>();
Floor = GameObject.Find("Floor");
ComponentHandler = GameObject.Find("ComponentHandler");
componentHandler = ComponentHandler.GetComponent<ComponentHandler>();
ObjectHandler = GameObject.Find("ObjectHandler");
createObject = ObjectHandler.GetComponent<CreateObject>();
TutorialMan = GameObject.Find("Tutorial Man");
Prefabs.Add(Resources.Load("Prefabs/Interfaces/Help Menu") as GameObject);
{
Stats = Instantiate(Prefabs[30]);
Stats.transform.SetParent(TheCanvas);
CenterRectTransform(Stats.GetComponent<RectTransform>());
Stats.name = Prefabs[30].name;
PauseMenu = Instantiate(Prefabs[18]);
PauseMenu.transform.SetParent(TheCanvas);
CenterRectTransform(PauseMenu.GetComponent<RectTransform>());
PauseMenu.name = Prefabs[18].name;
ConveyorInterface = Instantiate(Prefabs[19]);
ConveyorInterface.transform.SetParent(TheCanvas);
CenterRectTransform(ConveyorInterface.GetComponent<RectTransform>());
ConveyorInterface.name = Prefabs[19].name;
InputInterface = Instantiate(Prefabs[5]);
InputInterface.transform.SetParent(TheCanvas);
CenterRectTransform(InputInterface.GetComponent<RectTransform>());
InputInterface.name = Prefabs[5].name;
CrafterInterface = Instantiate(Prefabs[10]);
CrafterInterface.transform.SetParent(TheCanvas);
CenterRectTransform(CrafterInterface.GetComponent<RectTransform>());
CrafterInterface.name = Prefabs[10].name;
CrafterSelection = Instantiate(Prefabs[11]);
CrafterSelection.transform.SetParent(TheCanvas);
CenterRectTransform(CrafterSelection.GetComponent<RectTransform>());
CrafterSelection.name = Prefabs[11].name;
MachineInterface = Instantiate(Prefabs[7]);
MachineInterface.transform.SetParent(TheCanvas);
CenterRectTransform(MachineInterface.GetComponent<RectTransform>());
MachineInterface.name = Prefabs[7].name;
Topbar = Instantiate(Prefabs[6]);
Topbar.transform.SetParent(TheCanvas);
CenterRectTransform(Topbar.GetComponent<RectTransform>());
Topbar.name = Prefabs[6].name;
SelectorInterface = Instantiate(Prefabs[22]);
SelectorInterface.transform.SetParent(TheCanvas);
CenterRectTransform(SelectorInterface.GetComponent<RectTransform>());
SelectorInterface.name = Prefabs[22].name;
BuildSelection = Instantiate(Prefabs[8]);
BuildSelection.transform.SetParent(TheCanvas);
CenterRectTransform(BuildSelection.GetComponent<RectTransform>());
BuildSelection.name = Prefabs[8].name;
BuyingLandPrice = Instantiate(Prefabs[28]);
BuyingLandPrice.transform.SetParent(TheCanvas);
CenterRectTransform(BuyingLandPrice.GetComponent<RectTransform>());
BuyingLandPrice.name = Prefabs[28].name;
LeftSidebar = Instantiate(Prefabs[29]);
LeftSidebar.transform.SetParent(TheCanvas);
CenterRectTransform(LeftSidebar.GetComponent<RectTransform>());
LeftSidebar.name = Prefabs[29].name;
HelpMenu = Instantiate(Prefabs[Prefabs.Count - 1]);
HelpMenu.transform.SetParent(TheCanvas);
CenterRectTransform(HelpMenu.GetComponent<RectTransform>());
HelpMenu.name = Prefabs[Prefabs.Count - 1].name;
TeleportI = Instantiate(Prefabs[33]);
TeleportI.transform.SetParent(TheCanvas);
CenterRectTransform(TeleportI.GetComponent<RectTransform>());
TeleportI.name = Prefabs[33].name;
PaintSelection = Instantiate(Prefabs[32]);
PaintSelection.transform.SetParent(TheCanvas);
CenterRectTransform(PaintSelection.GetComponent<RectTransform>());
PaintSelection.name = Prefabs[32].name;
}
CrafterInterface.transform.GetChild(1).GetChild(4).GetComponentInChildren<Button>().
onClick.AddListener(CraftingInterface.ClearTheLists);
InputInterface.transform.GetChild(3).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
InputInterface.transform.GetChild(2).GetChild(0).GetComponent<Button>().onClick.AddListener(InputBlock.IncreaseAmount);
InputInterface.transform.GetChild(2).GetChild(1).GetComponent<Button>().onClick.AddListener(InputBlock.DecreaseAmount);
InputInterface.transform.GetChild(1).GetComponent<Button>().onClick.AddListener(MaterialInterface);
Transform i = GetChild(InputInterface.transform, 4, 0, 0);
i.GetChild(0).GetComponent<Button>().onClick.AddListener(ChangeMaterial);
i.GetChild(1).GetComponent<Button>().onClick.AddListener(ChangeMaterial);
i.GetChild(2).GetComponent<Button>().onClick.AddListener(ChangeMaterial);
i.GetChild(3).GetComponent<Button>().onClick.AddListener(ChangeMaterial);
i.GetChild(4).GetComponent<Button>().onClick.AddListener(ChangeMaterial);
Topbar.GetComponent<Topbar>().Setup(this);
MONEY = Topbar.transform.GetChild(1).GetChild(1).GetComponent<TextMeshProUGUI>();
Transform b = GetChild(BuildSelection.transform, 0, 0, 0);
b.GetChild(0) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(21, 10); });
b.GetChild(1) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(0, 10); });
b.GetChild(2) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(1, 20); });
b.GetChild(3) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(2, 20); });
b.GetChild(4) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(9, 20); });
b.GetChild(5) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(4, 20); });
b.GetChild(6) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(13, 30); });
b.GetChild(7) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(3, 5); });
b.GetChild(8) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(20, 60); });
b.GetChild(9) .GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(24, 60); });
b.GetChild(10).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(23, 60); });
b.GetChild(11).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(23, -1000); });
b.GetChild(12).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(23, -1001); });
b = LeftSidebar.transform.GetChild(0).GetChild(0).GetChild(0);
b.GetChild(0).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(0, -960); });
b.GetChild(1).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(21, -634); });
b.GetChild(2).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(31, 100); });
b.GetChild(3).GetComponent<Button>().onClick.AddListener(delegate { CreateComponent(31, -4); });
MachineInterface.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
CrafterInterface.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
TeleportI.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
CrafterInterface.transform.GetChild(1).GetChild(2).GetChild(0).GetComponent<Button>().onClick.AddListener(CraftInterface);
ConveyorInterface.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
SelectorInterface.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(PleaseExitTheInterface);
int temp = CrafterSelection.transform.GetChild(0).childCount;
for (int c = 0; c < temp; c++)
{
CrafterSelection.transform.GetChild(0).GetChild(c).GetComponent<Button>().onClick.AddListener(RecipeSelected);
}
GetChild(i, 0).GetComponentInChildren<RawImage>().texture = Icons.ElementAt(4).Value;
GetChild(i, 1).GetComponentInChildren<RawImage>().texture = Icons.ElementAt(4).Value;
GetChild(i, 2).GetComponentInChildren<RawImage>().texture = Icons.ElementAt(4).Value;
GetChild(i, 3).GetComponentInChildren<RawImage>().texture = Icons.ElementAt(4).Value;
GetChild(i, 4).GetComponentInChildren<RawImage>().texture = Icons.ElementAt(4).Value;
GetChild(i, 0).GetComponentInChildren<RawImage>().color = MatColors.ElementAt(3).Value;
GetChild(i, 1).GetComponentInChildren<RawImage>().color = MatColors.ElementAt(0).Value;
GetChild(i, 2).GetComponentInChildren<RawImage>().color = MatColors.ElementAt(1).Value;
GetChild(i, 3).GetComponentInChildren<RawImage>().color = MatColors.ElementAt(2).Value;
GetChild(i, 4).GetComponentInChildren<RawImage>().color = MatColors.ElementAt(4).Value;
InputInterface.transform.GetChild(4).localScale = Vector3.zero;
PauseMenu.transform.GetChild(3).localScale = Vector3.zero;
PauseMenu.transform.GetChild(4).localScale = Vector3.zero;
PauseMenu.transform.GetChild(5).localScale = Vector3.zero;
PauseMenu.transform.GetChild(1).GetChild(1).localScale = Vector3.zero;
PauseMenu.transform.GetChild(1).GetChild(2).localScale = Vector3.zero;
Topbar.SetActive(true);
GetComponent<Teleport>().Begin();
DealWithDataAndLoad();
}
private void OnDestroy()
{
Debug.Log("God was destroyed");
}
public void DealWithDataAndLoad()
{
AudioManager = FindObjectOfType<AudioManager>();
if (FindObjectOfType<TitleScreen>() != null)
{
TitleScreen t = FindObjectOfType<TitleScreen>();
TutorialPossible = t.TutorialPossible;
t.RetrieveData(this);
MoveSensitivity = t.MoveSensitivity;
GetPrefab("Seller").GetComponent<Seller>().AnimationAllowed = t.MoneyAnimation;
}
else
{
DefaultData();
}
if (GameObject.Find("SceneManager") != null)
{
GetChild(PauseMenu.transform, 1, 0, 1, 2).GetComponent<Button>().onClick.AddListener(FindObjectOfType<StartButton>().MainMenu);
}
}
Transform GetChild(Transform t, int a, int b, int c, int d) => t.GetChild(a).GetChild(b).GetChild(c).GetChild(d);
Transform GetChild(Transform t, int a, int b, int c) => t.GetChild(a).GetChild(b).GetChild(c);
Transform GetChild(Transform t, int a, int b) => t.GetChild(a).GetChild(b);
Transform GetChild(Transform t, int a) => t.GetChild(a);
public void ResetPrefabValues()
{
GetPrefab("Hydralic Press").GetComponent<MachineData>().Speed = 5;
GetPrefab("Gear Cutter").GetComponent<MachineData>().Speed = 5;
GetPrefab("Wire Drawer").GetComponent<MachineData>().Speed = 5;
GetPrefab("Crafter").GetComponent<MachineData>().Speed = 5;
GetPrefab("Furnace").GetComponent<MachineData>().Speed = 5;
GetPrefab("input").GetComponent<InputBlockData>().ProducingSpeed = 5;
GetPrefab("Hydralic Press").GetComponent<MachineData>().Cost = 5;
GetPrefab("Gear Cutter").GetComponent<MachineData>().Cost = 5;
GetPrefab("Wire Drawer").GetComponent<MachineData>().Cost = 5;
GetPrefab("Crafter").GetComponent<MachineData>().Cost = 5;
GetPrefab("Furnace").GetComponent<MachineData>().Cost = 5;
}
public void UpdatePrefabValues(PlayerData Data)
{
GetPrefab("Hydralic Press").GetComponent<MachineData>().Speed = Data.ComponentSpeed[5];
GetPrefab("Gear Cutter").GetComponent<MachineData>().Speed = Data.ComponentSpeed[4];
GetPrefab("Wire Drawer").GetComponent<MachineData>().Speed = Data.ComponentSpeed[2];
GetPrefab("Crafter").GetComponent<MachineData>().Speed = Data.ComponentSpeed[1];
GetPrefab("Furnace").GetComponent<MachineData>().Speed = Data.ComponentSpeed[3];
GetPrefab("input").GetComponent<InputBlockData>().ProducingSpeed = Data.ComponentSpeed[0];
GetPrefab("Hydralic Press").GetComponent<MachineData>().Cost = Data.ComponentCost[5];
GetPrefab("Gear Cutter").GetComponent<MachineData>().Cost = Data.ComponentCost[4];
GetPrefab("Wire Drawer").GetComponent<MachineData>().Cost = Data.ComponentCost[2];
GetPrefab("Crafter").GetComponent<MachineData>().Cost = Data.ComponentCost[1];
GetPrefab("Furnace").GetComponent<MachineData>().Cost = Data.ComponentCost[3];
GetPrefab("input").GetComponent<InputBlockData>().AmountRange[1] = Data.ComponentCost[0];
}
public void UpdateData()
{
PlayerData Data = GameObject.Find("Gatekeeper of Data").GetComponent<TitleScreen>().Data;
UpdatePrefabValues(Data);
Money = Data.Money;
UpdateMoney();
createObject.Awake2();
componentHandler.LoadComponents(Data, this);
GroundHandler.GetComponent<InfiniteLand>().LoadLand(Data, this);
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().LoadStuff(Data, this);
MoveOrCreate(GroundHandler);
if (TutorialPossible)
{
TutorialMan.GetComponent<TutorialMan>().CallTutorial(this);
}
}
public void DefaultData()
{
//Money = 275;
Money = 1000;
ResetPrefabValues();
UpdateMoney();
GroundHandler.GetComponent<InfiniteLand>().DefaultLandCreation();
if (TutorialPossible)
{
TutorialMan.GetComponent<TutorialMan>().CallTutorial(this);
}
}
private void RecipeSelected()
{
CraftingInterface.ChangeCraft(EventSystem.current.currentSelectedGameObject);
}
private void LeftSelectionScrollbarFix() => LeftSidebar.transform.GetChild(0).GetChild(1).GetComponent<Scrollbar>().value = 1;
private void BuyingLand()
{
BuyingLandNow = !BuyingLandNow;
if (BuyingLandNow)
{
GroundHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.CompareTag("DarkMatter")).ForEach(x => x.GetComponent<Renderer>().material = Buying);
GroundHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.CompareTag("Floor") && !x.IsChildOf(GroundHandler.transform.GetChild(0)))
.ForEach(x => x.GetComponent<Renderer>().material = BoughtLand);
BuyingLandPrice.transform.localScale = new Vector3(1, 1, 1);
BuyingLandPrice.transform.GetChild(1).GetComponent<TextMeshProUGUI>().text =
"$" + GroundHandler.GetComponent<InfiniteLand>().Price.ToString();
}
else
{
GroundHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.CompareTag("DarkMatter")).ForEach(x => x.GetComponent<Renderer>().material = TheVoid);
GroundHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.CompareTag("Floor") && !x.IsChildOf(GroundHandler.transform.GetChild(0)))
.ForEach(x => x.GetComponent<Renderer>().material = Normal);
BuyingLandPrice.transform.localScale = new Vector3(0, 0, 0);
}
}
private void CraftInterface()
{
SelectingCraft = !SelectingCraft;
if (SelectingCraft)
{
CrafterSelection.SetActive(true);
}
else
{
CrafterSelection.SetActive(false);
}
}
private void ChangeMaterial()
{
InputBlock.ChangeMaterial(EventSystem.current.currentSelectedGameObject);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Picked Material");
}
}
private void MaterialInterface()
{
SelectingMaterial = !SelectingMaterial;
if (SelectingMaterial)
{
InputInterface.transform.GetChild(4).localScale = new Vector3(1, 1, 1);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Select Material");
}
}
else
{
InputInterface.transform.GetChild(4).localScale = new Vector3(0, 0, 0);
}
}
public void UpdateMoney() => MONEY.text = NumberFormatInfo.CurrentInfo.CurrencySymbol + ReducedMoneyAmount(Money);
public void CenterRectTransform(RectTransform rt)
{
rt.offsetMin = new Vector2(0, 0);
rt.offsetMax = new Vector2(0, 0);
rt.transform.localScale = Vector3.one;
rt.gameObject.SetActive(false);
}
public void RightSide()
{
modeToggles.BuildMode();
componentHandler.Mode("Normal");
if (!buildbool || LeftSidebar.transform.localScale == Vector3.one)
{
BuildSelection.SetActive(true);
Invoke("BuildSelectionScrollbarFix", 0.025f);
buildbool = true;
}
else
{
BuildSelection.SetActive(false);
Creating = false;
buildbool = false;
BuyingPrice = 0;
}
MoveOrCreate(GroundHandler);
}
public void SidebarFunction(GameObject Side, GameObject OtherSide)
{
modeToggles.BuildMode();
if (!buildbool || OtherSide.activeSelf)
{
Side.SetActive(true);
OtherSide.SetActive(false);
Invoke(Side.name + "ScrollbarFix", 0.025f);
buildbool = true;
}
else
{
Side.SetActive(false);
Creating = false;
buildbool = false;
BuyingPrice = 0;
}
if(Side == LeftSidebar)
{
Topbar.GetComponent<Topbar>().ToggleButton("Left Build", buildbool);
}
else
{
Topbar.GetComponent<Topbar>().ToggleButton("Right Build", buildbool);
}
MoveOrCreate(GroundHandler);
}
public void RightSelectionScrollbarFix() => BuildSelection.transform.GetChild(0).GetChild(1).GetComponent<Scrollbar>().value = 1;
public void MoveOrCreate(GameObject GroundHandle, bool move = false)
{
if (move || Creating)
{
if (BuyingPrice != -634)
{
GroundHandle.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor")
.ForEach(x => x.GetComponent<Renderer>().material.color = StructureColors[1]); ;
}
else
{
GroundHandle.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor")
.ForEach(x => x.GetComponent<Renderer>().material.color = StructureColors[0]);
}
if (GroundHandle.transform.GetChild(0).childCount > 0)
{
if (BuyingPrice == -634 || BuyingPrice == -4)
{
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor" && x.GetComponent<Renderer>().enabled).ForEach(x =>
{
SetMainColorOf(x, StructureColors[1]);
SetTopColorOf(x, StructureColors[0]);
});
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Wall" && x.GetComponent<Renderer>().enabled)
.ForEach(x =>
{
SetMainColorOf(x, StructureColors[1]);
TurnOffTopOf(x);
});
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Lamp" && x.GetComponent<Renderer>().enabled)
.ForEach(x => {
SetMainColorOf(x, StructureColors[2]);
SetTopColorOf(x, StructureColors[1]);
});
}
else if(BuyingPrice == -960 || NewObject == Prefabs[31])
{
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor" && x.GetComponent<Renderer>().enabled).ForEach(x =>
{
SetMainColorOf(x, StructureColors[0]);
SetTopColorOf(x, StructureColors[1]);
});
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Wall" && x.GetComponent<Renderer>().enabled).ForEach(x =>
{
SetMainColorOf(x, StructureColors[2]);
SetTopColorOf(x, StructureColors[1]);
});
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Lamp" && x.GetComponent<Renderer>().enabled)
.ForEach(x => {
SetMainColorOf(x, StructureColors[2]);
SetTopColorOf(x, StructureColors[1]);
});
}
else
{
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor" && x.GetComponent<Renderer>().enabled).ForEach(x =>
{
SetMainColorOf(x, StructureColors[0]);
SetTopColorOf(x, StructureColors[1]);
});
}
}
}
else if (!move && !Creating)
{
GroundHandle.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "Floor")
.ForEach(x => x.GetComponent<Renderer>().material.color = StructureColors[0]);
if (GroundHandle.transform.GetChild(0).childCount > 0)
{
GroundHandle.transform.GetChild(0).GetComponentsInChildren<Transform>().ToList()
.FindAll(x => (x.name == "Floor" || x.name == "Wall" || x.name == "Lamp") && x.GetComponent<Renderer>().enabled)
.ForEach(x =>
{
if (x.name == "Floor")
{
SetMainColorOf(x, StructureColors[0]);
SetTopColorOf(x, StructureColors[0]);
}
else
{
SetMainColorOf(x, StructureColors[2]);
SetTopColorOf(x, StructureColors[2]);
}
TurnOffTopOf(x);
});
}
}
}
void SetTopColorOf(Transform x, Color color)
{
Transform Top = x.GetChild(0).GetChild(1);
Top.GetComponent<Renderer>().enabled = true;
Top.GetComponent<Renderer>().material.color = color;
Top.localPosition = new Vector3(0, 0.501f, 0);
}
void SetMainColorOf(Transform x, Color color)
{
x.GetComponent<Renderer>().material.color = color;
}
void TurnOffTopOf(Transform x)
{
Transform Top = x.GetChild(0).GetChild(1);
Top.GetComponent<Renderer>().enabled = false;
Top.localPosition = new Vector3(0, 0.5f, 0);
}
private void Update()
{
if (Input.mouseScrollDelta.y != 0 && !InterfaceOpen && !Paused && !buildbool && !HelpMenu.activeSelf)
{
if(MainCamera.transform.position.y - Input.mouseScrollDelta.y > 1 &&
MainCamera.transform.position.y - Input.mouseScrollDelta.y < 100)
{
MainCamera.transform.position -= new Vector3(0, Input.mouseScrollDelta.y, 0);
}
}
if (Input.anyKeyDown)
{
if (Input.GetKeyDown(KeyCode.F3))
{
if(Stats.activeSelf)
{
Stats.SetActive(false);
}
else
{
Stats.SetActive(true);
}
}
if (!Paused)
{
if (Input.GetKeyDown("r"))
{
ChangingModes("Rotate Mode");
}
else if (Input.GetKeyDown("m"))
{
ChangingModes("Move Mode");
}
else if (Input.GetKeyDown("d"))
{
ChangingModes("Delete Mode");
}
else if (Input.GetKeyDown("c"))
{
ChangingModes("Right Build");
}
else if (Input.GetKeyDown("f"))
{
ChangingModes("Left Build");
}
else if (Input.GetKeyDown("e"))
{
ChangingModes("Expansion");
}
/*else if (Input.GetKeyDown("space"))
{
Money += 1000;
UpdateMoney();
}*/
}
if (Input.GetKeyDown(KeyCode.Escape))
{
PleaseExitTheInterface();
if (!PauseMenu.activeSelf)
{
Topbar.SetActive(false);
PauseMenu.SetActive(true);
Paused = true;
Time.timeScale = 0;
}
else
{
PauseMenu.SetActive(false);
Topbar.SetActive(true);
Paused = false;
Time.timeScale = 1;
}
}
else if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)))
{
if (!Paused && !EventSystem.current.IsPointerOverGameObject())
{
int layerMask = 1 << 8;
layerMask = ~layerMask;
RaycastHit hit;
Ray ray = MainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100.0f, layerMask))
{
if (hit.transform)
{
MouseOver = hit.transform;
if (modeToggles.rotate)
{
if (MouseOver.IsChildOf(ComponentHandler.transform) &&
!MouseOver.CompareTag("Rail") &&
!MouseOver.name.Contains("Internal") &&
MouseOver.name != "TeleporterInput")
{
AudioManager.Play("Rotate");
int RotateDirection = 0;
if (Input.GetMouseButtonDown(0))
{
RotateDirection = 90;
}
else if (Input.GetMouseButtonDown(1))
{
RotateDirection = -90;
}
if (MouseOver.CompareTag("ConveyorBelt"))
{
MouseOver.gameObject.transform.localEulerAngles =
new Vector3(0,
Mathf.RoundToInt(MouseOver.gameObject.transform.localEulerAngles.y + RotateDirection),
0);
if (MouseOver.name == "ConveyorBelt")
{
MouseOver.GetComponent<ConveyorBelt>().Editing("Rotate");
}
}
else if (!MouseOver.CompareTag("Seller"))
{
MouseOver.gameObject.transform.GetChild(1).localEulerAngles =
new Vector3(0,
Mathf.RoundToInt(MouseOver.gameObject.transform.GetChild(1).localEulerAngles.y + RotateDirection),
0);
MouseOver.gameObject.transform.GetChild(2).localEulerAngles =
new Vector3(0,
Mathf.RoundToInt(MouseOver.gameObject.transform.GetChild(2).localEulerAngles.y + RotateDirection),
0);
if (MouseOver.CompareTag("Crafter") ||
MouseOver.CompareTag("InputObj") ||
MouseOver.CompareTag("Machine") ||
MouseOver.CompareTag("Teleporter"))
{
MouseOver.GetComponent<CreationAndDeleting>().PostRotate();
}
}
}
}
else if (Input.GetMouseButtonDown(0))
{
if (BuyingLandNow && MouseOver.CompareTag("DarkMatter"))
{
GroundHandler.GetComponent<InfiniteLand>().PurchaseLand(MouseOver.gameObject);
BuyingLandNow = false;
BuyingLand();
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Bought land");
}
}
else if (Creating && !EventSystem.current.IsPointerOverGameObject())
{
Vector3 FloorLocation = new Vector3(Mathf.RoundToInt(hit.point.x),
MouseOver.position.y + 1f,
Mathf.RoundToInt(hit.point.z));
Vector3 TopLocation = new Vector3(Mathf.RoundToInt(hit.point.x),
MouseOver.position.y + 0.5f,
Mathf.RoundToInt(hit.point.z));
if (BuyingPrice > 0)
{
if (!MouseOver.CompareTag("DarkMatter"))
{
if (MouseOver.CompareTag("Floor"))
{
if(NewObject == Prefabs[31])
{
if (MouseOver.name == "Floor")
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().CreateLamp(FloorLocation, NewObject);
}
else
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().CreateLamp(MouseOver.gameObject, NewObject);
}
return;
}
if (!AudioManager.IsPlaying("ConveyorBelt") &&
(NewObject == Prefabs[20] || NewObject == Prefabs[3] || NewObject == Prefabs[23] || NewObject == Prefabs[24]))
{
AudioManager.Play("ConveyorBelt");
}
AudioManager.Play("Place");
GameObject clone = Instantiate(NewObject);
clone.transform.parent = ComponentHandler.transform;
if (MouseOver.name == "Floor")
{
clone.transform.position = FloorLocation;
}
else
{
clone.transform.position = TopLocation;
}
clone.name = NewObject.name;
Money -= BuyingPrice;
UpdateMoney();
if (RunningThroughTutorial)
{
if(clone.name == "input")
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Placed input");
if (ComponentHandler.GetComponentsInChildren<Transform>().LongCount(x => x.name == "input") >= 3)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Placed inputs");
}
}
else if (clone.name == "Crafter")
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Placed Crafter");
}
else if (clone.name == "Wire Drawer")
{
if (ComponentHandler.GetComponentsInChildren<Transform>().LongCount(x => x.name == "Wire Drawer") >= 4)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Placed Wire Drawers");
}
}
else if (clone.name == "Seller")
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Placed Seller");
}
}
if (clone.name == "ConveyorBelt")
{
clone.GetComponent<ConveyorBelt>().OnCreation();
}
else if (clone.CompareTag("Machine") ||
clone.CompareTag("InputObj") ||
clone.CompareTag("Crafter") ||
clone.CompareTag("Teleporter"))
{
clone.GetComponent<CreationAndDeleting>().PostCreation();
}
}
}
else
{
AudioManager.Play("Error");
}
}
else
{
if (MouseOver.name == "Floor")
{
if (BuyingPrice != -1000 && BuyingPrice != -1001)
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().WallOrFloorCreation(FloorLocation, BuyingPrice);
}
else if (BuyingPrice == -1000)
{
BuddyManager.CreateTeleporterInput(FloorLocation, this);
BuildSelection.GetComponentsInChildren<Transform>().ToList()
.Find(x => x.name == "Teleporter I").GetComponentInChildren<TextMeshProUGUI>()
.text = $"Teleporter \n Input - {ReducedMoneyAmount(BuddyManager.I_Cost)}";
}
else if (BuyingPrice == -1001)
{
BuddyManager.CreateTeleporterOutput(FloorLocation, this);
BuildSelection.GetComponentsInChildren<Transform>().ToList()
.Find(x => x.name == "Teleporter O").GetComponentInChildren<TextMeshProUGUI>()
.text = $"Teleporter \n Output - {ReducedMoneyAmount(BuddyManager.O_Cost)}";
}
}
else if(MouseOver.CompareTag("Floor"))
{
if (BuyingPrice != -1000 && BuyingPrice != -1001)
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>()
.WallOrFloorCreation(MouseOver.gameObject, BuyingPrice);
}
else if(BuyingPrice == -1000)
{
BuddyManager.CreateTeleporterInput(TopLocation, this);
}
else if (BuyingPrice == -1001)
{
BuddyManager.CreateTeleporterOutput(TopLocation, this);
}
}
else
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>()
.WallOrFloorCreation(MouseOver.gameObject, BuyingPrice);
}
}
}
else if (modeToggles.move)
{
if (MouseOver.CompareTag("DarkMatter"))
{
if (HaveMovingObjectSelected && WaitForIt)
{
AudioManager.Play("Error");
}
}
else if (!MouseOver.CompareTag("Rail") &&
!MouseOver.name.Contains("Internal") &&
!MouseOver.IsChildOf(ObjectHandler.transform))
{
if (!MouseOver.CompareTag("Floor") && !MouseOver.CompareTag("World"))
{
Moving(MouseOver.gameObject);
}
if (HaveMovingObjectSelected && WaitForIt &&
(MouseOver.CompareTag("Floor") || MouseOver == Save.transform))
{
Vector3 newPos;
AudioManager.Play("Place");
if (MouseOver.IsChildOf(GroundHandler.transform.GetChild(0)))
{
newPos = new Vector3(Mathf.RoundToInt(hit.point.x), MouseOver.position.y + 0.5f, Mathf.RoundToInt(hit.point.z));
}
else
{
newPos = new Vector3(Mathf.RoundToInt(hit.point.x), MouseOver.position.y + 1, Mathf.RoundToInt(hit.point.z));
}
if (MouseOver == Save.transform)
{
Save.transform.position -= new Vector3(0, 0.5f, 0);
}
else
{
if (Save.name == "ConveyorBelt")
{
Vector3 pos = Save.transform.position;
Save.transform.position = newPos;
Save.GetComponent<ConveyorBelt>().Editing("Moved", pos);
}
else
{
if (Save.CompareTag("Crafter") ||
Save.CompareTag("InputObj") ||
Save.CompareTag("Machine") ||
Save.CompareTag("Teleporter"))
{
Save.GetComponent<CreationAndDeleting>().PreMove(Save.transform.position, this);
Save.transform.position = newPos;
Save.GetComponent<CreationAndDeleting>().PostMove();
}
else
{
Save.transform.position = newPos;
}
}
}
HaveMovingObjectSelected = false;
WaitForIt = false;
}
if (HaveMovingObjectSelected)
{
WaitForIt = true;
}
}
}
else if (modeToggles.delete)
{
if (MouseOver.IsChildOf(ComponentHandler.transform) &&
!MouseOver.name.Contains("Internal"))
{
if (MouseOver.name == "ConveyorBelt")
{
MouseOver.GetComponent<ConveyorBelt>().Editing("Delete");
}
else
{
if ((MouseOver.CompareTag("Machine")))
{
MouseOver.GetComponent<SimpleProducer>().PreDelete();
}
else if (MouseOver.CompareTag("Crafter")||
MouseOver.CompareTag("InputObj") ||
MouseOver.CompareTag("Teleporter"))
{
if (MouseOver.CompareTag("InputObj")) {
MouseOver.GetComponent<CreationAndDeleting>().PreDelete(this, 7);
}
else if (MouseOver.CompareTag("Crafter"))
{
MouseOver.GetComponent<CreationAndDeleting>().PreDelete(this, 23);
}
else if (MouseOver.CompareTag("Teleporter"))
{
MouseOver.GetComponent<CreationAndDeleting>().PreDelete(this,
500 * Mathf.RoundToInt(Mathf.Pow(10, MouseOver.GetComponent<Teleporter>().BuddySystem.PairNumber)));
}
}
Destroy(MouseOver.gameObject);
}
if (ComponentHandler.GetComponentsInChildren<Transform>().ToList().FindAll(x => x.CompareTag("ConveyorBelt")).Count <= 0 &&
!AudioManager.IsPlaying("ConveyorBelt"))
{
AudioManager.Stop("ConveyorBelt");
}
}
else if (MouseOver.IsChildOf(GroundHandler.transform.GetChild(0)))
{
if (MouseOver.name != "Floor")
{
GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().WallOrFloorDeletion(MouseOver.gameObject);
}
}
}
else if (modeToggles.paint)
{
if (MouseOver.CompareTag("ConveyorBelt"))
{
switch (MouseOver.name)
{
case "ConveyorBelt":
MouseOver.GetComponent<ConveyorBelt>().BeltColor.color = PaintSelection.GetComponent<PaintInterface>().color;
break;
case "ComplexConveyorBelt":
MouseOver.GetComponent<Splitter>().BeltColor.color = PaintSelection.GetComponent<PaintInterface>().color;
break;
case "RightSelector":
case "LeftSelector":
MouseOver.GetComponent<Selector>().BeltColor.color = PaintSelection.GetComponent<PaintInterface>().color;
break;
}
MouseOver.GetChild(0).GetComponent<Renderer>().material.color = PaintSelection.GetComponent<PaintInterface>().color;
}
}
else if (MouseOver.IsChildOf(ComponentHandler.transform))
{
ClickedOnComponent(MouseOver);
}
else if (MouseOver.CompareTag("Floor") || MouseOver.CompareTag("Wall"))
{
PleaseExitTheInterface();
}
if (!modeToggles.move && HaveMovingObjectSelected)
{
Save.transform.position -= new Vector3(0, 0.5f, 0);
Save.transform.position = new Vector3(Mathf.FloorToInt(Save.transform.position.x),
Mathf.FloorToInt(Save.transform.position.x),
Mathf.FloorToInt(Save.transform.position.x));
HaveMovingObjectSelected = false;
WaitForIt = false;
}
}
}
}
}
else
{
if (!modeToggles.move && HaveMovingObjectSelected)
{
Save.transform.position -= new Vector3(0, 0.5f, 0);
Save.transform.position = new Vector3(Mathf.FloorToInt(Save.transform.position.x),
Mathf.FloorToInt(Save.transform.position.x),
Mathf.FloorToInt(Save.transform.position.x));
HaveMovingObjectSelected = false;
WaitForIt = false;
}
}
}
}
else if (Input.anyKey)
{
if (Input.GetMouseButton(2) && !Paused)
{
MainCamera.transform.position -= Input.GetAxis("Mouse Y") * new Vector3(MainCamera.transform.forward.x, 0, MainCamera.transform.forward.z) * MoveSensitivity;
MainCamera.transform.position -= Input.GetAxis("Mouse X") * new Vector3(MainCamera.transform.right.x, 0, MainCamera.transform.right.z) * MoveSensitivity;
}
else if (Input.GetMouseButton(1) && !Paused && !modeToggles.rotate)
{
MainCamera.transform.eulerAngles += new Vector3(
-Input.GetAxis("Mouse Y") * RotationSensitivity,
Input.GetAxis("Mouse X") * RotationSensitivity,
0);
}
if (Input.GetKey("up"))
{
MainCamera.transform.position += new Vector3(MainCamera.transform.forward.x, 0, MainCamera.transform.forward.z) * MoveSensitivity;
}
if (Input.GetKey("down"))
{
MainCamera.transform.position -= new Vector3(MainCamera.transform.forward.x, 0, MainCamera.transform.forward.z) * MoveSensitivity;
}
if (Input.GetKey("left"))
{
MainCamera.transform.position += new Vector3(MainCamera.transform.right.x, 0, MainCamera.transform.right.z) * MoveSensitivity;
}
if (Input.GetKey("right"))
{
MainCamera.transform.position -= new Vector3(MainCamera.transform.right.x, 0, MainCamera.transform.right.z) * MoveSensitivity;
}
}
}
void ClickedOnComponent(Transform Who)
{
PleaseExitTheInterface();
if (!Who.CompareTag("ConveyorBelt"))
{
switch (Who.tag)
{
case "InputObj":
InputBlock.Interface(Who);
InputInterface.SetActive(true);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Click input");
}
break;
case "Machine":
Machine_Interface.Interface(Who);
MachineInterface.SetActive(true);
break;
case "Crafter":
CraftingInterface.Interface(Who);
CrafterInterface.SetActive(true);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Click crafter");
}
break;
case "Teleporter":
transform.GetComponent<Teleport>().Interface(Who);
TeleportI.SetActive(true);
break;
}
}
else
{
switch (Who.name)
{
case "ComplexConveyorBelt":
ConveyorInterfaceF.Interface(Who);
ConveyorInterface.SetActive(true);
break;
case "LeftSelector":
case "RightSelector":
SelectorInterfaceF.Interface(Who);
SelectorInterface.SetActive(true);
break;
}
}
InterfaceOpen = true;
}
private bool helpMenuOpen = false;
public void ChangingModes(string FunctionName = null)
{
AudioManager.Play("Click UI");
if (!FunctionName.Contains(" Build"))
{
buildbool = false;
}
PleaseExitTheInterfaceWithoutBuildBool();
if (FunctionName != "Expansion")
{
BuyingLandNow = true;
BuyingLand();
}
componentHandler.Mode("Normal");
MoveOrCreate(GroundHandler);
switch (FunctionName)
{
case "Move Mode":
modeToggles.MoveMode(componentHandler);
Topbar.GetComponent<Topbar>().ToggleButton("Move", modeToggles.move);
break;
case "Rotate Mode":
modeToggles.RotateMode(componentHandler);
Topbar.GetComponent<Topbar>().ToggleButton("Rotate", modeToggles.rotate);
break;
case "Delete Mode":
modeToggles.DeleteMode(componentHandler);
Topbar.GetComponent<Topbar>().ToggleButton("Delete", modeToggles.delete);
break;
case "Right Build":
SidebarFunction(Side: BuildSelection, OtherSide: LeftSidebar);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Right Sidebar");
}
break;
case "Paint":
modeToggles.PaintMode();
if (modeToggles.paint)
{
PaintSelection.SetActive(true);
PaintSelection.GetComponent<PaintInterface>().ChangeColor(4);
componentHandler.Mode("Paint");
}
else
{
PaintSelection.SetActive(false);
ComponentHandler.GetComponent<ComponentHandler>().Mode("Normal");
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
}
Topbar.GetComponent<Topbar>().ToggleButton("Paint", modeToggles.paint);
break;
case "Left Build":
SidebarFunction(Side: LeftSidebar, OtherSide: BuildSelection);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Left Sidebar");
}
break;
case "Expansion":
BuyingLand();
Topbar.GetComponent<Topbar>().ToggleButton("Expansion", BuyingLandNow);
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Expansion");
}
break;
case "Help Menu":
if(helpMenuOpen == false)
{
HelpMenu.SetActive(true);
Topbar.GetComponent<Topbar>().ToggleButton("Help Menu", true);
helpMenuOpen = true;
}
else
{
HelpMenu.SetActive(false);
Topbar.GetComponent<Topbar>().ToggleButton("Help Menu", false);
}
HelpMenu.GetComponent<HelpMenu>().Interface();
break;
case null:
return;
}
}
public void PleaseExitTheInterface()
{
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
InputInterface.SetActive(false);
MachineInterface.SetActive(false);
CrafterInterface.SetActive(false);
ConveyorInterface.SetActive(false);
CrafterSelection.SetActive(false);
SelectorInterface.SetActive(false);
BuildSelection.SetActive(false);
LeftSidebar.SetActive(false);
HelpMenu.SetActive(false);
TeleportI.SetActive(false);
PaintSelection.SetActive(false);
buildbool = false;
BuyingPrice = 0;
modeToggles.build = false;
Creating = false;
SelectingMaterial = true;
InterfaceOpen = false;
helpMenuOpen = false;
MaterialInterface();
if (RunningThroughTutorial)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Exit");
}
}
public void PleaseExitTheInterfaceWithoutBuildBool()
{
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
InputInterface.SetActive(false);
MachineInterface.SetActive(false);
CrafterInterface.SetActive(false);
ConveyorInterface.SetActive(false);
CrafterSelection.SetActive(false);
SelectorInterface.SetActive(false);
BuildSelection.SetActive(false);
LeftSidebar.SetActive(false);
HelpMenu.SetActive(false);
TeleportI.SetActive(false);
PaintSelection.SetActive(false);
BuyingPrice = 0;
modeToggles.build = false;
Creating = false;
SelectingMaterial = true;
InterfaceOpen = false;
MaterialInterface();
}
public void Moving(GameObject selected)
{
if (!HaveMovingObjectSelected)
{
selected.transform.position += new Vector3(0, 0.5f, 0);
HaveMovingObjectSelected = true;
Save = selected;
}
}
public void CreateComponent(int Prefab, int Price)
{
AudioManager.Play("Click UI");
NewObject = Prefabs[Prefab];
BuyingPrice = Price;
Creating = false;
MoveOrCreate(GroundHandler);
Creating = true;
MoveOrCreate(GroundHandler);
if(RunningThroughTutorial)
{
if(Prefab == 0)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Input");
}
if(Price == -960)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Wall");
}
if (Price == -634)
{
TutorialMan.GetComponent<TutorialMan>().NextStep("Floor");
}
}
}
public void LayerVisibility(int YLevelStart, int YLevelEnd, bool Visible)
{
componentHandler.LayerVisibility(YLevelStart, YLevelEnd, Visible);
createObject.LayerVisibility(YLevelStart, YLevelEnd, Visible);
}
public void LayerVisibility(int YLevel, bool Visible)
{
componentHandler.LayerVisibility(YLevel, Visible);
createObject.LayerVisibility(YLevel, Visible);
}
public void ComponentError(Transform Who, Vector3 WhereItLooksPretty)
{
AnimationFlag ErrorAnimation = Who.gameObject.GetComponent<AnimationFlag>() ?? Who.gameObject.AddComponent<AnimationFlag>();
GameObject ExclamationMark;
if (!ErrorAnimation.animating)
{
ExclamationMark = Instantiate(Prefabs[25]);
ExclamationMark.transform.SetParent(Who);
ExclamationMark.transform.SetAsLastSibling();
ExclamationMark.transform.position = WhereItLooksPretty;
ExclamationMark.name = Prefabs[25].name;
ErrorAnimation.animating = true;
}
else
{
}
}
public void ComponentErrorResolved(Transform Who)
{
AnimationFlag ErrorAnimation = Who.gameObject.GetComponent<AnimationFlag>() ?? Who.gameObject.AddComponent<AnimationFlag>();
if (ErrorAnimation.animating && Who.GetComponentsInChildren<Transform>().Any(x => x.gameObject.name == "ComponentError"))
{
Destroy(Who.GetComponentsInChildren<Transform>().FirstOrDefault(x => x.gameObject.name == "ComponentError").gameObject, 0.05f);
ErrorAnimation.animating = false;
}
}
public GameObject GetPrefab(string name)
{
if(name == "input")
{
return Prefabs[0];
}
else if (name == "Seller")
{
return Prefabs[21];
}
else if (name == "Furnace")
{
return Prefabs[1];
}
else if (name == "Hydralic Press")
{
return Prefabs[2];
}
else if (name == "Gear Cutter")
{
return Prefabs[9];
}
else if (name == "Wire Drawer")
{
return Prefabs[4];
}
else if (name == "Crafter")
{
return Prefabs[13];
}
else if (name == "ConveyorBelt")
{
return Prefabs[3];
}
else if (name == "ComplexConveyorBelt")
{
return Prefabs[20];
}
else if (name == "RightSelector")
{
return Prefabs[24];
}
else if (name == "LeftSelector")
{
return Prefabs[23];
}
else
{
return null;
}
}
public void SaveData(int slot)
{
SaveSystem.SaveGameData(
God: this,
SaveSlot: slot,
GroundHandler: GroundHandler.GetComponent<InfiniteLand>(),
MMSH: GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>(),
ComponentHandler: ComponentHandler.GetComponent<ComponentHandler>(),
WorldHandler: GameObject.Find("WorldHandler").GetComponent<WorldHandler>(),
T_in: BuddyManager.BuddyIndexSearcher[0].Count,
T_out: BuddyManager.BuddyIndexSearcher[1].Count,
T_count: BuddyManager.NextBuddyPair);
}
public string ReducedMoneyAmount(float Cost)
{
if (Cost < 1_000)
{
return Cost.ToString();
}
else if (Cost < 1_000_000)
{
return (Cost / 1_000).ToString("0.##") + "k";
}
else if (Cost < 1_000_000_000)
{
return (Cost / 1_000_000).ToString("0.##") + "m";
}
else if (Cost < 1_000_000_000_000)
{
return (Cost / 1_000_000_000).ToString("0.##") + "b";
}
else if (Cost < 1_000_000_000_000_000)
{
return (Cost / 1_000_000_000_000).ToString("0.##") + "t";
}
else
{
return Cost < 1_000_000_000_000_000_000 ? (Cost / 1_000_000_000_000_000).ToString("0.##") + "qa" : null;
}
}
private Collider[] TempColliders = new Collider[] { };
public void UpdateConveyors(Collider[] c)
{
TempColliders = c;
Invoke("UpdateConveyors", 0.025f);
}
private void UpdateConveyors()
{
TempColliders.ToList().FindAll(x => x.gameObject.name == "ConveyorBelt").ForEach(x => x.GetComponent<ConveyorBelt>().OnCreation(false));
}
}
The Component Handler is a GameObjects that holds all of instantiated machines and conveyor-belts as children. With access to all of their information, it is the one to manage their materials, viability, as well as being the key to identifying a certain component.
324 lines
Click to expandusing System.Linq;
using UnityEngine;
public class ComponentHandler : MonoBehaviour
{
private God God;
private Color Normal = new Color(1, 1, 1, 1),
Rotate = new Color(0, 1, 0, 1),
Delete = new Color(1, 0, 0, 1),
Rails = new Color(0.43f, 0.43f, 0.43f, 1);
#region Singleton
public static ComponentHandler Instance;
public void Awake()
{
Instance = this;
}
#endregion
private void Start()
{
God = God.Instance;
}
public void Mode(string Mode)
{
if (transform.childCount > 0)
{
int childCount = transform.childCount;
for(int c = 0; c < childCount; c++)
{
Transform child = transform.GetChild(c);
if (!(child.name == "TeleporterInput" && Mode == "Rotate"))
{
Renderer renderer = null;
if (child.gameObject.layer != 8)
{
if (!child.CompareTag("ConveyorBelt") &&
!child.CompareTag("Seller"))
{
renderer = child.GetChild(0).GetComponentInChildren<Renderer>();
Normal = new Color(1, 1, 1);
switch (Mode)
{
case "Normal":
renderer.material.color = Normal;
break;
case "Rotate":
renderer.material.color = Rotate;
break;
case "Delete":
renderer.material.color = Delete;
break;
case "Transparent":
renderer.material.color = Normal;
break;
}
}
else if (child.CompareTag("ConveyorBelt"))
{
renderer = child.GetChild(0).GetComponent<Renderer>();
switch (Mode)
{
case "Normal":
renderer.material.color = GetBeltColor(child);
PaintTheRails(child);
break;
case "Rotate":
renderer.material.color = Rotate;
PaintTheRails(child, PaintThemToColorCode: true);
break;
case "Delete":
renderer.material.color = Delete;
PaintTheRails(child, PaintThemToColorCode: true);
break;
case "Paint":
renderer.material.color = GetBeltColor(child);
PaintTheRails(child, rotate: true);
break;
case "Transparent":
renderer.material.color = GetBeltColor(child);
HideTheRails(child, true);
break;
}
}
else if (child.CompareTag("Seller"))
{
switch (Mode)
{
case "Normal":
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.material.color = new Color(0.12f, 0.12f, 0.12f));
break;
case "Rotate":
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.material.color = new Color(0, 0.35f, 0));
break;
case "Delete":
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.material.color = new Color(0.35f, 0, 0));
break;
case "Transparent":
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.enabled = true);
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.material.color = new Color(0.12f, 0.12f, 0.12f));
break;
}
}
}
else if (Mode == "Transparent")
{
if (!child.CompareTag("ConveyorBelt") &&
!child.CompareTag("Seller"))
{
renderer = child.GetChild(0).GetComponentInChildren<Renderer>();
renderer.material.color = new Color(Normal.r, Normal.g, Normal.b, 0.1f);
}
else if (child.CompareTag("ConveyorBelt"))
{
renderer = child.GetChild(0).GetComponent<Renderer>();
renderer.material.color = new Color(GetBeltColor(child).r, GetBeltColor(child).g, GetBeltColor(child).b, 0.1f);
HideTheRails(child, false);
}
else if (child.CompareTag("Seller"))
{
child.GetComponentsInChildren<Renderer>().ToList().ForEach(x => x.enabled = false);
}
}
}
}
}
if(Mode != "Rotate")
{
God.GroundHandler.transform.GetChild(0).GetComponent<ManMadeStructureHandler>().Mode(Mode);
}
}
void PaintTheRails(Transform child, bool PaintThemToColorCode = false, bool rotate = false)
{
Color color;
if (PaintThemToColorCode)
{
color = GetBeltColor(child);
color = new Color(color.r - 0.3f, color.g - 0.3f, color.b - 0.3f, 1);
}
else
{
color = Rails;
}
if (rotate)
{
color = Rotate;
}
switch (child.name)
{
case "ConveyorBelt":
child.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name.Contains("Rail") && !x.name.Contains("_Rail"))
.ForEach(x =>
{
x.GetComponent<Renderer>().material.color = color;
});
break;
case "ComplexConveyorBelt":
case "RightSelector":
case "LeftSelector":
child.GetChild(2).GetComponent<Renderer>().material.color = color;
child.GetChild(3).GetComponent<Renderer>().material.color = color;
child.GetChild(4).GetComponent<Renderer>().material.color = color;
child.GetChild(5).GetComponent<Renderer>().material.color = color;
break;
}
}
void HideTheRails(Transform child, bool hide)
{
switch (child.name)
{
case "ConveyorBelt":
child.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name.Contains("Rail") && !x.name.Contains("_Rail"))
.ForEach(x =>
{
x.GetComponent<Renderer>().enabled = hide;
});
break;
case "ComplexConveyorBelt":
case "RightSelector":
case "LeftSelector":
child.GetChild(2).GetComponent<Renderer>().enabled = hide;
child.GetChild(3).GetComponent<Renderer>().enabled = hide;
child.GetChild(4).GetComponent<Renderer>().enabled = hide;
child.GetChild(5).GetComponent<Renderer>().enabled = hide;
break;
}
}
Color GetBeltColor(Transform child)
{
switch (child.name)
{
case "ConveyorBelt":
return child.GetComponent<ConveyorBelt>().BeltColor.color;
case "ComplexConveyorBelt":
return child.GetComponent<Splitter>().BeltColor.color;
case "RightSelector":
case "LeftSelector":
return child.GetComponent<Selector>().BeltColor.color;
default:
return new Color(0.63f, 0.963f, 1);
}
}
public void LayerVisibility(int YLevelStart, int YLevelEnd, bool Visible)
{
if(transform.childCount > 0)
{
int childCount = transform.childCount;
for (int child = 0; child < childCount; child++)
{
if (transform.GetChild(child).position.y >= YLevelStart && transform.GetChild(child).position.y < YLevelEnd)
{
transform.GetChild(child).gameObject.layer = Visible
? 0
: 8;
Invoke("MakeTransparent", 0.025f);
}
}
}
}
public void LayerVisibility(int YLevel, bool Visible)
{
if (transform.childCount > 0)
{
int childCount = transform.childCount;
for(int child = 0; child < childCount; child++)
{
if (transform.GetChild(child).position.y >= YLevel)
{
transform.GetChild(child).gameObject.layer = Visible
? 0
: 8;
Invoke("MakeTransparent", 0.025f);
}
}
}
}
void MakeTransparent()
{
Mode("Transparent");
}
public void LoadComponents(PlayerData Data, God god)
{
int TeleInput = Data.TeleporterInputAmount;
int TeleOutput = Data.TeleporterOutputAmount;
int NameCount = Data.ComponentNames.Length;
for (int i = 0; i < TeleInput; i++)
{
god.BuddyManager.InputBuddies.Add(null);
}
for (int i = 0; i < TeleOutput; i++)
{
god.BuddyManager.OutputBuddies.Add(null);
}
for (int c = 0; c < NameCount; c++)
{
Vector3 pos = new Vector3(Data.ComponentPositions[c][0],
Data.ComponentPositions[c][1],
Data.ComponentPositions[c][2]);
GameObject Component;
if (Data.ComponentNames[c] != "TeleporterInput")
{
if (Data.ComponentNames[c] == "TeleporterOutput")
{
Component = god.BuddyManager.CreateTeleporterOutput(pos, god, Data.TeleporterSystems[c]);
}
else
{
Component = Instantiate(god.GetPrefab(Data.ComponentNames[c]), pos, Quaternion.identity, this.transform);
}
}
else
{
Component = god.BuddyManager.CreateTeleporterInput(pos, god, Data.TeleporterSystems[c]);
}
Component.name = Data.ComponentNames[c];
Component.tag = Data.ComponentTag[c];
Component.transform.eulerAngles = new Vector3(0, Data.ComponentRotation[c], 0);
if (!Component.CompareTag("ConveyorBelt"))
{
Component.transform.GetChild(1).localEulerAngles = new Vector3(0, Data.ComponentDirection[c], 0);
Component.transform.GetChild(2).localEulerAngles = new Vector3(0, Data.ComponentDirection[c], 0);
}
if (Component.name == "input")
{
Component.GetComponent<InputBlockData>().Material = Data.InputMaterial[c];
Component.GetComponent<InputBlockData>().AmountNum = Data.InputAmount[c];
Component.GetComponent<InputBlockData>().UpdateInfo();
}
else if (Component.name == "Crafter")
{
Component.GetComponent<Crafter>().ProductionItem = Data.CrafterProductionItem[c];
}
else if (Component.name == "ComplexConveyorBelt")
{
Component.GetComponent<Splitter>().LeftNum = Data.SplitterDirections[c][0];
Component.GetComponent<Splitter>().StraightNum = Data.SplitterDirections[c][1];
Component.GetComponent<Splitter>().RightNum = Data.SplitterDirections[c][2];
}
else if (Component.name.Contains("Select"))
{
Component.GetComponent<Selector>().Selected = Data.SelectorSelectedItem[c];
}
else if (Component.name.Contains("Teleport"))
{
Component.GetComponent<Teleporter>().BuddySystem = Data.TeleporterSystems[c];
}
}
god.BuddyManager.NextBuddyPair = Data.TeleporterPairAmount;
Invoke("UpdateThingsAfterConveyors", 0.01f);
}
void UpdateThingsAfterConveyors()
{
if(transform.childCount > 0)
{
transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "ConveyorBelt")
.ForEach(x => x.GetComponent<ConveyorBelt>().OnCreation());
transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "input" && x.GetComponent<BoxCollider>() != null)
.ForEach(x => x.GetComponent<InputBlockData>().UpdateInfo());
}
}
}
Similarly to the Component Handler, the Object handler has every object (materials and crafted objects) as children and thus has access to their information. It is the one to deal with their visibility, creation, and material assignment.
146 lines
Click to expandusing System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class CreateObject : MonoBehaviour
{
public God God;
private ReuseMaterials ObjectPooler;
public Material[] ConveyorBeltMats;
public List<Renderer> ChildRenderers = new List<Renderer>();
public static CreateObject Instance;
private static readonly string[] MatNames = new string[5] { "Iron", "Gold", "Copper", "Diamond", "Aluminum" };
private Material[] MatMats = new Material[6];
private void Awake()
{
Instance = this;
}
public void Awake2()
{
Instance = this;
}
private void Start()
{
God = God.Instance;
ObjectPooler = ReuseMaterials.Instance;
ConveyorBeltMats = new Material[4]
{
Resources.Load("Materials/Conveyor/SNormal") as Material,
Resources.Load("Materials/Conveyor/CNormal") as Material,
Resources.Load("Materials/Conveyor/RNormal") as Material,
Resources.Load("Materials/Conveyor/LNormal") as Material
};
MatMats = new Material[6]
{
Resources.Load("Materials/Iron") as Material,
Resources.Load("Materials/Gold") as Material,
Resources.Load("Materials/Copper") as Material,
Resources.Load("Materials/Diamond") as Material,
Resources.Load("Materials/Aluminum") as Material,
Resources.Load("Materials/Floor/Floor") as Material
};
}
public Material IdentifyMaterial(GameObject reactant){
int m = 0;
for (int c = 0; c < 5; c++)
{
if (MatNames[c] == reactant.name)
{
m = c;
break;
}
else if (c == 4 &&
!MatNames[c].Contains(reactant.name))
{
return MatMats[5];
}
}
return MatMats[m];
}
public GameObject CloneObject(Material m, GameObject blueprint, GameObject Creator)
{
GameObject clone = null;
string MaterialName = m.name;
if (MaterialName != "Floor" && MaterialName != null)
{
string CreatorName = Creator.name;
if (CreatorName == "Furnace")
{
clone = ObjectPooler.SpawnFromPool("Liquid", Creator.transform.position, Quaternion.identity);
clone.transform.GetChild(0).GetComponent<Renderer>().material = m;
clone.name = "Liquid_" + MaterialName;
ObjectPooler.Deactivate(blueprint);
}
else if (CreatorName == "Hydralic Press")
{
clone = ObjectPooler.SpawnFromPool("Plate", Creator.transform.position, Quaternion.identity);
clone.transform.GetChild(0).GetComponent<Renderer>().material = m;
clone.name = MaterialName + "_Plate";
ObjectPooler.Deactivate(blueprint);
}
else if (CreatorName == "Wire Drawer")
{
clone = ObjectPooler.SpawnFromPool("Wire", Creator.transform.position, Quaternion.identity);
clone.transform.GetChild(0).GetComponent<Renderer>().material = m;
clone.name = MaterialName + "_Wire";
ObjectPooler.Deactivate(blueprint);
}
else if (CreatorName == "Gear Cutter")
{
clone = ObjectPooler.SpawnFromPool("Gear", Creator.transform.position, Quaternion.identity);
clone.transform.GetChild(0).GetComponent<Renderer>().material = m;
clone.name = MaterialName + "_Gear";
ObjectPooler.Deactivate(blueprint);
}
else if (CreatorName == "input")
{
clone = ObjectPooler.SpawnFromPool("Material", Creator.transform.position, Quaternion.identity);
clone.GetComponent<Renderer>().material = m;
clone.name = MaterialName;
God.Money -= 5;
God.UpdateMoney();
}
if(Creator.layer == 8)
{
ChildRenderers[ChildRenderers.Count - 1].enabled = false;
ChildRenderers[ChildRenderers.Count - 1].GetComponent<RenderToggle>().enabled = false;
}
return clone;
}
return null;
}
public void LayerVisibility(int YLevelStart, int YLevelEnd, bool Visible)
{
int renderers = ChildRenderers.Count;
if (renderers > 0)
{
for (int i = 0; i < renderers; i++)
{
Renderer renderer = ChildRenderers[i];
float y = renderer.transform.position.y;
if(y >= YLevelStart && y < YLevelEnd)
{
renderer.enabled = Visible;
renderer.GetComponent<RenderToggle>().enabled = Visible;
}
}
}
}
public void LayerVisibility(int YLevel, bool Visible)
{
int renderers = ChildRenderers.Count;
if (renderers > 0)
{
for (int i = 0; i < renderers; i++)
{
Renderer renderer = ChildRenderers[i];
float y = renderer.transform.position.y;
if (y >= YLevel)
{
renderer.enabled = Visible;
renderer.GetComponent<RenderToggle>().enabled = Visible;
}
}
}
}
}
The Audio Manages controls the audio. It also retains it's settings when changing between scenes.
171 lines
Click to expandusing System.Collections.Generic;
using System;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
[Range(0f, 1f)] [Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float MasterVolume = 1f;
[Range(0f, 1f)] [Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float MusicVol = 0.57f;
[Range(0f, 1f)]
[Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float DeleteVol = 0.75f;
[Range(0f, 1f)]
[Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float PlacingVol = 0.75f;
[Range(0f, 1f)]
[Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float RotatingVol = 0.75f;
[Range(0f, 1f)]
[Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float MachinesVol = 0.2f;
[Range(0f, 1f)]
[Foldout("Volumes", 0f, 1f, 1f, 1f)]
public float UIVol = 1f;
private List<float> Volumes;
[Header("All Sounds")]
public Sound[] sounds;
private List<string> Types = new List<string>();
private List<List<string>> TypeList = new List<List<string>>();
[Space]
[Foldout("Groups")] public List<string> UI = new List<string>();
[Foldout("Groups")] public List<string> Music = new List<string>();
[Foldout("Groups")] public List<string> Delete = new List<string>();
[Foldout("Groups")] public List<string> Placing = new List<string>();
[Foldout("Groups")] public List<string> Machines = new List<string>();
[Foldout("Groups")] public List<string> Rotating = new List<string>();
// Because of using RuntimeInitializeOnLoadMethod attribute to find/create and
// initialize the instance, this property is accessible and
// usable even in Awake() methods.
public static AudioManager Instance
{
get; private set;
}
// Thanks to the attribute, this method is executed before any other MonoBehaviour
// logic in the game.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnRuntimeMethodLoad()
{
var instance = FindObjectOfType<AudioManager>();
if (instance == null)
instance = new GameObject("Audio Manager").AddComponent<AudioManager>();
DontDestroyOnLoad(instance);
Instance = instance;
}
void Awake()
{
Types = new List<string>()
{
"UI", "Music", "Delete", "Placing", "Machines", "Rotating"
};
TypeList = new List<List<string>>()
{
UI, Music, Delete, Placing, Machines, Rotating
};
Volumes = new List<float>()
{
UIVol, MusicVol, DeleteVol, PlacingVol, MachinesVol, RotatingVol
};
foreach(Sound s in sounds)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.playOnAwake = s.playOnAwake;
s.source.loop = s.loop;
if (Types.Contains(s.typeOrGroup)) {
TypeList[Types.IndexOf(s.typeOrGroup)].Add(s.name);
}
}
GameObject.Find("Canvas").transform.GetChild(5).GetComponent<MainMenuSettings>().AudioManager = this;
}
public void UpdateMenu()
{
FindObjectOfType<MainMenuSettings>().AudioManager = this;
FindObjectOfType<MainMenuSettings>().Gatekeeper = FindObjectOfType<TitleScreen>();
}
public void Play(string name)
{
Sound s = FindSound(name);
if(s == null)
{
Debug.LogWarning("Sound: " + name + " not found :(");
return;
}
UpdateVolume(s.typeOrGroup);
if (s.typeOrGroup == "Machines")
{
if (!s.source.isPlaying)
{
s.source.Play();
}
}
else
{
s.source.Play();
}
}
public void Stop(string name)
{
Sound s = FindSound(name);
if (s == null)
{
Debug.LogWarning("Sound: " + name + " not found :(");
return;
}
if (s.typeOrGroup == "Machines")
{
if (s.source.isPlaying)
{
s.source.Stop();
}
}
else
{
s.source.Stop();
}
}
public bool IsPlaying(string name)
{
Sound s = FindSound(name);
if (s == null)
{
Debug.LogWarning("Sound: " + name + " not found :(");
return false;
}
return s.source.isPlaying;
}
Sound FindSound(string name) => Array.Find(sounds, sound => sound.name == name);
public void UpdateVolume(string type)
{
if (type != "MasterVolume")
{
int t = Types.IndexOf(type);
Volumes = new List<float>()
{
UIVol, MusicVol, DeleteVol, PlacingVol, MachinesVol, RotatingVol
};
if (TypeList[t].Count > 0)
{
foreach (string s in TypeList[t])
{
FindSound(s).source.volume = Volumes[t] * MasterVolume;
}
}
}
else if (type == "MasterVolume") {
for(int s = 0; s < Types.Count; s++)
{
TypeList[s].ForEach(delegate { UpdateVolume(Types[s]); });
}
}
}
}
The Scene Manager call functions to tell all the necessary managers to save their data and communicate it to the GatekeeperOfData before changing scenes.
64 lines
Click to expandusing UnityEngine;
using UnityEngine.SceneManagement;
public class StartButton : MonoBehaviour
{
private bool LoadedGameplay = false;
public static StartButton Instance
{
get; private set;
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnRuntimeMethodLoad()
{
var instance = FindObjectOfType<StartButton>();
if (instance == null)
instance = new GameObject("SceneManager").AddComponent<StartButton>();
DontDestroyOnLoad(instance);
Instance = instance;
}
void Start()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneLoaded += OnSceneLoaded;
}
public void SceneLoader()
{
if (!LoadedGameplay)
{
SceneManager.LoadScene(1, LoadSceneMode.Single);
FindObjectOfType<TitleScreen>().RemoveListeners();
LoadedGameplay = true;
}
}
public void MainMenu()
{
SceneManager.LoadScene(0, LoadSceneMode.Single);
Time.timeScale = 1;
LoadedGameplay = false;
}
void OnSceneLoaded(Scene aScene, LoadSceneMode aMode)
{
if(aScene.name == "Title Screen")
{
FindObjectOfType<TitleScreen>().RefreshButtons();
FindObjectOfType<AudioManager>().UpdateMenu();
}
else
{
FindObjectOfType<TitleScreen>().UpdatePause();
}
if(aScene.buildIndex == 0)
{
SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex(0));
}
else
{
SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex(1));
}
}
}
The Gatekeeper acts as a middleman between G.O.D. and the Title Screen Scene. The class also manages the listeners for the buttons on the Title Screen Scene.
123 lines
Click to expandusing System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TitleScreen : MonoBehaviour
{
public PlayerData Data = null;
public bool DidILoad = false;
private List<Button> B = new List<Button>();
public bool TutorialPossible = false;
public bool MoneyAnimation = true;
public float MoveSensitivity = 0.15f;
public bool Shading = true;
public float FOV = 60;
private Transform TheCanvas;
private Transform LoadingBarPanel;
// Because of using RuntimeInitializeOnLoadMethod attribute to find/create and
// initialize the instance, this property is accessible and
// usable even in Awake() methods.
public static TitleScreen Instance
{
get; private set;
}
// Thanks to the attribute, this method is executed before any other MonoBehaviour
// logic in the game.
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnRuntimeMethodLoad()
{
var instance = FindObjectOfType<TitleScreen>();
if (instance == null)
instance = new GameObject("Gatekeeper of Data").AddComponent<TitleScreen>();
DontDestroyOnLoad(instance);
Instance = instance;
}
private void Start()
{
TheCanvas = GameObject.Find("Canvas").transform;
RefreshButtons();
TheCanvas.GetChild(5).GetComponent<MainMenuSettings>().Gatekeeper = this;
}
public void UpdatePause()
{
FindObjectOfType<God>().PauseMenu.GetComponent<PauseScreen>().Gatekeeper = this;
}
public void RefreshButtons()
{
B.Clear();
Transform T = GameObject.Find("Canvas").transform.GetChild(3).GetChild(0);
LoadingBarPanel = GameObject.Find("Canvas").transform.GetChild(6);
StartButton.Instance.LoadingBar = LoadingBarPanel.gameObject;
StartButton.Instance.LoadingSlider = LoadingBarPanel.GetChild(0).GetComponent<Slider>();
B.Add(T.GetChild(0).GetComponent<Button>());
B.Add(T.GetChild(1).GetComponent<Button>());
B.Add(T.GetChild(2).GetComponent<Button>());
B.Add(T.GetChild(3).GetComponent<Button>());
B.Add(T.GetChild(4).GetComponent<Button>());
B.Add(T.GetChild(5).GetComponent<Button>());
B.Add(T.GetChild(6).GetComponent<Button>());
B.Add(T.GetChild(7).GetComponent<Button>());
AddListeners();
GameObject.Find("Instructions").GetComponentInChildren<TextMeshProUGUI>().text = TutorialPossible
? "Tutorial: <color=#05af05>On"
: "Tutorial: <color=#af0505>Off";
GameObject.Find("Instructions").GetComponent<Button>().onClick.AddListener(ToggleTutorial);
}
private void ToggleTutorial()
{
TutorialPossible = !TutorialPossible;
GameObject.Find("Instructions").GetComponentInChildren<TextMeshProUGUI>().text = TutorialPossible
? "Tutorial: <color=#05af05>On"
: "Tutorial: <color=#af0505>Off";
}
private void AddListeners()
{
B[0].onClick.AddListener(delegate { LoadGameSlot(0); });
B[1].onClick.AddListener(delegate { LoadGameSlot(1); });
B[2].onClick.AddListener(delegate { LoadGameSlot(2); });
B[3].onClick.AddListener(delegate { LoadGameSlot(3); });
B[4].onClick.AddListener(delegate { LoadGameSlot(4); });
B[5].onClick.AddListener(delegate { LoadGameSlot(5); });
B[6].onClick.AddListener(delegate { LoadGameSlot(6); });
B[7].onClick.AddListener(delegate { LoadGameSlot(7); });
}
public void RemoveListeners()
{
B.ForEach(x => x.onClick.RemoveAllListeners());
B.Clear();
}
public void LoadGameSlot(int SaveSlot)
{
RemoveListeners();
Data = SaveSystem.LoadPlayer(SaveSlot);
if(Data != null)
{
DidILoad = true;
GameObject.Find("SceneManager").GetComponent<StartButton>().SceneLoader();
}
}
public void RetrieveData(God God)
{
if (DidILoad)
{
//Debug.Log("<color=#058505><b>Retrieved!</b></color> Duh...");
God.UpdateData();
}
else
{
//Debug.Log("<color=#850505><b>Did not retrieve :(</b></color>");
God.DefaultData();
}
LoadingBarPanel = God.LoadingBar;
StartButton.Instance.LoadingBar = LoadingBarPanel.gameObject;
StartButton.Instance.LoadingSlider = LoadingBarPanel.GetChild(0).GetComponent<Slider>();
DidILoad = false;
Data = null;
}
}
This script firstly controls the rails of the conveyor belt it is attached to. It also manages the list of objects that it is currently moving. If there is a backlog of objects to move, it informs G.O.D. of the overload error and displays it to the player.
585 lines
Click to expandusing System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ConveyorBelt : MonoBehaviour
{
public GameObject ObjectHandler;
private CreateObject OHCO;
private float speed = 0.03f;
private God God;
private int yo = 0;
[HideInInspector]
public string MaterialType = "S";
[SerializeField]
private List<GameObject> Queue = new List<GameObject>();
[SerializeField]
private List<GameObject> BlackList = new List<GameObject>();
private bool OverloadedBeltError = false;
private float ErrorResolutionTimestamp = 0;
private bool ThereWasAnError = false;
[HideInInspector]
public ConveyorColors BeltColor = new ConveyorColors();
private ReuseMaterials ObjectPooler;
public Renderer BeltRenderer;
private void Awake()
{
BeltRenderer = transform.GetChild(0).GetComponent<Renderer>();
ObjectHandler = GameObject.Find("ObjectHandler");
OHCO = ObjectHandler.GetComponent<CreateObject>();
God = God.Instance;
ObjectPooler = ReuseMaterials.Instance;
}
private void Update()
{
yo = 0;
if (!OverloadedBeltError /* The error is gone but */ && ThereWasAnError)
{
if (Time.time - ErrorResolutionTimestamp >= 5f)
{
God.ComponentErrorResolved(transform);
ThereWasAnError = false;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (!other.gameObject.CompareTag("Floor") &&
!other.CompareTag("Rail") &&
(other.transform.IsChildOf(God.ObjectHandler.transform) || other.CompareTag("Baby")))
{
CheckItem(other);
}
else
{
BlackList.Add(other.gameObject);
}
}
private void OnTriggerExit(Collider other)
{
if (Queue.Contains(other.gameObject))
{
Queue.Remove(other.gameObject);
}
else if (BlackList.Contains(other.gameObject))
{
BlackList.Remove(other.gameObject);
}
}
private void OnTriggerStay(Collider other)
{
if (Queue.Contains(other.gameObject))
{
Move(other.transform);
}
else if (!BlackList.Contains(other.gameObject))
{
CheckItem(other);
}
}
private void CheckItem(Collider other)
{
if (Queue.Count < 5)
{
Queue.Add(other.gameObject);
if (ThereWasAnError)
{
CheckForOverloadError();
}
}
else
{
CheckQueueIsNotBroken(other);
}
}
private void CheckQueueIsNotBroken(Collider other)
{
if(Queue.Count > 0)
{
if (Queue.Any(x => x.gameObject == null || x.transform.parent == ObjectPooler.transform))
{
Queue.RemoveAll(x => x.gameObject == null || x.transform.parent == ObjectPooler.transform);
}
if(Queue.Count < 5)
{
CheckItem(other);
return;
}
}
yo++;
if(yo > 10)
{
ObjectPooler.Deactivate(other.gameObject);
if (!ThereWasAnError)
{
God.ComponentError(transform, transform.position);
}
OverloadedBeltError = true;
ThereWasAnError = true;
}
else
{
CheckForOverloadError();
}
}
private void RefreshQueue()
{
if(Queue.Count > 0)
{
if (Queue.Any(x => x.gameObject == null || x.transform.parent == ObjectPooler.transform))
{
Queue.RemoveAll(x => x.gameObject == null || x.transform.parent == ObjectPooler.transform);
}
}
}
private void CheckForOverloadError()
{
if (yo < 10 && OverloadedBeltError)
{
OverloadedBeltError = false;
ErrorResolutionTimestamp = Time.time;
}
}
private void Move(Transform o)
{
if (Mathf.Round(transform.localEulerAngles.y) == 0)
{
if (Mathf.Abs(transform.position.x - o.position.x) >= 0.07)
{
o.position += new Vector3(((transform.position.x - o.position.x) /
Mathf.Abs(transform.position.x - o.position.x)) * speed, 0, 0);
}
else
{
o.position += new Vector3(0, 0, -speed);
}
}
else if (Mathf.Round(transform.localEulerAngles.y) == 90)
{
if (Mathf.Abs(transform.position.z - o.position.z) >= 0.07)
{
o.position += new Vector3(0, 0, ((transform.position.z - o.position.z) /
Mathf.Abs(transform.position.z - o.position.z)) * speed);
}
else
{
o.position += new Vector3(-speed, 0, 0);
}
}
else if (Mathf.Round(transform.localEulerAngles.y) == 180)
{
if (Mathf.Abs(transform.position.x - o.position.x) >= 0.07)
{
o.position += new Vector3(((transform.position.x - o.position.x) /
Mathf.Abs(transform.position.x - o.position.x)) * speed, 0, 0);
}
else
{
o.position += new Vector3(0, 0, speed);
}
}
else if (Mathf.Round(transform.localEulerAngles.y) == 270)
{
if (Mathf.Abs(transform.position.z - o.position.z) >= 0.07)
{
o.position += new Vector3(0, 0, ((transform.position.z - o.position.z) /
Mathf.Abs(transform.position.z - o.position.z)) * speed);
}
else
{
o.position += new Vector3(speed, 0, 0);
}
}
}
public void OnCreation(bool FirstTime = true, bool rotate = false)
{
Collider[] Left = new Collider[] { };
Collider[] Right = new Collider[] { };
Collider[] Front = new Collider[] { };
Collider[] Back = new Collider[] { };
bool LeftFull = false, RightFull = false;
Left = Physics.OverlapSphere(transform.position - transform.right, 0.4f);
Right = Physics.OverlapSphere(transform.position + transform.right, 0.4f);
Front = Physics.OverlapSphere(transform.position - transform.forward, 0.4f);
Back = Physics.OverlapSphere(transform.position + transform.forward, 0.4f);
if (!FirstTime)
{
if (transform.GetComponentsInChildren<Transform>().ToList()
.Exists(x => x.gameObject.name.Contains("_Rail")))
{
transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.gameObject.name.Contains("_Rail"))
.ForEach(x => Destroy(x.gameObject));
}
}
else
{
BeltRenderer.material.color = BeltColor.color;
}
if (!Back.ToList().Exists(x => x.CompareTag("ConveyorBelt")))
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.localEulerAngles = Vector3.zero;
Rail.transform.SetAsLastSibling();
}
else if (!Back.ToList().Exists(x => x.name.Contains("Internal")))
{
Transform Convey = Back.ToList().FirstOrDefault(x => x.name == "ConveyorBelt" ||
x.name == "ComplexConveyorBelt" ||
x.name == "RightSelector" ||
x.name == "LeftSelector").transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
Vector3 back = Convey.position + Convey.forward;
back = new Vector3(Mathf.RoundToInt(back.x), Mathf.RoundToInt(back.y), Mathf.RoundToInt(back.z));
bool IAmBehind = back == transform.position;
Vector3 left = Convey.position - Convey.right;
left = new Vector3(Mathf.RoundToInt(left.x), Mathf.RoundToInt(left.y), Mathf.RoundToInt(left.z));
bool IAmToTheLeft = left == transform.position;
Vector3 right = Convey.position + Convey.right;
right = new Vector3(Mathf.RoundToInt(right.x), Mathf.RoundToInt(right.y), Mathf.RoundToInt(right.z));
bool IAmToTheRight = right == transform.position;
switch (Convey.name)
{
case "ConveyorBelt":
if (!IAmInFront)
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
}
break;
case "ComplexConveyorBelt":
if (IAmBehind)
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
}
break;
case "RightSelector":
if (!IAmInFront && !IAmToTheRight)
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
}
break;
case "LeftSelector":
if (!IAmInFront && !IAmToTheLeft)
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
}
break;
}
}
else
{
Transform Convey = Back.ToList().FirstOrDefault(x => x.name.Contains("Internal")).transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
if (!IAmInFront)
{
GameObject Rail = Instantiate(God.RailPrefabs[4], transform.position, Quaternion.identity, transform);
Rail.name = "Back_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
}
}
if (!Left.ToList().Exists(x => x.CompareTag("ConveyorBelt")))
{
GameObject Rail = Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform);
Rail.name = "Left_Rail";
Rail.transform.localEulerAngles = Vector3.zero;
Rail.transform.SetAsLastSibling();
LeftFull = true;
}
else if (!Left.ToList().Exists(x => x.name.Contains("Internal")))
{
Transform Convey = Left.ToList().FirstOrDefault(x => x.name == "ConveyorBelt" ||
x.name == "ComplexConveyorBelt" ||
x.name == "RightSelector" ||
x.name == "LeftSelector").transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
Vector3 back = Convey.position + Convey.forward;
back = new Vector3(Mathf.RoundToInt(back.x), Mathf.RoundToInt(back.y), Mathf.RoundToInt(back.z));
bool IAmBehind = back == transform.position;
Vector3 left = Convey.position - Convey.right;
left = new Vector3(Mathf.RoundToInt(left.x), Mathf.RoundToInt(left.y), Mathf.RoundToInt(left.z));
bool IAmToTheLeft = left == transform.position;
Vector3 right = Convey.position + Convey.right;
right = new Vector3(Mathf.RoundToInt(right.x), Mathf.RoundToInt(right.y), Mathf.RoundToInt(right.z));
bool IAmToTheRight = right == transform.position;
GameObject Rail = null;
switch (Convey.name)
{
case "ConveyorBelt":
Rail = IAmInFront
? Instantiate(God.RailPrefabs[1], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront
? "Left_Rail_Cut"
: "Left_Rail";
Rail.transform.SetAsLastSibling();
break;
case "ComplexConveyorBelt":
Rail = IAmBehind
? Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[1], transform.position, Quaternion.identity, transform);
Rail.name = IAmBehind
? "Left_Rail"
: "Left_Rail_Cut";
Rail.transform.SetAsLastSibling();
break;
case "RightSelector":
Rail = IAmInFront || IAmToTheRight
? Instantiate(God.RailPrefabs[1], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront || IAmToTheRight
? "Left_Rail_Cut"
: "Left_Rail";
Rail.transform.SetAsLastSibling();
break;
case "LeftSelector":
Rail = IAmInFront || IAmToTheLeft
? Instantiate(God.RailPrefabs[1], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront || IAmToTheLeft
? "Left_Rail_Cut"
: "Left_Rail";
Rail.transform.SetAsLastSibling();
break;
}
Rail.transform.localEulerAngles = Vector3.zero;
LeftFull = !Rail.name.Contains("_Cut");
}
else
{
Transform Convey = Left.ToList().FirstOrDefault(x => x.name.Contains("Internal")).transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
GameObject Rail = IAmInFront
? Instantiate(God.RailPrefabs[1], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[0], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront
? "Left_Rail_Cut"
: "Left_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
LeftFull = !Rail.name.Contains("_Cut");
}
if (!Right.ToList().Exists(x => x.CompareTag("ConveyorBelt")))
{
GameObject Rail = Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform);
Rail.name = "Right_Rail";
Rail.transform.localEulerAngles = Vector3.zero;
Rail.transform.SetAsLastSibling();
RightFull = true;
}
else if (!Right.ToList().Exists(x => x.name.Contains("Internal")))
{
Transform Convey = Right.ToList().FirstOrDefault(x => x.name == "ConveyorBelt" ||
x.name == "ComplexConveyorBelt" ||
x.name == "RightSelector" ||
x.name == "LeftSelector").transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
Vector3 back = Convey.position + Convey.forward;
back = new Vector3(Mathf.RoundToInt(back.x), Mathf.RoundToInt(back.y), Mathf.RoundToInt(back.z));
bool IAmBehind = back == transform.position;
Vector3 left = Convey.position - Convey.right;
left = new Vector3(Mathf.RoundToInt(left.x), Mathf.RoundToInt(left.y), Mathf.RoundToInt(left.z));
bool IAmToTheLeft = left == transform.position;
Vector3 right = Convey.position + Convey.right;
right = new Vector3(Mathf.RoundToInt(right.x), Mathf.RoundToInt(right.y), Mathf.RoundToInt(right.z));
bool IAmToTheRight = right == transform.position;
GameObject Rail = null;
switch (Convey.name)
{
case "ConveyorBelt":
Rail = IAmInFront
? Instantiate(God.RailPrefabs[3], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront
? "Right_Rail_Cut"
: "Right_Rail";
Rail.transform.SetAsLastSibling();
break;
case "ComplexConveyorBelt":
Rail = IAmBehind
? Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[3], transform.position, Quaternion.identity, transform);
Rail.name = IAmBehind
? "Right_Rail"
: "Right_Rail_Cut";
Rail.transform.SetAsLastSibling();
break;
case "RightSelector":
Rail = IAmInFront || IAmToTheRight
? Instantiate(God.RailPrefabs[3], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront || IAmToTheRight
? "Right_Rail_Cut"
: "Right_Rail";
Rail.transform.SetAsLastSibling();
break;
case "LeftSelector":
Rail = IAmInFront || IAmToTheLeft
? Instantiate(God.RailPrefabs[3], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront || IAmToTheLeft
? "Right_Rail_Cut"
: "Right_Rail";
Rail.transform.SetAsLastSibling();
break;
}
Rail.transform.localEulerAngles = Vector3.zero;
RightFull = !Rail.name.Contains("_Cut");
}
else
{
Transform Convey = Right.ToList().FirstOrDefault(x => x.name.Contains("Internal")).transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
bool IAmInFront = front == transform.position;
GameObject Rail = IAmInFront
? Instantiate(God.RailPrefabs[3], transform.position, Quaternion.identity, transform)
: Instantiate(God.RailPrefabs[2], transform.position, Quaternion.identity, transform);
Rail.name = IAmInFront
? "Right_Rail_Cut"
: "Right_Rail";
Rail.transform.SetAsLastSibling();
Rail.transform.localEulerAngles = Vector3.zero;
RightFull = !Rail.name.Contains("_Cut");
}
if (Front.ToList().Exists(x => x.name == "ConveyorBelt" && x.gameObject != gameObject))
{
Transform Convey = Front.ToList().FirstOrDefault(x => x.name == "ConveyorBelt" && x.gameObject != gameObject).transform;
Vector3 front = Convey.position - Convey.forward;
front = new Vector3(Mathf.RoundToInt(front.x), Mathf.RoundToInt(front.y), Mathf.RoundToInt(front.z));
if (front != transform.position)
{
Front.ToList().FirstOrDefault(x => x.name == "ConveyorBelt").gameObject.GetComponent<ConveyorBelt>().InvokeMoveUpdate();
}
}
else if(Front.ToList().Exists(x => x.tag == "Seller"))
{
InvokeRepeating("RefreshQueue", 0.5f, 0.5f);
}
else
{
CancelInvoke("RefreshQueue");
}
Color c = BeltColor.color;
if (BeltRenderer.material.color != BeltColor.color)
{
c = BeltRenderer.material.color;
transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.gameObject.name.Contains("_Rail"))
.ForEach(x => x.GetComponentsInChildren<Renderer>().ToList()
.ForEach(a => a.material.color =
new Color(BeltColor.color.r - 0.3f, BeltColor.color.g - 0.3f, BeltColor.color.b - 0.3f)));
}
if (LeftFull)
{
if (RightFull)
{
BeltRenderer.material = OHCO.ConveyorBeltMats[0];
}
else
{
BeltRenderer.material = OHCO.ConveyorBeltMats[2];
}
}
else
{
if (RightFull)
{
BeltRenderer.material = OHCO.ConveyorBeltMats[3];
}
else
{
BeltRenderer.material = OHCO.ConveyorBeltMats[1];
}
}
BeltRenderer.material.color = c;
}
public void InvokeMoveUpdate()
{
Invoke("MoveUpdate", 0.025f);
}
void MoveUpdate()
{
OnCreation(false);
}
public void Editing(string mode, Vector3 pos = default) //Moved, Rotate, or Delete
{
if (mode == "Moved" || mode == "Rotate") {
Collider[] Pre = Physics.OverlapBox(pos, new Vector3(0.9f, 0.4f, 0.9f));
Collider[] Post = Physics.OverlapBox(transform.position, new Vector3(0.9f, 0.4f, 0.9f));
if (Pre.ToList().Exists(x => x.name == "ConveyorBelt") && mode == "Moved")
{
Pre.ToList().FindAll(x => x.name == "ConveyorBelt").ForEach(x => x.GetComponent<ConveyorBelt>().InvokeMoveUpdate());
}
if (Post.ToList().Exists(x => x.name == "ConveyorBelt"))
{
Post.ToList().FindAll(x => x.name == "ConveyorBelt").ForEach(x => x.GetComponent<ConveyorBelt>().InvokeMoveUpdate());
}
OnCreation(false, mode == "Rotate");
}
else if (mode == "Delete")
{
Collider[] Left = Physics.OverlapBox(new Vector3(transform.position.x - 1, transform.position.y, transform.position.z),
new Vector3(0.4f, 0.4f, 0.4f));
Collider[] Right = Physics.OverlapBox(new Vector3(transform.position.x + 1, transform.position.y, transform.position.z),
new Vector3(0.4f, 0.4f, 0.4f));
Collider[] Front = Physics.OverlapBox(new Vector3(transform.position.x, transform.position.y, transform.position.z - 1),
new Vector3(0.4f, 0.4f, 0.4f));
Collider[] Back = Physics.OverlapBox(new Vector3(transform.position.x, transform.position.y, transform.position.z + 1),
new Vector3(0.4f, 0.4f, 0.4f));
gameObject.SetActive(false);
if (Left.ToList().Exists(x => x.name == "ConveyorBelt"))
{
Left.ToList().FirstOrDefault(x => x.name == "ConveyorBelt").GetComponent<ConveyorBelt>().OnCreation(false);
}
if (Right.ToList().Exists(x => x.name == "ConveyorBelt") && mode != "Rotate")
{
Right.ToList().FirstOrDefault(x => x.name == "ConveyorBelt").GetComponent<ConveyorBelt>().OnCreation(false);
}
if (Front.ToList().Exists(x => x.name == "ConveyorBelt"))
{
Front.ToList().FirstOrDefault(x => x.name == "ConveyorBelt").GetComponent<ConveyorBelt>().OnCreation(false);
}
if (Back.ToList().Exists(x => x.name == "ConveyorBelt"))
{
Back.ToList().FirstOrDefault(x => x.name == "ConveyorBelt").GetComponent<ConveyorBelt>().OnCreation(false);
}
Destroy(gameObject);
}
}
}
This manages the UI for the Input component and updates the variables in the functional class.
116 lines
Click to expandusing UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Linq;
public class InputBlock : MonoBehaviour
{
public int AmountNum = 0;
public TextMeshProUGUI Amount;
public TextMeshProUGUI MaterialName;
public string Material = null;
public InputBlockData Data;
public God God;
private TextMeshProUGUI AmountPerSpeed, AmountPerSecond, MaxAmount;
public void Start()
{
God = God.Instance;
Amount = God.InputInterface.transform.GetChild(2).GetChild(2).GetComponent<TextMeshProUGUI>();
MaterialName = God.InputInterface.transform.GetChild(1).GetChild(0).GetComponent<TextMeshProUGUI>();
AmountPerSpeed = God.InputInterface.transform.GetChild(6).GetChild(0).GetComponentInChildren<TextMeshProUGUI>();
AmountPerSecond = God.InputInterface.transform.GetChild(6).GetChild(1).GetComponentInChildren<TextMeshProUGUI>();
MaxAmount = God.InputInterface.transform.GetChild(5).GetComponentInChildren<TextMeshProUGUI>();
Amount.SetText(AmountNum.ToString());
}
public void Interface(Transform Who)
{
Data = Who.GetComponent<InputBlockData>();
AmountNum = Data.AmountNum;
Material = Data.Material;
MaterialName.text = Material;
Amount.text = AmountNum.ToString();
AmountPerSpeed.text = AmountNum > 1 || AmountNum == 0
? $"{AmountNum} per \n {Data.ProducingSpeed} secs"
: $"{AmountNum} per \n {Data.ProducingSpeed} sec";
AmountPerSecond.text = $"{AmountNum / Data.ProducingSpeed} per \n 1 sec";
MaxAmount.text = $"Max: {Data.AmountRange[1]}";
if (Data.Material == "" || Data.Material == null)
{
God.InputInterface.transform.GetChild(2).GetChild(0).GetComponent<Button>().interactable = false;
God.InputInterface.transform.GetChild(2).GetChild(1).GetComponent<Button>().interactable = false;
}
else
{
God.InputInterface.transform.GetChild(2).GetChild(0).GetComponent<Button>().interactable = true;
God.InputInterface.transform.GetChild(2).GetChild(1).GetComponent<Button>().interactable = true;
}
}
public void IncreaseAmount()
{
if (AmountNum < Data.AmountRange[1] && Data.Material != null)
{
AmountNum++;
}
Amount.text = AmountNum.ToString();
Data.AmountNum = AmountNum;
AmountPerSpeed.text = AmountNum > 1 || AmountNum == 0
? $"{AmountNum} per \n {Data.ProducingSpeed} secs"
: $"{AmountNum} per \n {Data.ProducingSpeed} sec";
AmountPerSecond.text = $"{AmountNum / Data.ProducingSpeed} per \n 1 sec";
Data.UpdateInfo();
if (God.RunningThroughTutorial)
{
if(God.ComponentHandler.GetComponentsInChildren<Transform>().ToList().FindAll(x => x.name == "input").All(x => x.GetComponent<InputBlockData>().AmountNum >= 1))
{
GameObject.Find("Tutorial Man").GetComponent<TutorialMan>().NextStep("Increased amounts");
}
}
}
public void DecreaseAmount()
{
if (AmountNum > Data.AmountRange[0]) {
AmountNum--;
}
Amount.text = AmountNum.ToString();
Data.AmountNum = AmountNum;
AmountPerSpeed.text = AmountNum > 1 || AmountNum == 0
? $"{AmountNum} per \n {Data.ProducingSpeed} secs"
: $"{AmountNum} per \n {Data.ProducingSpeed} sec";
AmountPerSecond.text = $"{AmountNum / Data.ProducingSpeed} per \n 1 sec";
Data.UpdateInfo();
}
public void ChangeMaterial(GameObject Selected)
{
Material = Selected.name;
MaterialName.text = Material;
Data.Material = Material;
Data.UpdateInfo();
God.InputInterface.transform.GetChild(2).GetChild(0).GetComponent<Button>().interactable = true;
God.InputInterface.transform.GetChild(2).GetChild(1).GetComponent<Button>().interactable = true;
if (God.RunningThroughTutorial)
{
int cop = 0;
int gol = 0;
God.ComponentHandler.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name == "input")
.ForEach(x =>
{
if (x.GetComponent<InputBlockData>().Material == "Gold")
{
gol++;
}
else if (x.GetComponent<InputBlockData>().Material == "Copper")
{
cop++;
}
});
if(gol >= 1 && cop >= 2)
{
GameObject.Find("Tutorial Man").GetComponent<TutorialMan>().NextStep("Correct Materials");
}
}
}
}
This holds some data about how it's functioning to display to the player as well as communicates with the Object Handler to create new materials.
48 lines
Click to expandusing UnityEngine;
public class InputBlockData : MonoBehaviour
{
private GameObject ObjectHandler;
public bool CanIProduce = false;
public int AmountNum = 0;
public string Material = "Iron";
private Material Mat;
public float ProducingSpeed = 1f;
public float speed = 0.05f;
public CreateObject OHCO;
private bool Producing = false;
[HideInInspector]
public int[] AmountRange = new int[2] {0, 5};
void Start()
{
ObjectHandler = CreateObject.Instance.gameObject;
OHCO = CreateObject.Instance;
UpdateInfo();
Mat = Resources.Load<Material>("Materials/Iron");
}
public void UpdateInfo()
{
if(AmountNum > 0 && Material != null)
{
CanIProduce = true;
Mat = Resources.Load("Materials/" + Material) as Material;
}
else
{
CanIProduce = false;
}
}
void Update()
{
if (!Producing && CanIProduce && OHCO.God.Money > 0)
{
Producing = true;
Invoke("CallProducerUpAndTellHimToMake", ProducingSpeed/AmountNum);
}
}
public void CallProducerUpAndTellHimToMake()
{
OHCO.CloneObject(Mat, this.gameObject, this.gameObject);
Producing = false;
}
}
All the simple machines use the same UI interface. This script updates the interface to display what kind of machine it is and what it's currently making to the player.
132 lines
Click to expandusing System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SimpleProducerInterface : MonoBehaviour
{
[HideInInspector]
public TextMeshProUGUI Cost;
public float cost;
[HideInInspector]
public TextMeshProUGUI Speed;
public float speed;
[HideInInspector]
public TextMeshProUGUI Name;
[HideInInspector]
public MachineData Data;
[HideInInspector]
public God God;
public List<RawImage> QueuePics;
public RawImage InputPic;
public RawImage ProductPic;
private TextMeshProUGUI ProductText;
void Start()
{
God = God.Instance;
Cost = God.MachineInterface.transform.GetChild(1).GetChild(0).GetChild(2).GetComponent<TextMeshProUGUI>();
Speed = God.MachineInterface.transform.GetChild(1).GetChild(1).GetChild(2).GetComponent<TextMeshProUGUI>();
Name = God.MachineInterface.transform.GetChild(0).GetComponentInChildren<TextMeshProUGUI>();
ProductText = God.MachineInterface.transform.GetChild(1).GetChild(2).GetChild(1).GetComponent<TextMeshProUGUI>();
for (int i = 0; i < 5; i++)
{
QueuePics.Add(God.MachineInterface.transform.GetChild(1).GetChild(3).GetChild(i).GetComponentInChildren<RawImage>());
QueuePics[i].texture = God.Icons.FirstOrDefault(icon => icon.Key == "Basic").Value;
}
InputPic = God.MachineInterface.transform.GetChild(1).GetChild(2).GetChild(3).GetComponentInChildren<RawImage>();
InputPic.texture = God.Icons.FirstOrDefault(icon => icon.Key == "Basic").Value;
ProductPic = God.MachineInterface.transform.GetChild(1).GetChild(2).GetChild(0).GetComponentInChildren<RawImage>();
}
public void Interface(Transform Who)
{
Data = Who.GetComponent<MachineData>();
cost = Data.transform.GetComponent<MachineData>().Cost;
speed = Data.transform.GetComponent<MachineData>().Speed;
Cost.text = cost.ToString();
Speed.text = speed.ToString();
Name.text = Who.gameObject.name;
if (Who.GetComponent<SimpleProducer>().Producing)
{
CreatingObject();
}
else
{
ProductPic.color = new Color(0, 0, 0, 0);
InputPic.color = new Color(0, 0, 0, 0);
}
for(int i = 0; i < 5; i++)
{
if (Who.GetComponent<SimpleProducer>().Queue.Count-1 > i)
{
int i2 = i+1;
QueuePics[i].color = God.MatColors.FirstOrDefault(icon => icon.Key == Who.GetComponent<SimpleProducer>().Queue[i2].name).Value;
}
else
{
QueuePics[i].color = new Color(0, 0, 0, 0);
}
}
}
public void UpdateInterface()
{
cost = Data.Cost;
speed = Data.Speed;
Cost.text = cost.ToString();
Speed.text = speed.ToString();
Name.text = Data.gameObject.name;
if (Data.gameObject.GetComponent<SimpleProducer>().Producing)
{
CreatingObject();
}
else
{
ProductPic.color = new Color(0, 0, 0, 0);
InputPic.color = new Color(0, 0, 0, 0);
}
for (int i = 0; i < 5; i++)
{
if (Data.gameObject.GetComponent<SimpleProducer>().Queue.Count-1 > i)
{
int i2 = i + 1;
QueuePics[i].color = God.MatColors.FirstOrDefault(icon => icon.Key == Data.gameObject.GetComponent<SimpleProducer>().Queue[i2].name).Value;
}
else
{
QueuePics[i].color = new Color(0, 0, 0, 0);
}
}
}
public void CreatingObject()
{
Color c = God.MatColors.FirstOrDefault(icon => icon.Key ==
Data.gameObject.GetComponent<SimpleProducer>().WhatMatColor).Value;
string n = God.MatColors.FirstOrDefault(icon => icon.Key ==
Data.gameObject.GetComponent<SimpleProducer>().WhatMatColor).Key;
switch (Data.gameObject.name)
{
case "Furnace":
ProductPic.texture = God.Icons.FirstOrDefault(icon => icon.Key == "Liquid").Value;
ProductText.text = "Liquid " + n;
break;
case "Hydralic Press":
ProductPic.texture = God.Icons.FirstOrDefault(icon => icon.Key == "Plate").Value;
ProductText.text = n + " Plate";
break;
case "Gear Cutter":
ProductPic.texture = God.Icons.FirstOrDefault(icon => icon.Key == "Gear").Value;
ProductText.text = n + " Gear";
break;
case "Wire Drawer":
ProductPic.texture = God.Icons.FirstOrDefault(icon => icon.Key == "Wire").Value;
ProductText.text = n + " Wire";
break;
}
ProductPic.color = c;
InputPic.color = c;
}
}
All the simple machines use the same basic functions to run their tasks. When this script tells the Object Handler to instantiate a new material, the Object Handler looks at the name of the component the script is attached to in order to figure out what type of material it should make.
208 lines
Click to expandusing System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SimpleProducer : MonoBehaviour, IComponent
{
public string input;
public string output;
public GameObject ObjectHandler;
private CreateObject OHCO;
public Transform Direction;
public God God;
public bool Producing = false;
public string WhatMatColor = null;
public GameObject ListOMats;
GameObject o;
public List<GameObject> Queue;
private MachineData MachineData;
private float WaitTime = 1f;
private SimpleProducerInterface Interface;
public bool IPlayedMySound = false;
private ReuseMaterials ObjectPooler;
void Start()
{
ObjectPooler = ReuseMaterials.Instance;
God = God.Instance;
Interface = God.Machine_Interface;
Direction = transform.GetChild(1);
ObjectHandler = GameObject.Find("ObjectHandler");
OHCO = ObjectHandler.GetComponent<CreateObject>();
Queue = new List<GameObject>(6);
MachineData = transform.GetComponent<MachineData>();
WaitTime = MachineData.Speed;
InvokeRepeating("CostPerSecond", 1f, 1f);
}
public void CostPerSecond()
{
if (Producing)
{
God.Money -= GetComponent<MachineData>().Cost;
God.UpdateMoney();
}
}
void Update()
{
if (Queue.Count > 0)
{
if (!Producing && Queue[0] != null)
{
o = Queue[0].gameObject;
Producing = true;
WhatMatColor = OHCO.IdentifyMaterial(o.gameObject).name;
if (God.MouseOver == transform && God.InterfaceOpen)
{
Interface.UpdateInterface();
}
if (!IPlayedMySound)
{
IPlayedMySound = true;
switch (gameObject.name)
{
case "Hydralic Press":
God.AudioManager.Play("PressLoop");
break;
case "Gear Cutter":
God.AudioManager.Play("PressLoop");
break;
case "Wire Drawer":
God.AudioManager.Play("DieCutting");
break;
case "Furnace":
break;
}
}
Invoke("something", WaitTime);
}
if (Queue[0] == null)
{
Queue.RemoveAt(0);
}
}
}
public void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Material"))
{
if (Queue.Count < Queue.Capacity)
{
Queue.Add(other.gameObject);
if (God.MouseOver == transform && God.InterfaceOpen)
{
Interface.UpdateInterface();
}
other.transform.position = transform.position;
other.gameObject.SetActive(false);
}
else
{
ObjectPooler.Deactivate(other.gameObject);
}
}
else if (other.CompareTag("Baby"))
{
other.tag = "SimpleMaterial";
}
else if (other.CompareTag("SimpleMaterial") || other.CompareTag("CraftedObject"))
{
ObjectPooler.Deactivate(other.gameObject);
}
}
void something()
{
if (Queue.Count >= 1)
{
Queue.RemoveAt(0);
OHCO.CloneObject(OHCO.IdentifyMaterial(o.gameObject), o.gameObject, this.gameObject);
Producing = false;
}
if (God.MouseOver == transform && God.InterfaceOpen)
{
Interface.UpdateInterface();
}
}
private Collider[] TempColliders = new Collider[] { };
public void PreDelete()
{
if (IPlayedMySound)
{
switch (gameObject.name)
{
case "Hydralic Press":
God.AudioManager.Stop("PressLoop");
if (transform.parent.GetComponentsInChildren<Transform>().ToList().Exists(x => (x.name == "Hydralic Press" || x.name == "Gear Cutter") &&
x.gameObject != gameObject && x.parent == transform.parent))
{
transform.parent.GetComponentsInChildren<Transform>().ToList().Find(x => (x.name == "Hydralic Press" || x.name == "Gear Cutter") &&
x.gameObject != gameObject && x.parent == transform.parent).gameObject.GetComponent<SimpleProducer>().IPlayedMySound = false;
}
break;
case "Gear Cutter":
God.AudioManager.Stop("PressLoop");
if (transform.parent.GetComponentsInChildren<Transform>().ToList().Exists(x => (x.name == "Hydralic Press" || x.name == "Gear Cutter") &&
x.gameObject != gameObject && x.parent == transform.parent))
{
transform.parent.GetComponentsInChildren<Transform>().ToList().Find(x => (x.name == "Hydralic Press" || x.name == "Gear Cutter") &&
x.gameObject != gameObject && x.parent == transform.parent).gameObject.GetComponent<SimpleProducer>().IPlayedMySound = false;
}
break;
case "Wire Drawer":
God.AudioManager.Stop("DieCutting");
if (transform.parent.GetComponentsInChildren<Transform>().LongCount(x => x.name == "Wire Drawer") > 1)
{
transform.parent.GetComponentsInChildren<Transform>().FirstOrDefault(x => x.name == "Wire Drawer" &&
x.gameObject != gameObject).gameObject.GetComponent<SimpleProducer>().IPlayedMySound = false;
}
break;
case "Furnace":
break;
}
}
CancelInvoke();
if (Queue.Count > 0)
{
for (int g = Queue.Count - 1; g >= 0; g--)
{
ObjectPooler.Deactivate(Queue[g]);
God.Money += 5;
}
}
Queue.Clear();
God.Money += 15;
God.UpdateMoney();
Collider[] c = Physics.OverlapBox(transform.position - transform.forward, new Vector3(0.4f, 0.4f, 0.4f));
if(c.ToList().Exists(x => x.gameObject.name == "ConveyorBelt"))
{
TempColliders = c;
God.UpdateConveyors(TempColliders);
}
}
public void PostCreation()
{
if (transform.parent.GetComponentsInChildren<Transform>().Any(x => x.gameObject.name == "ConveyorBelt"))
{
Collider[] c = Physics.OverlapBox(transform.position - transform.forward, new Vector3(0.4f, 0.4f, 0.4f));
if (c.ToList().Exists(x => x.gameObject.name == "ConveyorBelt"))
{
TempColliders = c;
Invoke("UpdateConveyors", 0.025f);
}
}
}
public void PreMove()
{
}
public void PostMove()
{
}
public void PostRotate()
{
}
private void UpdateConveyors()
{
TempColliders.ToList().FindAll(x => x.gameObject.name == "ConveyorBelt").ForEach(x => x.transform.GetComponent<ConveyorBelt>().OnCreation(false));
}
}
This class manages the interface for the crafter. That includes being able to select a crafting recipe, seeing the ingredients for said material, displaying whether or not the crafter contains enough of the ingredients to craft the recipe, and displaying everything that the crafter component has in it's storage.
197 lines
Click to expandusing System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Linq;
public class CraftingInterface : MonoBehaviour
{
[HideInInspector]
public TextMeshProUGUI Cost;
[HideInInspector]
public TextMeshProUGUI Speed;
[HideInInspector]
public TextMeshProUGUI ProductionItem;
public List<TextMeshProUGUI> IngedientAmounts = new List<TextMeshProUGUI>();
public List<Image> IngedientBubbles = new List<Image>();
public List<RawImage> IngedientPics = new List<RawImage>();
public List<GameObject> PrisonSlots = new List<GameObject>();
public RawImage ProductPic;
[HideInInspector]
public Crafter Data;
[HideInInspector]
public God God;
private RecipeDatabase rd;
private Transform transformT;
private GameObject ObjectHandler;
private List<string> MatNames;
void Start()
{
God = God.Instance;
MatNames = new List<string>()
{
"Iron",
"Copper",
"Gold",
"Aluminum",
"Diamond"
};
ObjectHandler = GameObject.Find("ObjectHandler");
transformT = God.CrafterInterface.transform;
ProductPic = transformT.GetChild(1).GetChild(2).GetChild(0).GetComponentInChildren<RawImage>();
Cost = transformT.GetChild(1).GetChild(0).GetChild(2).GetComponent<TextMeshProUGUI>();
Speed = transformT.GetChild(1).GetChild(1).GetChild(2).GetComponent<TextMeshProUGUI>();
ProductionItem = transformT.GetChild(1).GetChild(2).GetChild(1).GetComponent<TextMeshProUGUI>();
for (int i = 3; i < 6; i++)
{
IngedientPics.Add(transformT.GetChild(1).GetChild(2).GetChild(i).GetChild(0).GetComponent<RawImage>());
IngedientAmounts.Add(transformT.GetChild(1).GetChild(2).GetChild(i).GetChild(1).GetComponentInChildren<TextMeshProUGUI>());
IngedientAmounts.Add(transformT.GetChild(1).GetChild(2).GetChild(i).GetChild(2).GetComponentInChildren<TextMeshProUGUI>());
IngedientBubbles.Add(transformT.GetChild(1).GetChild(2).GetChild(i).GetChild(1).GetComponent<Image>());
}
for(int i = 0; i < 5; i++)
{
PrisonSlots.Add(transformT.GetChild(1).GetChild(3).GetChild(i).gameObject);
}
}
public void UpdateInterface()
{
UpdateRecipe();
UpdatePrisonSlots();
}
private RawImage PrisonImage(int i) => PrisonSlots[i].transform.GetChild(1).GetComponent<RawImage>();
public void Interface(Transform Who)
{
Data = Who.GetComponent<Crafter>();
ProductionItem.text = Data.ProductionItem;
if(God.ProductIcons.ContainsKey(Data.CurrentRecipe.Name)){
ProductPic.texture = God.ProductIcons.FirstOrDefault(icon => icon.Key == Data.CurrentRecipe.Name).Value;
}
else
{
ProductPic.texture = God.NullImagePic;
}
for (int i = 0; i < 3; i++)
{
if (Data.CurrentRecipe.Ingredients.Count > i)
{
IngedientAmounts[(i * 2) + 1].text = Data.CurrentRecipe.Ingredients.ElementAt(i).Value.ToString();
GetImageForSlot(Data.CurrentRecipe.Ingredients.ElementAt(i).Key, IngedientPics[i]);
}
else
{
IngedientAmounts[(i * 2) + 1].text = "0";
IngedientPics[i].color = new Color(0, 0, 0, 0);
}
}
UpdateRecipe();
UpdatePrisonSlots();
Cost.text = Data.transform.GetComponent<MachineData>().Cost.ToString();
Speed.text = Data.transform.GetComponent<MachineData>().Speed.ToString();
}
private void UpdateRecipe()
{
for (int i = 0; i < 3; i++)
{
if (Data.CurrentRecipe.Ingredients.Count > i)
{
IngedientAmounts[i * 2].text = Data.CollectedNames.LongCount(n => n ==
Data.CurrentRecipe.Ingredients.ElementAt(i).Key).ToString();
if (Data.CollectedNames.LongCount(n => n == Data.CurrentRecipe.Ingredients.ElementAt(i).Key) >=
Data.CurrentRecipe.Ingredients.ElementAt(i).Value)
{
IngedientBubbles[i].color = new Color(0.4352f, 0.7058f, 0.4352f, 0.7921f);
}
else
{
IngedientBubbles[i].color = new Color(0.7058f, 0.4352f, 0.4352f, 0.7921f);
}
}
else
{
IngedientAmounts[i * 2].text = "0";
IngedientBubbles[i].color = new Color(0.4352f, 0.7058f, 0.4352f, 0.7921f);
}
}
}
private void UpdatePrisonSlots()
{
for (int i = 0; i < 5; i++)
{
if (Data.Prison.Count > i)
{
PrisonSlots[i].transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = Data.HeldNames.LongCount(n => n ==
Data.Prison[i]).ToString();
GetImageForSlot(Data.Prison[i], PrisonImage(i));
}
else
{
PrisonSlots[i].transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = "0";
PrisonImage(i).color = new Color(0, 0, 0, 0);
}
}
}
private void GetImageForSlot(string Slot, RawImage SlotPic)
{
if (Slot.Split('_').Length == 2)
{
if (God.Icons.FirstOrDefault(icon => icon.Key ==
Slot.Split('_')[1] || icon.Key ==
Slot.Split('_')[0]).Value != null)
{
SlotPic.GetComponentInChildren<RawImage>().texture = God.Icons.FirstOrDefault(icon => icon.Key ==
Slot.Split('_')[1] || icon.Key ==
Slot.Split('_')[0]).Value;
SlotPic.GetComponentInChildren<RawImage>().color = God.MatColors.FirstOrDefault(icon => icon.Key ==
Slot.Split('_')[0] || icon.Key ==
Slot.Split('_')[1]).Value;
}
else
{
SlotPic.texture = God.NullImagePic;
SlotPic.color = new Color(1, 1, 1, 1);
}
}
else if (MatNames.Contains(Slot))
{
SlotPic.texture = God.Icons.FirstOrDefault(icon => icon.Key ==
"Basic").Value;
SlotPic.color = God.MatColors.FirstOrDefault(icon => icon.Key ==
Slot).Value;
}
else if (God.ProductIcons.ContainsKey(Slot))
{
SlotPic.texture =
God.ProductIcons.FirstOrDefault(icon => icon.Key == Slot).Value;
SlotPic.color = new Color(1, 1, 1, 1);
}
else
{
SlotPic.texture = God.NullImagePic;
SlotPic.color = new Color(1, 1, 1, 1);
}
}
public void ChangeCraft(GameObject Selection)
{
Data.ProductionItem = Selection.name;
ProductionItem.text = Data.ProductionItem;
if (God.ProductIcons.ContainsKey(Data.CurrentRecipe.Name))
{
ProductPic.texture = God.ProductIcons.FirstOrDefault(icon => icon.Key == Data.CurrentRecipe.Name).Value;
}
else
{
ProductPic.texture = God.NullImagePic;
}
Data.RefreshRecipe();
Interface(Data.transform);
}
public void ClearTheLists()
{
Data.ClearLists();
UpdateInterface();
}
}
This class checks for a connection, and if it's a stable connection, this class teleports materials to the output's location.
44 lines
Click to expandusing System.Collections;
using UnityEngine;
public class Teleporter : MonoBehaviour
{
public bool isInput;
private GameObject ObjectHandler;
//[HideInInspector]
public BuddySystem BuddySystem = new BuddySystem();
private God God;
void Start()
{
isInput = gameObject.name.Contains("Input");
ObjectHandler = GameObject.Find("ObjectHandler");
God = GameObject.Find("God").GetComponent<God>();
}
private void OnTriggerEnter(Collider other)
{
if (BuddySystem.IHaveABuddy)
{
if (other.gameObject.transform.IsChildOf(ObjectHandler.transform) && isInput)
{
other.gameObject.transform.position = transform.position;
StartCoroutine(TeleportToBuddy(other.gameObject));
}
}
else
{
if (other.gameObject.transform.IsChildOf(ObjectHandler.transform) && isInput)
{
Destroy(other.gameObject, 2f);
}
}
}
public IEnumerator TeleportToBuddy(GameObject Teleportee)
{
yield return new WaitForSeconds(1f);
if (Teleportee != null)
{
Teleportee.transform.position = God.BuddyManager.BuddyIndexSearcher[1][BuddySystem.BuddyPairNumber.Value].transform.position;
}
StopCoroutine(TeleportToBuddy(Teleportee));
}
}
This class manages the UI for the teleporters, similarly to many of the other interfaces. This includes managing the pairing connection and displaying the components ID information.
165 lines
Click to expandusing System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class Teleport : MonoBehaviour
{
private Teleporter Data;
private TextMeshProUGUI Type,
ID,
BuddyID,
ConnectionT;
private God God;
private Transform PairingSelection,
Display,
Details;
public List<GameObject> InputOptions = new List<GameObject>(),
OutputOptions = new List<GameObject>();
public void Begin()
{
God = transform.GetComponent<God>();
Details = God.TeleportI.transform.GetChild(0);
Display = God.TeleportI.transform.GetChild(1);
Type = Details.GetChild(1).GetComponentInChildren<TextMeshProUGUI>();
ID = Details.GetChild(2).GetComponentInChildren<TextMeshProUGUI>();
BuddyID = Details.GetChild(3).GetComponentInChildren<TextMeshProUGUI>();
ConnectionT = Display.GetChild(0).GetComponent<TextMeshProUGUI>();
PairingSelection = God.TeleportI.transform.GetChild(3);
PairingSelection.localScale = Vector3.zero;
Display.GetChild(2).GetComponent<Button>().onClick.AddListener(OpenOrClosePairingInterface);
}
public void Interface(Transform Who)
{
PairingSelection.localScale = Vector3.zero;
Data = Who.GetComponent<Teleporter>();
if (Data.isInput)
{
Type.text = "Type: Input";
ConnectionT.text = Data.BuddySystem.IHaveABuddy
? "Connection to output: <color=#00AF50><b>Stable"
: "Connection to output: <color=#AF0050><b>Unstable";
}
else
{
Type.text = "Type: Output";
ConnectionT.text = Data.BuddySystem.IHaveABuddy
? "Connection to input: <color=#00AF50><b>Stable"
: "Connection to input: <color=#AF0050><b>Unstable";
}
ID.text = $"ID: {Data.BuddySystem.PairNumber}";
BuddyID.text = Data.BuddySystem.BuddyPairNumber.HasValue
? $"Pair ID: {Data.BuddySystem.BuddyPairNumber}"
: $"Pair ID: ---";
}
void OpenOrClosePairingInterface()
{
UpdatePairingButtonInteractability();
PairingSelection.localScale = PairingSelection.localScale == Vector3.zero
? Vector3.one
: Vector3.zero;
if (!Data.isInput)
{
InputOptions .ForEach(x => x.SetActive(true));
OutputOptions.ForEach(x => x.SetActive(false));
}
else
{
InputOptions .ForEach(x => x.SetActive(false));
OutputOptions.ForEach(x => x.SetActive(true));
}
Invoke("fixScrollbar", 0.025f);
}
void fixScrollbar()
{
PairingSelection.GetChild(0).GetChild(1).GetComponent<Scrollbar>().value = 1;
}
public void AddOptionToInterface(GameObject button)
{
button.transform.SetParent(PairingSelection.GetChild(0).GetChild(0).GetChild(0));
button.GetComponent<Button>().onClick.AddListener(delegate
{
ChangePairingTo(int.Parse(button.GetComponentInChildren<TextMeshProUGUI>().text));
});
button.transform.localScale = Vector3.one;
}
public void ChangePairingTo(int NewBuddyPairNumber)
{
Data.BuddySystem.IHaveABuddy = true;
Teleporter Buddy = null;
DisconnectFromPreviousBuddy(Data);
UpdatePairingButtonInteractability(Data.BuddySystem.BuddyPairNumber, NewBuddyPairNumber);
Data.BuddySystem.BuddyPairNumber = NewBuddyPairNumber;
Buddy = Data.isInput
? God.BuddyManager.BuddyIndexSearcher[1][NewBuddyPairNumber].GetComponent<Teleporter>()
: God.BuddyManager.BuddyIndexSearcher[0][NewBuddyPairNumber].GetComponent<Teleporter>();
Buddy.BuddySystem.IHaveABuddy = true;
DisconnectFromPreviousBuddy(Buddy);
Buddy.BuddySystem.BuddyPairNumber = Data.BuddySystem.PairNumber;
Interface(Data.transform);
}
public void DisconnectFromPreviousBuddy(Teleporter Who)
{
if (Who.BuddySystem.BuddyPairNumber.HasValue)
{
Teleporter Buddy = Who.isInput
? God.BuddyManager.BuddyIndexSearcher[1][Who.BuddySystem.BuddyPairNumber.Value].GetComponent<Teleporter>()
: God.BuddyManager.BuddyIndexSearcher[0][Who.BuddySystem.BuddyPairNumber.Value].GetComponent<Teleporter>();
Buddy.BuddySystem.IHaveABuddy = false;
Buddy.BuddySystem.BuddyPairNumber = null;
}
}
void UpdatePairingButtonInteractability()
{
if (Data.isInput)
{
OutputOptions.ForEach(x =>
{
if (OutputOptions.IndexOf(x) != Data.BuddySystem.BuddyPairNumber)
{
x.GetComponent<Button>().interactable = true;
}
else
{
x.GetComponent<Button>().interactable = false;
}
});
}
else
{
InputOptions.ForEach(x =>
{
if (InputOptions.IndexOf(x) != Data.BuddySystem.BuddyPairNumber)
{
x.GetComponent<Button>().interactable = true;
}
else
{
x.GetComponent<Button>().interactable = false;
}
});
}
}
void UpdatePairingButtonInteractability(int? OldBuddy, int NewBuddy)
{
if (Data.isInput)
{
OutputOptions[NewBuddy].GetComponent<Button>().interactable = false;
}
else
{
InputOptions[NewBuddy].GetComponent<Button>().interactable = false;
}
if (OldBuddy.HasValue)
{
if (Data.isInput)
{
OutputOptions[OldBuddy.Value].GetComponent<Button>().interactable = true;
}
else
{
InputOptions[OldBuddy.Value].GetComponent<Button>().interactable = true;
}
}
}
}
This is not a major manager and thus is not consider a true "manager." What the Buddy Manager does is manage the connection between teleporters and maintain a Buddy Index Searcher (A list containing Buddy Systems for easy location of specific teleporters).
137 lines
Click to expandusing System.Collections.Generic;
using TMPro;
using UnityEngine;
[System.Serializable]
public class BuddyManager
{
public int NextBuddyPair;
public List<GameObject> InputBuddies;
public List<GameObject> OutputBuddies;
public List<GameObject>[] BuddyIndexSearcher;
public GameObject TeleporterInputP, TeleporterOutputP, ButtonP;
public int I_Cost, O_Cost;
public void Begin()
{
TeleporterInputP = Resources.Load("Prefabs/Components/TeleporterInput") as GameObject;
TeleporterOutputP = Resources.Load("Prefabs/Components/TeleporterOutput") as GameObject;
ButtonP = Resources.Load("Prefabs/Interfaces/Button") as GameObject;
}
public void CreateTeleporterInput(Vector3 Location, God God)
{
if (BuddyIndexSearcher[0].Count <= NextBuddyPair)
{
//Create the teleporter and update the money
GameObject Teleporter = UnityEngine.Object.Instantiate(TeleporterInputP,
Location,
Quaternion.identity,
God.ComponentHandler.transform);
Teleporter.name = TeleporterInputP.name;
Teleporter.gameObject.SetActive(true);
God.Money -= I_Cost;
God.UpdateMoney();
I_Cost *= 10;
//Setup Pairing System
BuddyIndexSearcher[0].Add(Teleporter);
Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber = NextBuddyPair;
if (BuddyIndexSearcher[1].Count > NextBuddyPair)
{
Teleporter.GetComponent<Teleporter>().BuddySystem.IHaveABuddy = true;
Teleporter.GetComponent<Teleporter>().BuddySystem.BuddyPairNumber = NextBuddyPair;
BuddyIndexSearcher[1][NextBuddyPair].GetComponent<Teleporter>().BuddySystem.IHaveABuddy = true;
BuddyIndexSearcher[1][NextBuddyPair].GetComponent<Teleporter>().BuddySystem.BuddyPairNumber = NextBuddyPair;
NextBuddyPair++;
}
//Add option to the interface
GameObject NewOption = UnityEngine.Object.Instantiate(ButtonP);
NewOption.GetComponentInChildren<TextMeshProUGUI>().text = Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber.ToString();
NewOption.name = $"In_Op_{Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber}";
God.transform.GetComponent<Teleport>().AddOptionToInterface(NewOption);
God.transform.GetComponent<Teleport>().InputOptions.Add(NewOption);
}
}
public void CreateTeleporterOutput(Vector3 Location, God God)
{
if (BuddyIndexSearcher[1].Count <= NextBuddyPair)
{
//Create the teleporter and update the money
GameObject Teleporter = UnityEngine.Object.Instantiate(TeleporterOutputP,
Location,
Quaternion.identity,
God.ComponentHandler.transform);
Teleporter.name = TeleporterOutputP.name;
Teleporter.gameObject.SetActive(true);
God.Money -= O_Cost;
God.UpdateMoney();
O_Cost *= 10;
//Setup Pairing System
BuddyIndexSearcher[1].Add(Teleporter);
Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber = NextBuddyPair;
if (BuddyIndexSearcher[0].Count > NextBuddyPair)
{
Teleporter.GetComponent<Teleporter>().BuddySystem.IHaveABuddy = true;
Teleporter.GetComponent<Teleporter>().BuddySystem.BuddyPairNumber = NextBuddyPair;
BuddyIndexSearcher[0][NextBuddyPair].GetComponent<Teleporter>().BuddySystem.IHaveABuddy = true;
BuddyIndexSearcher[0][NextBuddyPair].GetComponent<Teleporter>().BuddySystem.BuddyPairNumber = NextBuddyPair;
NextBuddyPair++;
}
//Add option to the interface
GameObject NewOption = UnityEngine.Object.Instantiate(ButtonP);
NewOption.GetComponentInChildren<TextMeshProUGUI>().text = Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber.ToString();
NewOption.name = $"Out_Op_{Teleporter.GetComponent<Teleporter>().BuddySystem.PairNumber}";
God.transform.GetComponent<Teleport>().AddOptionToInterface(NewOption);
God.transform.GetComponent<Teleport>().OutputOptions.Add(NewOption);
}
}
public GameObject CreateTeleporterInput(Vector3 Location, God God, BuddySystem buddySystem)
{
//Create the teleporter and update the money
GameObject Teleporter = UnityEngine.Object.Instantiate(TeleporterInputP,
Location,
Quaternion.identity,
God.ComponentHandler.transform);
Teleporter.name = TeleporterInputP.name;
I_Cost *= 10;
//Setup Pairing System
BuddyIndexSearcher[0][buddySystem.PairNumber] = Teleporter;
//Add option to the interface
GameObject NewOption = UnityEngine.Object.Instantiate(ButtonP);
NewOption.GetComponentInChildren<TextMeshProUGUI>().text = buddySystem.PairNumber.ToString();
NewOption.name = $"In_Op_{buddySystem.PairNumber}";
God.transform.GetComponent<Teleport>().AddOptionToInterface(NewOption);
God.transform.GetComponent<Teleport>().InputOptions.Add(NewOption);
return Teleporter;
}
public GameObject CreateTeleporterOutput(Vector3 Location, God God, BuddySystem buddySystem)
{
//Create the teleporter and update the money
GameObject Teleporter = UnityEngine.Object.Instantiate(TeleporterOutputP,
Location,
Quaternion.identity,
God.ComponentHandler.transform);
Teleporter.name = TeleporterOutputP.name;
O_Cost *= 10;
//Setup Pairing System
BuddyIndexSearcher[1][buddySystem.PairNumber] = Teleporter;
//Add option to the interface
GameObject NewOption = UnityEngine.Object.Instantiate(ButtonP);
NewOption.GetComponentInChildren<TextMeshProUGUI>().text = buddySystem.PairNumber.ToString();
NewOption.name = $"Out_Op_{buddySystem.PairNumber}";
God.transform.GetComponent<Teleport>().AddOptionToInterface(NewOption);
God.transform.GetComponent<Teleport>().OutputOptions.Add(NewOption);
return Teleporter;
}
public BuddyManager()
{
NextBuddyPair = 0;
InputBuddies = new List<GameObject>();
OutputBuddies = new List<GameObject>();
I_Cost = 1000;
O_Cost = 1000;
BuddyIndexSearcher = new List<GameObject>[2] { InputBuddies, OutputBuddies };
}
}
This script is a definition of a data structure attached to the teleporter's functional class in order for the Buddy Manager to pair it up correctly.
13 lines
Click to expand[System.Serializable]
public class BuddySystem
{
public int PairNumber;
public bool IHaveABuddy;
public int? BuddyPairNumber;
public BuddySystem()
{
PairNumber = 0;
IHaveABuddy = false;
BuddyPairNumber = null;
}
}
This is a class to encrypt and save the PlayerData into LIE binary file, as well as decrypt said data to be usable later.
47 lines
Click to expandusing UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class SaveSystem
{
public static void SaveGameData(God God,
int SaveSlot,
InfiniteLand GroundHandler,
ManMadeStructureHandler MMSH,
WorldHandler WorldHandler,
ComponentHandler ComponentHandler, int T_in, int T_out, int T_count)
{
God.AudioManager.Play("Rotate");
BinaryFormatter formatter = new BinaryFormatter();
string path = $"{Application.persistentDataPath}/SaveSlot{SaveSlot}.lie";
FileStream stream = new FileStream(path, FileMode.Create);
PlayerData data = new PlayerData(
God: God,
GroundHandler: GroundHandler,
MMSH: MMSH,
WorldHandler: WorldHandler,
ComponentHandler: ComponentHandler,
T_in: T_in,
T_out: T_out,
T_count: T_count);
formatter.Serialize(stream, data);
stream.Close();
}
public static PlayerData LoadPlayer(int SaveSlot)
{
string path = $"{Application.persistentDataPath}/SaveSlot{SaveSlot}.lie";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
PlayerData data = formatter.Deserialize(stream) as PlayerData;
stream.Close();
return data;
}
else
{
Debug.LogError($"Save file not found at {path}");
return null;
}
}
}
This is the definition of the data structure used to store all the necessary information about the game.
170 lines
Click to expandusing System.Collections.Generic;
using System.Linq;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public int Money;
public string[] ComponentNames;
public float[][] ComponentPositions;
public int[] ComponentDirection;
public string[] ComponentTag;
public int[] ComponentRotation;
public string[] InputMaterial;
public int[] InputAmount;
public string[] CrafterProductionItem;
public float[][] FloorPosition;
public int GroundPrice;
public string[] MMSH_Names;
public float[][] MMSH_Positions;
public string[] MMSH_Tags;
public int[][] SplitterDirections;
public string[] SelectorSelectedItem;
public string[] Names;
public int[] ComponentCost;
public float[] ComponentSpeed;
public int TeleporterInputAmount,
TeleporterOutputAmount,
TeleporterPairAmount;
public BuddySystem[] TeleporterSystems;
public PlayerData (God God,
InfiniteLand GroundHandler,
ManMadeStructureHandler MMSH,
WorldHandler WorldHandler,
ComponentHandler ComponentHandler, int T_in, int T_out, int T_count)
{
Money = God.Money;
TeleporterInputAmount = T_in;
TeleporterOutputAmount = T_out;
TeleporterPairAmount = T_count;
//Components
{
List<Transform> Components = new List<Transform>();
ComponentHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => (God.GetPrefab(x.gameObject.name) != null &&
x.gameObject.GetComponent<BoxCollider>()) ||
x.name.Contains("Teleporter"))
.ForEach(x => Components.Add(x));
//Resize the arrays
ComponentNames = new string[Components.Count];
ComponentPositions = new float[Components.Count][];
ComponentRotation = new int[Components.Count];
ComponentDirection = new int[Components.Count];
ComponentTag = new string[Components.Count];
InputMaterial = new string[Components.Count];
InputAmount = new int[Components.Count];
TeleporterSystems = new BuddySystem[Components.Count];
SplitterDirections = new int[Components.Count][];
CrafterProductionItem = new string[Components.Count];
SelectorSelectedItem = new string[Components.Count];
//Get basics of all components
Components.ForEach(x => {
//Get index of this component
int index = Components.IndexOf(x);
//Set variables
ComponentNames [index] = x.gameObject.name;
ComponentPositions [index] = new float[3] {x.position.x, x.position.y, x.position.z};
ComponentTag [index] = x.tag;
ComponentRotation [index] = Mathf.RoundToInt(x.eulerAngles.y);
ComponentDirection [index] = Mathf.RoundToInt(x.GetChild(1).localEulerAngles.y);
});
//Setup inputs
Components.FindAll(x => x.name == "input").ForEach(x => {
int Index = Components.IndexOf(x);
InputMaterial[Index] = Components[Index].GetComponent<InputBlockData>().Material;
InputAmount [Index] = Components[Index].GetComponent<InputBlockData>().AmountNum;
});
//Setup crafter
Components.FindAll(x => x.name == "Crafter").ForEach(x => CrafterProductionItem[Components.IndexOf(x)] =
Components[Components.IndexOf(x)].GetComponent<Crafter>().ProductionItem);
//Setup splitters
Components.FindAll(x => x.name == "ComplexConveyorBelt").ForEach(x => {
int Index = Components.IndexOf(x);
SplitterDirections[Index] = new int[3] {Components[Index].GetComponent<Splitter>().LeftNum,
Components[Index].GetComponent<Splitter>().StraightNum,
Components[Index].GetComponent<Splitter>().RightNum};
});
//Setup selectors
Components.FindAll(x => x.name.Contains("Select")).ForEach(x => {
int Index = Components.IndexOf(x);
Debug.Log(Components[Index].GetComponent<Selector>().Selected);
SelectorSelectedItem[Index] = Components[Index].GetComponent<Selector>().Selected;
});
//Setup teleporters
Components.FindAll(x => x.name.Contains("Teleporter")).ForEach(x => {
int Index = Components.IndexOf(x);
TeleporterSystems[Index] = Components[Index].GetComponent<Teleporter>().BuddySystem;
});
}
//Ground
{
List<Transform> Land = new List<Transform>();
GroundHandler.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x != GroundHandler.transform.GetChild(0) &&
!x.IsChildOf(GroundHandler.transform.GetChild(0)) &&
x.name == "Floor")
.ForEach(x => Land.Add(x));
FloorPosition = new float[Land.Count][];
Land.ForEach(x => FloorPosition[Land.IndexOf(x)] = new float[3]
{x.position.x, x.position.y, x.position.z});
GroundPrice = GroundHandler.Price;
}
//MMSH
{
List<Transform> Structures = new List<Transform>();
MMSH.transform.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.name != "Cube" &&
x.name != "Top" &&
x.name != "Bottom" &&
x.name != "Left" &&
x.name != "Right" &&
x.name != "Back" &&
x.name != "Front")
.ForEach(x => Structures.Add(x));
MMSH_Names = new string[Structures.Count];
MMSH_Positions = new float[Structures.Count][];
MMSH_Tags = new string[Structures.Count];
Structures.ForEach(x =>
{
int index = Structures.IndexOf(x);
MMSH_Positions[index] = new float[3] { x.position.x, x.position.y, x.position.z };
MMSH_Names[index] = x.name;
MMSH_Tags[index] = x.tag;
});
}
//Components part 2
{
Names = new string[6]{
"input",
"Crafter",
"Wire Drawer",
"Furnace",
"Gear Cutter",
"Hydralic Press"
};
ComponentCost = new int[6];
ComponentSpeed = new float[6];
for (int c = 0; c < 6; c++)
{
if (Names[c] != "input")
{
ComponentCost[c] = God.GetPrefab(Names[c]).GetComponent<MachineData>().Cost;
ComponentSpeed[c] = God.GetPrefab(Names[c]).GetComponent<MachineData>().Speed;
}
else
{
ComponentCost[c] = God.GetPrefab(Names[c]).GetComponent<InputBlockData>().AmountRange[1];
ComponentSpeed[c] = God.GetPrefab(Names[c]).GetComponent<InputBlockData>().ProducingSpeed;
}
}
}
}
}
This class manages the entirety of the pause screen and updates settings such as the Audio Manager's volumes and the global shading. It also allows the player to save the game, go back to the main menu, and read the About section.
315 lines
Click to expandusing System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class PauseScreen : MonoBehaviour
{
private God God;
private Transform OptionsPanel;
private Transform BackPanel;
private Transform AudioPanel;
private Transform GraphicsPanel;
private Transform InfoPanel;
private Transform QuitConfirmation;
private Transform SaveSlotsPanel;
private GameObject Lighting;
private Vector3 small = new Vector3(0, 0, 0);
private Vector3 big = new Vector3(1, 1, 1);
private Dictionary<string, TextMeshProUGUI> AudioPercentages = new Dictionary<string, TextMeshProUGUI>();
private Dictionary<string, TextMeshProUGUI> GraphicsPercentages = new Dictionary<string, TextMeshProUGUI>();
private List<Button> GraphicButtons = new List<Button>();
private List<bool> GraphicValues = new List<bool>();
private List<Button> SaveSlots = new List<Button>();
public TitleScreen Gatekeeper;
void Start()
{
God = GameObject.Find("God").GetComponent<God>();
Lighting = GameObject.Find("Directional Light");
OptionsPanel = transform.GetChild(1).GetChild(1);
BackPanel = transform.GetChild(1);
SaveSlotsPanel = transform.GetChild(3);
AudioPanel = transform.GetChild(4);
GraphicsPanel = transform.GetChild(5);
InfoPanel = transform.GetChild(6);
QuitConfirmation = BackPanel.GetChild(2);
BackPanel.GetChild(0).GetChild(0).GetChild(0).GetComponent<Button>().onClick.AddListener(ResumeGame);
BackPanel.GetChild(0).GetChild(0).GetChild(1).GetComponent<Button>().onClick.AddListener(OptionButton);
BackPanel.GetChild(0).GetChild(0).GetChild(2).GetComponent<Button>().onClick.AddListener(Info);
BackPanel.GetChild(0).GetChild(0).GetChild(3).GetComponent<Button>().onClick.AddListener(Quit);
BackPanel.GetChild(0).GetChild(1).GetChild(3).GetComponent<Button>().onClick.AddListener(SaveGame);
OptionsPanel.GetChild(0).GetChild(1).GetComponent<Button>().onClick.AddListener(AudioAndSound);
OptionsPanel.GetChild(0).GetChild(2).GetComponent<Button>().onClick.AddListener(Graphics);
OptionsPanel.GetChild(0).GetChild(3).GetComponent<Button>().onClick.AddListener(Other);
AudioPanel.GetChild(4).GetComponent<Button>().onClick.AddListener(Back);
GraphicsPanel.GetChild(6).GetComponent<Button>().onClick.AddListener(Back);
InfoPanel.GetChild(1).GetComponent<Button>().onClick.AddListener(Back);
SaveSlotsPanel.GetChild(1).GetComponent<Button>().onClick.AddListener(Back);
AudioPercentages.Add("Master Volume", GetChildNumber(AudioPanel, 0, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Music", GetChildNumber(AudioPanel, 1, 0, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Delete", GetChildNumber(AudioPanel, 1, 1, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Placing", GetChildNumber(AudioPanel, 2, 0, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Rotating", GetChildNumber(AudioPanel, 2, 1, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Machines", GetChildNumber(AudioPanel, 3, 0, 3).GetComponent<TextMeshProUGUI>());
AudioPercentages.Add("Buttons", GetChildNumber(AudioPanel, 3, 1, 3).GetComponent<TextMeshProUGUI>());
GraphicsPercentages.Add("Mouse Sensitivity", GetChildNumber(GraphicsPanel, 0, 3).GetComponent<TextMeshProUGUI>());
GraphicsPercentages.Add("Brightness", GetChildNumber(GraphicsPanel, 3, 3).GetComponent<TextMeshProUGUI>());
GraphicsPercentages.Add("FOV", GetChildNumber(GraphicsPanel, 5, 3).GetComponent<TextMeshProUGUI>());
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 0, 0));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 0, 1));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 0, 2));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 0, 3));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 1, 0));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 1, 1));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 1, 2));
SaveSlots.Add(GetButton(SaveSlotsPanel, 0, 1, 3));
GraphicButtons.Add(GetButton(GraphicsPanel, 1));
GraphicButtons.Add(GetButton(GraphicsPanel, 2));
GraphicButtons.Add(GetButton(GraphicsPanel, 4));
GraphicValues.Add(Gatekeeper.MoneyAnimation);
GraphicValues.Add(false);
GraphicValues.Add(Gatekeeper.Shading);
SaveSlots.ToList().ForEach(x => x.onClick.AddListener
(delegate { SaveInSaveSlot(SaveSlots.ToList().IndexOf(x)); }));
AudioPercentages.ToList().ForEach(x => GetSlider(x.Value).onValueChanged.AddListener
(delegate { UpdateAudioSlider(GetSlider(x.Value)); }));
GraphicsPercentages.ToList().ForEach(x => GetSlider(x.Value).onValueChanged.AddListener
(delegate {
if (x.Key != "FOV") { UpdateSlider(GetSlider(x.Value)); }
else { UpdateSlider(GetSlider(x.Value), 0); }
}));
GetSlider(GetChildNumber(GraphicsPanel, 5, 3).GetComponent<TextMeshProUGUI>()).value = Gatekeeper.FOV;
GetSlider(GetChildNumber(GraphicsPanel, 0, 3).GetComponent<TextMeshProUGUI>()).value = God.MoveSensitivity;
UpdateSlider(GetSlider(GetChildNumber(GraphicsPanel, 5, 3).GetComponent<TextMeshProUGUI>()), 0);
GraphicButtons[0].onClick.AddListener(delegate { UpdateBool(0); });
GraphicButtons[1].onClick.AddListener(delegate { UpdateBool(1); });
GraphicButtons[2].onClick.AddListener(UpdateShading);
GetChildNumber(QuitConfirmation, 0, 0, 1).GetComponent<Button>().onClick.AddListener(ConfirmQuit);
GetChildNumber(QuitConfirmation, 0, 0, 2).GetComponent<Button>().onClick.AddListener(Back);
SaveSlotsPanel.localScale = small;
InfoPanel.localScale = small;
AudioPanel.localScale = small;
GraphicsPanel.localScale = small;
AudioPercentages.ToList().ForEach(x => UpdateAudioSliderBackwards(GetSlider(x.Value)));
UpdateButton(GraphicButtons[0], GraphicValues[0]);
UpdateButton(GraphicButtons[1], GraphicValues[1]);
UpdateButton(GraphicButtons[2], GraphicValues[2]);
}
Button GetButton(Transform t, int index) => t.GetChild(index).GetComponent<Button>();
Button GetButton(Transform t, int index, int index2, int index3) => t.GetChild(index).GetChild(index2).GetChild(index3).GetComponent<Button>();
Slider GetSlider(TextMeshProUGUI d) => d.transform.parent.GetComponent<Slider>();
Transform GetChildNumber(Transform t, int a, int b, int c) => t.GetChild(a).GetChild(b).GetChild(c);
Transform GetChildNumber(Transform t, int a, int b) => t.GetChild(a).GetChild(b);
void UpdateBool(int index) {
GraphicValues[index] = !GraphicValues[index];
if(index == 0)
{
God.ComponentHandler.GetComponentsInChildren<Transform>().ToList()
.FindAll(x => x.CompareTag("Seller") && x.name == "Seller")
.ForEach(x => x.GetComponent<Seller>().AnimationAllowed = GraphicValues[index]);
God.GetPrefab("Seller").GetComponent<Seller>().AnimationAllowed = GraphicValues[index];
}
UpdateButton(GraphicButtons[index], GraphicValues[index]);
}
void SaveInSaveSlot(int SaveSlot)
{
God.SaveData(SaveSlot);
}
void SaveGame()
{
SaveSlotsPanel.localScale = big;
}
void ResumeGame()
{
God.AudioManager.Play("Click UI");
transform.localScale = small;
God.Paused = false;
God.Topbar.transform.localScale = big;
OptionsPanel.localScale = small;
Time.timeScale = 1;
}
void OptionButton()
{
God.AudioManager.Play("Click UI");
if (OptionsPanel.localScale == small)
{
OptionsPanel.localScale = big;
}
else
{
OptionsPanel.localScale = small;
}
}
void Info()
{
transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "Info / About";
God.AudioManager.Play("Click UI");
InfoPanel.localScale = big;
}
void Quit()
{
God.AudioManager.Play("Click UI");
QuitConfirmation.localScale = big;
}
void ConfirmQuit()
{
God.AudioManager.Play("Click UI");
Application.Quit();
//UnityEditor.EditorApplication.ExitPlaymode();
}
void AudioAndSound()
{
God.AudioManager.Play("Click UI");
transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "Sound & Audio";
BackPanel.localScale = small;
AudioPanel.localScale = big;
GraphicsPanel.localScale = small;
for(int i = 0; i < AudioPercentages.Count; i++)
{
AudioPercentages.ToList()[i].Value.text = AudioPercentages.ToList()[i].Key + ": " +
(Mathf.Round(AudioPercentages.ToList()[i].Value.transform.parent.GetComponent<Slider>().value * 100)) +"%";
}
}
void UpdateAudioSlider(Slider s)
{
switch (s.transform.name)
{
case "MasterVolume":
God.AudioManager.MasterVolume = Mathf.Round(s.value*100)/100;
break;
case "Music":
God.AudioManager.MusicVol = Mathf.Round(s.value * 100) / 100;
break;
case "Machines":
God.AudioManager.MachinesVol = Mathf.Round(s.value * 100) / 100;
break;
case "Placing":
God.AudioManager.PlacingVol = Mathf.Round(s.value * 100) / 100;
break;
case "Delete":
God.AudioManager.DeleteVol = Mathf.Round(s.value * 100) / 100;
break;
case "Rotating":
God.AudioManager.RotatingVol = Mathf.Round(s.value * 100) / 100;
break;
case "Buttons":
God.AudioManager.UIVol = Mathf.Round(s.value * 100) / 100;
break;
}
if(s.transform.name != "Buttons")
{
God.AudioManager.UpdateVolume(s.transform.name);
}
else
{
God.AudioManager.UpdateVolume("UI");
}
UpdateSlider(s);
}
void UpdateAudioSliderBackwards(Slider s)
{
switch (s.transform.name)
{
case "MasterVolume":
s.value = God.AudioManager.MasterVolume;
break;
case "Music":
s.value = God.AudioManager.MusicVol;
break;
case "Machines":
s.value = God.AudioManager.MachinesVol;
break;
case "Placing":
s.value = God.AudioManager.PlacingVol;
break;
case "Delete":
s.value = God.AudioManager.DeleteVol;
break;
case "Rotating":
s.value = God.AudioManager.RotatingVol;
break;
case "Buttons":
s.value = God.AudioManager.UIVol;
break;
}
UpdateSlider(s);
}
void UpdateSlider(Slider s)
{
s.transform.GetChild(3).GetComponent<TextMeshProUGUI>().text = s.name + ": " + (Mathf.Round(s.value*100)) + "%";
if(s.name == "Mouse Sensitivity")
{
God.MoveSensitivity = s.value;
Gatekeeper.MoveSensitivity = s.value;
}
}
void UpdateSlider(Slider s, int i)
{
s.transform.GetChild(3).GetComponent<TextMeshProUGUI>().text = s.name + ": " + s.value;
Camera.main.fieldOfView = s.value;
Gatekeeper.FOV = s.value;
}
public float map(float value, float low1, float high1, float low2, float high2)
{
return low2 + ((value - low1) * (high2 - low2)) / (high1 - low1);
}
void UpdateButton(Button b, bool val)
{
God.AudioManager.Play("Click UI");
if (val)
{
b.transform.GetComponentInChildren<TextMeshProUGUI>().text = b.transform.name + ": <color=#05af05>On";
}
else
{
b.transform.GetComponentInChildren<TextMeshProUGUI>().text = b.transform.name + ": <color=#af0505>Off";
}
}
void UpdateShading()
{
GraphicValues[2] = !GraphicValues[2];
if (GraphicValues[2])
{
Lighting.GetComponent<Light>().shadows = LightShadows.Soft;
}
else
{
Lighting.GetComponent<Light>().shadows = LightShadows.None;
}
UpdateButton(GraphicButtons[2], GraphicValues[2]);
}
void Graphics()
{
God.AudioManager.Play("Click UI");
transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "Graphics";
BackPanel.localScale = small;
GraphicsPanel.localScale = big;
AudioPanel.localScale = small;
GraphicsPercentages.ToList().ForEach(x => {
if (x.Key != "FOV") { UpdateSlider(GetSlider(x.Value)); }
else { UpdateSlider(GetSlider(x.Value), 0); } });
foreach(Button b in GraphicButtons)
{
UpdateButton(b, GraphicValues[GraphicButtons.IndexOf(b)]);
}
}
void Other()
{
God.AudioManager.Play("Click UI");
}
void Back()
{
God.AudioManager.Play("Click UI");
transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "Paused";
AudioPanel.localScale = small;
BackPanel.localScale = big;
GraphicsPanel.localScale = small;
QuitConfirmation.localScale = small;
InfoPanel.localScale = small;
OptionsPanel.localScale = small;
SaveSlotsPanel.localScale = small;
}
}
This class was made to reduce performance issues and reduce the amount of calls made to the instantiate and destroy functions. Basically, it keeps reusing the same objects, rotating them through the cycle as if they were being created again for the first time.
207 lines
Click to expandusing System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ReuseMaterials : MonoBehaviour
{
[System.Serializable]
public class Pool
{
public string tag;
public GameObject prefab;
public int size;
}
[System.Serializable]
public class ObjectIdentifier
{
public GameObject gameObject;
public string tag;
}
#region Singleton
public static ReuseMaterials Instance;
public void Awake()
{
Instance = this;
}
#endregion
public List<Pool> pools;
[HideInInspector]
public List<ObjectIdentifier>[] poolIndexSearcher;
public List<ObjectIdentifier> Active, Inactive;
[HideInInspector]
public List<string>[] poolTagSearcher;
[HideInInspector]
public List<string> ActiveTags, InactiveTags;
private int InactiveList = 0, ActiveList = 1;
private Transform ObjectHandler;
private RecipeDatabase RD;
private CreateObject createObject;
private List<Collider> ChildColliders = new List<Collider>();
private void Start()
{
RD = GameObject.Find("RecipeDatabase").GetComponent<RecipeDatabase>();
int recipeCount = RD.recipes.Count - 1;
for (int i = 0; i < recipeCount; i++)
{
Recipe r = RD.recipes[i];
Pool pool = new Pool
{
tag = r.Name,
prefab = God.Instance.Prefabs[r.ID],
size = 1
};
pools.Add(pool);
}
createObject = CreateObject.Instance;
ObjectHandler = createObject.transform;
Active = new List<ObjectIdentifier>();
Inactive = new List<ObjectIdentifier>();
poolIndexSearcher = new List<ObjectIdentifier>[2] { Inactive, Active };
ActiveTags = new List<string>();
InactiveTags = new List<string>();
poolTagSearcher = new List<string>[2] { InactiveTags, ActiveTags };
int poolAmount = pools.Count;
for (int i = 0; i < poolAmount; i++)
{
Pool pool = pools[i];
int poolSize = pool.size;
for (int c = 0; c < poolSize; c++)
{
GameObject obj = Instantiate(pool.prefab, transform);
obj.SetActive(false);
ObjectIdentifier objectIdentifier = new ObjectIdentifier
{
gameObject = obj,
tag = pool.tag
};
poolIndexSearcher[InactiveList].Add(objectIdentifier);
ChildColliders.Add(obj.GetComponent<Collider>());
}
poolTagSearcher[InactiveList].Add(pool.tag);
}
int colliders = ChildColliders.Count;
for (int i = 0; i < colliders; i++)
{
for (int t = 0; t < colliders; t++)
{
Physics.IgnoreCollision(ChildColliders[i], ChildColliders[t], true);
}
}
}
public GameObject SpawnFromPool(string tag, Vector3 position, Quaternion rotation, string OptionalGameObjectTag = "abc123")
{
if (!poolTagSearcher[InactiveList].Contains(tag))
{
if (!pools.Any(x => x.tag == tag))
{
Debug.LogWarning($"There are no pools with tag type {tag}");
return null;
}
if (!poolTagSearcher[ActiveList].Contains(tag))
{
Debug.LogWarning($"Both Active & Inactive lists do not contain pool with tag type {tag}. But pool exists. Idk what you did buddy.");
return null;
}
Pool Type = pools.FirstOrDefault(x => x.tag == tag);
if (Type != null)
{
Debug.Log($"Creating new object in pool type {Type.tag}");
GameObject NewObject = Instantiate(Type.prefab, position, rotation);
NewObject.transform.SetParent(ObjectHandler);
ObjectIdentifier NewID = new ObjectIdentifier
{
gameObject = NewObject,
tag = tag
};
poolIndexSearcher[ActiveList].Add(NewID);
createObject.ChildRenderers.Add(NewObject.GetComponentInChildren<Renderer>());
Collider newCollider = NewObject.GetComponent<Collider>();
int colliders = ChildColliders.Count;
for (int i = 0; i < colliders; i++)
{
Physics.IgnoreCollision(ChildColliders[i], newCollider, true);
}
ChildColliders.Add(newCollider);
return NewObject;
}
else
{
Debug.LogWarning($"Tried to make a new object in the {tag} pool and failed");
return null;
}
}
ObjectIdentifier id = poolIndexSearcher[InactiveList].FirstOrDefault(x => x.tag == tag);
//GameObject objectToSpawn = id.gameObject;
if (id.gameObject != null)
{
if (OptionalGameObjectTag != "abc123")
{
id.gameObject.tag = OptionalGameObjectTag;
}
id.gameObject.SetActive(true);
id.gameObject.transform.SetParent(ObjectHandler);
id.gameObject.transform.position = position;
id.gameObject.transform.rotation = rotation;
poolIndexSearcher[InactiveList].Remove(id);
poolIndexSearcher[ActiveList].Add(id);
if (!poolTagSearcher[ActiveList].Contains(id.tag))
{
poolTagSearcher[ActiveList].Add(id.tag);
}
if (!poolIndexSearcher[InactiveList].Any(x => x.tag == id.tag))
{
poolTagSearcher[InactiveList].Remove(id.tag);
}
createObject.ChildRenderers.Add(id.gameObject.GetComponentInChildren<Renderer>());
return id.gameObject;
}
else
{
Debug.LogWarning($"Id in pool {id.tag} does not exist. It disappeared. We're removing it. Sorry.");
poolIndexSearcher[InactiveList].Remove(id);
return null;
}
}
public void Deactivate(GameObject obj)
{
ObjectIdentifier id = poolIndexSearcher[ActiveList].Any(x => x.gameObject == obj)
? poolIndexSearcher[ActiveList].FirstOrDefault(x => x.gameObject == obj)
: null;
if (!poolIndexSearcher[ActiveList].Contains(id) || !(id != null))
{
Debug.LogWarning($"Active pool does not contain a(n) {obj.name}");
createObject.ChildRenderers.Remove(obj.GetComponentInChildren<Renderer>());
ChildColliders.Remove(obj.GetComponent<Collider>());
Destroy(obj);
return;
}
GameObject ObjectToRemove = id.gameObject;
ObjectToRemove.transform.position = transform.position;
ObjectToRemove.transform.SetParent(transform);
ObjectToRemove.SetActive(false);
createObject.ChildRenderers.Remove(ObjectToRemove.GetComponentInChildren<Renderer>());
poolIndexSearcher[ActiveList].Remove(id);
poolIndexSearcher[InactiveList].Add(id);
if (!poolTagSearcher[InactiveList].Contains(id.tag))
{
poolTagSearcher[InactiveList].Add(id.tag);
}
if (!poolIndexSearcher[ActiveList].Any(x => x.tag == id.tag))
{
poolTagSearcher[ActiveList].Remove(id.tag);
}
}
}