RPG小端游

【龙魂世界6职业】2025最新整理Win一键服务端+网页注册+教程 3D魔幻RPG端游【龙魂世界6职业】2025最新整理Win一键服务端+网页注册+教程。 阅读详情


  
  
  


说下自我感觉比较难的部分

  1. 背包系统
  2. 快捷系统
  3. 攻击与技能特效部分

背包有inventory(全局控制),inventoryGrid(格子),inventoryItem(格子上的物品)组成;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class inventory : MonoBehaviour {

    public static inventory _instance;

    private TweenPosition tween;


    public List<inventoryGrid> itemGridList = new List<inventoryGrid>();
    public UILabel coinNumberLabel;
    private int coinCount = 1000;

    public GameObject inventoryItem;//拾取到的物品,(模拟)
    void Awake()
    {
        _instance = this;
        tween = this.GetComponent<TweenPosition>();
        //tween.AddOnFinished(this.OnTweenPlayFinished);//监听某个

        //this.gameObject.SetActive(false);
        
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.X))//随机生成一个
        {
            GetId(Random.Range(2001, 2023));
        }
    }
    //传进来一个,显示在格子;
    public void GetId(int id,int number=1)
    {
        inventoryGrid grid = null;//空格子
        ///////////////
        foreach (inventoryGrid temp in itemGridList)//遍历每个格子
        {
            if(temp.id==id)
            {
                grid = temp;break;//如果一个格子里东西等于传过来的ID,这个空格子就是这个物品ID的格子赋值过来
            }
        }
        if (grid != null)        //如果存在这个物品(保险)
        {
            grid.PlusNumber(number);
        }
        //如果有拾取到的物品那就跳出赋值,格子上的NUMBEL+1; 没有的话不赋值grid = null
        else                      //如果不存在这个物品
        {
            foreach(inventoryGrid temp in itemGridList)
            {
                if(temp.id==0)//找空的格子
                {
                    grid = temp;break;
                }
            }
            if(grid!=null)
            {
                GameObject ItemGo=NGUITools.AddChild(grid.gameObject,inventoryItem);//在空格子里创建格子物品
                ItemGo.transform.localPosition = Vector3.zero;
                grid.setId(id,number);

            }
        }
        int ii = 0;
        foreach (inventoryGrid temp in itemGridList)//遍历每个格子
        {
            if (temp.id != id)
            {
               
                ii += 1;
                if (ii == 20)
                {
                    print("满了");
                }
            }
        }

    }

    public bool MinusId(int id,int count=1)       //大面板里的减少接口
    {
        inventoryGrid grid = null;
        foreach (inventoryGrid temp in itemGridList)
        {
            if (temp.id==id)
            {
                grid = temp;break;
            }
        }
        if (grid==null)
        {
            return false;
        } else
        {
            bool isSuccess = grid.MinusNumber(count);
            return isSuccess;
        }
    }

    public bool isShow;
    public void Show()
    {
        isShow = true;

        
        tween.PlayForward();
    }
    public void Hide()
    {
                
            tween.PlayReverse();
            
            isShow = false;

    }
	// Use this for initialization
	void Start () {
        tween.PlayReverse();//初始化动画的时候会自动播放
        //GameObject self = GameObject.Find("Inventory");
        //self.transform.enabled = true;
        //this.gameObject.GetComponent<Renderer>().enabled = false;
        //_instance.renderer.enabled = false;
    }
  
    public void TransFromState()//打开背包的方法
    {
        if (isShow == false)
        {
            Show();

        }
        else
        {
            Hide();
        }
    }

    public bool GetCoint(int coin)          //判断身上的钱是否够
    {
        if (coin<=coinCount)
        {
            coinCount -= coin;
            coinNumberLabel.text = coinCount.ToString();
            return true;
        }
        else
        {
            return false;
        }
    }

    public void AddCoin(int count)                              //添加金币函数
    {
        this.coinCount += count;
        coinNumberLabel.text = coinCount.ToString();
    }
	
	// Update is called once per frame

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class inventoryGrid : MonoBehaviour {

    // Use this for initialization
    public int id = 0;//物件ID
    private objectInfo info = null;
    public UILabel numLabel;
    public int num=0;//物件数量

	void Start () {
        numLabel = this.GetComponentInChildren<UILabel>();
	}

    //赋格子信息
    public void setId(int id,int num=1)//传来一个id和num
    {
        this.id = id;
        info = objectsInfo._instance.getObjectById(id);//获取object组
        inventoryItem item = this.GetComponentInChildren<inventoryItem>();//本来(物品格子)item里面的UIspite的图片的空,透明;
        item.SetIconName(id,info.icon_name);     //给格子物品传一个,组里name
        numLabel.enabled = true;
        this.num = num;
        numLabel.text = num.ToString();//转数组

    }

    public void PlusNumber(int num = 1)//模拟拾取到同样装备加一;
    {
        this.num += num;
        numLabel.text = this.num.ToString();//转数组
    }   
    public bool MinusNumber(int num=1)  //同样装备减一
    {
        if (this.num>=num)
        {
            this.num -= num;
            numLabel.text = this.num.ToString();//转数组
            if (this.num==0)
            {
                clearInfo();//清空信息
                GameObject.Destroy(this.GetComponentInChildren<inventoryItem>().gameObject);//删除物品格子
            }
            return true;


        }
        return false;
    }

    //清格子信息
    public void clearInfo()
    {
        id = 0;
        num = 0;
        info = null;
        numLabel.enabled = false;
    }
	
	// Update is called once per frame
	void Update () {
		
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class inventoryItem : UIDragDropItem {
    public UISprite sprite;
    public int id;

    public bool isMouse1=true;       //鼠标在背包上吗

    //public float timer=1;
    //public bool comeTo = false;
    

    // Use this for initialization
    //继承拖动类,可跟鼠标交互
    //删去start update,避免覆盖父类

    void Awake()
    {
        sprite = this.GetComponent<UISprite>();

    }



    void Update()
    {
        if (isHover)
        {
            
            //if (Input.GetMouseButtonDown(0))
            //{
            //    isMouse1 = true;

            //    //print(Input.GetMouseButtonDown(0));
            //}
            //if (Input.GetMouseButtonUp(0))
            //{
            //    isMouse1 = false;

            //    //print(Input.GetMouseButtonDown(0));
            //}



            if (isMouse1==true)                     //鼠标在
            {
                inventDes._instance.Show(id);
            }


            //comeTo = true;
            //timer -= Time.deltaTime;
            //inventDes._instance.Show(id);

            if (Input.GetMouseButtonDown(1))//右键穿
            {
                
                

                bool success = EquipmentUI._instance.Dress(id);
                if (success)
                {
                    transform.parent.GetComponent<inventoryGrid>().MinusNumber();//穿成功调用减一函数
                    //EquipmentUI._instance.UpdatePropperty();
                }
                

            }

        }
        //else
        //{
        //    inventDes._instance.Show(0);
            
        //}
        
    }


    protected override void OnDragDropRelease(GameObject surface)//焦点转化为射线,surface.tag
    {
        base.OnDragDropRelease(surface);
        //print(surface.tag);
        if (surface!=null)
        {

            isMouse1 = true;                        //鼠标下物体不为空,那么暂且认为在背包上 

            if (surface.tag==Tags.inventory_item_grid)//鼠标点击,则射线点是下面(如果该点是格子)
            {
                if (surface==this.transform.parent.gameObject)//如果当前的object==点击的item的grid的object
                {
                    ResetPosition();
                }else 
                {
                    inventoryGrid oldGrid = this.transform.parent.GetComponent<inventoryGrid>();//当前的grid(老grids)

                    this.transform.parent= surface.transform;//把鼠标下的grid位置赋值给当前grid
                    ResetPosition();                        //点击的是item;只要没被点都是在item 上偏移
                    inventoryGrid newGrid = surface.GetComponent<inventoryGrid>();//
                    newGrid.setId(oldGrid.id,oldGrid.num);//只是为了传个num;//提示版也要用到
                    

                    oldGrid.clearInfo();
                    //print(this.transform.parent.gameObject.tag);
                    //print(this.transform.gameObject.tag);
                    //print(this.transform.parent.tag);
                }
            }else if (surface.tag == Tags.inventory_item)//点击的是物品
            {
                inventoryGrid oldGrid = this.transform.parent.GetComponent<inventoryGrid>();
                inventoryGrid newGrid = surface.GetComponentInParent<inventoryGrid>();//
                int id = oldGrid.id;int num = oldGrid.num;
                oldGrid.setId(newGrid.id,newGrid.num); ResetPosition();
                newGrid.setId(id,num); ResetPosition();

            }else if(surface.tag == Tags.shortCut)
            {
                surface.GetComponent<ShorCutGrid>().SetInventory(id);
                ResetPosition();
                isMouse1 = false;                       //物品快捷之后也要取消提示面板
            }
            else//点击其他
            {
                ResetPosition();
                //this.id = 0;
            }

        }else
        {
            isMouse1 = false;                           //鼠标下物体为空,那么暂且认为不在背包上 
            ResetPosition();
            
        }

    }

    public void ResetPosition()//点击的是item;只要没被点都是在item 上偏移
    {
        transform.localPosition = Vector3.zero;
    }


    //通过传ID调用object
    public void setId(int id)
    {
        objectInfo info = objectsInfo._instance.getObjectById(id);
        sprite.spriteName = info.icon_name;//给sprite付上图片名 
    }
    //收name自己给label赋值
    public void SetIconName(int id,string icon_name)
    {
        sprite.spriteName = icon_name;
        this.id = id;//为了传给提示版
    }

    private bool isHover ;
    public void OnHoverOver()///////要添加UI tiger和UI Listen
    {
        isHover = true;
        
    }
    public void OnHoverOut()
    {
        isHover = false;
        
    }

}

快捷跟其他类调用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum ShortCutType{

    Skill,
    Drug,
    None

}


public class ShorCutGrid : MonoBehaviour {

    public KeyCode keyCode;

    public UISprite icon;

    public ShortCutType Type = ShortCutType.None;

    public int id;
    public SkillInfo skillInfo;

    public objectInfo objInfo;
    public PlayerStatus ps;
    public PlayerAttack pa;

    void Awake()
    {

        icon = transform.Find("icon").GetComponent<UISprite>();
        icon.gameObject.SetActive(false);
    }
    void Start()
    {
        ps = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<PlayerStatus>();
        pa = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<PlayerAttack>();
    }
    void Update()
    {
        if (Input.GetKeyDown(keyCode))
        {

            if (Type==ShortCutType.Drug)            //使用药物
            {

                OnDrugUse();

            }else if (Type == ShortCutType.Skill)
            {
                bool success = ps.TakeMP(skillInfo.mp);         //适用技能
                if (success==false)
                {
                   
                }
                else
                {
                    pa.UseSkill(skillInfo);
                }
            }
        }
    }

    public void SetSkill(int id)        //接收技能id
    {
        this.id = id;
        skillInfo = SkillsInfo._instance.GetSkillInfoById(id);
        icon.gameObject.SetActive(true);
        icon.spriteName = skillInfo.icon_name;
        Type = ShortCutType.Skill;
    }

    public void SetInventory(int id)            //给物品添加快捷
    {
        this.id = id;
        objInfo = objectsInfo._instance.getObjectById(id);
        if (objInfo.type==objectType.Drug)
        {
            icon.gameObject.SetActive(true);
            icon.spriteName = objInfo.icon_name;
            Type = ShortCutType.Drug;
            //inventDes._instance.removeDes();
            //inventoryItem.Restriction();
        }
    }

    public void OnDrugUse()         //物品使用时接口
    {
        bool isSuccess= inventory._instance.MinusId(id,1);
        if (isSuccess)
        {
            ps.GetDrug(objInfo.hp, objInfo.mp);
        }
        else
        {
            Type =ShortCutType.None;
            icon.gameObject.SetActive(false);
            id = 0;
            objInfo = null;
            skillInfo = null;
        }
    }


	// Use this for initialization

	
	// Update is called once per frame

}

攻击与动画特效

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum PlayerState
{
    ControlWalk,
    NormalAttack,
    SkillAttack,         //技能攻击
    Death
}

public enum AttackSate      //攻击状态下的状态
{
    Moving,
    Idle,
    Attack
}

public class PlayerAttack : MonoBehaviour {

    public static PlayerAttack _instance;

    public PlayerState state = PlayerState.ControlWalk;

    public AttackSate attackState = AttackSate.Idle;

    public string animname_normallattack;           //普通攻击动画
    public string animname_idle;                    //休息动画
    public string animname_now;                     //当前动画
    public float time_normalattck;               //普通攻击时间
    public float rate_normalattck=0.5f;                  //普通攻击速率
    private float timer = 1;                    //攻击计时
    public float min_distance = 5;              //最小攻击距离

    public Transform target_normalAttack;          //将要正常攻击物体

    public playerMove move;                     //调用接口

    public bool showEffect=false;                     //特效是否用过
    public GameObject effect;

    public PlayerStatus ps;                     //角色属性             

    private GameObject HUDTextGo;                //实例出来的一个
    public GameObject HUDTextPre;                  //模型
    private GameObject hudtextFollow;               //跟随。。。出现在UIROOT ,实例出来的位置


    //public UIFollowTarget followTarget;             //HUD上的组件
    public HUDText hudText;                        //HUD上的组件

    public float  missRate=0.5f;                         //miss概率
    public string animname_death;                    //死亡动画

    
    public AudioClip missVoice;


    public GameObject body;

    public Color normaleColor;                       //
    public GameObject[] efxArray;                       //储存特效模型

    public Dictionary<string, GameObject> skillPre = new Dictionary<string, GameObject>();          //用数组去遍历

    public bool singleDamge = false;                    //标志单体攻击鼠标图标是否正在使用
    public SkillInfo infoSingle = null;

    





    // Use this for initialization
    void Awake () {
        _instance = this;
        move = this.GetComponent<playerMove>();
        ps = this.GetComponent<PlayerStatus>();
        hudtextFollow = transform.Find("HUDText").gameObject;
        normaleColor = body.GetComponent<Renderer>().material.color;

        foreach (GameObject go in efxArray)
        {
            skillPre.Add(go.name,go);
        }

    }

    void Start()
    {
        //infoSingle.applyType = ApplyType.SingleTarget;



        HeadStatusUI._instance.UpdateShow();
        HUDTextGo = NGUITools.AddChild(HUDTextParent._instance.gameObject,HUDTextPre);
        hudText = HUDTextGo.GetComponent<HUDText>();
        UIFollowTarget followTarget = HUDTextGo.GetComponent<UIFollowTarget>();
        followTarget.target = hudtextFollow.transform;
        followTarget.gameCamera = Camera.main;

    }
	
	// Update is called once per frame
	void Update () {

        

        if (Input.GetMouseButtonDown(0)&&state!= PlayerState.Death)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    //鼠标生成射线
            RaycastHit hitInfo;                                             //碰撞信息
            bool isCollider = Physics.Raycast(ray,out hitInfo);              //是否碰撞到物体
            if (isCollider&&hitInfo.collider.tag==Tags.enemy)
            {
                //state = PlayerState.NormalAttack;
                if (state == PlayerState.ControlWalk)
                {
                    animname_now = animname_normallattack;                        //点到敌人是第一个要播放的动画是攻击动画,不需要携程       


                    target_normalAttack = hitInfo.collider.transform;             //赋值自动攻击的物体
                    state = PlayerState.NormalAttack;
                    timer = 0;
                    showEffect = false;                                  //
                    this.transform.LookAt(target_normalAttack.position);                 //攻击时望向它
                }
                
            }
            else
            {
                state = PlayerState.ControlWalk;
                target_normalAttack = null;                         //
            }
        }

        



        if (state == PlayerState.NormalAttack)
        {
            if (target_normalAttack==null)                                                  //如果攻击的物体变为空,状态改变
            {
                state = PlayerState.ControlWalk;
            }
            else
            {
                float distance = Vector3.Distance(transform.position, target_normalAttack.position);
                if (distance <= min_distance)                                                          //
                {
                    //StartCoroutine(showAnimator());


                    //animname_now = animname_normallattack;
                    transform.LookAt(target_normalAttack.position);                         //攻击时望向它

                    attackState = AttackSate.Attack;
                    timer += Time.deltaTime;
                    GetComponent<Animation>().CrossFade(animname_now);                      //先播放以一个攻击动画

                    if (timer > (0.3f / rate_normalattck))                                  //攻击动画播放到0.3是产生伤害,看起来真实s(重要)
                    {
                        if (showEffect == false)
                        {
                            showEffect = true;
                            GameObject.Instantiate(effect, target_normalAttack.position, Quaternion.identity);
                            target_normalAttack.GetComponent<WolfBaby>().TakeDamage(GetAttack());
                        }
                    }


                    //攻速一秒两次就等于0.5一次,也就是说第一个动画播到0.5的时候直接从头开始播,有时间限制(好像动画名一样会播完,不会从头播,每帧检测)
                    //但是由于第二个IF,定时器时间如果小于攻击时间0.83则不会调用狼伤害函数                                                           


                    if (timer > (1f / rate_normalattck))                                //计时器大于攻击一次的时间,进行下一次攻击
                    {
                        
                        timer = 0;                                                      //计时器归零
                        showEffect = false;
                        
                        animname_now = animname_normallattack;                          //就播放一次攻击

                    }

              
                    if (timer >= time_normalattck)                                      //攻击一次时间休息
                    {
                        animname_now = animname_idle;                                   //播放休息动画
    
                    }

                }
                else
                {
                    attackState = AttackSate.Moving;
                    move.SimpleMove(target_normalAttack.position);              //调用接口走向敌人
                }
            }  
            
        }


        /////////////////////////////////////////////////////////////////////////////////

        if (Input.GetMouseButtonDown(1))                                        //鼠标右键时状态改为行走
        {
            CursorManager._instance.SetNormal();
            state = PlayerState.ControlWalk;
        }
        if ((Input.GetMouseButtonDown(0) && state == PlayerState.SkillAttack))
        {
            if (infoSingle.applyType==ApplyType.SingleTarget)
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    //鼠标生成射线
                RaycastHit hitInfo;                                             //碰撞信息
                bool isCollider = Physics.Raycast(ray, out hitInfo);              //是否碰撞到物体
                if (isCollider && hitInfo.collider.tag == Tags.enemy)
                {
                    if (state == PlayerState.SkillAttack)                              //状态是否为技能攻击
                    {

                        target_normalAttack = hitInfo.collider.transform;             //赋值自动攻击的物体
                        state = PlayerState.SkillAttack;

                        this.transform.LookAt(target_normalAttack.position);                 //攻击时望向它
                        StartCoroutine(SinglePre(infoSingle));                        //调用协程实例函数
                        return;
                    }
                    return;

                }
            }
            
            
        }
        /////////////////////////////////////////////////////////////////////////////////
        
  
        
    }




    public int GetAttack()                                                  //传出伤害接口
    {
        return (int)(EquipmentUI._instance.attack + ps.attack + ps.attack_plus);     //plus是等级攻击加成点数


        
    }

    public void TakeDamage(int attack)                                                    //收到伤害
    {
        if (state == PlayerState.Death) return;
        float finalDamage = attack -(ps.defense+ps.defense_plus+EquipmentUI._instance.defense);
        if (finalDamage < 1) finalDamage = 1;
        float rag= Random.Range(0f,1f);
        if (rag<missRate)
        {
            hudText.Add("miss",Color.gray,1);
            AudioSource.PlayClipAtPoint(missVoice, transform.position);
        }
        else
        {
            StartCoroutine(ShowBodyRed());
            ShowBodyRed();
            ps.hp_remain -= finalDamage;
            hudText.Add("-" + finalDamage, Color.red, 1);
            HeadStatusUI._instance.UpdateShow();
            if (ps.hp_remain<0)
            {
                GetComponent<Animation>().CrossFade(animname_death);
                state = PlayerState.Death;
            }
            

        }





    }

    IEnumerator ShowBodyRed()
    {
        body.GetComponent<Renderer>().material.color=Color.red;
        yield return new WaitForSeconds(1f);
        body.GetComponent<Renderer>().material.color = normaleColor;
    }



    void Desrory()
    {
        GameObject.Destroy(HUDTextGo);          
    }


    public void UseSkill(SkillInfo info)                                            //使用技能
    {
        if (ps.heroType==HeroType.Magician)
        {
            if (info.applicableRole==ApplicableRole.Swordman)
            {
                return;
            }
        }

        if (ps.heroType == HeroType.Swordman)
        {
            if (info.applicableRole == ApplicableRole.Magician)
            {
                return;
            }
        }

        switch (info.applyType)
        {
            case
                ApplyType.Buff:
                StartCoroutine(BuffTake(info));//增强
                break;
            case
                ApplyType.MultiTarget:          //多个个角
                infoSingle = info;              //存储技能
                state = PlayerState.SkillAttack;                                    //修改状态
                singleDamge = true;                                                 //修改标志位
                CursorManager._instance.SetLockEnemy();                             //修改鼠标图标,在UPDATE里面调用

                print(infoSingle.applyType);


               StartCoroutine(MultPre(info));

                break;
            case
                ApplyType.SingleTarget:         //单个角色
                
                infoSingle = info;              //存储技能
                state = PlayerState.SkillAttack;                                    //修改状态
                singleDamge = true;                                                 //修改标志位
                CursorManager._instance.SetLockEnemy();                             //修改鼠标图标,在UPDATE里面调用


                break;
            case
                ApplyType.Passive:              //增益
                StartCoroutine(PassiveTake(info));

                break;

        }


    }

    IEnumerator PassiveTake(SkillInfo info)         //增益接口
    {
        state = PlayerState.SkillAttack;

        GetComponent<Animation>().CrossFade(info.animname);
        yield return new WaitForSeconds(info.anitime);
        state = PlayerState.ControlWalk;



        int hp = 0;
        int mp = 0;

        int def = 0;
        int attack = 0;
        if (info.applyProperty == ApplyProperty.HP)
        {
            hp = info.applyValue;
            ps.GetDrug(hp, 0);
            
        }else if (info.applyProperty == ApplyProperty.MP)
        {
            mp = info.applyValue;
            ps.GetDrug(0, mp);
        }
        

        GameObject passPre = null;
        skillPre.TryGetValue(info.efx_name, out passPre);
        GameObject.Instantiate(passPre, transform.position, Quaternion.identity);
        state = PlayerState.ControlWalk;                                                //技能用完状态改为行走
        CursorManager._instance.SetNormal();
        HeadStatusUI._instance.UpdateShow();

    }

    IEnumerator BuffTake(SkillInfo info)                    //增强接口
    {
        
        GetComponent<Animation>().CrossFade(info.animname);
        yield return new WaitForSeconds(info.anitime);
        state = PlayerState.ControlWalk;


        GameObject passPre = null;
        skillPre.TryGetValue(info.efx_name,out passPre);
        GameObject.Instantiate(passPre,transform.position,Quaternion.identity);

        state = PlayerState.ControlWalk;                                                //技能用完状态改为行走
        CursorManager._instance.SetNormal();


        switch (info.applyProperty)
        {
            case ApplyProperty.Attack:
                ps.attack *= (info.applyValue / 100f);
                break;
            case ApplyProperty.AttackSpeed:
                rate_normalattck *= (info.applyValue / 100f);
                break;
            case ApplyProperty.Def:
                ps.defense *= (info.applyValue / 100f);
                break;
            case ApplyProperty.Speed:
                move.speed *= (info.applyValue / 100f);
                break;
            
        }
        yield return new WaitForSeconds(info.applyTime);
        switch (info.applyProperty)
        {
            case ApplyProperty.Attack:
                ps.attack /= (info.applyValue / 100f);
                break;
            case ApplyProperty.AttackSpeed:
                rate_normalattck /= (info.applyValue / 100f);
                break;
            case ApplyProperty.Def:
                ps.defense /= (info.applyValue / 100f);
                break;
            case ApplyProperty.Speed:
                move.speed /= (info.applyValue / 100f);
                break;

        }
    }

    IEnumerator SinglePre(SkillInfo info)                                //攻击单个目标
    {
  
        
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    //鼠标生成射线
        RaycastHit hitInfo;                                             //碰撞信息
        bool isCollider = Physics.Raycast(ray, out hitInfo);              //是否碰撞到物体
        if (isCollider&&(Input.GetMouseButtonDown(0)&&hitInfo.collider.tag==Tags.enemy))
        {
            
            GetComponent<Animation>().CrossFade(info.animname);
            yield return new WaitForSeconds(info.anitime);
            state = PlayerState.ControlWalk;                            //状态设置为行走

            if (target_normalAttack!=null)                              //目标不为空
            {
                GameObject passPre = null;
                skillPre.TryGetValue(info.efx_name, out passPre);
                GameObject.Instantiate(passPre, hitInfo.transform.position, Quaternion.identity);
                target_normalAttack = hitInfo.collider.transform;
                target_normalAttack.GetComponent<WolfBaby>().TakeDamage((int)(GetAttack() * info.applyValue / 100f));
            }
            

            
            singleDamge = false;                                        //标志位

            CursorManager._instance.SetNormal();                        //鼠标图案设置回来
        }
        yield return new WaitForSeconds(0);
        
    }


    IEnumerator MultPre(SkillInfo info)                                //攻击单个目标
    {

        print("31");
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);    //鼠标生成射线
        RaycastHit hitInfo;                                             //碰撞信息
        bool isCollider = Physics.Raycast(ray, out hitInfo);              //是否碰撞到物体
        if (isCollider)                                                   //&&hitInfo.collider.tag==Tags.ground 限制在什么物体上释放
        {

            GetComponent<Animation>().CrossFade(info.animname);
            yield return new WaitForSeconds(info.anitime);
            state = PlayerState.ControlWalk;                            //状态设置为行走

            GameObject passPre = null;
            skillPre.TryGetValue(info.efx_name, out passPre);
            GameObject.Instantiate(passPre, hitInfo.point, Quaternion.identity);
            //target_normalAttack = hitInfo.collider.transform;
            //target_normalAttack.GetComponent<WolfBaby>().TakeDamage((int)(GetAttack() * info.applyValue / 100f));

            passPre.GetComponent<MagicMultPre>().deamge = (GetAttack() * info.applyValue / 100f);

            print("32");

            singleDamge = false;                                        //标志位

            state = PlayerState.ControlWalk;

            CursorManager._instance.SetNormal();                        //鼠标图案设置回来
        }
        else
        {
            state = PlayerState.ControlWalk;                            //状态设置为行走
        }
        yield return new WaitForSeconds(0);

    }
}

人物系统

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum HeroType
{
    Swordman,
    Magician
    
}

public class PlayerStatus : MonoBehaviour {


    public HeroType heroType;

    public int level = 1;       //100+level*30
    public string name="130";
    public int hp = 100;    //最大值
    public int mp = 100;
    public float hp_remain =100 ;
    public float mp_remain =100 ;

    public float exp = 0;       //当前获得的经验



    public int coin = 200;//金币


    public float attack = 20;
    public int attack_plus = 0;
    public float defense = 20;
    public int defense_plus = 0;
    public float speed = 20;
    public int speed_plus = 0;
    public int point_remain = 0;//升级分配点;



    void Start()
    {
        GetExp(0);
    }

    public void GetDrug(int hp,int mp)      //快捷键加血加魔法
    {
        hp_remain += hp;
        mp_remain += mp;
        if (hp_remain>this.hp)
        {
            hp_remain = this.hp;
        }
        if (mp_remain>this.mp)
        {
            mp_remain = this.mp;
        }
    }


    public bool GetPoint(int point=1)//让分配点减少
    {
        if (point_remain >= point)
        {
            point_remain -= point;
            return true;
        }
        else
        {
            return false;
        }
        
    }


    public void GetExp(int exp)
    {
        this.exp += exp;                        //本来的经验+获得的经验
        int total_exp = 100 + level * 30;       //升级总的经验
        while (this.exp >= total_exp)
        {
            this.level++;
            this.exp -= total_exp;                  //本来的经验+获得的经验-升级总的经验
            total_exp = 100 + level * 30;           //新的升级总的经验
        }

        ExpBar._instance.SetVaule(this.exp/total_exp);
    }



    

