说下自我感觉比较难的部分
背包有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 itemGridList = new List();
public UILabel coinNumberLabel;
private int coinCount = 1000;
public GameObject inventoryItem;//拾取到的物品,(模拟)
void Awake()
{
_instance = this;
tween = this.GetComponent();
//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().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();
}
//赋格子信息
public void setId(int id,int num=1)//传来一个id和num
{
this.id = id;
info = objectsInfo._instance.getObjectById(id);//获取object组
inventoryItem item = this.GetComponentInChildren();//本来(物品格子)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().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();
}
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().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();//当前的grid(老grids)
this.transform.parent= surface.transform;//把鼠标下的grid位置赋值给当前grid
ResetPosition(); //点击的是item;只要没被点都是在item 上偏移
inventoryGrid newGrid = surface.GetComponent();//
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 newGrid = surface.GetComponentInParent();//
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().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();
icon.gameObject.SetActive(false);
}
void Start()
{
ps = GameObject.FindGameObjectWithTag(Tags.player).GetComponent();
pa = GameObject.FindGameObjectWithTag(Tags.player).GetComponent();
}
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 skillPre = new Dictionary(); //用数组去遍历
public bool singleDamge = false; //标志单体攻击鼠标图标是否正在使用
public SkillInfo infoSingle = null;
// Use this for initialization
void Awake () {
_instance = this;
move = this.GetComponent();
ps = this.GetComponent();
hudtextFollow = transform.Find("HUDText").gameObject;
normaleColor = body.GetComponent().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();
UIFollowTarget followTarget = HUDTextGo.GetComponent();
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().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().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().CrossFade(animname_death);
state = PlayerState.Death;
}
}
}
IEnumerator ShowBodyRed()
{
body.GetComponent().material.color=Color.red;
yield return new WaitForSeconds(1f);
body.GetComponent().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().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().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().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().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().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().TakeDamage((int)(GetAttack() * info.applyValue / 100f));
passPre.GetComponent().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