
Stranded Alone is another title that was created for a college assignment. We were tasked to research and create assets for a suitable audience that have an interest in Sci Fi and the British nationality.
This game was my most exaggerated game yet, more than ROLLCORE and therfore will plan to keep updating this title. At the moment is currently playable and has minimal bugs and issues which will be fixed in due time.
The aim of the game is to power up a base that you find yourself in by going round and gathering resources to help craft materials, resources, tools and more while also managing health, hunger and thirst.
Stranded Alone is intended to be played on 1920x1080 or any 16:9 Aspect Ratio
Windows/Linux Builds are available on Itch.io
You start off in an empty chamber with inactive portals; this is where you slowly explore the environment, following some kind of light that leads to a room that helps restore the power for the environment you find yourself in, however it seems to break which lead you to the explore around the power room to find resources and be able to craft fuses to help power the generator, allowing you to only traverse 1 environment. When you step in, you find yourself in an abandoned version of Britain with alienlike substances around the world, as you survive and explore the environment you learn of your past and what has happened in the past to cause all of this, you also come across rare materials and resources to help you craft tools, vehicles to help with survival and exploration, you will have to fabricate more fuses to use back in the generator room to allow the player to power more portals leading to more environments with unique materials and resources. Your main goal is to find and power and interstellar portal leading to somewhere unknown however you feel attached to the need to explore through it, maybe all the answers can be answered through the master portal. During the tutorial of the game (the section between the character waking up and the first portal being active) the environment of the level will be able to direct the player towards where they must go, using WASD keys to move around. When they reach certain obstacles, they will learn how to jump, gather materials and craft to be able to access the full content and environment (being the abandoned British environments). The tutorial will help the player learn the basic mechanics of this game, allowing the player to have all the skills they need to explore and survive as well as figure out different kinds of mechanics that may also exist within the game such as vehicles. The objective of the game is to power and go through the master portal, however it would the player to craft rare components and powerful fuses which their recipes and materials can be found throughout the 3 environments. The player will have to use all the mechanics, craft many tools, explore many environments to complete the game.
The gameplay UI elements that I will implement in the project will consist of a health value to show how much health the player has, a mini map to help direct the player and navigate through different environments, world space elements detailing a certain selected resource as well. In terms of the menu, I decided to proceed with making an Inventory System, that display the different materials and resources that the player has collected.
You can explore up to 4 environemnts being the Starter Base, Big Ben, Tower Bridge and finally Buckingham palace, with each environemnt being a block out of its original look. Each environemnt will have their charatceristics with many hazardous patches and plants as well as resource hotspots for the player to gather resources from. Different environments will have different kinds of materials and resources for the player to collect ranging from different rarities such as wood, stone and metal which all can be used to craft various tools, base elements. However, the most important crafting recipe would be the fuses that allow the other portals to the other environments to activate, allowing the player to explore and gather more different kinds of materials. Each environment will also be covered in vegetation, resource hotspots and this thick alienlike substance that grows flora that explodes and damages the player if they are to get too close to it.
No major story elements just yet, lore not planned out
Like any basic survival game you have the ability to manage your inventory which was scripted in Scriptable Object fashion for the first time, you can craft item, tools, materials and more using the crafting Station lpaced near the portals, an advanced crafting located in the power room will help the player be able to craft fuses to power the base and its portals, however recepies will have to be unlocked by exploring the environemnts and finding the recepie caches placed in each environemnt.
A minimap can also help you guide yourself within the environement that can be toggled on and off in the settings menu.

Resource Gathering
This flowchart covers the most parts of the Resource Gathering mechanic, it shows my idea on how to go about performing this mechanic in terms of looking at a resource and it is showing UI for which I will use Look At(player) and animation controllers to help create a seamless world space UI that details what the player is looking at.

