Feature: Hearts to track player lives

Added:
- Lives for the player
- Hearts to show the player how many lives they have
- Quits on 0 lives
Changed:
- Refactored code for easier maintainance
    - Better variable names
    - Easier to read conditions
    - Subroutines to handle specific logic
This commit is contained in:
Arlo Filley 2024-04-30 21:26:34 +01:00
parent 694b5f9d8c
commit 373211a586
5 changed files with 323 additions and 30 deletions

BIN
Assets/Heart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

111
Assets/Heart.png.meta Normal file
View File

@ -0,0 +1,111 @@
fileFormatVersion: 2
guid: d5215e49f8c63448caec0cdebd13c876
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -315,6 +315,134 @@ Transform:
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 1 m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &932053743
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 932053745}
- component: {fileID: 932053744}
m_Layer: 0
m_Name: Player Audio
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!82 &932053744
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 932053743}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 8300000, guid: 2f2aa64d405e14e95aee0dd410072bf6, type: 3}
m_PlayOnAwake: 0
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!4 &932053745
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 932053743}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -0.5, z: 0}
m_LocalScale: {x: 2, y: 2, z: 2}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1261174833}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &963194225 --- !u!1 &963194225
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -415,7 +543,7 @@ GameObject:
- component: {fileID: 1261174829} - component: {fileID: 1261174829}
m_Layer: 0 m_Layer: 0
m_Name: Player m_Name: Player
m_TagString: Untagged m_TagString: Player
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
@ -432,19 +560,16 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 1167bd91a13a6284192daa3f96ad9357, type: 3} m_Script: {fileID: 11500000, guid: 1167bd91a13a6284192daa3f96ad9357, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
acceleration: 10
maxSpeed: 2
horizontalInput: 0
verticalInput: 0
moveDirection: {x: 0, y: 0, z: 0}
rb: {fileID: 1261174834}
drag: 3
orientation: {fileID: 1261174833}
speed: 5
forwardKey: 44 forwardKey: 44
backwardKey: 111 backwardKey: 111
leftKey: 97 leftKey: 97
rightKey: 101 rightKey: 101
speed: 5
moveDirection: {x: 0, y: 0, z: 0}
rb: {fileID: 1261174834}
invulnerabilityTimeSeconds: 1.92
lastHit: 0
metalPipe: {fileID: 932053744}
--- !u!65 &1261174830 --- !u!65 &1261174830
BoxCollider: BoxCollider:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -519,7 +644,8 @@ Transform:
m_LocalPosition: {x: 0, y: 0.25, z: 0} m_LocalPosition: {x: 0, y: 0.25, z: 0}
m_LocalScale: {x: 0.5, y: 0.5, z: 0.5} m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children:
- {fileID: 932053745}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 3 m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@ -991,10 +1117,11 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 2715678257314441011} - component: {fileID: 2715678257314441011}
- component: {fileID: 3385535184014867851}
- component: {fileID: 3385535184014867850} - component: {fileID: 3385535184014867850}
m_Layer: 0 m_Layer: 0
m_Name: Enemy m_Name: Enemy
m_TagString: Untagged m_TagString: Enemy
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
@ -1014,6 +1141,19 @@ MonoBehaviour:
speed: 1 speed: 1
range: 4 range: 4
enemy: {fileID: 2715678257314441011} enemy: {fileID: 2715678257314441011}
--- !u!65 &3385535184014867851
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3385535184014867849}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 5, y: 5, z: 5}
m_Center: {x: 4, y: 2, z: 1}
--- !u!23 &4126550418253595862 --- !u!23 &4126550418253595862
MeshRenderer: MeshRenderer:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -1,8 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class PlayerController : MonoBehaviour public class PlayerController : MonoBehaviour
{ {
@ -15,42 +16,82 @@ public class PlayerController : MonoBehaviour
[Header("Speed")] [Header("Speed")]
public float speed = 5; public float speed = 5;
[Header("Player Object")] [Header("Lives")]
public Vector3 moveDirection; public string enemyTag = "Enemy";
public Rigidbody rb; public float invulnerabilityTimeSeconds = 0.25f;
public float lastHit = 0;
public int lives = 3;
public GameObject[] hearts;
[Header("Audio")] [Header("Audio")]
public AudioSource metalPipe; public AudioSource metalPipe;
[Header("Player Object")]
public Vector3 moveDirection;
public Rigidbody rb;
void Start() void Start()
{ {
rb = GetComponent<Rigidbody>(); if (hearts.Length != 3)
{
Debug.LogError("Hearts array not properly configured. Expected length 3.");
enabled = false;
return;
}
if (!TryGetComponent(out rb))
{
Debug.LogError("Rigidbody not found!");
enabled = false; // Disable script if Rigidbody is missing.
}
else
{
rb.freezeRotation = true; rb.freezeRotation = true;
} }
}
void Update() void Update()
{ {
moveDirection = PlayerInput(); moveDirection = PlayerInput();
rb.velocity = moveDirection.normalized * speed; rb.velocity = moveDirection.normalized * speed;
} }
Vector3 PlayerInput() Vector3 PlayerInput()
{ {
float forward = Convert.ToSingle(Input.GetKey(forwardKey)); Vector3 direction = Vector3.zero;
float backward = Convert.ToSingle(Input.GetKey(backwardKey));
float right = Convert.ToSingle(Input.GetKey(rightKey)); if (Input.GetKey(rightKey)) direction.x += 1f;
float left = Convert.ToSingle(Input.GetKey(leftKey)); if (Input.GetKey(leftKey)) direction.x -= 1f;
return new Vector3(right - left, 0, forward - backward); if (Input.GetKey(forwardKey)) direction.z += 1f;
if (Input.GetKey(backwardKey)) direction.z -= 1f;
return direction;
} }
void OnCollisionEnter(Collision collision) void OnCollisionEnter(Collision collision)
{ {
if (collision.gameObject.name == "Enemy") bool collidedWithEnemy = collision.gameObject.tag == enemyTag;
bool isInvulnerable = invulnerabilityTimeSeconds >= Time.time - lastHit;
if (collidedWithEnemy && !isInvulnerable)
{ {
Debug.Log("OWIE"); lastHit = Time.time;
metalPipe.Play(); metalPipe.Play();
lives--;
hearts[lives].GetComponent<RawImage>().color = Color.gray;
bool playerOutOfLives = lives == 0;
if (playerOutOfLives) ExitGame();
} }
} }
void ExitGame()
{
#if UNITY_EDITOR
EditorApplication.ExitPlaymode();
#endif
Application.Quit();
}
} }

View File

@ -3,7 +3,8 @@
--- !u!78 &1 --- !u!78 &1
TagManager: TagManager:
serializedVersion: 2 serializedVersion: 2
tags: [] tags:
- Enemy
layers: layers:
- Default - Default
- TransparentFX - TransparentFX