using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// 控制角色移动、生命、动画等
/// </summary>
public class PlayerController : MonoBehaviour
{
public float speed = 5f;//移动速度
private int maxHealth = 5;//最大生命值
private int currentHealth;//当前的生命值
//========玩家死亡结束游戏==============================
//游戏结束提示
//public GameObject GameOver;
//指定为主角并销毁
public GameObject GameOverPlayer;
public int MyMaxHealth { get { return maxHealth; } }//在这里定义一个公共属性以便Collectible.cs可以访问生命属性
public int MyCurrentHealth { get { return currentHealth; } }//在这里定义一个公共属性以便Collectible.cs可以访问生命属性
//给个无敌时间
private float invincibleTime = 2f;//无敌时间2秒
private float invincibleTimer;//无敌计时器
private bool isInvincible;//给个状态-是否处于无敌状态
public GameObject bulletPrefab;//子弹
//==============玩家的音效===============================
public AudioClip hitClip;//受伤音效
public AudioClip launchClip;//发射齿轮音效
//==============玩家的方向的朝向=========================
private Vector2 lookDirection = new Vector2(1, 0);//(动画)默认朝向右方
//==============玩家的子弹数量============================
[SerializeField ]//序列化一下 也能在属性面板直接调整
private int curBulletCount;//当前子弹数量
private int maxBulletCount = 10;//最大子弹数量
public int MyCurBulletCount { get { return curBulletCount; } }
public int MyMaxBulletCount { get { return maxBulletCount; } }//这样就能在齿轮子弹包BulletBag.cs那边进行访问了
public static object pc { get; internal set; }
Passform currentPassform; //当前玩家处在的位置
Rigidbody2D rbody;//先获取它的刚体组件
Animator anim;//(动画)获取动画组件
/// <summary>
/// 背包系统
/// </summary>
public GameObject myBag;
bool isOpen;//反复按同一个按键 实现打开和关闭效果
/// <summary>
/// 智能提示
/// </summary>
//无法实现在其他脚本中销毁提示,故在此脚本中限时销毁
public float showTime = 3;
private float showTimer;
//智能提示框计时器
public float tiptime = 6;
private float tiptimer;
//智能提示文本
public Text tips;
public GameObject tipsframe;
void Start()
{
curBulletCount = 2;//一开始子弹数量为0
currentHealth = 5;
invincibleTimer = 0;//一开始是可以受到伤害的
rbody = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();//(动画)获取动画组件
UImanager.instance.UpdateHealthBar(currentHealth, maxHealth);//更新以下血条状态
UImanager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
}
void Update()
{
//智能提示文本
showTimer -= Time.deltaTime;//任务完成显示 计时器
tiptimer -= Time.deltaTime;//提示框显示 计时器
if (tiptimer<0)//超过时间就取消显示提示文本
{
tipsframe.SetActive(false);
}
if (showTimer + 5 < 0)//取消显示提示文本
{
tipsframe.SetActive(false);
}
if (currentHealth <= 2)//如果生命<=2了,则进行提示
{
tip();
}
if (curBulletCount == 0 && currentHealth !=0)//如果没有子弹了,则进行提示
{
tip();
}
OPenMyBag();//在Update里进行调用
/**
* 测试左朝向有误 故暂改代码
* float horizontal = Input.GetAxis("Horizontal");//控制水平移动方向A: -1 D: 1 0
float vertical = Input.GetAxis("Vertical"); //控制垂直移动方向 W: 1 S:-1 0
Vector2 moveVector = new Vector2(horizontal, vertical);//(动画)
if (moveVector.x != 0 || moveVector.y != 0) {
lookDirection = moveVector;
}//按键不按的时候是为0的
anim.SetFloat("Look X", lookDirection.x);
anim.SetFloat("Look Y", lookDirection.y);
anim.SetFloat("Speed", moveVector.magnitude);
**/
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 moveVector = new Vector2(horizontal, vertical);//将输入值存储在名为 moveVector 的 Vector2 变量中,而不是独立设置用于移动的 x 和 y
/*检查 move.x 或 move.y 是否不等于 0
* 使用 Mathf.Approximately 而不是 ==,这是因为计算机存储浮点数的方式意味着精度会有很小的损失
* 所以,不应测试完美的相等性,因为最终结果应该是 0.0f 的运算可能会得出类似 0.0000000001f 的结果。Approximately 会考虑这种不精确性,如果除去这种不精确性可以认为数值相等,将返回 true
* 本可以设置 lookDirection = moveVector,但这是另一种分配向量的 x 和 y 的方式
*/
if (!Mathf.Approximately(moveVector.x, 0.0f) || !Mathf.Approximately(moveVector.y, 0.0f))
{
lookDirection.Set(moveVector.x, moveVector.y);
lookDirection.Normalize();//在 lookDirection 上调用 Normalize,从而使长度等于 1。Vector2 类型存储位置,但也可以存储方向
}
anim.SetFloat("Look X", lookDirection.x);
anim.SetFloat("Look Y", lookDirection.y);
anim.SetFloat("Speed", moveVector.magnitude);
//=========移动=================================================================
Vector2 position = rbody .position;
//position.x = position.x + 1f * moveX * speed* Time.fixedDeltaTime; //消除抖动把Time.deltaTime改成Time.fixedDeltaTime
//position.y = position.y + 1f * moveY * speed* Time.fixedDeltaTime;
//因为上面定义了moveVector 所以把上面的注释掉 换另一种写法
position += moveVector * speed * Time.fixedDeltaTime;
rbody .MovePosition ( position);//把transform.position = position;修改成刚体移动
//=============无敌计时==========================================================
if (isInvincible) {
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
{
isInvincible = false; //倒计时结束以后(2秒),取消无敌状态
}
}
//=============按下J键 并且子弹数量>0 进行攻击===================================================
if (Input.GetKeyDown(KeyCode.J)&&curBulletCount >0)
{
Launch();
}
//=============按下 E 键 进行NPC交互
if (Input.GetKeyDown(KeyCode.E)) {
RaycastHit2D hit = Physics2D.Raycast(rbody.position, lookDirection, 2f,LayerMask .GetMask ("NPC"));//根据层级来进行索引 把NPC设为NPC层级 这样玩家发射的射线就只会和NPC触碰
if (hit.collider != null) {
NPCmanager npc = hit.collider.GetComponent<NPCmanager>();
if (npc != null) {
npc.ShowDialog();//显示对话框
}
}
}
//==================玩家死亡结束游戏===================================
//如果生命值为0,显示游戏结束字样,并销毁主角
if (currentHealth == 0)
{
//GameOver.SetActive(true);
//tip();
//GameObject.Find("Ruby").GetComponent<PlayerController >().enabled = false;
//gameObject.SetActive(false);
Destroy(GameOverPlayer,2f);
SceneManager.LoadScene(1);
}
//穿越
if (currentPassform != null)
{
currentPassform.Pass(gameObject);
}
}
/// <summary>
/// 改变玩家的生命值
/// </summary>
/// <param name="amount"></param>
public void ChangeHealth(int amount) {
//如果玩家受到伤害
if (amount < 0) {
if (isInvincible == true) {
return; //如果处于无敌状态就不让它进行下一步的伤害检测了
}
isInvincible = true;//如果不是无敌状态 改为true 让它受到这次伤害后就是无敌状态了 只让它受到一次伤害
anim.SetTrigger("Hit");//添加受伤动画
AudioManager.instance.AudioPlay(hitClip);//播放受伤音效
invincibleTimer = invincibleTime;//把时间进行重置 这样update里就能进行检测 它就开始减 如果小于0后它就解除无敌状态
}
//把玩家的生命值约束在0和最大值之间
Debug.Log(currentHealth + "/" + maxHealth);
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UImanager.instance.UpdateHealthBar(currentHealth, maxHealth);//更新血条
Debug.Log(currentHealth + "/" + maxHealth);
}
public void ChangeBulletCount(int amount) {
curBulletCount = Mathf.Clamp(curBulletCount + amount, 0, maxBulletCount);//限制子弹数量在0-最大值之间
UImanager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
}
public void Launch()
{
if (!UImanager.instance.hasTask) //当没有任务的时候
{
return;
}
ChangeBulletCount(-1);//每次攻击减1个齿轮
anim.SetTrigger("Launch");//播放攻击动画
AudioManager.instance.AudioPlay(launchClip);//播放攻击音效
GameObject bullet = Instantiate(bulletPrefab, rbody.position + Vector2.up * 0.5f, Quaternion.identity);
BulletController bc = bullet.GetComponent<BulletController>();
if (bc != null)
{
bc.Move(lookDirection, 300);
}
}
/// <summary>
/// 穿越功能
/// </summary>
/// <param name="collision"></param>
private void OnCollisionEnter2D(Collision2D collision)
{
currentPassform = collision.gameObject.GetComponent<Passform>();
}
private void OnCollisionExit2D(Collision2D collision)
{
currentPassform = null;
}
/// <summary>
/// 背包功能
/// </summary>
void OPenMyBag()
{
if (Input.GetKeyDown(KeyCode.O))//按下O键打开背包
{
isOpen = !isOpen;//反复切换背包打开开关
myBag.SetActive(isOpen);//不要忘记在Update里进行调用
}
}
/// <summary>
/// 智能提示
/// </summary>
public void tip()
{
if (currentHealth <=2)
{
tipsframe.SetActive(true);
int index = SceneManager.GetActiveScene().buildIndex;
if (index == 1||index ==3)
{
tips.text = "Tips:\n要小心一点噢!现在快去吃点草莓压压惊吧!";
}
else
{
return;
}
}
else if (curBulletCount == 0 && currentHealth != 0)
{
tipsframe.SetActive(true);
tips.text = "Tips:\n没有齿轮了噢,先去找一些齿轮吧!";
}
}
}
EnemyController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 敌人控制相关
/// </summary>
public class EnemyController : MonoBehaviour
{
public float speed = 3;//移动
public float changeDirectionTime = 2f;//改变方向的时间
public bool isVertical;//是否垂直方向移动
private float changeTimer;//改变方向的计时器
private Vector2 moveDirection;//移动方向
public ParticleSystem brokenEffect;//损坏特效
public AudioClip fixedClip;//被修复的音效
private bool isFixed;//是否被修复了
private Rigidbody2D rbody;
private Animator anim;//(动画设置部分)1.设置动画代码前 先获取一下它的Animator组件(动画直接根据它的moveDirection来设置)
// Start is called before the first frame update
void Start()
{
rbody = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();//(动画设置部分)2.同上面的刚体组件获取一样 把这个组件获取一下
moveDirection = isVertical ? Vector2.up : Vector2.right;//给它一个条件选择 如果是垂直移动,方向就朝上;否则方向朝右
changeTimer = changeDirectionTime;//让它初始的时候就等于它
isFixed = false;
}
// Update is called once per frame
void Update()
{
if (isFixed) return; //如果被修复 这里面的所有函数都不会执行了
changeTimer -= Time.deltaTime;
if (changeTimer < 0) {
moveDirection *= -1;//改变方向
changeTimer = changeDirectionTime;//让它改变时间的时间 计时器重新开始计时
}
Vector2 position = rbody.position;
position.x += moveDirection.x * speed * Time.fixedDeltaTime;
position.y += moveDirection.y * speed * Time.fixedDeltaTime;
rbody.MovePosition(position);
anim.SetFloat("moveX", moveDirection.x);//(动画设置部分)3.获取动画
anim.SetFloat("moveY", moveDirection.y);//(动画设置部分)3.获取动画
}
/// <summary>
/// 与玩家的碰撞检测
/// </summary>
/// <param name="collision"></param>
private void OnCollisionEnter2D(Collision2D collision)//与Trigger(只要求一个为刚体)比较OnCollisionEnter是真实的物理碰撞检测 要求两个物体都有刚体
{
PlayerController pc = collision.gameObject.GetComponent<PlayerController>();
if (pc != null) {
pc.ChangeHealth(-1);//给一点伤害
}
}
/// <summary>
/// 敌人被修复
/// </summary>
public void Fixed()
{
isFixed = true;
if (brokenEffect.isPlaying == true)
{
brokenEffect.Stop();
}
AudioManager.instance.AudioPlay(fixedClip);//播放被修复的音效
rbody.simulated = false;//禁用物理
anim.SetTrigger("fix");//播放被修复的动画
UImanager.instance.fixedNum = UImanager.instance.fixedNum + 1;//修复机器人的数量加1
//UImanager.instance.fixedNum++;
Destroy(this.gameObject,2f);
}
}
Enemy01.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
public class Enemy01 : MonoBehaviour
{
public AIPath aiPath;
void Update()
{
if (aiPath.desiredVelocity.x >= 0.01f)
{
transform.localScale = new Vector3(-1f, 1f, 1f);
}
else if (aiPath.desiredVelocity.x <= 0.01f)
{
transform.localScale = new Vector3(1f, 1f, 1f);
}
}
}
BulletController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制子弹的移动、碰撞
/// </summary>
public class BulletController : MonoBehaviour
{
Rigidbody2D rbody;
public AudioClip hitClip;//命中音效
// Start is called before the first frame update
void Awake()//Start改为Awake Awake在Start的前面会执行
{
rbody = GetComponent<Rigidbody2D>();
Destroy(this.gameObject , 2f);//不管碰没碰到物体 两秒后消失
}
// Update is called once per frame
void Update()
{
}
public void Move(Vector2 moveDirection,float moveForce)
{
rbody.AddForce(moveDirection * moveForce);
}
///碰撞检测
private void OnCollisionEnter2D(Collision2D collision)
{
EnemyController ec = collision.gameObject.GetComponent<EnemyController >();
if (ec != null) {
ec.Fixed();//修复敌人
}
AudioManager.instance.AudioPlay(hitClip);//播放命中音效
Destroy(this.gameObject);
}
}
SceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
public class SceneController
{
public static SceneController _instance;
public static SceneController Instance
{
get
{
if (_instance == null)
{
_instance = new SceneController();
}
return _instance;
}
}
public AsyncOperation currectLoadOperation; //加载的信息
//加载场景
public void LoadScene(int target)
{
//加载页面
if (SceneLoadPanel._instance == null)
{
//加载Prefabs/View/LoadScenePanel路径下的这个加载页面并实例化
GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/View/LoadScenePanel"));
}
//加载
currectLoadOperation = SceneManager.LoadSceneAsync(target);
//显示一个加载界面
//SceneLoadPanel._instance.Show();//通过调用SceneLoadPanel脚本里面的单例显示
SceneLoadPanel._instance.UpdateProcess(currectLoadOperation);//并调用UpdateProcess方法跟新进度
}
public void LoadScene( int target,Action<AsyncOperation> onComplete )
{
//加载页面
if (SceneLoadPanel._instance == null)
{
//加载Prefabs/View/LoadScenePanel路径下的这个加载页面并实例化
GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/View/LoadScenePanel"));
}
//加载
currectLoadOperation = SceneManager.LoadSceneAsync(target);
//显示一个加载界面
//SceneLoadPanel._instance.Show();//通过调用SceneLoadPanel脚本里面的单例显示
SceneLoadPanel._instance.UpdateProcess(currectLoadOperation);//并调用UpdateProcess方法跟新进度
//回调的事件
currectLoadOperation.completed += onComplete;
}
//重载函数,加上一个游戏物体的名称以及位置的名称
public void LoadScene(int target, string objName,string posName)
{
//调用target
LoadScene(target ,(asyncOperation) => {
//在当前的场景中进行查找这个游戏物体的名字
GameObject gameObject = GameObject.Find("objName");
//在当前的场景中进行查找这个游戏物体的位置
GameObject posObject = GameObject.Find("posName");
//把当前游戏物体的位置设置成posObject物体的位置
//gameObject.transform.position = posObject.transform.position;
//gameObject.transform.rotation = posObject.transform.rotation;
});
}
}
Videoontroller.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//用户交互视频播放
using UnityEngine.Video;
public class Videoontroller : MonoBehaviour
{
//得到Video Play组件vp
VideoPlayer vp;
// Use this for initialization
void Start()
{
//vp通过GetComponen这个模板函数得到
vp = GetComponent<VideoPlayer>();
}
// Update is called once per frame
void Update()
{
//如果某个用户点下了一个按键(空格)
if (Input.GetKeyDown(KeyCode.Space))
{
//判断当前视频是否为播放状态
if (vp.isPlaying)
{
//如果是播放状态让其先变成暂停状态
vp.Pause();
}
else
{
//如果不是播放状态让其继续播放
vp.Play();
}
}
}
}
BulletBag.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 子弹补给包
/// </summary>
public class BulletBag : MonoBehaviour
{
public int bulletCount=5;//包里含有的子弹数量
public ParticleSystem collectEffect;//获取一下拾取特效
public AudioClip collectClip;//拾取音效
private void OnTriggerEnter2D(Collider2D collision)
{
PlayerController pc = collision.GetComponent<PlayerController>();
if (pc != null) {
if (pc.MyCurBulletCount < pc.MyMaxBulletCount) {
pc.ChangeBulletCount(bulletCount);//增加玩家的子弹数
Instantiate(collectEffect, transform.position, Quaternion.identity);//添加拾取特效
AudioManager.instance.AudioPlay(collectClip);//播放音效
Destroy(this.gameObject);
}
}
}
}
Collectible.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 草莓被玩家碰撞时检测的相关类
/// </summary>
public class Collectible : MonoBehaviour
{
public ParticleSystem collectEffect;//拾取特效
public AudioClip collectClip;//拾取音效
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
/// <summary>
/// 碰撞检测相关
/// </summary>
/// <param name="collision"></param>
void OnTriggerEnter2D(Collider2D collision)
{
PlayerController pc = collision.GetComponent<PlayerController>();
if (pc != null)
{
if (pc.MyCurrentHealth < pc.MyMaxHealth) {
pc.ChangeHealth(1);//角色当前生命值小于最大生命值时生命值+1
Instantiate(collectEffect, transform.position, Quaternion.identity);//生成特效
AudioManager.instance.AudioPlay(collectClip);//播放音效
Destroy(this.gameObject);
}
//Debug.Log("玩家碰到草莓");
}
}
}
Inventory.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 创建背包
/// </summary>
[CreateAssetMenu(fileName = "New Inventory", menuName = "Inventory/New Inventory")]
public class Inventory : ScriptableObject
{
public List<Item> itemList = new List<Item>();
}
InventoryManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InventoryManager : MonoBehaviour
{
static InventoryManager instance;//单例模式(类似静态变量),一个类仅有一个实例,并提供一个访问点
/// <summary>
/// 我们要知道我们的背包是哪一个 要把背包里的物品生成出来
/// </summary>
public Inventory myBag;
public GameObject slotGrid;//定义之前的格子 在这个格子范围内生成物品
public Slot slotPrefab;
public Text itemInfromation; //物品的详情
private void Awake()
{
if (instance != null)
{
Destroy(this);
}
instance = this;
}
/// <summary>
/// 游戏运行时就刷新背包
/// </summary>
private void OnEnable()
{
RefreshItem();
instance.itemInfromation.text = "";//将描述信息内容变为空白显示内容
}
/// <summary>
/// 添加更新描述信息方法
/// </summary>
/// <param name="itemDescription"></param>
public static void UpdateItemInfo(string itemDescription)
{
instance.itemInfromation.text = itemDescription;
}
/// <summary>
/// 新的物品的方法 希望能在Item里所有的信息获得它 在把这个信息传输给Slot
/// </summary>
/// 需要在ItemOnWorld被调用
public static void CreateNewItem(Item item)//在网格范围内生成一个储物格
{
Slot newItem = Instantiate(instance.slotPrefab, instance.slotGrid.transform.position, Quaternion.identity);/*生成一个slotPrefab的实体叫newItem newItem是含有Slot这个函数的 所有这个新的物品它包括图片
数字和这个物品本身 在这里将Item.cs列表里面的本来的信息的传输给Slot.cs 然后在这里面生成出来*/
newItem.gameObject.transform.SetParent(instance.slotGrid.transform);//可以挂在这个下面成为它的子集了
newItem.slotItem = item;
newItem.slotImage.sprite = item.itemImag;//传输主要数据 这样就可以把图片传输过来了
newItem.slotNum.text = item.itemHeld.ToString();
}
/// <summary>
/// 添加刷新列表方法
/// </summary>
public static void RefreshItem()
{
for (int i = 0; i < instance.slotGrid.transform.childCount; i++)
{
if (instance.slotGrid.transform.childCount == 0)
{
break;
}
Destroy(instance.slotGrid.transform.GetChild(i).gameObject);//销毁所有相同物品所包含的子集
}
for (int i = 0; i < instance.myBag.itemList.Count; i++)
{
CreateNewItem(instance.myBag.itemList[i]);
}
}
}
Item.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 存储物品的所有属性信息 比如 名字 图片 数量
/// </summary>
[CreateAssetMenu (fileName ="New Item",menuName ="Inventory/New Item")]
public class Item : ScriptableObject
{
/// <summary>
/// 给物品添加属性 用公开变量来存储物品的不同属性
/// </summary>
public string itemName;//物品名字
public Sprite itemImag;//物品特殊图片
public int itemHeld;//存储这物品有几个 现在持有多少个
[TextArea ]
public string itemInfo;//它的一些描述
public bool equip;//(判断是装备还是药水)
}
ItemOnWorld.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemOnWorld : MonoBehaviour
{
public Item thisItem;
public Inventory playerInventory;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
AddNewItem();
Destroy(gameObject);//删除场景中的物体
}
}
/// <summary>
/// 添加一个物品
/// </summary>
public void AddNewItem()
{
if (!playerInventory.itemList.Contains(thisItem))
{
playerInventory.itemList.Add(thisItem);//如果不包含这物品 那么在背包里添加该物品
//调用InventoryManager里的功能
//InventoryManager.CreateNewItem(thisItem); //这个方法就不需要了 创建物品测试
}
else
{
thisItem.itemHeld += 1;//如果已经存在 那将该物品的持有数增加1
}
InventoryManager.RefreshItem();//刷新物品格
}
}
Slot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Slot : MonoBehaviour
{
public Item slotItem;//此变量不可用
public Image slotImage;//物品类型图片
public Text slotNum;//物品持有量
/// <summary>
/// (显示物品信息)添加 预制体按钮点击关联方法
/// </summary>
public void ItemOnClicked() {
InventoryManager.UpdateItemInfo(slotItem.itemInfo);
}
}
AudioManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 播放音乐 音效
/// </summary>
public class AudioManager : MonoBehaviour
{
public static AudioManager instance { get; private set; }
private AudioSource audioS;
// Start is called before the first frame update
void Start()
{
instance = this;
audioS = GetComponent<AudioSource>();
}
/// <summary>
/// 播放指定的音效
/// </summary>
/// <param name="clip"></param>
public void AudioPlay(AudioClip clip) {
audioS.PlayOneShot(clip);
}
}
AuManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AuManager : MonoBehaviour
{
public Toggle musicToggle;//定义公有的音乐开关键
public AudioSource musicAudio;//音乐源
public AudioSource musicAudio1;//每个机器人身上都有一个声音源
public AudioSource musicAudio2;
public AudioSource musicAudio3;
public AudioSource musicAudio4;
public AudioSource musicAudio5;
private bool musicOn = true;
void Update()
{
MusicSwicth();
}
/// <summary>
/// 判断音乐开关键状态
/// </summary>
private void MusicSwicth()
{
if (musicToggle.isOn == false)
{
musicOn = false;
musicAudio.enabled = false;
musicAudio1.enabled = false;
musicAudio2.enabled = false;
musicAudio3.enabled = false;
musicAudio4.enabled = false;
musicAudio5.enabled = false;
}
else
{
musicOn = true;
musicAudio.enabled = true;
musicAudio1.enabled = true;
musicAudio2.enabled = true;
musicAudio3.enabled = true;
musicAudio4.enabled = true;
musicAudio5.enabled = true;
}
}
}
ChangeScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ChangeScene : MonoBehaviour
{
public int targetScene;
public string posName;//游戏物体的位置
public string objName; //需要设置位置的游戏物体
private void OnTriggerEnter2D(Collider2D collision)
{
if (UImanager.instance.fixedNum >= 5 && collision.tag == "Player")//必须完成任务才能进入下一关。必须是主角进入
{
//如果位置的名字等于空 (其中一个为空)
if (string.IsNullOrEmpty(posName) || string.IsNullOrEmpty(objName))
{
//加载
SceneController.Instance.LoadScene(targetScene);
}else
{
//如果都不为空
//加载
SceneController.Instance.LoadScene(targetScene, objName, posName);
}
}
}
}
ChangeScene1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ChangeScene1 : MonoBehaviour
{
public int targetScene;
public string posName;//游戏物体的位置
public string objName; //需要设置位置的游戏物体
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Player")//必须完成任务才能进入下一关。必须是主角进入
{
//如果位置的名字等于空 (其中一个为空)
if (string.IsNullOrEmpty(posName) || string.IsNullOrEmpty(objName))
{
//加载
SceneController.Instance.LoadScene(targetScene);
}
else
{
//如果都不为空
//加载
SceneController.Instance.LoadScene(targetScene, objName, posName);
}
}
}
}
GameManger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManger : MonoBehaviour
{
public static GameManger _instance;//设成单列模式
public bool isPaused = true;//是否是暂停状态
public GameObject menuGO;
/// <summary>
/// 加载场景
/// </summary>
private string SceneName;//场景名称
private int index;//场景序号
private void Awake()
{
_instance = this;
/*
* if(GameManager._instance.isPaused==false){
* //满足这个if的时候这里面的代码才可以执行 游戏是非暂停状态时才可以正常游戏
* }
*
*/
//Pause();//游戏开始时是暂停的状态
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))//判断是否按下ESC键,按下则调出Menu菜单 并将游戏更改为暂停状态
{
Pause();
}
}
/// <summary>
/// 游戏暂停状态
/// </summary>
private void Pause()
{
isPaused = true;
menuGO.SetActive(true);//把菜单显示出来
Time.timeScale = 0;//用时间的缩放把场景时间停止掉 0停止 1游戏正常状态 2加速
}
/// <summary>
/// 游戏非暂停状态
/// </summary>
private void UpPause() {
isPaused = false;
menuGO.SetActive(false);
Time.timeScale = 1;
}
/// <summary>
/// 从暂停状态恢复到非暂停状态
/// </summary>
public void ContinueGame()
{
UpPause();
}
public void NewGame() {
//print(SceneManager.GetActiveScene().buildIndex);//获取本场景号
SceneManager.LoadScene(1);
UpPause();
}
public void QuitGame() {
SceneManager.LoadScene(0);//0是场景的索引
UpPause();
}
}
NPCmanager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// npc交互相关
/// </summary>
public class NPCmanager : MonoBehaviour
{
public GameObject tipImage;//按键提示
public GameObject dialogImage;//对话
public float showTime=4;//对话框显示时间
private float showTimer;//对话框显示计时器
public Text dialogText; //(任务设置)获取Test组件
// Start is called before the first frame update
void Start()
{
tipImage.SetActive(true);//初始默认显示提示键
dialogImage.SetActive(false);//初始默认隐藏对话框
showTimer = -1;
}
// Update is called once per frame
void Update()
{
showTimer -= Time.deltaTime;
if (showTimer < 0) {
tipImage.SetActive(true);//显示提示对话框
dialogImage.SetActive(false);
}
}
/// <summary>
/// 显示对话框
/// </summary>
public void ShowDialog() {
showTimer = showTime;
tipImage.SetActive(false );//显示对话框的时候把提示键隐藏
dialogImage.SetActive(true);
UImanager.instance.hasTask = true; //调用UImanager脚本里面的任务
if (UImanager.instance.fixedNum >=5) //如果以及完成任务
{
//需要修改对话框内容
dialogText.text = "哦,伟大的Ruby,你已经帮我修好他们啦,谢谢你!";
}
}
}
Passform.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Passform : MonoBehaviour
{
int targrtLayer; //穿越的层级
PlatformEffector2D platformEffector;
private void Start()
{
platformEffector = transform.GetComponent<PlatformEffector2D>();
}
//穿越的方法
public void Pass(GameObject target) //把要落下去的游戏物体传递给它
{
targrtLayer = 1 << target.layer; //把这个层级取消
//获取到这个组件,并设置把当前的这个值取消
platformEffector.colliderMask &= ~targrtLayer;
//把这个层级回复,即不能穿越
Invoke("ResetLayer", 1f);
}
public void ResetLayer()
{
platformEffector.colliderMask |= targrtLayer;
}
}
SceneLoadPanel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class SceneLoadPanel : ViewBase
{
public static SceneLoadPanel _instance;
private void Awake()
{
_instance = this; //赋值
DontDestroyOnLoad(gameObject); //防止加载页面被销毁
}
Slider slider_process;//声明Slider组件
AsyncOperation currentLoadScen; //当前加载的场景
// Start is called before the first frame update
void Start()
{
//("LoadScenePanel/Slider")是初始化LoadScenePanel下的子节点Slider
slider_process = transform.Find("bg/Slider").GetComponent<Slider>();
}
// Update is called once per frame
void Update()
{
if (currentLoadScen != null) //如果当前加载的场景不为空
{
//更新加载的进度
UpdateProcess(currentLoadScen.progress);
}
}
//更新进度
public void UpdateProcess(float process)
{
this.Show();
this.slider_process.value = process;
if (process >= 1)//如果process大于等于1,说明加载完成
{
Invoke("Hide", 2); //延时2s隐藏界面
}
}
//更新加载场景的进度
public void UpdateProcess(AsyncOperation asyncOperation)
{
this.Show();
currentLoadScen = asyncOperation; //给当前加载的场景赋值
}
public void Hide()
{
transform.gameObject.SetActive(false); //给当前加载的场景赋值 //如果界面隐藏
currentLoadScen = null; //就让当前加载的场景为空;
}
}
UIEntry.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class UIEntry : MonoBehaviour
{
public GameObject about;
private bool flag;
public Text Button1;//按钮1文本
public Text Button2;//按钮2文本
public Text AboutText;//关于文本
// Start is called before the first frame update
void Start()
{
flag = false;
}
public void StartGame()
{
if (flag == false)
{
SceneManager.LoadScene(5);
}
else
{
Application.OpenURL("https://www.bilibili.com/video/BV1V4411W787");
}
}
public void About()
{
if (flag == false)//显示
{
about.SetActive(true);//介绍文本显示
flag = true;
Button1.text = "游戏试玩视频";//按钮1从开始游戏变更为游戏试玩视频
Button1.fontSize = 49;
Button2.text = "游戏参考教程";//按钮2从开始游戏变更为游戏参考教程
Button2.fontSize = 49;
AboutText.text = "返回";//关于按钮变为返回按钮
AboutText.fontSize = 49;
return;
}
if (flag == true)//隐藏
{
about.SetActive(false);
flag = false;
Button1.text = "开始";//按钮1从试玩视频变更为开始游戏
Button1.fontSize = 49;
Button2.text = "设置";//按钮2从游戏参考教程变更为设置
Button2.fontSize = 49;
AboutText.text = "关于";//按钮变为关于按钮
AboutText.fontSize = 49;
return;
}
}
/// <summary>
/// 应用申请.打开网址链接 游戏试玩视频网页跳转
/// </summary>
public void DemoVideo()
{
Application.OpenURL("https://www.bilibili.com/video/BV1V4411W787");
}
/// <summary>
/// 参考教程网页跳转
/// </summary>
public void ctrl()
{
if (flag == false)
{
Debug.Log("1");
}
else
{
Application.OpenURL("https://www.bilibili.com/video/BV1V4411W787");
}
}
/// <summary>
/// ViewBase
/// </summary>
public virtual void Show()
{
gameObject.SetActive(true);
}
public virtual void Hide()
{
gameObject.SetActive(false);
}
/// <summary>
/// GameController
/// </summary>
public void ExitGame() {
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
UImanager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// UI管理相关
/// </summary>
public class UImanager : MonoBehaviour
{
//单例模式
public static UImanager instance { get; private set; }
public bool hasTask; //是否接收任务
//public bool CompleteTask//是否完成任务
public int fixedNum; //修理机器人的数量
void Awake()
{
instance = this;
}
public Image healthBar;//角色的血条
public Text BulletCountText;//子弹数量内容显示
/// <summary>
/// 更新血条
/// </summary>
/// <param name="curAmount"></param>
/// <param name="maxAmount"></param>
public void UpdateHealthBar(int curAmount, int maxAmount) {
healthBar.fillAmount = (float)curAmount / (float)maxAmount;
}
/// <summary>
/// 更新子弹数量文本的显示
/// </summary>
/// <param name="curAmount"></param>
/// <param name="maxAmount"></param>
public void UpdateBulletCount(int curAmount,int maxAmount) {
BulletCountText.text = curAmount.ToString() + "/" + maxAmount.ToString();
}
}
ViewBase.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ViewBase : MonoBehaviour
{
//显示界面
public void Show()
{
transform.gameObject.SetActive(true);
}
隐藏界面
//public void Hide()
//{
// transform.gameObject.SetActive(false );
//}
//判断是否显示
public bool IsShow()
{
return gameObject.activeSelf;
}
}
DamageArea.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DamageArea : MonoBehaviour
{
void OnTriggerStay2D(Collider2D collision)
{
PlayerController pc = collision.GetComponent<PlayerController>();
if (pc != null) {
pc.ChangeHealth(-1);
}
}
}
ImageShift.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// 场景剧情介绍图片切换代码
/// </summary>
public class ImageShift : MonoBehaviour
{
public GameObject imageConversation;
public Sprite[] textures;//定义精灵数组
private int i = 0;
/// <summary>
/// 定义图片纹理数组,便于后面用拖拽的方式赋值
/// </summary>
void Update()
{
if (Input.GetButtonDown("Fire1"))//切换图片
{
i++;
if (i == 3)
{
SceneManager.LoadScene("Scene1");
}
else
{
imageConversation.GetComponent<Image>().sprite = textures[i];
}
}
}
}