Skip to content

Instantly share code, notes, and snippets.

@niiicolai
Created July 10, 2020 02:40
Embed
What would you like to do?
/* Arrow.cs */
using UnityEngine;
public class Arrow : MonoBehaviour
{
[SerializeField]
private float damage;
[SerializeField]
private float torque;
[SerializeField]
private Rigidbody rigidbody;
private string enemyTag;
private bool didHit;
public void SetEnemyTag(string enemyTag)
{
this.enemyTag = enemyTag;
}
public void Fly(Vector3 force)
{
rigidbody.isKinematic = false;
rigidbody.AddForce(force, ForceMode.Impulse);
rigidbody.AddTorque(transform.right * torque);
transform.SetParent(null);
}
void OnTriggerEnter(Collider collider)
{
if (didHit) return;
didHit = true;
if (collider.CompareTag(enemyTag))
{
var health = collider.GetComponent<HealthController>();
health.ApplyDamage(damage);
}
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
rigidbody.isKinematic = true;
transform.SetParent(collider.transform);
}
}
/* Weapon.cs */
using System.Collections;
using UnityEngine;
public class Weapon : MonoBehaviour
{
[SerializeField]
private float reloadTime;
[SerializeField]
private Arrow arrowPrefab;
[SerializeField]
private Transform spawnPoint;
private Arrow currentArrow;
private string enemyTag;
private bool isReloading;
public void SetEnemyTag(string enemyTag)
{
this.enemyTag = enemyTag;
}
public void Reload()
{
if (isReloading || currentArrow != null) return;
isReloading = true;
StartCoroutine(ReloadAfterTime());
}
private IEnumerator ReloadAfterTime()
{
yield return new WaitForSeconds(reloadTime);
currentArrow = Instantiate(arrowPrefab, spawnPoint);
currentArrow.transform.localPosition = Vector3.zero;
currentArrow.SetEnemyTag(enemyTag);
isReloading = false;
}
public void Fire(float firePower)
{
if (isReloading || currentArrow == null) return;
var force = spawnPoint.TransformDirection(Vector3.forward * firePower);
currentArrow.Fly(force);
currentArrow = null;
Reload();
}
public bool IsReady()
{
return (!isReloading && currentArrow != null);
}
}
/* WeaponController.cs */
using UnityEngine;
using UnityEngine.UI;
public class WeaponController : MonoBehaviour
{
[SerializeField]
private Text firePowerText;
[SerializeField]
private Weapon weapon;
[SerializeField]
private string enemyTag;
[SerializeField]
private float maxFirePower;
[SerializeField]
private float firePowerSpeed;
private float firePower;
[SerializeField]
private float rotateSpeed;
[SerializeField]
private float minRotation;
[SerializeField]
private float maxRotation;
private float mouseY;
private bool fire;
void Start()
{
weapon.SetEnemyTag(enemyTag);
weapon.Reload();
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
mouseY -= Input.GetAxis("Mouse Y") * rotateSpeed;
mouseY = Mathf.Clamp(mouseY, minRotation, maxRotation);
weapon.transform.localRotation = Quaternion.Euler(mouseY, weapon.transform.localEulerAngles.y, weapon.transform.localEulerAngles.z);
if (Input.GetMouseButtonDown(0))
{
fire = true;
}
if (fire && firePower < maxFirePower)
{
firePower += Time.deltaTime * firePowerSpeed;
}
if (fire && Input.GetMouseButtonUp(0))
{
weapon.Fire(firePower);
firePower = 0;
fire = false;
}
if (fire)
{
firePowerText.text = firePower.ToString();
}
}
}
/* HealthController.cs */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthController : MonoBehaviour
{
[SerializeField]
private float maxHealth;
private float currentHealth;
[SerializeField]
private float respawnTime;
[SerializeField]
private GameObject healthPanel;
[SerializeField]
private Text healthText;
[SerializeField]
private RectTransform healthBar;
private float healthBarStartWidth;
private MeshRenderer meshRenderer;
private bool isDead;
void Start()
{
meshRenderer = GetComponent<MeshRenderer>();
currentHealth = maxHealth;
healthBarStartWidth = healthBar.sizeDelta.x;
UpdateUI();
}
public void ApplyDamage(float damage)
{
if (isDead) return;
currentHealth -= damage;
if (currentHealth <= 0)
{
currentHealth = 0;
isDead = true;
meshRenderer.enabled = false;
healthPanel.SetActive(false);
StartCoroutine(RespawnAfterTime());
}
UpdateUI();
}
private IEnumerator RespawnAfterTime()
{
yield return new WaitForSeconds(respawnTime);
ResetHealth();
}
private void ResetHealth()
{
currentHealth = maxHealth;
isDead = false;
meshRenderer.enabled = true;
healthPanel.SetActive(true);
UpdateUI();
}
private void UpdateUI()
{
float percentOutOf = (currentHealth / maxHealth) * 100;
float newWidth = (percentOutOf / 100) * healthBarStartWidth;
healthBar.sizeDelta = new Vector2(newWidth, healthBar.sizeDelta.y);
healthText.text = currentHealth + "/" + maxHealth;
}
}
/* Movement.cs */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
[SerializeField]
private float movementSpeed = 10;
private new Rigidbody rigidbody;
void Start ()
{
rigidbody = GetComponent<Rigidbody>();
}
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 velocity = new Vector3(h, 0, v);
velocity = transform.TransformDirection(velocity);
velocity *= movementSpeed;
velocity -= rigidbody.velocity;
rigidbody.AddForce(velocity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment