My First RPG Game总结二

背包栏打开点击的时候也会触发主角移动,解决办法

   if (Input.GetMouseButtonDown(0)&&UICamera.hoveredObject==null)

鼠标点击NPC触发事件:

给npc添加box collider,在脚本中调用 private void OnMouseOver()当有鼠标指针落到npc上面就自动触发该函数

要想弹出任务框,还得将任务框的图片拖动到脚本中

public TweenPosition questTween;

    private void OnMouseOver()
    {
        if (Input.GetMouseButtonDown(0))
        {
            ShowQuest();
        }
    }
    //显示任务框
    void ShowQuest()
    {
        questTween.gameObject.SetActive(true);
        questTween.PlayForward();
    }

如果让任务框的动画倒回去播放,也即让任务框退回去消失,questTween,PlayReverse();

如果一个物体不能添加c#脚本,检查下该脚本的类名写错没

下面是背包系统的制作:

首先物品种类的分析:

创建txt文件,放入所有物品信息:

1001,小瓶血药,icon-potion1,Drug,50,0,50,60

1002,大瓶血药,icon-potion2,Drug,100,0,70,100

1003,蓝药,icon-potion3,Drug,0,100,60,80

我们发现,当物品种类是药品的时候才会有4,5,也即加血量和加魔法值,我们可以通过物品id得到一条信息,该信息可以得到该物品的名称,类型,价格等等,所以用字典的方式,key为id,value为ObjectInfo集合来标识

public class ObjectsInfo : MonoBehaviour {

    public static ObjectsInfo _instance;

    private Dictionary<int, ObjectInfo> objectInfoDict = new Dictionary<int, ObjectInfo>();

    public TextAsset objectsInfoListText;

    void Awake() {
        _instance = this;
        ReadInfo();
    }

    public ObjectInfo GetObjectInfoById(int id) {
        ObjectInfo info=null;
        objectInfoDict.TryGetValue(id, out info);
        return info;
    }

    void ReadInfo() {
        string text = objectsInfoListText.text;
        string[] strArray = text.Split(‘\n‘);

        foreach (string str in strArray) {
            string[] proArray = str.Split(‘,‘);
            ObjectInfo info = new ObjectInfo();

            int id = int.Parse(proArray[0]);
            string name = proArray[1];
            string icon_name = proArray[2];
            string str_type = proArray[3];
            ObjectType type = ObjectType.Drug;
            switch (str_type) {
                case "Drug":
                    type = ObjectType.Drug;
                    break;
                case "Equip":
                    type = ObjectType.Equip;
                    break;
                case "Mat":
                    type = ObjectType.Mat;
                    break;
            }
            info.id = id; info.name = name; info.icon_name = icon_name;
            info.type = type;
            if (type == ObjectType.Drug) {
                int hp = int.Parse(proArray[4]);
                int mp = int.Parse(proArray[5]);
                int price_sell = int.Parse(proArray[6]);
                int price_buy = int.Parse(proArray[7]);
                info.hp = hp; info.mp = mp;
                info.price_buy = price_buy; info.price_sell = price_sell;
            }
            objectInfoDict.Add(id, info);//添加到字典中,id为key,可以很方便的根据id查找到这个物品信息
        }
    }

}

//id
//名称
//icon名称
//类型(药品drug)
//加血量值
//加魔法值
//出售价
//购买
public enum ObjectType {
    Drug,
    Equip,
    Mat
}
//该集合保存了物品的所有信息
public class ObjectInfo {
    public int id;
    public string name;
    public string icon_name;//这个名称是存储在图集中的名称
    public ObjectType type;
    public int hp;
    public int mp;
    public int price_sell;
    public int price_buy;
}

注意上面的这个脚本定义了2个类ObjectInfo和ObjectsInfo,看清楚

给背包物品添加可拖拽功能:给物品添加脚本,让它继承UIDragDropItem,这个应该是NGUI的一个类,而且由于物品要和鼠标拖拽交互,需要给他添加box collider,这是游戏里发现可以对物品进行拖拽了,给物品和背包的格子添加tag来区分,给每个格子都添加box collider,这里注意的是物品,格子,背包全部添加了box collider,给物品添加这样的脚本,当拖拽结束的时候如果下面是格子,就会打印出格子的tag

public class Inventory_item : UIDragDropItem{

