
This is a long an complex tutorial. Take your time and know that it will be frustrating at times.
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>(); } }