Crafting
These two flowcharts above show how I would be able to implement the feature that allows the camera to focus on the crafting station when interacted with and show its UI, locking movement and rotation from the player to ensure that the view of the station is not obscured in any way due to movement and rotation. I have implemented features like this before in my work with projects, especially in Drowsy Yokai, allowing the player to click on an interactable and proceed to focus closer to that element and inspect it. I felt like reusing this as it would increase the immersive element the player using the station. It makes the user and player feel like they are looking onto the station. To help me create this, I would have to use cinemachine to increase the control I have over the camera’s movement with the help of transition blends and camera priority. The focus and unfocus methos controls when the UI on the camera station activates and when it locks/ unlocks the movement and rotation of the player. The script can be seen below.
For the recipes, I decided to make another set of scriptable objects, by referencing an array of Items (the other scriptable object that holds that data of all resources and tools), as well as the item rewarded after the craft as an Item object, as everything the player crafts will be added to their inventory. When a certain recipe is clicked, it checks through the whole inventory to see if it has the items that are in the recipe and stores the index position in a temporary array, if there are more items in the recipe, it continues along with the inventory to attempt to find that item in the inventory and stores them to the array If they have been found. If all items have been found, it goes through all the elements within the temporary array and removes all those items from the inventory, after that is complete, it goes ahead with adding the crafted item to the inventory

