【Python】除了多线程和多进程,你还要会协程

【Mysql】锁机制、事务、并发控制总结

  返回  

2D Rubys冒险记游戏实现脚本合集

2021/7/20 23:53:35 浏览:

文章目录

    • PlayerController.cs
    • EnemyController.cs
    • Enemy01.cs
    • BulletController.cs
    • SceneController.cs
    • Videoontroller.cs
    • BulletBag.cs
    • Collectible.cs
    • Inventory.cs
    • InventoryManager.cs
    • Item.cs
    • ItemOnWorld.cs
    • Slot.cs
    • AudioManager.cs
    • AuManager.cs
    • ChangeScene.cs
    • ChangeScene1.cs
    • GameManger.cs
    • NPCmanager.cs
    • Passform.cs
    • SceneLoadPanel.cs
    • UIEntry.cs
    • UImanager.cs
    • ViewBase.cs
    • DamageArea.cs
    • ImageShift.cs

PlayerController.cs

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];
            }
        }
    }
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号