Inputs and Outputs – 05/03/21

For todays Programming headache, we learned about inputs and outputs. We learned how to make a save and load system and using controls in video games. So to start, we opened up Unity and created a basic scene. For mine I set up a capsule for a player, a platform, a couple of buttons and text objects.

Once this was done, we went to work on the player movement, this is nothing new to me but I have to demonstrate that what I’ve coded is picked up by Unity. My Player Controller is as follows.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour 
{

	private Rigidbody rb;

	public float speed;

	// Use this for initialization
	void Start () 
	{
		rb = GetComponent<Rigidbody>();
	}
	
	// Update is called once per frame
	void Update () 
	{
		float moveHorizontal = Input.GetAxis("Horizontal");
		float moveVertical = Input.GetAxis("Vertical");

		if (Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow))
        {
			Debug.Log("You Pressed S // Down Arrow - This means Down");
        }

		if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow))
		{
			Debug.Log("You Pressed W // Up Arrow - This means Up");
		}

		if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow))
		{
			Debug.Log("You Pressed A // Left Arrow - This means Left");
		}

		if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow))
		{
			Debug.Log("You Pressed D // Right Arrow - This means Right");
		}

		Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

		rb.AddForce(movement * speed);
	}
}

The code is simple. I made a rigidbody variable component and a float named speed. In Start I locate the rigidbody attached to my Player object. Then in Update, as this runs every frame, it constantly checks for updates. I convert the axis to a float value so I can use this in a Vector3 for movement. The horizontal axis is defaulted to A and D and Left and Right Arrows in Unity, and vertical axis is defaulted to W and S and Up and Down arrows.

I made an if statement to detect the button presses which then prints to the Unity Console when those buttons are pressed. Finally to make the player move, we use the AddForce function from the rigidbody, get the Vector3 named movement and multiply it by the speed.

Next it was time to make the save and load buttons work. I made a script named SaveManager and this is how it looks.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System;

public class SaveManager : MonoBehaviour
{
	StreamWriter fileSave;
	StreamReader fileLoad;

	string saveLoc;
	string playerLastPos;

	public Text gameSaved;
	public Transform player;

	float playerPosX;
	float playerPosY;
	float playerPosZ;

	// Use this for initialization
	void Start()
	{
		//This finds current location of file
		saveLoc = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
		saveLoc = Application.dataPath;
		saveLoc += "/save.txt";

		playerLastPos = player.transform.ToString();
	}

	// Update is called once per frame
	void Update()
	{

	}

	public void Save()
	{
		//Writes user input from file and saves to string
		fileSave = new StreamWriter(saveLoc);
		string infoToWrite = "File Saved";

		playerPosX = player.transform.position.x;
		playerPosY = player.transform.position.y;
		playerPosZ = player.transform.position.z;

		fileSave.WriteLine(infoToWrite);
		fileSave.Close();

		gameSaved.text = "Game Saved!";

		Debug.Log("The file was saved in: " + saveLoc);
	}

	public void Load()
	{
		//Read user input from file and saves to string
		fileLoad = new StreamReader(saveLoc);
		string fileInformation = fileLoad.ReadToEnd();

		player.transform.position = new Vector3(playerPosX, playerPosY, playerPosZ);

		
		
		fileLoad.Close();

		gameSaved.text = "Game Loaded!";

		Debug.Log("The file at " + saveLoc + " was loaded! " + fileInformation);
	}
}

In the Start Function, we determine where to save the save file to and what to call the save file.

StreamWriter and StreamReader are the methods we use to save and load data. So we made a couple of functions called Save and Load. Firstly in these functions, I had to declare the read/write functionality. This was done by opening a new StreamWriter and then saving the information I needed to it before closing the StreamWriter. In my example, I had it so that when I clicked the save button, it saved the players position and changed the text to Game Saved. It saves the players position by saving the transform position to float variables.

For the Loading side of things, we declare a new StreamReader and then that loads the information from the file that was saved previously. In my example, this changes the on screen text to Game Loaded and loads the players previously saved position by making the transform equal to a new Vector3 containing the aforementioned transform float variable values.

Finally for the purpose of gameplay, I added a camera controller, this script simply follows the players transform.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour {

	public Transform target;

	// Use this for initialization
	void Start () 
	{
		
	}
	
	// Update is called once per frame
	void Update () 
	{
		transform.LookAt(target);	
	}
}

Leave a comment