	// Use this for initialization

	
	// Update is called once per frame
	void Update () {
		
	}


    public bool TakeMP(int count)           //为技能魔法提供接口
    {
        if (count<mp_remain)
        {
            mp_remain -= count;
            HeadStatusUI._instance.UpdateShow();
            return true;

        }
        else
        {
            return false;
        }
    }
}


从TM1到TM9:手把手教你用Wireshark抓包分析LTE下行调度与传输模式切换 本文详细解析了如何使用Wireshark抓包分析LTE下行调度中的传输模式切换,从TM1到TM9的动态调整过程。通过实战案例,包括小区边缘移动、高速场景和多用户调度,揭示eNodeB如何基于信道质量指标(如RSRP、SINR)动态切换传输模式,并提供关键信令解析和优化建议,助力网络工程师提升LTE网络性能。 阅读详情

相关推荐

S32K314 EB配置MCAL全模块讲解【Autosar——1 MCU模块详解】持续更新中

FIRC(fast internal RC Oscillator) :高速内部时钟,固定48MHZ;SIRC(Slow Internal RC Oscillator):低速内部时钟,固定32KHZ;FXOSC(Fast Crystal Oscillator Digital Controller):高速外部晶振(8-40MHZ),根据原理图选型进行配置;SXOSC():外部低速外部时钟,固定输入32.768KHZ;PLL_PHIn_CLK:时钟倍频锁相环时钟范围(640-1280MHZ);

