arpg游戏 unity3d

2018-03-16 15:16:05 MadBam_boo 阅读数 1159
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity3d实战之Unity3d网络游戏实战篇(6):服务端框架的搭建

学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社
本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽老师的书籍
以下为个人的学习简记,与诸君共论 由于U3D的官方案例Tank Tutorial中对坦克的基本操作已经有了详尽的描述,因此本文着重于面板系统、服务端基本网络框架和客户端基本网络框架的搭建
如有疑问或者描述错误的地方,欢迎各位提出或修正,讨论交流是获取和巩固知识的重要途径之一!

 整个服务端框架分为3层:
这里写图片描述
 底层:负责Client的监听、数据处理、协议构建、数据库操作等。
 中间层:对客观世界事物的抽象,实现类对象的各种方法;
 逻辑层:实现游戏逻辑,根据接收到的不同协议实现不同的逻辑。

 服务端框架的目录结构如下:
 这里写图片描述
 底层:
  ServNet:处理Server与各Client的连接以及数据接收;
  DataMgr:根据需求实现对数据库的各种操作;
  Protocol:编写协议实现Server与Client之间的有效通信;
 中间层:
  Player:对玩家的抽象,拥有玩家id、角色、下线等方法的实现;
  Conn:实现Server与Client之间的连接的管理,其作用与第四节描述的一致;
 逻辑层:
  HandleConnMsg:处理连接相关的事务,如心跳机制、用户登陆登出等;
  HandlePlayerMsg:处理玩家相关的事务,如位置同步、得分获取等;
  HandlePlayerEvent:处理玩家事件,某个时间发生时要处理的事情,如玩家登陆登出等;
  PlayerData:指定需要保存到数据库的角色属性,如金币、等级、胜负数等;
  PlayerTempData:指定玩家角色的临时属性,如是否在房间内、是否在战斗中、是否已准备等;

2015-06-03 23:39:34 sunsetv8 阅读数 10356
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

今天考完了大学最后一门考试,是瞬间感觉轻松了一点,花了一天多的时间预习一本书,马上就去考试了,就结果而言还是不错的。但是不知道是一种解脱,还是马上要戴上的一种新的枷锁。总归还是不错的。好了,闲话少扯,继续谈谈如何制作一款ARPG游戏,sunset在上两篇博客中已经介绍过了几种常见的ARPG游戏的人物控制方式,都比较简单,易于理解。接下来来看看制作ARPG游戏还需要什么,先从玩家可操作的角色出发,我们还需要人物的血量,或者用于释放魔法的魔量,这样就转入一种新的概念——人物属性。下面开始sunset个人编写的可视化人物属性编辑器:

人物属性分析

我们不能还没有经过分析或者思考就去动手写代码,这样只会一味给自己增加难度,延后代码编写完成的时间,这也是软件工程的基本理论。在首先编写代码之前,先来分析一下:我们需要什么?一个属性编辑器;这个编辑器中包含哪些属性?只要玩过一定数量的游戏,就会明白游戏人物一般都会有移动速度,攻击速度,攻击力,防御力等等属性值。我举例一款对属性比较看重的游戏——《Dota2》。虽然这款游戏是一款Moba游戏,但是丝毫不妨碍我们对属性经行分析,《Dota2》里英雄的属性包括:力量、敏捷、智力、攻击力、护甲、移动速度、转身速率、攻击速度、攻击距离等等等等。通过一款优秀的游戏可以得出我们所需要的解决的问题的答案,我们是否也需要敏捷、智力等等属性呢?一切都由你来决定,因为这是你的游戏。
sunset在个人制作的ARPG游戏项目中采用了这样一些属性:等级(LV)、血量(HP)、魔法值(MP)、攻击力(Attack)、防御力(Defend)、强壮(Strength)、敏捷(Agility)、智力(Intelligence)、体力(Power)、移动速度(MoveSpeed)、转身速度(RotationSpeed)、攻击距离(AttackRange)、暴击伤害百分比(CriticalDamage)、暴击概率(CriticalRate)等。这些属性值基本上满足了一款ARPG游戏的属性要求。接下来sunset给出的属性编辑器也基本上是基于这些属性进行编写的。

编辑器编写思考

经过属性中基本的属性量的定义后,我们还要进一步思考脚本该怎么编写才能使其更加易用与将来可能出现的武器属性加成或者被动技能属性加成等问题。所以将属性又分别分成几种类型:1)基础属性(BaseAttribute);2)额外(附加)属性(AdditiveAtribute);3)当前属性(CurrentAttribute);4)升级属性(GrowthAttribute);5)总属性(SumAttribute)等。这部分必须进行仔细思考,当写到一半才发觉还需要定义新的属性类型才能完成编写而不得不回头的时候,你会感觉非常无奈而致使完成时间向后拖延,所以经过仔细思考后再动手会事半功倍(个人经验)。

编写第一步——定义属性类

C#是面向对象的编程语言,所以我们直接定义“属性”类,并定义类属性,针对每个类的实例对象编写实现方法。代码如下:

[System.Serializable]
    public class BaseAttribute
    {
        //等级
        public int LV;
        /// <summary>
        ///血量,魔量 
        /// </summary>
        public float HP, MP;
        /// <summary>
        ///攻击力, 防御力, 力量, 智力, 敏捷, 体力 
        /// </summary>
        public float Attack, Defend, Strong, Intelligence, Agility, Power;
        /// <summary>
        /// 攻击速度,散步速度,跑步速度,后退速度,转身移动速度,转身速度,攻击范围,经验值,暴击概率,暴击伤害百分比;
        /// </summary>
        public float AttackSpeed, MoveSpeed, RotationSpeed, AttackRange, Exp, CriticalRate, CriticalDamage;
        /// <summary>
        /// 每秒血量回复,每秒魔量回复
        /// </summary>
        public float HPRecoverPerSecond, MPRecoverPerSecond;
    }

    [System.Serializable]
    public class AdditionAttribute
    {
        /// <summary>
        ///血量,魔量 
        /// </summary>
        public float HP, MP;
        /// <summary>
        ///攻击力, 防御力, 力量, 智力, 敏捷, 体力 
        /// </summary>
        public float Attack, Defend, Strong, Intelligence, Agility, Power;
        /// <summary>
        /// 攻击速度,散步速度,跑步速度,后退速度,转身移动速度,转身速度,攻击范围,暴击概率,暴击伤害百分比;//暴击概率和攻击范围仅由装备影响。
        /// </summary>
        public float AttackSpeed, MoveSpeed, RotationSpeed, AttackRange, CriticalRate,CriticalDamage;

        /// <summary>
        /// 每秒血量回复,每秒魔量回复
        /// </summary>
        public float HPRecoverPerSecond, MPRecoverPerSecond;
    }

    [System.Serializable]
    public class CurAttribute
    {
        /// <summary>
        ///血量,魔量 
        /// </summary>
        public float CurHP, CurMP;
        /// <summary>
        ///攻击力, 防御力, 力量, 智力, 敏捷, 体力 
        /// </summary>
        public float CurAttack, CurDefend, CurStrong, CurIntelligence, CurAgility, CurPower;
        /// <summary>
        /// 当前攻击速度,当前散步速度,当前跑步速度,当前后退速度,当前转身移动速度,当前转身速度,当前攻击范围,当前暴击概率, 当前暴击伤害百分比;
        /// </summary>
        public float CurAttackSpeed, CurMoveSpeed, CurRotationSpeed, CurAttackRange, CurCriticalRate, CurCriticalDamage;

        /// <summary>
        /// 每秒血量回复,每秒魔量回复
        /// </summary>
        public float HPRecoverPerSecond, MPRecoverPerSecond;
    }

    [System.Serializable]
    public class SumAttribute
    {
        /// <summary>
        ///血量,魔量 
        /// </summary>
        public float HP, MP;
        /// <summary>
        ///攻击力, 防御力, 力量, 智力, 敏捷, 体力 
        /// </summary>
        public float Attack, Defend, Strong, Intelligence, Agility, Power;
        /// <summary>
        /// 攻击速度,移动速度,转身速度,攻击范围,暴击概率,暴击伤害百分比;
        /// </summary>
        public float AttackSpeed, MoveSpeed, RotationSpeed, AttackRange, CriticalRate, CriticalDamage;

        /// <summary>
        /// 每秒血量回复,每秒魔量回复
        /// </summary>
        public float HPRecoverPerSecond, MPRecoverPerSecond;
    }

    [System.Serializable]
    public class AttributeGrowth
    {
        /// <summary>
        ///血量,魔量 
        /// </summary>
        public float HP, MP;
        /// <summary>
        ///攻击力, 防御力, 力量, 智力, 敏捷, 体力 
        /// </summary>
        public float Attack, Defend, Strong, Intelligence, Agility, Power;
    }

注释的相当仔细,一看就懂。
然后我们还需要定义一些单独存在的量:比如最高等级,最大经验值、当前等级所需经验,如果有各种动画状态,还需要单独定义步行速度(WalkSpeed)、跑步速度(RunSpeed)、左右转身时向左或向右移动的速度(TurnSpeed),或者还可以定义后退时的移动速度(BackwardSpeed),看个人需求。然后定义出上文代码中定义的类对象的实例对象,编写过程中主要是使用类的实例对象。代码:

/// <summary>
    /// 最高等级
    /// </summary>
    public int MaxLV;
    /// <summary>
    /// 当前等级所需要的经验总量
    /// </summary>
    public float NeedExpPerLV;
    //当前等级到下一个等级还需要的经验量
    public float EXP2NextLV;
    //到当前为止所获得的所有经验量
    public float MaxExp;
    //各类的实例对象:
    public BaseAttribute BaseStatus;
    public AdditionAttribute AddStatus;
    public CurAttribute CurStatus;
    public SumAttribute SumStatus;

    public AttributeGrowth attributeGrowth, growthPoint;
    //定义各种速度:
public float RunSpeed;
    public float WalkSpeed;
    public float TurnSpeed;
    public float BackSpeed;

嗯,基本需要用到的量都已经定义好了,下一步开始编写方法使用这些量。

编写第二步——实施方法

我们首先来编写人物经验的计算方法,这里sunset个人所用的经验计算公式是:基数A * 当前等级 * 当前等级 + 基数B * 当前等级。这算是一种较为简单的计算方法了,一个一元二次方程。这个可以自行决定。先计算到当前为止所获得的所有经验量(包括当前等级到下一级),然后计算当前等级所需经验:(这里所采用的基数A和B分别为40和60)

void CalculateExp()
    {
        //更新到当前等级为止的所有经验,包括本级到下一级
        MaxExp = 40.0f * BaseStatus.LV * BaseStatus.LV + 60.0f * BaseStatus.LV;
        //更新本级到下一级所需要的经验值;
        NeedExpPerLV = MaxExp - (40.0f * (BaseStatus.LV - 1) * (BaseStatus.LV - 1) + 60.0f * (BaseStatus.LV - 1));
    }

然后更新当前经验值:

public void UpdateExp()//更新经验值
    {
        if (BaseStatus.LV >= MaxLV) 
        {
            BaseStatus.Exp = NeedExpPerLV;
            BaseStatus.LV = MaxLV;
        }
        else 
        {
            if(BaseStatus.Exp >= NeedExpPerLV)
            {
                GetLvUp = true;
                //更新当前在本级拥有经验
                BaseStatus.Exp = BaseStatus.Exp - NeedExpPerLV;
                //更新等级
                BaseStatus.LV += 1;

                CalculateExp();
                GrowthisAdd = false;
                //更新属性
                UpdateAttribute();

                CurStatus.CurHP = SumStatus.HP;
                CurStatus.CurMP = SumStatus.MP;
            }
        }
    }