    protected override void OnDragDropRelease(GameObject surface)
    {
        base.OnDragDropRelease(surface);
        if (surface != null) {
            Debug.Log(surface.tag);
        }

    }
}

这里特别注意的是,自己在调试的时候,发现什么都不打印,一直空指针,弄了TMD 3小时才发现,给格子的box collider的范围要设置合理才能行,如果太小就空指针,妈了个bb的

Inventory_item中代码如下:

private void Awake()
    {
        sprite = GetComponent<UISprite>();
    }

首先给item传进id的时候得到物品的信息,我们要显示出该item的图片,所以拿到UISprite

添加2个方法:

public void SetId(int id)
    {
        //根据ObjectInfo的id拿到该id的物品所有信息
        ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
        sprite.spriteName = info.icon_name;
    }
  public void SetIconName(string icon_name)
    {
        sprite.spriteName = icon_name;
    }

给格子的右下角添加物品的个数,放一个UI label,并把它隐藏

在Bag_Grid中添加脚本Inventory_item_Grid脚本

public class Inventory_item_Grid : MonoBehaviour {

   public int id = 0;
    private int num = 0;
    private UILabel numLabel;
    private Inventory_item item;
    private ObjectInfo info;

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

    //物品拖过去的时候让物品初始化个数为1
    public void SetId(int id,int num=1)
    {
        this.id = id;//这行容易忽略,当拖动了已有的物品要把拖动的id和grid的id判断是否相等
        info = ObjectsInfo._instance.GetObjectInfoById(id);
        //这里容易犯错不是getComponent<>看清父子关系
        item = this.GetComponentInChildren<Inventory_item>();
        item.SetIconName(info.icon_name);
        //不是numLabel.Setactive看清楚
        numLabel.gameObject.SetActive(true);
         this.num = num;
        numLabel.text = num.ToString();
    }

    //让物品的数量加一
    public void PlusNumber(int num = 1)
    {
        this.num += num;
        //注意是this.num.ToString()可不是num.ToString
        numLabel.text = this.num.ToString();
    }

    //清空格子
    public void ClearInfo()
    {
        id = 0;
        info = null;
        num = 0;
        numLabel.gameObject.SetActive(false);
    }
}

对于ShowInventory脚本添加给背包bag,当人物拾取一个物品,遍历所有格子

public class ShowInventory : MonoBehaviour {

    public static ShowInventory _instance;
    private TweenPosition tween;
    private int coinCount = 1000;
    public UILabel coinNumber;
    //在这里创建list保存所以格子,把所有格子拖动到这里
    public List<Inventory_item_Grid> list = new List<Inventory_item_Grid>();
    //这里把物品的prefab拖动到这里,Inventory_item时物品的脚本,看清楚
    public Inventory_item item;

    private void Awake()
    {
        _instance = this;
    }

    private void Start()
    {
        tween = GetComponent<TweenPosition>();
    }
    public void Show()
    {
        tween.PlayForward();
    }
    public void Off()
    {
        tween.PlayReverse();
    }

    private void Update()
    {
        //暂时用键盘的X来代表拿到了随机的一个药品
        if(Input.GetKeyDown(KeyCode.X)){
            GetId(Random.Range(1001,1004));
        }
    }
    //拾取到id物品,添加到物品栏
    public void GetId(int id)
    {
        //如果拿到了物品的id就要实例化一个inventory_item添加到物品栏里面,但是物品栏不知道哪个空着,所以要遍历一下
        //物品栏看看哪个空着,当然有两种情况,首先看看所有物品栏里面有没有已经有该物品的格子,如果有,就让它数量+1
        //如果没有,就实例化该物体
        Inventory_item_Grid grid=null;
        foreach (Inventory_item_Grid temp in list)
        {
            if (temp.id==id)
            {
                grid = temp;
                break;
            }
        }
        if (grid!=null)
        {
            //数量加一即可
            grid.PlusNumber();
        }
        else
        {
            //实例化物品item
            foreach (Inventory_item_Grid temp in list)
            {
                if (temp.id == 0)
                {
                    grid = temp;
                    //记得要break跳出循环,否则会得到最后一个格子
                    break;
                }
            }
            //如果格子全部都有物品,那么grid就为null,这个判断也得加上
            if (grid!=null)
            {
                //注意在这里是实例化NGUI的控件,所以要用NGUI的接口, NGUITools.AddChild方法中第一个参数是添加的
                //物品的父类,这里的父类是第几个格子,所以是grid.gameObject第二个参数是添加的实例物品,在最上面public
                //该物品,拖动过来就行
                //这里犯的错误是第二个错误不是item,而是item.gameObject,item是那个物品的脚本
                GameObject go = NGUITools.AddChild(grid.gameObject,item.gameObject);
                go.transform.localPosition = Vector3.zero;
                grid.SetId(id);
            }
        }

    }
}