The images above show the visor UI element that I stuck to the mask, helping to increase the immersion that your vision is somewhat restricted due to you wearing a mask, on the image to the right above here shows the layout of the inventory/menu that will help guide the player. It shows the inventory grid to the left, and will be able to show you details on the right once you hover over a resource that you have gathered, it also contains tabs for a Map and your settings and quit button which will allow the player to switch the settings while in gameplay as well as quit more efficiently. I really liked how it turned out, and it was quite challenging to implement, and its not 100% complete as I still need to implement the resource information as well to drop materials and finally to check if the inventory is full or not which will all be implemented in the future.
public class InventoryManager : MonoBehaviour
{
private Animator _animator;
public bool _activeInventory;
public bool LockInventory;
private FirstPersonController _characterController;
private RawImage[] _resourcesIcons;
private bool _hovering;
public Inventory[] items;
private int _hoverindex;
private Objectives _mission;
private PlayerStats _playerStats;
[SerializeField] private Transform _recepieGrid;
[SerializeField] public Texture _emptySlot;
[SerializeField] private TMP_Text _itemName;
[SerializeField] private TMP_Text _itemDescription;
public CanvasGroup GameplayCanvasGroup;
private void Start()
{
_animator = _recepieGrid.transform.parent.GetComponentInParent();
_characterController = GetComponent();
_mission = GetComponent();
_playerStats = GetComponent();
_resourcesIcons = new RawImage[items.Length];
for (int i = 0; i < _recepieGrid.childCount; i++)
{
_resourcesIcons[i] = _recepieGrid.GetChild(i).GetComponent();
_resourcesIcons[i].texture = _emptySlot;
}
}
public void ConsumeItem()
{
if (!_hovering)
{ return; }
if (items[_hoverindex].Consumable)
{
_playerStats.ConsumeFoodDrink(items[_hoverindex]);
items[_hoverindex] = null;
_resourcesIcons[_hoverindex].texture = _emptySlot;
_hovering = false;
}
}
public void AddItem(Inventory newItem)
{
if (!_mission.Missions[2].Achieved && newItem.Name == "Common Fuse")
{
_mission.Missions[2].Achieved = true;
_mission.ChangeMission(_mission.Missions[2]);
}
for (int i = 0; i < items.Length; i++)
{
if (items[i] == null)
{
items[i] = newItem;
_resourcesIcons[i].texture = newItem.Texture;
return;
}
}
}
public void RemoveItem(Inventory itemToRemove)
{
for (int i = 0; i < items.Length; i++)
{
if (items[i] == itemToRemove)
{
items[i] = null;
_resourcesIcons[i].texture = _emptySlot;
return;
}
}
}
public void Death()
{
for (int i = 0; i < items.Length; i++)
{
if (items[i] == null) continue;
Instantiate(items[i].Prefab, transform.position, transform.rotation);
RemoveItem(items[i]);
}
}
public void DropItem()
{
if (!_hovering)
{ return; }
Instantiate(items[_hoverindex].Prefab, transform.position, transform.rotation);
items[_hoverindex] = null;
_resourcesIcons[_hoverindex].texture = _emptySlot;
_hovering = false;
}
public void ToggleInventory()
{
if(LockInventory)
{ return; }
if (!_activeInventory)
{
_animator.SetTrigger("Activate");
_activeInventory = true;
GameplayCanvasGroup.alpha = 0;
_characterController.enabled = false;
Cursor.lockState = CursorLockMode.None;
}
else
{
_animator.SetTrigger("Deactivate");
_activeInventory = false;
GameplayCanvasGroup.alpha = 1;
_characterController.enabled = true;
Cursor.lockState = CursorLockMode.Locked;
}
}
public void SetIndex(GameObject child)
{
for (int i = 0; i < _recepieGrid.childCount; i++)
{
if( _recepieGrid.GetChild(i).gameObject == child )
{
_hoverindex = i;
}
}
}
public void Hover(RawImage texture)
{
if (texture.texture == _emptySlot)
{ return; }
_hovering = true;
for (int i = 0; i < items.Length; i++)
{
if(items[i] == null)
{ continue; }
if (texture.texture == items[i].Texture)
{
_itemName.text = items[i].Name;
_itemDescription.text = items[i].Description;
return;
}
}
}
public void UnHover()
{
_itemName.text = "";
_itemDescription.text = "";
_hovering = false;
}
public bool FullInventoryCheck()
{
foreach(Inventory item in items)
{
if (item == null)
{ return false; }
}
return true;
}
}
public class Crafting : MonoBehaviour
{
[SerializeField] private TMP_Text _recepieText;
private InventoryManager _inventoryManager;
private bool _inFocus = false;
private CinemachineCamera _focusCamera;
private CinemachineCamera _playerCamera;
private Animator _animator;
private FirstPersonController _firstPersonController;
private PlayerTools _playerTools;
void Start()
{
_focusCamera = GetComponentInChildren();
_playerCamera = GameObject.FindGameObjectWithTag("Cinemachine").GetComponent();
_firstPersonController = GameObject.FindGameObjectWithTag("Player").GetComponent();
_inventoryManager = GameObject.FindGameObjectWithTag("Player").GetComponent();
_playerTools = GameObject.FindGameObjectWithTag("Player").GetComponent();
_animator = GetComponentInChildren();
}
public void Craft(RecepieObject recepie)
{
int NumberOfResourcesNeeded = recepie.Recepie.Length;
int CurrentResourceCount = 0;
int[] index = new int[NumberOfResourcesNeeded];
for (int i = 0; i < _inventoryManager.items.Length; i++)
{
if (Array.Exists(recepie.Recepie, element => element == _inventoryManager.items[i]))
{
index[CurrentResourceCount] = i;
CurrentResourceCount++;
if (CurrentResourceCount == NumberOfResourcesNeeded)
{
foreach (int x in index)
{
_inventoryManager.RemoveItem(_inventoryManager.items[x]);
}
_inventoryManager.AddItem(recepie.Item);
CurrentResourceCount = 0;
break;
}
}
}
}
public void Focus()
{
if (_inFocus)
{
UnFocus();
return;
}
_inventoryManager.GameplayCanvasGroup.alpha = 0.15f;
_inventoryManager.LockInventory = true;
_playerCamera.Priority = 0;
_focusCamera.Priority = 1;
_firstPersonController.enabled = false;
_animator.SetTrigger("Activate");
Cursor.lockState = CursorLockMode.None;
_inFocus = true;
_playerTools.Lock = true;
}
public void UnFocus()
{
_inventoryManager.GameplayCanvasGroup.alpha = 1f;
_inventoryManager.LockInventory = false;
_playerCamera.Priority = 1;
_focusCamera.Priority = 0;
_firstPersonController.enabled = true;
_animator.SetTrigger("Deactivate");
Cursor.lockState = CursorLockMode.Locked;
_inFocus = false;
_playerTools.Lock = false;
}
public void Hover(RecepieObject recepie)
{
var builder = new StringBuilder();
for(int i = 0; i < recepie.Recepie.Length; i++)
{
builder.Append(recepie.Recepie[i].name + ", ");
}
string result = builder.ToString();
_recepieText.text = result;
}
}
using JetBrains.Annotations;
using StarterAssets;
using UnityEngine;
using TMPro;
using Unity.Cinemachine;
public class PlayerStats : MonoBehaviour
{
private Vector3 _spawnPos;
private FirstPersonController _firstPersonController;
private InventoryManager _inventoryManager;
private CharacterController _charctercontroller;
[SerializeField] private CinemachineCamera _cinemachineCamera;
private bool _dead;
private bool _starving;
public int _health;
public int _maxHealth;
public int _hunger;
public int _thirst;
public GameObject _deathUI;
public TMP_Text HealthValue, ThirstValue, HungerValue;
void Start()
{
_health = 100;
_maxHealth = 100;
_thirst = 50;
_hunger = 75;
_deathUI.SetActive(false);
InvokeRepeating("HungerThirstDecrease", 100f, 10f);
_spawnPos = transform.position;
_firstPersonController = GetComponent();
_inventoryManager = GetComponent();
_charctercontroller = GetComponent();
HealthValue.text = _health.ToString();
HungerValue.text = _hunger.ToString();
ThirstValue.text = _thirst.ToString();
}
private void HungerThirstDecrease()
{
if (_dead) return;
if(_hunger > 0)
{ _hunger -= 1; HungerValue.text = _hunger.ToString(); }
else if(!_starving)
{
_hunger = 0;
HungerValue.text = _hunger.ToString();
InvokeRepeating("PassiveDamage", 5f, 10f);
}
if (_thirst > 0)
{ _thirst -= 1; ThirstValue.text = _thirst.ToString(); }
else if(!_starving)
{
_thirst = 0;
ThirstValue.text = _thirst.ToString();
InvokeRepeating("PassiveDamage", 5f, 10f);
}
}
public void StopPassiveHealing()
{
CancelInvoke(nameof(PassiveHealing));
}
public void PassiveHealing()
{
if(_health >= 100)
{
_health = 100;
return;
}
_health = _health + 5;
HealthValue.text = _health.ToString();
}
public void PassiveDamage()
{
_starving = true;
_health -= 5;
HealthValue.text = _health.ToString();
if (_health <= 0)
{
_dead = true;
death();
}
if (_hunger > 0 && _thirst > 0)
{
CancelInvoke(nameof(PassiveDamage));
_starving = false;
}
}
public void ConsumeFoodDrink(Inventory Consumable)
{
_hunger = _hunger + Consumable.hungerAdded;
_thirst = _thirst + Consumable.thirstAdded;
if (_hunger > 100) _hunger = 100;
if (_thirst > 100) _thirst = 100;
HungerValue.text = _hunger.ToString();
ThirstValue.text = _thirst.ToString();
if (_hunger > 90 && _thirst > 75)
{
InvokeRepeating("PassiveHealing", 0f, 20f);
}
}
public void death()
{
CancelInvoke(nameof(PassiveDamage));
_deathUI.SetActive(true);
_firstPersonController.enabled = false;
_charctercontroller.enabled = false;
_inventoryManager.Death();
Cursor.lockState = CursorLockMode.None;
_dead = true;
_inventoryManager.LockInventory = true;
}
public void Respawn()
{
transform.position = _spawnPos;
_cinemachineCamera.Priority = 4;
_deathUI.SetActive(false);
_firstPersonController.enabled = true;
_charctercontroller.enabled = true;
Cursor.lockState = CursorLockMode.Locked;
_health = 100;
_maxHealth = 100;
_thirst = 50;
_hunger = 75;
_dead = false;
_inventoryManager.LockInventory = false;
HealthValue.text = _health.ToString();
HungerValue.text = _hunger.ToString();
ThirstValue.text = _thirst.ToString();
}
}
I used the Standard Assets First Person Controller to help get a headstart on player movement and rotation, the movement scripting was not completed by me, although I did tweak some elements within the scripts such as the "head bob" effect that you will see when sprinting.