先判断当前等级是否大于最高等级,再判断当前经验是否达到当前等级所要求的经验量,如果达到就升级,并更新相关属性。升级时恢复血量和魔量到最大值。
接下来是更新相关属性的方法:

void UpdateAttribute()
    {
        if (!GrowthisAdd) 
        {
            CalculateAttributePointGrowth ();
            BaseStatus.HP += attributeGrowth.HP;
            BaseStatus.MP += attributeGrowth.MP;
            BaseStatus.Attack += attributeGrowth.Attack;
            BaseStatus.Defend += attributeGrowth.Defend;
            BaseStatus.Strong += attributeGrowth.Strong;
            BaseStatus.Intelligence += attributeGrowth.Intelligence;
            BaseStatus.Agility += attributeGrowth.Agility;
            BaseStatus.Power += attributeGrowth.Power;
            GrowthisAdd = true;
        }
        SumStatus.Strong = BaseStatus.Strong + AddStatus.Strong;
        SumStatus.Intelligence = BaseStatus.Intelligence + AddStatus.Intelligence;
        SumStatus.Agility = BaseStatus.Agility + AddStatus.Agility;
        SumStatus.Power = BaseStatus.Power + AddStatus.Power;

        SumStatus.Attack = BaseStatus.Attack + AddStatus.Attack + Mathf.FloorToInt(SumStatus.Strong * 0.2f);
        SumStatus.Defend = BaseStatus.Defend + AddStatus.Defend + Mathf.FloorToInt(SumStatus.Power * 0.2f);

        SumStatus.HP = BaseStatus.HP + AddStatus.HP + Mathf.FloorToInt(SumStatus.Strong * 0.4f);
        SumStatus.MP = BaseStatus.MP + AddStatus.MP + Mathf.FloorToInt(SumStatus.Intelligence * 0.4f);
        SumStatus.AttackSpeed = BaseStatus.AttackSpeed + AddStatus.AttackSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.2f);
        SumStatus.MoveSpeed = BaseStatus.MoveSpeed + AddStatus.MoveSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.3f);
        SumStatus.RotationSpeed = BaseStatus.RotationSpeed + AddStatus.RotationSpeed + Mathf.FloorToInt(SumStatus.Agility * 0.2f);
        SumStatus.CriticalRate = BaseStatus.CriticalRate + AddStatus.CriticalRate;
        SumStatus.CriticalDamage = BaseStatus.CriticalDamage + AddStatus.CriticalDamage;

        CurStatus.CurAttack = SumStatus.Attack;
        CurStatus.CurDefend = SumStatus.Defend;
        CurStatus.CurStrong = SumStatus.Strong;
        CurStatus.CurIntelligence = SumStatus.Intelligence;
        CurStatus.CurAgility = SumStatus.Agility;
        CurStatus.CurPower = SumStatus.Power;
        CurStatus.CurCriticalRate = SumStatus.CriticalRate;
        CurStatus.CurCriticalDamage = SumStatus.CriticalDamage;
    }

这里主要说明一下,sunset个人定义的属性中强壮部分决定了攻击力和血量上限,体力部分决定了防御力,智力部分决定了魔法值上限,敏捷部分决定了各种速度等等,自行理解。
然后在计算更新属性方法中还定义了一种当存在升级点数加成时,计算升级属性相关的方法:

    void CalculateAttributePointGrowth()
    {
        if (growthPoint.HP > 0) 
        {
            attributeGrowth.HP += 2 * growthPoint.HP;

        }
        if (growthPoint.Attack > 0) 
        {
            attributeGrowth.Attack += 2 * growthPoint.Attack; 
        }
        if(growthPoint.MP > 0)
        {
            attributeGrowth.MP += 2 * growthPoint.MP;
        }   
        if(growthPoint.Defend > 0)
        {
            attributeGrowth.Defend += 2 * growthPoint.Defend;

        }
        if(growthPoint.Strong > 0)
        {
            attributeGrowth.Strong += 2 * growthPoint.Strong;

        }
        if(growthPoint.Intelligence > 0)
        {
            attributeGrowth.Intelligence += 2 * growthPoint.Intelligence;
        }
        if(growthPoint.Agility > 0)
        {
            attributeGrowth.Agility += 2 * growthPoint.Agility;

        }
        if(growthPoint.Power > 0)
        {
            attributeGrowth.Power += 2 * growthPoint.Power;
        }
    }

这样更新属性方面的相关方法就差不多了,然后我们还要检测血量等属性值,避免血量等属性值超过总属性值。

    //检测HP、MP的当前值是否超出规定,每帧调用
    void CheckHPMP()
    {
        AnimatorStateInfo H_CurrentState = H_Animator.GetCurrentAnimatorStateInfo (0);
        if (!H_CurrentState.IsName ("Base.H_Death"))
        {
            CurStatus.CurHP += Mathf.FloorToInt(BaseStatus.HPRecoverPerSecond * 0.33f);
            CurStatus.CurMP += Mathf.FloorToInt(BaseStatus.MPRecoverPerSecond * 0.50f);
        }
        else 
        {
            CurStatus.CurHP = 0;
            CurStatus.CurMP = 0;
        }
        if (CurStatus.CurHP < 0) 
        {
            CurStatus.CurHP = 0;
        }
        if (CurStatus.CurMP < 0) 
        {
            CurStatus.CurMP = 0;
        }
        if (CurStatus.CurHP >= SumStatus.HP) 
        {
            CurStatus.CurHP = SumStatus.HP;
        }
        if (CurStatus.CurMP >= SumStatus.MP) 
        {
            CurStatus.CurMP = SumStatus.MP;
        }
    }