这样的话当在游戏中一直按x来添加物品,那么物品的效果如下;

实际中在取得UI Label显示物品数量的时候GetComponentInChildren<UI Label>一直取不到,这是因为我们已经把他隐藏了,通过getComponent方式拿不到隐藏的Gameobject,那么我们不隐藏,在该显示的时候让label.enabled=true,在该清空物品的时候false即可

另外说明的是在测试bug的时候,要看哪个Gameobject有没有取到,如果是private,可以改成public在play模式下可以查看有没有获取到

如果物品的数量被物品的图片挡住了,修改Depth即可

this.transform.parent的使用:

作用在克隆的时候,因为克隆出来的物体为了位置的统一和管理的统一,你要把他们放到同一个父体里面,也就是直接设置clone.transform.parent=某个对象。这样克隆出来的对象直接就放到“某个对象”里面了

下面来讲解这样的效果:

 protected override void OnDragDropRelease(GameObject surface)
    {
        base.OnDragDropRelease(surface);
        if (surface != null) {
          //  print(surface.tag);
            //下面进行拖拽功能,分为三种,当把物品拖拽到没有物品的格子,把图片和数量移动到其他格子,当把物品拖拽到已有物品
            //的格子,那么进行交换,当把物品拖拽到原来的格子,不变
            if (surface.tag==Tags.bag)
            {
                transform.localPosition = Vector3.zero;
            }else if (surface.tag == Tags.grid)
            {
                //分为拖到其他格子和拖到自己格子
                if (surface==transform.parent.gameObject)//移动到了当前格子
                {
                    transform.localPosition = Vector3.zero;
                }
                else//移动到其他格子
                {
                    //获取父物体的Gameobject采用this.transform.parent.gameObject的方式
                    Inventory_item_Grid newGrid = surface.GetComponent<Inventory_item_Grid>();
                    Inventory_item_Grid oldGrid = this.transform.parent.GetComponent<Inventory_item_Grid>();
                    //我对这行代码的理解错了,我以为是把当前的格子grid的位置放到拖动的格子上面,真正的意思是
              //把让item的坐标移动到surface为父物体的下面,也即让item坐标移动到拖动到的格子下面,原来的格子位置不变
                    this.transform.parent = surface.transform;
                    newGrid.SetId(oldGrid.id,oldGrid.num);
                    transform.localPosition = Vector3.zero;
                    oldGrid.ClearInfo();
                }

            }else if (surface.tag==Tags.item)//移动到了也有物体的格子上面
            {
                //由于surface碰到的是item,所以newGrid不能等于surface.GetComponent<Inventory_item_Grid>();
                Inventory_item_Grid newGrid = surface.transform.parent.GetComponent<Inventory_item_Grid>();
                Inventory_item_Grid oldGrid = this.transform.parent.GetComponent<Inventory_item_Grid>();
                int id = newGrid.id;int num = newGrid.num;
                newGrid.SetId(oldGrid.id,oldGrid.num);
                oldGrid.SetId(id, num);
                transform.localPosition = Vector3.zero;
            }

        }
        else
        {
            //如果拖到没有tag的地方
        }
    }
 
时间: 2024-10-10 17:16:39

My First RPG Game总结二的相关文章

Unity3d - RPG项目学习笔记(二十八)

前期工程我们终于实现了技能列表的显示,嗯,终于可以看到角色的技能啦.但是依照现在的尿性,你不做出快捷栏的话,这些技能都是只能看的.为了更好的释放技能/使用物品,现在开始制作快捷栏. 那么首先,我们必须持有一个快捷栏. 一.建立快捷栏 首先现建立一个Invisiable Wiedgt,命名为ShortCutUI,然后在内部建立6个UISprite,将图标定义为Grid,加上BoxCollider,这样我们初步的快捷栏就做好了. 二.实现技能的拖动 先明确一个概念,基于最优方案,一定是将技能的图标拖

Unity3d - RPG项目学习笔记(二十)