qq_40488886的博客 1782

NGUI Tween几种用法随手记

需要明确下几种动画的用法 play begin EventDelegate.add TweenPlayer ------------------------------------------------------------------------ 最基本的用法 TweenScale ts = TweenScale.Begin(mStartObj,...

aikb6223的博客 366

Ubuntu20.04下 嵌入式 Qt 开发环境的搭建(适用于Tiny6410)

Ubuntu 下 Tiny6410 嵌入式 Qt 开发环境的搭建 目录导航Ubuntu 下 Tiny6410 嵌入式 Qt 开发环境的搭建前言1.安装前的准备工作2.安装交叉编译器 前言 这篇文章,主要是基于 Ubuntu19.10版本而写,写此文的初衷,是为了自己使用,因为最近正在以Tiny6410板子做实训,所以也是初学者一枚,只能保证我遇上的问题统统能够解决掉,至于一些没遇上的,欢迎各位看客给我留言,大家一起讨论,一起解决。 注:本文会持续更新 1.安装前的准备工作 环境要求 Linux系统:U

繁臻的小窝 4895

Unity3d的GameObject.Find()的一些使用心得体会

今天跟着视频写代码,最后是获得游戏主角身上的脚本的信息来使物品栏显示。 就在Awake()方法里面写了GameObject.FindGameObjectWithTag(Tags.player).GetComponentInParent();这句代码 报空指针错误,调试发现是Getcomponent出错了。 查了好久发现脚本确实在本体而没有在子物体,也没有在别的脚本禁用PlayerStatus

脚踏实地,给自己一个更好的生活 1万+

String+CytoScape构建PPI网络

1.下载CytoScape Cytoscape是一款专业强大好用的物生信息分析软件,主要达用于专业的研究人员使用,软件主要适用于整合模块化网络和生物科学联系网络图的绘制,支持多种文件格式,导入后就可以直接进行编辑或者分析等操作了,除此之外,软件还提供了强大的编辑工具,支持添加相应的注释信息,软件基于java环境组件打造。 下载地址:https://cytoscape.org/ 因为软件基于java...

xiaobai1_1的博客 1万+

草莓成熟度与叶片病虫害智能检测数据集应用全解析

本文深入解析草莓成熟度与叶片病虫害智能检测数据集的应用价值,涵盖从绿草莓到红果转色的完整成熟周期及白粉病、炭疽病等7种病害的精准识别。通过实战案例展示如何提升病害识别率至94%,并介绍数据集的科研价值,包括跨品种迁移学习和多模态数据融合技术。

weixin_28366353的博客 275

堪比端游!欧美十大RPG网页游戏推荐

你喜欢RPG游戏吗?大多数玩家的回答是肯定的,身临其境的控制一个角色在虚拟的世界中冒险是一种非常神奇的体验。不得不承认,在目前的游戏市场上,不管是客户端游戏和网页游戏,RPG游戏都占据了很大的市场份额,在如此繁多的RPG游戏中肯定不乏精品,今天,小编沧海识珠,选取了10款激动人心的RPG页游(排名不分先后)供大家鉴赏,想知道你心中的游戏是否名列其中吗,让我们来一探究竟: 1.Drakensang

痞子龙3D编程 1万+

MATLAB图像去噪实战:如何用巴特沃斯滤波器完美去除横条纹(附完整代码)

本文详细介绍了如何使用MATLAB中的巴特沃斯滤波器有效去除图像中的横条纹噪声。通过频域分析和滤波处理,结合完整的代码示例,帮助读者掌握从噪声分析到参数优化的全流程技术,实现高质量的图像去噪效果。

weixin_30566063的博客 563

【RPG黑暗之光】第四章· 物品模块

RPG游戏黑暗之光Part4:物品模块   (由于电脑出了点问题重装以后好多写好的文档没有了,所以说各位一定要好好备份啊!这里博主微(ku)笑(B)着回来填坑啦~) RPG游戏主要组成中道具的构成是很大一部分的内容,其中从属性分类包括药品,武器(上装,饰品,宝石等),药品等。 这里RPG游戏游戏人物自身需要有个背包系统,商店(武器,药品)也要有自己的商品系统,这里我们先分后和的来介绍。 ...

唐三十胖子的博客 975

AMD KFD的SDMA Packet 类型和定义解析

本文详细分析了AMD GPU架构中的SDMA(System Direct Memory Access)数据传输机制,重点介绍了其核心数据结构——SDMA Packet。SDMA通过8种主要Packet类型(包括内存拷贝、数据写入、屏障同步、中断触发等)实现高效主机-设备通信。每种Packet采用位域结构和联合体封装设计,在保证功能完整性的同时实现空间优化。这些Packet支持丰富的访问属性和扩展字段,适用于高性能数据搬运、内存初始化、任务同步、性能分析等场景,为GPU计算提供了灵活高效的数据传输解决方案。

图形/计算GPU的驱动与虚拟化技术分享园地 1254

10、利用智能合约实现公平的私有集合交集

本文探讨了利用智能合约实现公平的私有集合交集(PSI)的多种协议,重点分析了协议 Π 和 Π∗ 的气体成本与性能特点。同时对比了包括 Justitia 和 Anesidora 在内的现有方案,突出了仅使用智能合约实现硬币补偿公平性的优势。文中还介绍了相关密码学基础、安全模型及隐私保障机制,为在不同应用场景下选择高效、安全的 PSI 协议提供了理论支持和实践指导。

linux的博客 96

堪比端游 欧美十大RPG网页游戏推荐

你喜欢RPG游戏吗?大多数玩家的回答是肯定的,身临其境的控制一个角色在虚拟的世界中冒险是一种非常神奇的体验。不得不承认,在目前的游戏市场上,不管是客户端游戏和网页游戏,RPG游戏都占据了很大的市场份额,在如此繁多的RPG游戏中肯定不乏精品,今天,小编沧海识珠,选取了10款激动人心的RPG页游(排名不分先后)供大家鉴赏,想知道你心中的游戏是否名列其中吗,让我们来一探究竟: 1.Drakensa...

weixin_30915275的博客 1417

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

免费能玩端游游戏手机软件推荐 手机畅玩端游教学

市面上多数工具要么收费解锁高清高帧,要么延迟卡顿严重,体验极差,而这款免费能玩端游游戏手机软件——无界趣连2.0,完美解决各类游玩痛点,凭借多重实用优势,成为手机远程畅玩端游的首选工具。无界趣连2.0支持4K高清画面传输,画面无压缩、无模糊,完美还原电脑端游的光影、场景与细节,同时账号存档和电脑互通,无需重新练级。想要随时随地用手机畅玩各类电脑端游,这款免费能玩端游游戏手机软件值得一试,无界趣连2.0凭借真低延迟、真免费、真4K的硬核优势,全方位满足玩家的远程游玩需求。不同端游的操作逻辑各不相同,

wjql2的博客 166

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

关于手游的一些知识

1、游戏画面:2D平面、3D立体(人物、场景均有360度视角,一般用的最多的是U3D开发)、 准3D、2.5D(人物或场景是由3D建模后期渲染成平面的)。 2、手游题材风格: 武侠类;仙侠类;动漫、Q版、萌系类;魔幻类(西方魔幻、暗黑题材) 3、端游、页游、手游的区别? 端游:客户端游戏,需要安装包;画面特效较精致,操作性、趣味性较强;但便携性差,需花费时间较多,需要较高配置;大部分游戏需要收费 页游:网页游戏,仅需有网络和浏览器就可以进行游戏,游戏加载快,画质、操作性较低 手游:手机游戏,指尖操作,

qq_48452140的博客 624

游戏创作的尽头是社会大环境

游戏的内容和核心也在不断丰富和变化,世界上第一款游戏是1961年由麻省理工学院的学生开发的一款名为“Space War”的游戏,而现在游戏的分类已经日趋完善,有RPG,ARPG,Shotter,Strategy等类型游戏,随着时代发展,社会也在潜移默化的影响着人们对于游戏的爱好,而今端游开放型游戏“GTA”系列游戏以其高度自由玩法和探索性深受玩家喜爱,因为社会大环境给予端游的是自由且开放的需求,这一点是吸引端游玩家的主要点。而手游的游戏则是侧重于社交性,社会给予它的更多是社交性。

god_wpc030714的博客 320

按头安利 好看又实用的端游源码 PC端 客户端 电脑游戏源码素材看这里

想必大家都在为找端游源码 PC端 客户端 电脑游戏源码而头疼吧,今天小编都为大家整理好咯,上资源的端游源码 PC端 客户端 电脑游戏源码,大家喜欢的可以先行收藏哈,之后会持续更新哒~ 在找寻资源的时候,无意中发现了爱给网这个网站,资源多,质量好,让我深深的喜欢上这个网站,网站页面干净简约,不光有我需要的端游源码 PC端 客户端 电脑游戏源码资源,还有很多其他种类的东西,是一个全品类的素材网站,有爱给网就相当于有了一个百宝箱! 为大家整理了游戏源码-端游源码 PC端 客户端 电脑游戏源码合集 为了方便

m0_61354124的博客 2158

如何串流玩电脑游戏 手机可以远程玩端游吗

对于动作、射击类游戏来说,延迟直接决定游玩手感。不论内网WiFi还是户外移动网络,都能够快速配对,哪怕不熟悉数码设置的玩家,几分钟就能完成配置,立刻开启游戏串流。游玩FPS、RPG等不同类型游戏,可以保存多套按键方案,切换游戏时一键调用,贴合每个人的握持习惯,大幅降低触屏操控的失误率。不少玩家希望摆脱电脑座椅束缚,尝试串流玩电脑游戏,可很多串流工具调试繁琐、操控拖沓,很难拥有舒服的体验。想要顺畅串流玩电脑游戏,不妨试试无界趣连2.0,不用升级手机硬件,依托家中电脑的性能,躺在床上、休闲时刻随时开启端游。

wjql2的博客 259

bilibili有电脑版吗_《原神》15号开放PC版测试,你的电脑配置带的动吗

《原神》是一款RPG冒险游戏,是由国内著名游戏厂商“米哈游”继《崩坏3》之后的最新巨作,将于本月28日在PS4、IOS、Andriod、PC四大平台同步公测,其中PC版的不删档测试将在15日开启,13日可提前预下载。随后,官方也公布了PC版的配置要求:● 最低配置操作系统: Windows 7 SP1 64-bit 或 Windows 8.1 64-bit 或 Windows 10 64-bit处...

weixin_39682897的博客 2792

崩坏星穹铁道电脑版 如何用模拟器在PC上玩崩坏星穹铁道手游教程

如何在电脑上搜索下载崩坏星穹铁道电脑版呢? 首先在电脑上安装逍遥安卓模拟器,并在逍遥安卓模拟器的市场中搜索下载崩坏星穹铁道,就可在电脑上玩崩坏星穹铁道电脑版手游了

weixin_44038589的博客 1315

远程控制电脑玩游戏的软件 手机怎么玩电脑游戏

无论是竞技类端游的精准走位、快速开镜,还是休闲游戏的持续操作,指令都能即时同步,全程无拖影、无脱节,手感贴近本地电脑操作。很多游戏玩家外出时,总希望摆脱设备束缚,用手机远程控制电脑玩游戏,随时解锁电脑端各类大作。但多数远控工具适配性差,操作繁琐、手感拉垮,很难满足游戏娱乐需求。想轻松实现手机远程控制电脑玩游戏,不妨试试无界趣连2.0,适配各类端游串流,体验远超普通远控工具。无界趣连2.0支持按键自定义功能,玩家可以根据自身操作习惯、不同游戏玩法,自由调整虚拟按键的位置、大小,还能保存专属按键方案。

wjql2的博客 241

c语言汉字属于什么类型_DNF究竟属于什么游戏类型终于真相大白了

DNF作为一款经历了十二年起起落落的网游,玩家们的讨论之声也不绝于耳。而DNF也经常能够造出一些迅速出圈广为传播的梗,比如“假猪套天下第一”,可以看出DNF的玩家们之间相当乐于交流,且玩家数量庞大。在各大论坛和贴吧中,我们也一直能听到关于DNF究竟是不是RPG游戏的讨论。首先,RPG究竟是什么?在传统的RPG定义中,玩家在角色扮演游戏(英文全称 Role-playing game)中,玩家扮演虚拟...

weixin_39683692的博客 203

端游和桌游的区别?

桌游(桌面游戏): "桌游"是指在桌面或平面上进行的游戏,通常包括棋盘游戏、卡牌游戏、策略游戏等。端游的玩法多种多样,可以涵盖各种游戏类型,包括角色扮演游戏(RPG)、射击游戏、策略游戏等。这些游戏通常依赖于实体的游戏组件,例如棋盘、骰子、牌等,玩家通过面对面的方式进行互动。以实体游戏组件的形式存在,通常包括游戏板、棋子、卡牌等,玩家通过物理互动来进行游戏。"端游"和"桌游"是两种不同的游戏类型,它们在平台、形式、玩法等方面存在明显的区别。端游(端游戏): "端游"是指端口游戏,通常是指在个人电脑(PC)

weixin_43501408的博客 2584

RPG 游戏分类

RPG 游戏分类

u013768914的博客 6477
上一篇: xlua基础
下一篇: unity自带的导航构建一个简单的地图寻路
RootTimeYu
博客等级 码龄9年 4粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值