这样属性编辑器在原始属性定义方面就差不多完成了,然而现在我们编写的还只是脚本,不能算的上是一种可视化编辑器,还需要编辑一个Editor文件来对上文定义的变量进行值的输入。Editor文件的编写在原理上是十分简单的,就是一味的套用Unity本身的制定的GUIEditor的方法就好了,编写插件也是通过这种方法进行编写的,只是编写的好坏以及是否美观简洁、是否易于输入与识别的区别而已,这当然需要大量的动手编写经验。基本的语法都可以在API文档中找到sunset在这里不再赘述给出sunset个人编写的一个简单的人物属性Editor文件的源代码:

using UnityEditor;
using UnityEngine;
using System.Collections;

[CustomEditor(typeof(HeroStatus))]
public class HeroStatusEditor : Editor {

    public bool ShowBaseAttribute = true;
    public bool ShowAddtitionAttribute = true;
    public bool ShowCurAttribute = true;
    public bool ShowSumAttribute = true;
    public bool ShowAttributeGrowth = true;


    public override void OnInspectorGUI()
    {
        HeroStatus heroStatus = (HeroStatus)target;

        heroStatus.HeroName = EditorGUILayout.TextField ("Hero Name:", heroStatus.HeroName);
        heroStatus.BaseStatus.LV = EditorGUILayout.IntField ("Hero Lv:", heroStatus.BaseStatus.LV);
        heroStatus.MaxLV = EditorGUILayout.IntField ("Max LV:", heroStatus.MaxLV);
        heroStatus.BaseStatus.Exp = EditorGUILayout.FloatField ("Hero Current Exp:", heroStatus.BaseStatus.Exp);
        heroStatus.EXP2NextLV = EditorGUILayout.FloatField ("Need Exp To Next LV:", (heroStatus.NeedExpPerLV - heroStatus.BaseStatus.Exp));
        heroStatus.CurrentPoint = EditorGUILayout.IntField ("Growth Point:", heroStatus.CurrentPoint);

        EditorGUILayout.BeginHorizontal ();
        EditorGUILayout.LabelField ("Walk Speed:" , heroStatus.WalkSpeed.ToString());
        EditorGUILayout.LabelField ("Run Speed:" , heroStatus.RunSpeed.ToString());
        EditorGUILayout.EndHorizontal ();
        EditorGUILayout.BeginHorizontal ();
        EditorGUILayout.LabelField ("Back Speed:" , heroStatus.BackSpeed.ToString());
        EditorGUILayout.LabelField ("Turn Speed:" , heroStatus.TurnSpeed.ToString());
        EditorGUILayout.EndHorizontal ();
        ShowCurAttribute = EditorGUILayout.Foldout (ShowCurAttribute, "Current Status:");
        if (ShowCurAttribute)
        {
            EditorGUI.indentLevel++;

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("HP:", heroStatus.CurStatus.CurHP.ToString ());
            EditorGUILayout.LabelField ("MP:", heroStatus.CurStatus.CurMP.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Attack:", heroStatus.CurStatus.CurAttack.ToString ());
            EditorGUILayout.LabelField ("Defend:", heroStatus.CurStatus.CurDefend.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Strong:", heroStatus.CurStatus.CurStrong.ToString ());
            EditorGUILayout.LabelField ("Intelligence:", heroStatus.CurStatus.CurIntelligence.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Agility:", heroStatus.CurStatus.CurAgility.ToString ());
            EditorGUILayout.LabelField ("Power:", heroStatus.CurStatus.CurPower.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Attack Speed:", heroStatus.CurStatus.CurAttackSpeed.ToString ());
            EditorGUILayout.LabelField ("Attack Range:", heroStatus.CurStatus.CurAttackRange.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Move Speed:", heroStatus.CurStatus.CurMoveSpeed.ToString ());
            EditorGUILayout.LabelField ("Rotation Range:", heroStatus.CurStatus.CurRotationSpeed.ToString ().ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal ();
            EditorGUILayout.LabelField ("Cur Critical Damage:", heroStatus.CurStatus.CurCriticalDamage.ToString ());
            EditorGUILayout.LabelField ("Critical Rate:", heroStatus.CurStatus.CurCriticalRate.ToString ());
            EditorGUILayout.EndHorizontal ();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Cur HP Recover Per Second:", heroStatus.CurStatus.HPRecoverPerSecond.ToString());
            EditorGUILayout.LabelField("Cur MP Recover Per Second:", heroStatus.CurStatus.MPRecoverPerSecond.ToString());
            EditorGUILayout.EndHorizontal();
        }
        EditorGUI.indentLevel--;
        EditorGUILayout.Space();


        ShowBaseAttribute = EditorGUILayout.Foldout (ShowBaseAttribute, "Base Attribute");
        EditorGUI.indentLevel++;
        if (ShowBaseAttribute) 
        {
            heroStatus.BaseStatus.HP = (float)EditorGUILayout.Slider("Base HP:", heroStatus.BaseStatus.HP, 0.0f, 9999.0f);
            ProgressBar(heroStatus.BaseStatus.HP/9999f,"Base HP");
            heroStatus.BaseStatus.MP = (float)EditorGUILayout.Slider("Base MP:", heroStatus.BaseStatus.MP, 0.0f, 9999.0f);
            ProgressBar(heroStatus.BaseStatus.MP/9999f,"Base MP");
            heroStatus.BaseStatus.Attack = (float)EditorGUILayout.Slider("Base Attack", heroStatus.BaseStatus.Attack, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Attack/999.0f,"Base Attack");
            heroStatus.BaseStatus.Defend = (float)EditorGUILayout.Slider("Base Defend", heroStatus.BaseStatus.Defend, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Defend/999.0f,"Base Defend");
            heroStatus.BaseStatus.Strong = (float)EditorGUILayout.Slider("Base Strong", heroStatus.BaseStatus.Strong, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Strong/999.0f,"Base Strong");
            heroStatus.BaseStatus.Intelligence = (float)EditorGUILayout.Slider("Base Intelligence", heroStatus.BaseStatus.Intelligence, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Intelligence/999.0f,"Base Intelligence");
            heroStatus.BaseStatus.Agility = (float)EditorGUILayout.Slider("Base Agility", heroStatus.BaseStatus.Agility, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Agility/999.0f,"Base Agility");
            heroStatus.BaseStatus.Power = (float)EditorGUILayout.Slider("Base Power", heroStatus.BaseStatus.Power, 0.0f, 999.0f);
            ProgressBar(heroStatus.BaseStatus.Power/999.0f,"Base Power");
            heroStatus.BaseStatus.AttackSpeed = (float)EditorGUILayout.Slider("Base AttackSpeed", heroStatus.BaseStatus.AttackSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.AttackSpeed/100.0f,"Base AttackSpeed");
            heroStatus.BaseStatus.MoveSpeed = (float)EditorGUILayout.Slider("Base MoveSpeed", heroStatus.BaseStatus.MoveSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.MoveSpeed/100.0f,"Base MoveSpeed");
            heroStatus.BaseStatus.RotationSpeed = (float)EditorGUILayout.Slider("Base RotationSpeed", heroStatus.BaseStatus.RotationSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.RotationSpeed/100.0f,"Base RotationSpeed");
            heroStatus.BaseStatus.AttackRange = (float)EditorGUILayout.Slider("Base AttackRange", heroStatus.BaseStatus.AttackRange, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.AttackRange/100.0f,"Base AttackRange");
            heroStatus.BaseStatus.CriticalRate = (float)EditorGUILayout.Slider("Base CriticalRate", heroStatus.BaseStatus.CriticalRate, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.CriticalRate/100.0f,"Base CriticalRate");
            heroStatus.BaseStatus.CriticalDamage = (float)EditorGUILayout.Slider("Base CriticalDamage", heroStatus.BaseStatus.CriticalDamage, 0.0f, 100.0f);
            ProgressBar(heroStatus.BaseStatus.CriticalDamage/100.0f,"Base CriticalDamage");
            heroStatus.BaseStatus.HPRecoverPerSecond = EditorGUILayout.FloatField("HP Recover Per Second:", heroStatus.BaseStatus.HPRecoverPerSecond);
            ProgressBar(heroStatus.BaseStatus.HPRecoverPerSecond / 100.0f, "Base HP Recover Per Second:");
            heroStatus.BaseStatus.MPRecoverPerSecond = EditorGUILayout.FloatField("MP Recover Per Second:", heroStatus.BaseStatus.MPRecoverPerSecond);
            ProgressBar(heroStatus.BaseStatus.MPRecoverPerSecond / 100.0f, "Base MP Recover Per Second:");
        }
        EditorGUI.indentLevel--;
        EditorGUILayout.Space ();

        ShowAddtitionAttribute = EditorGUILayout.Foldout (ShowAddtitionAttribute, "Addtition Attribute:");
        EditorGUI.indentLevel++;
        if (ShowAddtitionAttribute) 
        {
            heroStatus.AddStatus.HP = (float)EditorGUILayout.Slider("Addtition HP:", heroStatus.AddStatus.HP, 0.0f, 9999.0f);
            ProgressBar(heroStatus.AddStatus.HP/9999f,"Addtition HP");
            heroStatus.AddStatus.MP = (float)EditorGUILayout.Slider("Addtition MP:", heroStatus.AddStatus.MP, 0.0f, 9999.0f);
            ProgressBar(heroStatus.AddStatus.MP/9999f,"Addtition MP");
            heroStatus.AddStatus.Attack = (float)EditorGUILayout.Slider("Addtition Attack", heroStatus.AddStatus.Attack, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Attack/999.0f,"Addtition Attack");
            heroStatus.AddStatus.Defend = (float)EditorGUILayout.Slider("Addtition Defend", heroStatus.AddStatus.Defend, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Defend/999.0f,"Addtition Defend");
            heroStatus.AddStatus.Strong = (float)EditorGUILayout.Slider("Addtition Strong", heroStatus.AddStatus.Strong, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Strong/999.0f,"Addtition Strong");
            heroStatus.AddStatus.Intelligence = (float)EditorGUILayout.Slider("Addtition Intelligence", heroStatus.AddStatus.Intelligence, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Intelligence/999.0f,"Addtition Intelligence");
            heroStatus.AddStatus.Agility = (float)EditorGUILayout.Slider("Addtition Agility", heroStatus.AddStatus.Agility, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Agility/999.0f,"Addtition Agility");
            heroStatus.AddStatus.Power = (float)EditorGUILayout.Slider("Addtition Power", heroStatus.AddStatus.Power, 0.0f, 999.0f);
            ProgressBar(heroStatus.AddStatus.Power/999.0f,"Addtition Power");
            heroStatus.AddStatus.AttackSpeed = (float)EditorGUILayout.Slider("Addtition AttackSpeed", heroStatus.AddStatus.AttackSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.AttackSpeed/100.0f,"Addtition AttackSpeed");
            heroStatus.AddStatus.MoveSpeed = (float)EditorGUILayout.Slider("Addtition MoveSpeed", heroStatus.AddStatus.MoveSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.MoveSpeed/100.0f,"Addtition MoveSpeed");
            heroStatus.AddStatus.RotationSpeed = (float)EditorGUILayout.Slider("Addtition RotationSpeed", heroStatus.AddStatus.RotationSpeed, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.RotationSpeed/100.0f,"Addtition RotationSpeed");
            heroStatus.AddStatus.AttackRange = (float)EditorGUILayout.Slider("Addtition AttackRange", heroStatus.AddStatus.AttackRange, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.AttackRange/100.0f,"Addtition AttackRange");
            heroStatus.AddStatus.CriticalRate = (float)EditorGUILayout.Slider("Addtition CriticalRate", heroStatus.AddStatus.CriticalRate, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.CriticalRate/100.0f,"Addtition CriticalRate");
            heroStatus.AddStatus.CriticalDamage = (float)EditorGUILayout.Slider("Addtition CriticalDamage", heroStatus.AddStatus.CriticalDamage, 0.0f, 100.0f);
            ProgressBar(heroStatus.AddStatus.CriticalDamage/100.0f,"Addtition CriticalDamage");
        }
        EditorGUI.indentLevel--;
        EditorGUILayout.Space ();

        ShowAttributeGrowth = EditorGUILayout.Foldout (ShowAttributeGrowth, "Growth Attribute:");
        EditorGUI.indentLevel++;
        if (ShowAttributeGrowth) 
        {
            EditorGUILayout.BeginHorizontal();
            heroStatus.attributeGrowth.HP = EditorGUILayout.FloatField("HP:", heroStatus.attributeGrowth.HP);
            heroStatus.attributeGrowth.MP = EditorGUILayout.FloatField("MP:", heroStatus.attributeGrowth.MP);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            heroStatus.attributeGrowth.Attack = EditorGUILayout.FloatField("Attack:", heroStatus.attributeGrowth.Attack);
            heroStatus.attributeGrowth.Defend = EditorGUILayout.FloatField("Defend:", heroStatus.attributeGrowth.Defend);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            heroStatus.attributeGrowth.Strong = EditorGUILayout.FloatField("Strong:", heroStatus.attributeGrowth.Strong);
            heroStatus.attributeGrowth.Intelligence = EditorGUILayout.FloatField("Intelligence:", heroStatus.attributeGrowth.Intelligence);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            heroStatus.attributeGrowth.Agility = EditorGUILayout.FloatField("Agility:", heroStatus.attributeGrowth.Agility);
            heroStatus.attributeGrowth.Power = EditorGUILayout.FloatField("Power:", heroStatus.attributeGrowth.Power);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            heroStatus.attributeGrowth.Agility = EditorGUILayout.FloatField("Agility:", heroStatus.attributeGrowth.Agility);
            heroStatus.attributeGrowth.Power = EditorGUILayout.FloatField("Power:", heroStatus.attributeGrowth.Power);
            EditorGUILayout.EndHorizontal();
        }
        EditorGUI.indentLevel--;
        EditorGUILayout.Space ();

        ShowSumAttribute = EditorGUILayout.Foldout (ShowSumAttribute, "Total Attribute:");
        EditorGUI.indentLevel++;
        if (ShowSumAttribute) 
        {
            EditorGUILayout.LabelField("Total HP:", heroStatus.SumStatus.HP.ToString());
            ProgressBar(heroStatus.SumStatus.HP/9999f,"Total HP");
            EditorGUILayout.LabelField("Total MP:", heroStatus.SumStatus.MP.ToString());
            ProgressBar(heroStatus.SumStatus.MP/9999f,"Total MP");
            EditorGUILayout.LabelField("Total Attack", heroStatus.SumStatus.Attack.ToString());
            ProgressBar(heroStatus.SumStatus.Attack/999.0f,"Total Attack");
            EditorGUILayout.LabelField("Total Defend", heroStatus.SumStatus.Defend.ToString());
            ProgressBar(heroStatus.SumStatus.Defend/999.0f,"Total Defend");
            EditorGUILayout.LabelField("Total Strong", heroStatus.SumStatus.Strong.ToString());
            ProgressBar(heroStatus.SumStatus.Strong/999.0f,"Total Strong");
            EditorGUILayout.LabelField("Total Intelligence", heroStatus.SumStatus.Intelligence.ToString());
            ProgressBar(heroStatus.SumStatus.Intelligence/999.0f,"Total Intelligence");
            EditorGUILayout.LabelField("Total Agility", heroStatus.SumStatus.Agility.ToString());
            ProgressBar(heroStatus.SumStatus.Agility/999.0f,"Total Agility");
            EditorGUILayout.LabelField("Total Power", heroStatus.SumStatus.Power.ToString());
            ProgressBar(heroStatus.SumStatus.Power/999.0f,"Total Power");
            EditorGUILayout.LabelField("Addtition AttackSpeed", heroStatus.SumStatus.AttackSpeed.ToString());
            ProgressBar(heroStatus.SumStatus.AttackSpeed/100.0f,"Addtition AttackSpeed");
            EditorGUILayout.LabelField("Addtition MoveSpeed", heroStatus.SumStatus.MoveSpeed.ToString());
            ProgressBar(heroStatus.SumStatus.MoveSpeed/100.0f,"Addtition MoveSpeed");
            EditorGUILayout.LabelField("Total RotationSpeed", heroStatus.SumStatus.RotationSpeed.ToString());
            ProgressBar(heroStatus.SumStatus.RotationSpeed/100.0f,"Total RotationSpeed");
            EditorGUILayout.LabelField("Total AttackRange", heroStatus.SumStatus.AttackRange.ToString());
            ProgressBar(heroStatus.SumStatus.AttackRange/100.0f,"Total AttackRange");
            EditorGUILayout.LabelField("Total CriticalRate", heroStatus.SumStatus.CriticalRate.ToString());
            ProgressBar(heroStatus.SumStatus.CriticalRate/100.0f,"Total CriticalRate");
            EditorGUILayout.LabelField("Total CriticalDamage", heroStatus.SumStatus.CriticalDamage.ToString());
            ProgressBar(heroStatus.SumStatus.CriticalDamage/100.0f,"Total CriticalDamage");
            EditorGUILayout.LabelField("Total HP Recover Per Second:", heroStatus.SumStatus.HPRecoverPerSecond.ToString());
            ProgressBar(heroStatus.SumStatus.HPRecoverPerSecond / 100.0f, "Total HP Recover Per Second:");
            EditorGUILayout.LabelField("Total MP Recover Per Second:", heroStatus.SumStatus.MPRecoverPerSecond.ToString());
            ProgressBar(heroStatus.SumStatus.MPRecoverPerSecond / 100.0f, "Total MP Recover Per Second:");
        }




    }

    public void ProgressBar (float val,string label) {
        Rect rect = GUILayoutUtility.GetRect (18, 18, "TextField");
        EditorGUI.ProgressBar (rect, val, label);
        EditorGUILayout.Space ();
    }
}

嗯,Editor文件只是一系列重复的语句,修改其中的关键词以符合各种属性就好了,是不是很简单呢?程序编写的脚本能让策划简单易懂的实现值的输入是非常重要的,写的美观简洁易懂不止是给策划方便,也是给自己方便。嗯,今天写的有点多了,现在时间也很晚了至于人物编辑器编写的剩下部分就明天下午更吧,就这样。

2015-05-27 21:54:39 jcracker 阅读数 1200
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。


2019-09-22 14:05:19 fengliaoai 阅读数 14639
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

每周更新unity3d视频教程,从入门到就业,官方unity3d培训,上千门实时更新课程,供学员在线观看学习,unity3d游戏开发,可以让学员随时随地学习!
免费网上学习unity3d自学教程,国内名师机构专业授课,O基础快速学习,1小时快速入门,7天unity3d自学教程学习,能力快速提升,优质作品随手呈现!

unity3d菜鸟自学教程介绍

unity3d难学吗?

unity3d自学教程目录

unity3d视频教程百度网盘下载

unity3d难学吗?
学习unity3d特效,多来学习路线网看教程,一线游戏特效老师,游戏特效就业安排!学习unity3d特效入门+进阶+精通选择专业才能学得专业!

unity3d自学教程目录
课程介绍:
Unity3d史诗 MMO ARPG 课程《泰斗破坏神》,精心设计将包含200+课时,由视频课时+直播课时+测试课时混合组成。最重头unity3d ARGP课程,完整的 ARPG 网络游戏开发教学。包含多人合作,在线多人游戏开发,角色创建系统,作战系统,RPG系统,技能系统,任务系统,商店系统。

课程大纲:

单机版功能实现

项目概要
登录系统
角色创建、选择、自定义系统
场景加载与游戏存储记录
角色控制
聊天通讯
游戏AI
战斗系统
游戏角色与玩家信息系统
商店系统
道具系统
装备系统
装备与道具掉落
仓库与背包系统
副本系统
任务系统
地图与寻路系统

网络版功能实现

服务端搭建
登录系统
角色选择
游戏场景
聊天功能
角色具体信息
商店系统
道具系统
装备系统
仓库和背包
副本系统
任务系统

unity3d视频教程百度网盘下载
http://www.xuexiluxian.net/unity3d-cainiao-zixue.html

2019-03-21 11:34:53 xiumang 阅读数 1067
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

自学Unity3D比较辛苦和困难,找到一些Unity3D资源,与君共勉。

Unity3D 3d射击游戏源码 EZFPS Multiplayer FPS Kit
http://www.idoubi.net/unity3d/complete-project/282.html
Unity3D 暴力之城游戏源码 Full Game Kit – Hammer 2
http://www.idoubi.net/unity3d/complete-project/279.html
Unity3D 2D射击游戏模板 2D Wave Shooter
http://www.idoubi.net/unity3d/complete-project/276.html
Unity3D 像素太空大战游戏源码 Space Fighters Basic Pixel Art Pack
http://www.idoubi.net/unity3d/complete-project/273.html
Unity3D 3d高质量第三人称射击游戏TPS项目源码 Intense TPS
http://www.idoubi.net/unity3d/complete-project/269.html
Unity3D 空战游戏 完整源码 Air Strike Starter Kit
http://www.idoubi.net/unity3d/complete-project/265.html
Unity3D 高仿泡泡堂游戏 祖玛 完整源码 Zuma Ball Blast
http://www.idoubi.net/unity3d/complete-project/262.html
Unity3D 弹弓游戏 完整源码 Slingshot Playmaker Kit
http://www.idoubi.net/unity3d/complete-project/258.html
Unity3D 仿抢滩登陆游戏 完整源码 Counter Commander Assault Duty
http://www.idoubi.net/unity3d/complete-project/255.html
Unity3D 儿童益智游戏 类似宝宝学英语 完整源码 Feed the monster
http://www.idoubi.net/unity3d/complete-project/252.html
Unity3D 赛车游戏 越野翻滚摩托车 完整源码 Side Scroller Motorcycle v1
http://www.idoubi.net/unity3d/complete-project/249.html
Unity3D 多人射击高仿吃鸡游戏源码 MFPS 2.0 Multiplayer FPS
http://www.idoubi.net/unity3d/complete-project/242.html
Unity3D 多人在线游戏 Ultron Mini Glory
http://www.idoubi.net/unity3d/complete-project/238.html
Unity3D 僵尸类射击游戏源码 Top Down Shooter – Zombie Survival KIT
http://www.idoubi.net/unity3d/complete-project/235.html
Unity3D 格斗游戏 高仿功夫拳皇 源码 Kung Fu2 Fighting
http://www.idoubi.net/unity3d/complete-project/230.html
Unity3D 3d俯视角度科幻射击游戏 Sci Fi Top Down Game Template
http://www.idoubi.net/unity3d/complete-project/228.html
Unity3D 使用超级简单的RPG地图编辑器 rpg-editor
http://www.idoubi.net/unity3d/complete-project/221.html
Unity3D 复古手机游戏源码 RetroBlit
http://www.idoubi.net/unity3d/complete-project/216.html
Unity3D makinom职业游戏工具箱 Makinom Pro Game Toolkit
http://www.idoubi.net/unity3d/complete-project/211.html
Unity3D 2d复古游戏像素包 2D Retro Pixel Art Platformer Pack v1.0
http://www.idoubi.net/unity3d/complete-project/206.html
Unity3D 类似绝地求生FPS游戏 末日生存完整源码 uSurvival
http://www.idoubi.net/unity3d/complete-project/199.html
Unity3D 三消游戏源码 Ultimate Match-Three
http://www.idoubi.net/unity3d/complete-project/201.html
Unity3D 游戏模块化建筑系统 uBuild- In-game modular building system
http://www.idoubi.net/unity3d/complete-project/196.html
Unity3D 手机游戏框架 Turn-Based ToolKit (TBTK)
http://www.idoubi.net/unity3d/complete-project/193.html
Unity3D 高仿微信跳一跳游戏源码 Sky Jump
http://www.idoubi.net/unity3d/complete-project/187.html
Unity3D 低模人物射击游戏 完整源码 Low Poly FPS Pack
http://www.idoubi.net/unity3d/complete-project/171.html
Unity3D 高仿海岛争霸策略游戏源码 Simple City Builder
http://www.idoubi.net/unity3d/complete-project/181.html
Unity3D 第三人称射击游戏源码 Third Person Cover Shooter Template
http://www.idoubi.net/unity3d/complete-project/178.html
Unity3D 3dRPG游戏音效管理 SoundManager for UMMORPG
http://www.idoubi.net/unity3d/complete-project/175.html
Unity3D 高仿疯狂小鸟游戏源码 Flap The Bird
http://www.idoubi.net/unity3d/complete-project/172.html
Unity3D 3d塔防游戏源码 Tower Defense 3D
http://www.idoubi.net/unity3d/complete-project/167.html
Unity3D 格斗游戏 浪人武士 完整源码 ASTS Samurai Warriors
http://www.idoubi.net/unity3d/complete-project/161.html
Unity3D 地牢破坏者游戏源码 Dungeon Breaker
http://www.idoubi.net/unity3d/complete-project/163.html
Unity3D 2d游戏编辑器 Ekume Engine 2D
http://www.idoubi.net/unity3d/complete-project/158.html
Unity3D 儿童益智游戏 打扫屋子 完整源码 House Cleaning
http://www.idoubi.net/unity3d/complete-project/152.html
Unity3D 盒子人跑酷游戏源码 Box Infinite Run
http://www.idoubi.net/unity3d/complete-project/154.html
Unity3D 大炮射击游戏源码 Cannon Siege
http://www.idoubi.net/unity3d/complete-project/149.html
Unity3D 横版街机游戏 盒子人跑酷 完整源码 Mr. Dubstep – 2.5D arcade runner
http://www.idoubi.net/unity3d/complete-project/140.html
Unity3D 3d暗黑魔幻rpg游戏项目源码 RPG Kit
http://www.idoubi.net/unity3d/complete-project/146.html
Unity3D 隧道生存游戏源码 Contrast Tunnel Survival
http://www.idoubi.net/unity3d/complete-project/142.html
Unity3D 沙漠王子跑酷游戏源码 Desert Prince Runner
http://www.idoubi.net/unity3d/complete-project/137.html
Unity3D 模拟经营航空公司游戏 完整源码 Merge Plane (Top Free Game)
http://www.idoubi.net/unity3d/complete-project/131.html
Unity3D 自定义老虎机拉霸游戏框架源码 Custom Slots fr amework
http://www.idoubi.net/unity3d/complete-project/133.html
Unity3D 射箭猎人游戏源码 Archery Hunter – Source Code
http://www.idoubi.net/unity3d/complete-project/128.html
Unity3D 格斗游戏 七龙珠赛亚人之战 完整源码 Dragon ball Saiyan Battle
http://www.idoubi.net/unity3d/complete-project/120.html
Unity3D 像素弹鸟手游源码 Pixel Bounce 2D +Mobile
http://www.idoubi.net/unity3d/complete-project/125.html
Unity3D 危险的龙游戏源码 States Most at Risk Dragon
http://www.idoubi.net/unity3d/complete-project/121.html
Unity3D 忍者武士游戏源码 Ninja Hero v1.0.5
http://www.idoubi.net/unity3d/complete-project/115.html
Unity3D 有1200关卡的2D躲避球游戏完整源码 Complete Game Template With 1200 levels
http://www.idoubi.net/unity3d/complete-project/109.html
Unity3D 2D模拟经营游戏 洗车沙龙 完整源码 Car Wash Salon Game
http://www.idoubi.net/unity3d/complete-project/108.html
Unity3D 3d跳跃的小球游戏完整源码 Wall Ball
http://www.idoubi.net/unity3d/complete-project/99.html
Unity3D 低模仿绝地求生游戏 MMORPG KIT (2D/3D/Survival) v1.36
http://www.idoubi.net/unity3d/complete-project/97.html
Unity3D 2d游戏模板 2D Platformer Easiest Way to make a 2D Game
http://www.idoubi.net/unity3d/complete-project/93.html
Unity3D 城市模拟交通系统完整源码 Driver (Traffic System)
http://www.idoubi.net/unity3d/complete-project/80.html
Unity3D 2D太空战斗机游戏 完整源码 Neon Space Fighter
http://www.idoubi.net/unity3d/complete-project/77.html
Unity3D 休闲打砖头游戏完整源码 BallX Complete Game Template v1.0.1
http://www.idoubi.net/unity3d/complete-project/63.html