- Home /
Script becoming too big to maintain?
So I've got a script on the player that handles basically everything that has to do with the player, but I'm not really sure what to do when the script gets this big, it's getting too big to handle and I'm not sure what to do if it were to grow to like 1,000 lines at some point. Should I be breaking this up even though it all seems to have something to do with the player?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.FirstPerson;
using UnityEngine.EventSystems;
public class PlayerScript : DavidBehaviour{
public List<RaycastResult> Results = new List<RaycastResult>();
public string[] Recipes;
public GameObject[] Objects;
public GameObject SelectedItem;
public GameObject TargetedBlock;
public GameObject SelectionBar;
public GameObject TheCamera;
public GameObject CraftingGrid;
public GameObject Inventory;
public GameObject OutputSlot;
public GameObject Menu;
public GameObject MouseSlot;
public GameObject[] HotSlots;
public GameObject[] InventorySlots;
public GameObject[] AllSlots;
public GameObject[] CraftingGridSlots;
public float MoveSpeed;
public float WalkProgress;
public int SelectedSlotNumber;
public bool InventoryFull;
public bool Grounded;
public bool MenuShown;
public Texture2D MouseTexture;
void Start () {
//Cursor.SetCursor (MouseTexture, Vector3.zero, CursorMode.Auto);
Cursor.lockState = CursorLockMode.Locked;
}
void Update ()
{
if (MouseSlot.GetComponent<SlotScript> ().ContainedItem != null) {
MouseSlot.SetActive (true);
MouseSlot.transform.position = Input.mousePosition;
} else {
MouseSlot.SetActive (false);
}
if (AllSlots [SelectedSlotNumber]) {
SelectedItem = (AllSlots [SelectedSlotNumber]);
} else {
SelectedItem = null;
}
if (Input.GetKeyDown ("e")) {
if (MenuShown) {
MenuShown = false;
Menu.SetActive (false);
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
} else {
MenuShown = true;
Menu.SetActive (true);
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
}
if (MenuShown == true) {
GetComponent<CameraMouseLook> ().CanMove = false;
} else {
GetComponent<CameraMouseLook> ().CanMove = true;
}
if (!MenuShown) {
if (Input.GetMouseButtonDown (1)) {
if (SelectedItem != null){
if (SelectedItem.GetComponent<SlotScript>().ContainedItem.GetComponent<ItemScript>().BlockForm != null){
var Block = SelectedItem.GetComponent<SlotScript>().ContainedItem.GetComponent<ItemScript> ().BlockForm;
Ray TheRay = new Ray (Camera.main.transform.position, Camera.main.transform.forward);
RaycastHit HitResult;
if (Physics.Raycast (TheRay, out HitResult, 5)) {
if (Vector3.Distance (HitResult.transform.gameObject.transform.position + HitResult.normal, transform.position) >= 1) {
var PlacedBlock = Instantiate (Block, HitResult.transform.gameObject.transform.position + HitResult.normal, Quaternion.identity);
PlacedBlock.name = SelectedItem.name;
PlaySound ("PlaceBlock", PlacedBlock.transform.position, (3 + Random.value) / 3.5f, 2);
ChangeItemAmount (SelectedItem.GetComponent<SlotScript>().ContainedItem, -1);
}
}
}
}
}
if (Input.GetKeyDown ("q")) {
if (HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem != null) {
var DroppedItem = Instantiate (HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem, Camera.main.transform.position + Camera.main.transform.forward, Quaternion.identity);
DroppedItem.GetComponent<ItemScript> ().ItemAmount = 1;
DroppedItem.SetActive (true);
DroppedItem.name = HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem.name;
DroppedItem.GetComponent<Rigidbody> ().AddForce (Camera.main.transform.forward * 200);
if (HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem.GetComponent<ItemScript> ().ItemAmount > 1) {
HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem.GetComponent<ItemScript> ().ItemAmount += -1;
} else {
Destroy (HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem);
HotSlots [SelectedSlotNumber].GetComponent<SlotScript>().ContainedItem = null;
}
}
}
if (Input.GetMouseButton (0)) {
Ray TheRay = new Ray (Camera.main.transform.position, Camera.main.transform.forward);
RaycastHit HitResult;
if (Physics.Raycast (TheRay, out HitResult, 100)) {
if (HitResult.transform.gameObject.GetComponent<BlockScript> () != null) {
TargetedBlock = HitResult.transform.gameObject;
TargetedBlock.GetComponent<BlockScript> ().Brokeness += Time.deltaTime / HitResult.transform.gameObject.GetComponent<BlockScript> ().Hardness;
if (TargetedBlock.GetComponent<BlockScript> ().Brokeness >= 1) {
TargetedBlock.GetComponent<BlockScript> ().Break ();
}
}
}
} else if (TargetedBlock != null) {
TargetedBlock.GetComponent<BlockScript> ().Brokeness = 0;
TargetedBlock = null;
}
} else {
CraftObject ();
if (Input.GetMouseButtonDown (0)) {
var Pointer = new PointerEventData (EventSystem.current);
Pointer.position = Input.mousePosition;
EventSystem.current.RaycastAll (Pointer, Results);
if (Results.Count > 0) {
var ClickedItem = Results [0].gameObject;
if (ClickedItem.GetComponent<SlotScript> () != null) {
MoveItemToNewSlot (ClickedItem, MouseSlot);
}
}
} else if (Input.GetMouseButtonDown (1)) {
var Pointer = new PointerEventData (EventSystem.current);
Pointer.position = Input.mousePosition;
EventSystem.current.RaycastAll (Pointer, Results);
if (Results.Count > 0) {
var ClickedItem = Results [0].gameObject;
if (ClickedItem.GetComponent<SlotScript> () != null) {
MoveOneItemToNewSlot (ClickedItem, MouseSlot);
}
}
}
}
if (Input.GetAxis ("Mouse ScrollWheel") > 0) {
SelectedSlotNumber += 1;
if (SelectedSlotNumber > 9) {
SelectedSlotNumber = 0;
}
SelectionBar.transform.position = HotSlots [SelectedSlotNumber].transform.position;
}
if (Input.GetAxis ("Mouse ScrollWheel") < 0) {
SelectedSlotNumber += -1;
if (SelectedSlotNumber < 0) {
SelectedSlotNumber = 9;
}
SelectionBar.transform.position = HotSlots [SelectedSlotNumber].transform.position;
}
Ray FloorRay = new Ray (transform.position + new Vector3 (0, -1.1f, 0), -transform.up);
RaycastHit FloorHit;
if (Physics.Raycast (FloorRay, out FloorHit, 0.5f)) {
if (FloorHit.transform.gameObject != null) {
Grounded = true;
} else {
Grounded = false;
}
}
if (Input.GetKeyDown (KeyCode.Space) & Grounded == true) {
GetComponent<Rigidbody> ().AddForce (transform.up * 15000);
Grounded = false;
}
}
void FixedUpdate(){
if (Input.GetKey ("w")) {
transform.position = Vector3.Lerp (transform.position, transform.position + transform.forward, Time.deltaTime * MoveSpeed);
if (Grounded == true){
WalkProgress += 0.05f;
if (WalkProgress >= 1) {
PlaySound ("Footstep" + Random.Range (1, 4), transform.position, 1, 2);
WalkProgress = 0;
}
}
}
if (Input.GetKey ("s")) {
transform.position = Vector3.Lerp (transform.position, transform.position + transform.forward * -0.5f, Time.deltaTime * MoveSpeed);
if (Grounded == true) {
WalkProgress += 0.025f;
if (WalkProgress >= 1) {
PlaySound ("Footstep" + Random.Range (1, 4), transform.position, 1, 2);
WalkProgress = 0;
}
}
}
if (Input.GetKey ("d")) {
transform.position = Vector3.Lerp (transform.position, transform.position + transform.right, Time.deltaTime * MoveSpeed);
}
if (Input.GetKey ("a")) {
transform.position = Vector3.Lerp (transform.position, transform.position + transform.right * -1, Time.deltaTime * MoveSpeed);
}
}
void OnCollisionEnter(Collision TheCollision){
if (TheCollision.gameObject.GetComponent<ItemScript> () != null) {
var InventoryNumber = 0;
var SlotFound = false;
var EmptySlots = new List<GameObject> ();
foreach (GameObject Slot in AllSlots) {
if (Slot.GetComponent<SlotScript> ().ContainedItem != null) {
if (Slot.GetComponent<SlotScript> ().ContainedItem.name == TheCollision.gameObject.name) {
ChangeItemAmount (Slot.GetComponent<SlotScript> ().ContainedItem, TheCollision.gameObject.GetComponent<ItemScript> ().ItemAmount);
Destroy (TheCollision.gameObject);
PlaySound ("Pop", transform.position, 1, 3);
SlotFound = true;
break;
}
} else {
EmptySlots.Add (Slot);
}
}
if (SlotFound == false) {
if (EmptySlots.Count > 0) {
EmptySlots [0].GetComponent<SlotScript> ().ContainedItem = TheCollision.gameObject;
TheCollision.gameObject.SetActive (false);
PlaySound ("Pop", transform.position, 1, 3);
} else {
InventoryFull = true;
}
}
}
}
void ChangeItemAmount(GameObject Item, int Difference){
Item.GetComponent<ItemScript> ().ItemAmount += Difference;
if (Item.GetComponent<ItemScript> ().ItemAmount < 1) {
Destroy (Item);
}
}
void CraftObject(){
var i = 0;
var CraftingString = "";
foreach (GameObject Slot in CraftingGridSlots) {
if (CraftingGridSlots [i].GetComponent<SlotScript> ().ContainedItem != null) {
CraftingString += CraftingGridSlots [i].GetComponent<SlotScript> ().ContainedItem.GetComponent<ItemScript> ().name;
} else {
CraftingString += "Empty";
}
i += 1;
}
foreach (GameObject Object in Objects) {
if (CraftingString == Object.GetComponent<ItemScript> ().CraftingRecipe) {
if (OutputSlot.GetComponent<SlotScript> ().ContainedItem == null) {
var CraftedItem = Instantiate (Object, Camera.main.transform.position + Camera.main.transform.forward, Quaternion.identity);
CraftedItem.GetComponent<ItemScript> ().ItemAmount = 1;
CraftedItem.name = Object.name;
CraftedItem.SetActive (false);
OutputSlot.GetComponent<SlotScript> ().ContainedItem = CraftedItem;
}
} else {
if (OutputSlot.GetComponent<SlotScript> ().ContainedItem != null) {
OutputSlot.GetComponent<SlotScript> ().ContainedItem = null;
}
Debug.Log (CraftingString);
Debug.Log(Object.GetComponent<ItemScript> ().CraftingRecipe);
}
}
}
public void WipeGrid(){
var i = 0;
foreach (GameObject Slot in CraftingGridSlots){
if (Slot.GetComponent<SlotScript> ().ContainedItem != null) {
ChangeItemAmount (Slot.GetComponent<SlotScript>().ContainedItem, -1);
}
i += 1;
}
}
public void MoveItemToNewSlot(GameObject OriginalSlot, GameObject NewSlot){
if (MouseSlot.GetComponent<SlotScript> ().ContainedItem == null) {
if (OriginalSlot == OutputSlot) {
WipeGrid();
}
}
if (NewSlot.GetComponent<SlotScript> ().ContainedItem == null) {
NewSlot.GetComponent<SlotScript> ().ContainedItem = OriginalSlot.GetComponent<SlotScript> ().ContainedItem;
OriginalSlot.GetComponent<SlotScript> ().ContainedItem = null;
} else {
if (OriginalSlot.GetComponent<SlotScript>().ContainedItem != null){
if (OriginalSlot.GetComponent<SlotScript> ().ContainedItem.name == NewSlot.GetComponent<SlotScript> ().ContainedItem.name) {
NewSlot.GetComponent<SlotScript> ().ContainedItem.GetComponent<ItemScript> ().ItemAmount += OriginalSlot.GetComponent<SlotScript> ().ContainedItem.GetComponent<ItemScript> ().ItemAmount;
Destroy (OriginalSlot.GetComponent<SlotScript> ().ContainedItem);
}
}
var OldItem = NewSlot.GetComponent<SlotScript> ().ContainedItem;
NewSlot.GetComponent<SlotScript> ().ContainedItem = OriginalSlot.GetComponent<SlotScript> ().ContainedItem;
OriginalSlot.GetComponent<SlotScript> ().ContainedItem = OldItem;
}
}
public void MoveOneItemToNewSlot(GameObject OriginalSlot, GameObject NewSlot){
if (NewSlot.GetComponent<SlotScript> ().ContainedItem == null) {
if (OriginalSlot.GetComponent<SlotScript> ().ContainedItem != null){
if (OriginalSlot.GetComponent<SlotScript> ().ContainedItem.GetComponent<ItemScript> ().ItemAmount > 1) {
var NewItem = Instantiate (OriginalSlot.GetComponent<SlotScript> ().ContainedItem, Vector3.zero, Quaternion.identity);
NewItem.GetComponent<ItemScript> ().ItemAmount = 1;
NewItem.name = OriginalSlot.GetComponent<SlotScript> ().ContainedItem.name;
OriginalSlot.GetComponent<SlotScript> ().ContainedItem.GetComponent<ItemScript> ().ItemAmount += -1;
NewSlot.GetComponent<SlotScript> ().ContainedItem = NewItem;
}
}
}
}
}
You could write sub-classes and have an instance of them in your main script. If the classes need an Updata method, just give them one and call it from your main class' Update method. If the only concern is readability, remember that in Visual Studio, you can collapse methods and also navigate not just by scrolling through the whole script but also by selecting namespaces and methods from thedrop-down fields in the bar above the main script view.
It's more of just the fact that as I make more and more progress, the script gets increasingly complex and I might not even be able to understand what's going on at some point.
Comments are key to keep it understandable. Some scripts just grow big, that's not inherently wrong. You can also use #region and #endregion to have several visually separated and foldable regions in the code. Of course splitting it into multiple scripts is also a good idea, I would at least try to separate inventory related and movement related code.
Answer by SunnyChow · Apr 16, 2018 at 03:16 AM
i suggest you separate the script to two components: user control, game mechanic. For example, the user control component do ray cast to get the block, and call a function of game mechanic component so that the game mechanic component can deal with the block. Or, the user control component detect key press, and call the move function of game mechanic component.
The benefit is that, it's easier for you to change the control in the future, in you want to make the game also support game pad or touch screen, because you can just change the user control component .
Your answer