Ruby’s Adventure
1.DamageZone
using UnityEngine;
public class DamageZone : MonoBehaviour
{
private void OnTriggerStay2D(Collider2D collision)
{
//Debug.Log("与我们发生碰撞的对象是:"+collision);
RubyController rubyController = collision.GetComponent<RubyController>();
//当前发生触发检测的游戏物体对象身上有否有RubyController脚本
if (rubyController != null)
{
rubyController.ChangeHealth(-1);
//Debug.Log("Ruby当前的生命值是:" + rubyController.Health);
}
}
}
2.EnemyController
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public float speed = 3;
private Rigidbody2D rigidbody2d;
//轴向控制
public bool vertical;
//方向控制
private int direction = 1;
//方向改变时间间隔,常量
public float changeTime = 3;
//计时器
private float timer;
private Animator animator;
//当前机器人是否故障
private bool broken;
public ParticleSystem smokeEffect;
private AudioSource audioSource;
public AudioClip fixedSound;
public AudioClip[] hitSounds;
public GameObject hitEffectParticle;
// Start is called before the first frame update
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
timer = changeTime;
animator = GetComponent<Animator>();
//animator.SetFloat("MoveX", direction);
//animator.SetBool("Vertical",vertical);
PlayMoveAnimation();
broken = true;
audioSource = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
if (!broken)
{
//已修好,那么不再移动
return;
}
timer -= Time.deltaTime;
if (timer < 0)
{
direction = -direction;
//animator.SetFloat("MoveX",direction);
PlayMoveAnimation();
timer = changeTime;
}
Vector2 position = rigidbody2d.position;
if (vertical) //垂直轴向
{
position.y = position.y + Time.deltaTime * speed * direction;
}
else //水平轴向
{
position.x = position.x + Time.deltaTime * speed * direction;
}
rigidbody2d.MovePosition(position);
}
//触发检测
private void OnCollisionEnter2D(Collision2D collision)
{
RubyController rubyController = collision.gameObject.GetComponent<RubyController>();
if (rubyController != null)
{
rubyController.ChangeHealth(-1);
}
}
//控制移动动画的方法
private void PlayMoveAnimation()
{
if (vertical) //垂直轴向动画的控制
{
animator.SetFloat("MoveX", 0);
animator.SetFloat("MoveY", direction);
}
else //水平轴向动画的控制
{
animator.SetFloat("MoveX", direction);
animator.SetFloat("MoveY", 0);
}
}
//修复机器人
public void Fix()
{
Instantiate(hitEffectParticle, transform.position, Quaternion.identity);
broken = false;
rigidbody2d.simulated = false;
animator.SetTrigger("Fixed");
smokeEffect.Stop();
int randomNum = Random.Range(0, 2);
//float randomNum2 = Random.Range(1f,2f);
audioSource.Stop();
audioSource.volume = 0.5f;
audioSource.PlayOneShot(hitSounds[randomNum]);
Invoke("PlayFixedSound", 1f);
//UIHealthBar.instance.fixedNum = UIHealthBar.instance.fixedNum + 1;
UIHealthBar.instance.fixedNum++;
//Destroy(smokeEffect);
}
private void PlayFixedSound()
{
audioSource.PlayOneShot(fixedSound);
}
}
3.HealthCollectible
using UnityEngine;
public class HealthCollectible : MonoBehaviour
{
public AudioClip audioClip;
public GameObject effectParticle;
private void OnTriggerEnter2D(Collider2D collision)
{
//Debug.Log("与我们发生碰撞的对象是:"+collision);
RubyController rubyController = collision.GetComponent<RubyController>();
//当前发生触发检测的游戏物体对象身上有否有RubyController脚本
if (rubyController != null)
{
//有RubyController脚本
//Ruby是否满血
if (rubyController.Health < rubyController.maxHealth)
{
//Ruby是不满血状态
//rubyController.Health=rubyController.Health+1;
rubyController.ChangeHealth(1);
rubyController.PlaySound(audioClip);
Instantiate(effectParticle, transform.position, Quaternion.identity);
Destroy(gameObject);
}
}
}
}
4.NPCDialog
using UnityEngine;
using UnityEngine.UI;
public class NPCDialog : MonoBehaviour
{
public GameObject dialogBox;
public float displayTime = 4.0f;
private float timerDisplay;
public Text dialogText;
public AudioSource audioSource;
public AudioClip completeTaskclip;
private bool hasPlayed;
void Start()
{
dialogBox.SetActive(false);
timerDisplay = -1;
}
void Update()
{
if (timerDisplay >= 0)
{
timerDisplay -= Time.deltaTime;
if (timerDisplay < 0)
{
dialogBox.SetActive(false);
}
}
}
public void DisplayDialog()
{
timerDisplay = displayTime;
dialogBox.SetActive(true);
UIHealthBar.instance.hasTask = true;
if (UIHealthBar.instance.fixedNum >= 5)
{
//已经完成任务,需要修改对话框内容
dialogText.text = "哦,伟大的Ruby,谢谢你,你真的太棒了!";
if (!hasPlayed)
{
audioSource.PlayOneShot(completeTaskclip);
hasPlayed = true;
}
}
}
}
5.Projectile
using UnityEngine;
public class Projectile : MonoBehaviour
{
private Rigidbody2D rigidbody2d;
void Awake()
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
public void Launch(Vector2 direction, float force)
{
rigidbody2d.AddForce(direction * force);
}
private void Update()
{
if (transform.position.magnitude > 100)
{
Destroy(gameObject);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
//Debug.Log("当前子弹碰撞到的游戏物体是:"+collision.gameObject);
EnemyController enemyController = collision.gameObject.GetComponent<EnemyController>();
if (enemyController != null)
{
enemyController.Fix();
}
Destroy(gameObject);
}
}
6.RubyController
using UnityEngine;
public class RubyController : MonoBehaviour
{
private Rigidbody2D rigidbody2d;
public float speed; //Ruby的速度
//Ruby生命值
public int maxHealth = 5; //最大生命值
private int currentHealth; //Ruby的当前生命值
public int Health
{
get { return currentHealth; }
}
//Ruby的无敌时间
public float timeInvincible = 2.0f; //无敌时间常量
public bool isInvincible;
public float invincibleTimer; //计时器
private Vector2 lookDirection = new Vector2(1, 0);
private Animator animator;
public GameObject projectilePrefab;
public AudioSource audioSource;
public AudioSource walkAudioSource;
public AudioClip playerHit;
public AudioClip attackSoundClip;
public AudioClip walkSound;
private Vector3 respawnPosition;
private void Start()
{
//Application.targetFrameRate = 30;
rigidbody2d = GetComponent<Rigidbody2D>();
currentHealth = maxHealth;
animator = GetComponent<Animator>();
//audioSource = GetComponent<AudioSource>();
//currentHealth = 3;
//speed = 4;
//int a = GetRubyHealthValue();
//Debug.Log("Ruby当前的血量是:"+a);
respawnPosition = transform.position;
}
// Update is called once per frame
void Update()
{
//玩家输入监听
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical);
//当前玩家输入的某个轴向值不为0
if (!Mathf.Approximately(move.x, 0) || !Mathf.Approximately(move.y, 0))
{
lookDirection.Set(move.x, move.y);
//lookDirection = move;
lookDirection.Normalize();
if (!walkAudioSource.isPlaying)
{
walkAudioSource.clip = walkSound;
walkAudioSource.Play();
}
}
else
{
walkAudioSource.Stop();
}
//动画的控制
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
//移动
Vector2 position = transform.position;
Ruby的水平方向移动
//position.x = position.x + speed * horizontal*Time.deltaTime;
Ruby的垂直方向移动
//position.y = position.y + speed * vertical*Time.deltaTime;
//Ruby位置的移动
position = position + speed * move * Time.deltaTime;
//transform.position = position;
rigidbody2d.MovePosition(position);
//无敌时间计算
if (isInvincible)
{
invincibleTimer = invincibleTimer - Time.deltaTime;
if (invincibleTimer <= 0)
{
isInvincible = false;
}
}
//修理机器人的方法(攻击)
if (Input.GetKeyDown(KeyCode.H))
{
Launch();
}
//检测是否与NPC对话
if (Input.GetKeyDown(KeyCode.T))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position +
Vector2.up * 0.2f, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
if (hit.collider != null)
{
NPCDialog npcDialog = hit.collider.GetComponent<NPCDialog>();
if (npcDialog != null)
{
npcDialog.DisplayDialog();
}
}
}
}
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
{
return;
}
//收到伤害
isInvincible = true;
invincibleTimer = timeInvincible;
animator.SetTrigger("Hit");
PlaySound(playerHit);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
//Debug.Log(currentHealth+"/"+maxHealth);
if (currentHealth <= 0)
{
Respawn();
}
UIHealthBar.instance.SetValue(currentHealth / (float) maxHealth);
}
//public int GetRubyHealthValue()
//{
// return currentHealth;
//}
private void Launch()
{
if (!UIHealthBar.instance.hasTask)
{
return;
}
GameObject projectileObject = Instantiate(projectilePrefab,
rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
PlaySound(attackSoundClip);
}
public void PlaySound(AudioClip audioClip)
{
audioSource.PlayOneShot(audioClip);
}
private void Respawn()
{
ChangeHealth(maxHealth);
transform.position = respawnPosition;
}
}
7.UIHealthBar
using UnityEngine;
using UnityEngine.UI;
public class UIHealthBar : MonoBehaviour
{
public Image mask;
private float originalSize;
public static UIHealthBar instance { get; private set; }
public bool hasTask;
//public bool ifCompleteTask;
public int fixedNum;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
originalSize = mask.rectTransform.rect.width;
}
/// <summary>
/// 血条UI填充显示
/// </summary>
/// <param name="fillPercent">填充百分比</param>
public void SetValue(float fillPercent)
{
mask.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, originalSize * fillPercent);
}
}