前期工程将装备信息导入到了工程中,且实现了在背包内鼠标移动显示物品提示信息,本次工程开始构建装备穿戴功能. 项目需求: 右键点击背包内的装备,使其穿戴在身上. 需求分析: 右键点击背包内的装备,注意,此时的装备还是背包内的一个物品,即是工程所定义的id为2001-2010的InventoryItem而已:需求可以抽象为右键点击背包内的一个物品,如果该物品是装备类,则在角色的EquipmentUI相应的位置生成一个与之图标相同的EquipmentItem,则视为“装备”了该物品. 具体实现: ①右

hdu4800_Josephina and RPG(二维状态dp)

/////////////////////////////////////////////////////////////////////////////////////////////////////// 作者:tt2767 声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 查看本文更新与讨论请点击:http://blog.csdn.net/tt2767 链接被删请百度: CSDN tt2767 ///////////////

Unity3d - RPG项目学习笔记(二十三)

前期建立了装备信息及装配功能,现在开始着手建立技能系统. 类似于物品信息,我们首先需要设计好技能系统文本,设计好技能的分类. 设计过程中还是需要把技能作用及释放目标的分类做好,技能文本如下: 4001,致命一击,skill-02,伤害250%,SinglTarget,Attack,250,0,6,1,Swordman,1,Enemy,1.54002,格挡精通,skill-07,防御130%,Buff,Def,130,5,3,5,Swordman,3,Self,04003,战神咆哮,skill-0

Unity3d - RPG项目学习笔记(二十一)

上期工程实现了装备的穿上功能,但是还有些不完善,我们必须进行进一步完善. 需要完善的内容主要有2个: ①如果穿带前该栏有装备,那么需要将原装备退回至背包内: ②成功穿戴装备后,需要使背包内的相应装备数量-1,如果数量为0了,那么删除该格内的物品. 脚本如下: 实现功能①,只需要在Class EquipmentUI中的Dress方法中检测格子内是否有物品的条件的代码块更新为: if(item != null) { Inventory._instance.GetId(item.id); item.S

D2D RPG游戏开发日记(二)--角色/队伍

角色图片类似于这种的四向图每次只绘制其中一个 初始的player类属性 class Player { public: //队伍中角色数目 int length = 3; //是否激活--角色是否在队伍中 int is_active = 0; //window上坐标 int x = 0; int y = 0; //位置修正参数--角色图像的大小 int x_offset = 46; int y_offset = 92; //角色在地图上的坐标 int x_map = 0; int y_map =

Unity3d - RPG项目学习笔记(二十二)

上期工程完成了装备的穿戴功能,本期开始创建装备的卸下功能. 需求: 右键点击装备栏上的装备图标,使其返回至背包中. 需求拆解: 鼠标移动至装备图标上,右键点击,销毁装备,在背包中生成该装备的镜像,完毕. 根据上述思路,这个功能实现起来比较简单: ①首先为EquipmentItem添加BoxCollider,使装备栏中的装备可以被点击: ②对该EquipmentItem添加脚本如下: Class EquipmentItem { private bool isHovering = false; vo

Unity3d - RPG项目学习笔记(十二)

前期实现了背包基本的存储功能,现在开始构建背包物品的移动及调换功能,具体思路如下: ①读取现有物品所在的格子信息. ②对移动目标地点进行判断(即surface的Tag): 如果surface的Tag为空,则使物品的局部坐标归零: 如果surface的Tag不为空,分为几个情况考虑: 1.Tag为背包格子:说明移动地点为空格子,所以讲物品信息赋值到目标下,清除现有信息即可: 2.Tag为背包物品:说明移动地点为有物品格子,将两格子的信息交换即可: 3.Tag为其他物品:说明非常规移动,将物品的位移

Unity3d - RPG项目学习笔记(二十六)

上期工程实现了将技能信息读取至内存中来,现在开始实现技能在技能栏中的显示——SrollView技术的应用. 需求: 在技能栏中显示角色的所有技能,侧边栏加入滚动条,通过滚动条可以实现技能的滚动浏览. 思路: 建立一个SrollView栏,在其中建立一个Grid用于技能的排序.然后建立一个Invisiable Widget,在其中建立起技能描述所需要的图标.名称.类型.描述及消耗. 将Widget复制多份,上下排好,然后向每个Widget加入SrollView属性,并且将SrollView栏中的卷