Skip to main content

Timed Power Ups

This is a long an complex tutorial. Take your time and know that it will be frustrating at times.

https://www.youtube.com/watch?v=5C9t3ux6PWA&ab\_channel=LearnICTNow

The class below is attached to a pick up or power up object.

It is used to store details of the type of powerup that it is so that the player can be updated correctly.

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

public class PickUpProperties : MonoBehaviour
{
public string type;
public float durationSeconds = 3.0f;
public float pickupImpactMultiplier = 5.0f;
}

Below is the code for running a timed pickup on the player.

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

public class PlayerPickUpManager : MonoBehaviour
{
private bool speedPickUpActive = false;
private bool sizePickUpActive = false;

// Check if objects are overlapping
void OnTriggerEnter(Collider col) {
//Debug.Log("I hit something");
if(col.CompareTag("PickUp")) {
//Debug.Log("I hit a pickup");
//

// Determine type of pickup
GameObject pickup = col.gameObject;
PickUpProperties pickupHit;
if(pickup.TryGetComponent<PickUpProperties>(out pickupHit)) {
// Check the type of pickup
if(pickupHit.type == "size" && speedPickUpActive == false) {
Debug.Log("Size hit");
transform.localScale = transform.localScale * pickupHit.pickupImpactMultiplier;
sizePickUpActive = true;
} else if(pickupHit.type == "speed") {
Debug.Log("Speed hit");
PlayerMovement playerMovement;
if(TryGetComponent<PlayerMovement>(out playerMovement)) {
// Gets here if the player movement script found
playerMovement.SetSpeed(playerMovement.GetSpeed() * pickupHit.pickupImpactMultiplier);
speedPickUpActive = true;
}
}
StartCoroutine(Timer(pickupHit.durationSeconds, pickup, pickupHit.pickupImpactMultiplier));
}


}
}

IEnumerator Timer(float timeDelay, GameObject go, float multipler) {
go.SetActive(false);

// Wait for timeDelay seconds
yield return new WaitForSeconds(timeDelay);

if(sizePickUpActive) {
sizePickUpActive = false;
transform.localScale = transform.localScale / multipler;
}
if(speedPickUpActive) {
speedPickUpActive = false;
PlayerMovement playerMovement;
if(TryGetComponent<PlayerMovement>(out playerMovement)) {
playerMovement.SetSpeed(playerMovement.GetSpeed() / multipler);
}
}


go.SetActive(true);
}
}

A basic playermovement script with speed Get and Set methods.

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

[RequireComponent(typeof(CharacterController))]
public class PlayerMovement : MonoBehaviour
{
// Player Variables
private CharacterController _characterController;
private float _speed = 5.0f;
private Vector2 _playerMovementInput;

public float GetSpeed() {
return _speed;
}
public void SetSpeed(float speed) {
_speed = speed;
}

// Start is called before the first frame update
void Start()
{
_characterController = GetComponent<CharacterController>();
}

// Update is called once per frame
void FixedUpdate()
{
MovePlayer();
}

void MovePlayer() {
Vector3 movement = new Vector3(_playerMovementInput.x, 0.0f , _playerMovementInput.y);

_characterController.SimpleMove(movement * _speed);
//_characterController.Move(movement * _speed * Time.deltaTime);
}

void OnMove(InputValue iv) {
_playerMovementInput = iv.Get<Vector2>();
}
}