====== Prototyping Zombie Minigame ======
{{ :wiki:image_2022-08-16_075049458.png?600 |}}
This is the way I make function of models before I make it official.
====== Player Prototyping ======
{{ :wiki:zombieprototype.gif?nolink |}}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Micosmo.SensorToolkit;
using System;
using Sirenix.OdinInspector;
using UnityEngine.Events;
using HighlightPlus;
public class ZombiePlayerController : MonoBehaviour
{
[BoxGroup("GameObject Serialization")]
public GameObject cross;
[BoxGroup("GameObject Serialization")]
public Transform charater;
[BoxGroup("DoLookAt Fine Tune")]
public float lookAtSpeed = 1f;
[BoxGroup("Movement Fine Tune")]
public float movementSpeed = 1f;
[BoxGroup("Movement Fine Tune")]
public float movementSprintSpeed = 1f;
[BoxGroup("Movement Fine Tune")]
public float jumpHeight = 1f;
[BoxGroup("Movement Fine Tune")]
public float groundGravity = 1f;
[BoxGroup("Movement Fine Tune")]
public float runStamina = 15f;
[BoxGroup("Private Variable")]
[ShowInInspector]
private bool _groundedStatus;
[BoxGroup("Private Variable")]
[ShowInInspector]
private Vector3 _finalMoveValue;
[BoxGroup("Private Variable")]
[ShowInInspector]
private float _fowardDirection;
[BoxGroup("Private Variable")]
[ShowInInspector]
private float _righDirection;
[BoxGroup("Private Variable")]
[ShowInInspector]
private float _velocity;
[BoxGroup("Private Variable")]
[ShowInInspector]
private float _storedRunStamina;
private CharacterController _characterController;
private ZombieHealth _zombieHealth;
private HighlightEffect _highlight;
[HideInEditorMode]
public UnityEvent sendEventToUI;
[HideInEditorMode]
public UnityEvent onPlayerDied;
private void Awake()
{
Initialization();
}
private void Start()
{
_storedRunStamina = runStamina;
_zombieHealth.sendEventOnMinusHealth.AddListener(ReceivedEventOnPlayerHit);
SendEventToUI();
}
private void Initialization()
{
_characterController = this.GetComponent();
_zombieHealth = this.GetComponent();
_highlight = this.GetComponent();
}
private void Update()
{
if (_zombieHealth.IsDead())
{
onPlayerDied.Invoke();
return;
}
_velocity = GetVelocity();
SetRightFowardDirection();
PlayerLookAtCross();
//this will update _movement value that will be called by MovePlayer(_movement);
SetFinalMoveValue();
MovePlayer(_finalMoveValue);
}
#region INPUT
private Vector3 InputRelativeToCamera()
{
//reading the input:
float horizontalAxis = Input.GetAxis("Horizontal");
float verticalAxis = Input.GetAxis("Vertical");
//assuming we only using the single camera:
var camera = Camera.main;
//camera forward and right vectors:
var forward = camera.transform.forward;
var right = camera.transform.right;
//project forward and right vectors on the horizontal plane (y = 0)
forward.y = 0f;
right.y = 0f;
forward.Normalize();
right.Normalize();
//this is the direction in the world space we want to move:
var desiredMoveDirection = (forward * verticalAxis + right * horizontalAxis).normalized * movementSpeed;
SprintController();
if (Input.GetKey(KeyCode.LeftShift) && runStamina >= 0)
{
return desiredMoveDirection * movementSprintSpeed;
}
return desiredMoveDirection;
}
private void SprintController()
{
SendEventToUI();
if(GetVelocity() > 5)
{
runStamina -= Time.deltaTime;
return;
}
if (runStamina < _storedRunStamina && GetVelocity() == 0) runStamina += Time.deltaTime;
}
private float _jumpDuration = 0;
private float InputMovementJump()
{
if (!_groundedStatus)
{
_jumpDuration -= Time.deltaTime * groundGravity;
}
else
{
_jumpDuration = Input.GetAxis("Jump");
}
return _jumpDuration;
}
#endregion
#region MONOBEHAVIOUR
private void SetRightFowardDirection()
{
//This method will take dot value to detect character moving direction in local axis (so kalau axis tu rotate dia akan rotate sama)
_righDirection = Vector3.Dot(transform.right, new Vector3(_finalMoveValue.x, 0f, _finalMoveValue.z));
_fowardDirection = Vector3.Dot(transform.forward, new Vector3(_finalMoveValue.x, 0, _finalMoveValue.z));
}
private void PlayerLookAtCross() => charater.DOLookAt(cross.transform.position, lookAtSpeed, AxisConstraint.Y);
private void SetFinalMoveValue()
{
Vector3 _moveDirectionAtXZ = InputRelativeToCamera();
float _jumpDuration = InputMovementJump();
_finalMoveValue = new Vector3(_moveDirectionAtXZ.x, _jumpDuration * jumpHeight, _moveDirectionAtXZ.z);
}
private void MovePlayer(Vector3 _finalMoveValue) => _characterController.Move(_finalMoveValue * Time.deltaTime);
#endregion
#region SET METHOD
public void SetWhenGrounded() => _groundedStatus = true;
public void SetWhenNotGrounded() => _groundedStatus = false;
#endregion
#region GET METHOD
public bool IsGroundedStatus() => _groundedStatus;
public bool GetCursor() => Cursor.visible;
public float GetFowardDiretion() => _fowardDirection;
public float GetRightDirection() => _righDirection;
public float GetVelocity() => _characterController.velocity.magnitude;
#endregion
#region EVENT
private void InitializeEvent()
{
if (sendEventToUI == null) sendEventToUI = new UnityEvent();
SendEventToUI();
}
private void SendEventToUI()
{
sendEventToUI.Invoke(runStamina);
}
private void ReceivedEventOnPlayerHit()
{
_highlight.HitFX();
}
# endregion
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
using HellTap.PoolKit;
using UnityEngine.Events;
using SkyConsole.Utils;
public class ZombieGunController : MonoBehaviour
{
[BoxGroup("GameObject Initialization")]
public Spawner gunBarrelPoolSpawner;
[BoxGroup("Weapon Porperties")]
public float bulletSpeed;
[BoxGroup("Weapon Porperties")]
public float shootCooldown = 1f;
[BoxGroup("Weapon Porperties")]
private int bullet = 10;
[BoxGroup("Weapon Porperties")]
public AudioClip shootSound;
[BoxGroup("Weapon Porperties")]
public AudioClip emptyShootSound;
[BoxGroup("Weapon Porperties")]
public AudioSource gunSoundSource;
[HideInEditorMode]
public UnityEvent sendEventToUI;
private void Start()
{
gunSoundSource = this.GetComponent();
InitializeEvent();
}
private void Update()
{
BulletShootHandler();
}
[SerializeField]
private float timer = 0;
private void BulletShootHandler()
{
if (timer > 0)
{
timer -= Time.deltaTime;
return;
}
if (Input.GetKey(KeyCode.Mouse0))
{
timer = shootCooldown;
if (bullet == 0)
{
PlaySound(emptyShootSound);
return;
}
if (gunBarrelPoolSpawner != null)
{
gunBarrelPoolSpawner.Play();
PlaySound(shootSound);
bullet -= 1;
SendEventToUI();
}
}
}
private void PlaySound(AudioClip sound)
{
gunSoundSource.PlayOneShot(sound);
}
#region EVENT
private void InitializeEvent()
{
if (sendEventToUI == null) sendEventToUI = new UnityEvent();
SendEventToUI();
}
private void SendEventToUI()
{
sendEventToUI.Invoke(bullet);
}
#endregion
public void addBullet(int bulletCount)
{
bullet += bulletCount;
SendEventToUI();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Micosmo.SensorToolkit;
using DG.Tweening;
using System;
using Sirenix.OdinInspector;
public class ZombieCameraController : MonoBehaviour
{
[BoxGroup("Serialize GameObject")]
public GameObject cross;
[BoxGroup("Serialize GameObject")]
public GameObject crossCylinder;
[BoxGroup("Serialize GameObject")]
public GameObject player;
[BoxGroup("Cross Fine Tuning")]
public float crossSpeed = 1f;
[BoxGroup("Camera Porperties")]
public float zTilt;
[BoxGroup("Camera Porperties")]
public float xTilt;
private Camera _camera;
private RaySensor _sensor;
private RangeSensor _crossRangeSensor;
private void Awake()
{
_sensor = this.GetComponent();
_camera = this.GetComponent();
_crossRangeSensor = cross.GetComponentInChildren();
}
private void Update()
{
MoveRaycastToMousePosition();
CameraMovement();
SetCrossCylinderActive();
}
private void MoveRaycastToMousePosition()
{
var ray = _camera.ScreenPointToRay(Input.mousePosition);
_sensor.Direction = ray.direction;
MoveCrossToRaycastObstructionRayHit();
}
private void MoveCrossToRaycastObstructionRayHit()
{
float x = _sensor.GetObstructionRayHit().Point.x;
float z = _sensor.GetObstructionRayHit().Point.z;
if (_sensor.IsObstructed) cross.transform.DOMove(new Vector3(x, cross.transform.position.y, z), crossSpeed);
}
private void CameraMovement()
{
this.transform.DOLookAt(player.transform.position, 1f);
float x = player.transform.position.x + xTilt;
float z = player.transform.position.z + zTilt;
this.transform.DOMove(new Vector3(x, this.transform.position.y, z), 1f);
}
private void SetCrossCylinderActive()
{
if (_crossRangeSensor.GetNearestDetection() != null)
{
crossCylinder.SetActive(true);
}
else
{
crossCylinder.SetActive(false);
}
}
}
using Micosmo.SensorToolkit;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using HellTap.PoolKit;
using Sirenix.OdinInspector;
using SkyConsole.Utils;
public class ZombieBullet : MonoBehaviour
{
public float bulletSpeed = 25f;
public ParticleSystem bulletCollideParticle;
public float bulletDamage = 10;
public RangeSensor _rangeSensor;
private MeshRenderer _meshRenderer;
private Pool _pool;
private bool canMove = true;
private void Awake()
{
_meshRenderer = this.GetComponent();
_pool = FindObjectOfType();
_rangeSensor.OnSomeDetection.AddListener(ReceivedListenerOnCollided);
}
private void Update()
{
moveBullet(canMove);
}
private void moveBullet(bool canMove)
{
if(canMove == true) transform.position += transform.forward * Time.deltaTime * bulletSpeed;
}
private IEnumerator DespawnGameObject(float duration)
{
yield return new WaitForSeconds(duration);
canMove = true;
_pool.Despawn(this.gameObject);
}
#region Called From Event & Outside
private void ReceivedListenerOnCollided()
{
canMove = false;
bulletCollideParticle.Play();
if(_rangeSensor.GetNearestDetection().TryGetComponent(out ZombieHealth zombieHealth))
{
zombieHealth.MinusHealth(bulletDamage);
}
StartCoroutine(DespawnGameObject(bulletCollideParticle.main.duration));
}
private void OnDisable()
{
_rangeSensor.enabled = false;
}
private void OnEnable()
{
_rangeSensor.enabled = true;
}
#endregion
}