基于"RPG项目01_场景及人物动画管理器",我们创建一个XML文档
在资源文件夹下创建一个文件夹,

命名为Xml

将Xnl文档拖拽至文件夹中,

再在文件夹的Manager下新建脚本LoadManager


写代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadManager
{
public static AudioClip LoadAudio(string str) {
AudioClip clip = Resources.Load<AudioClip>("Audio/" + str);
return clip;
}
public static GameObject LoadGameObject(string str)
{
GameObject obj = Resources.Load<GameObject>("Prefab/" + str);
return obj;
}
public static Sprite LoadSprite(string str)
{
Sprite sprite = Resources.Load<Sprite>("Pic/" + str);
return sprite;
}
public static TextAsset LoadXml(string str)
{
TextAsset t = Resources.Load<TextAsset>("Xml/" + str);
return t;
}
}
继续在Manager文件夹下创建脚本
新建GameManager脚本:


using System.Collections.Generic;
using System.Xml;
using Unity.VisualScripting;
using UnityEngine;
public enum GameState { Play, Menu };
public class GameManager{
//当只需要一个的时候使用静态类
public static GameState gameState = GameState.Play;
public static void Init()
{
//SetGoods();
}
public static T FindType<T>(Transform t, string n)
{
return t.Find(n).GetComponent<T>();
}
public static T ParseEnum<T>(string value)
{
return (T)System.Enum.Parse(typeof(T), value, true);
}
}
继续在Manager文件夹下创建脚本

写代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainGame : MonoBehaviour
{
public static Transform canvas;
private void Awake()
{
GameManager.Init();
canvas = transform;
}
}
再在Scripts脚本文件夹下新建文件夹命名为:Living(活着的生物)

在Living创建基类People(狼人也是人)


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class People : MonoBehaviour{
}
再创建两个子类:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyPlayer : People
{
}
第二个子类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : People
{
}
重新修改MainGame代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainGame : MonoBehaviour
{
public static Transform canvas;
public static MyPlayer player;
private void Awake()
{
GameManager.Init();
player = GameObject.Find("Player").GetComponent<MyPlayer>();
canvas = transform;
}
}
接下来挂载脚本:
再挂载人物脚本:

新建脚本文件夹Data

新建脚本DataObject

写代码(数据类:为角色提供数据):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DataObject : MonoBehaviour
{
public string _name;
public int hp = 100;
public int mp = 100;
public int hpMax = 100;
public int mpMax = 100;
public int lv;
[Header("速度:")]
public float spd = 3;
[Header("攻击:")]
public int att;
[Header("防御:")]
public int def;
[Header("魔抗:")]
public int mdf;
[Header("经验价值:")]
public int expValue;
[Header("金钱价值:")]
public int goldValue;
[Header("攻击力稳定值:")]
public int randomAtk;
}
将DataObject脚本挂载到Player人物上

运行

在文件夹下创建SkillBase
写代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public enum SkillType { Up, Magic, Physics };
public class SkillBase : MonoBehaviour
{
}
修改People代码:

using System.Collections.Generic;
using UnityEngine;
public class People : MonoBehaviour{
//等价知识点:1 = 2
//1.public int Num { get; }
//------------------------------
//2.int num;
// public int Num(){
// return num;
// }
public DataObject data;
public int Hp {
protected set {
data.hp = value;
}
get {
return Mathf.Clamp(data.hp, 0, HpMax);
}
}
public int HpMax {
protected set {
data.hpMax = value;
}
get {
return data.hpMax + OffsetHp;
}
}
public int Mp
{
protected set
{
data.mp = value;
}
get
{
return Mathf.Clamp(data.mp, 0, MpMax);
}
}
public int MpMax
{
protected set
{
data.mpMax = value;
}
get
{
return data.mpMax + OffsetMp;
}
}
public float Spd {
protected set {
data.spd = value;
}
get {
return data.spd + OffsetSpd;
}
}
public int Att
{
protected set
{
data.att = value;
}
get
{
return (int)(data.att * GetRandomRate()) + OffsetAtt;
}
}
public int Def
{
protected set
{
data.def = value;
}
get
{
return data.def + OffsetDef;
}
}
public int Mdf
{
protected set
{
data.mdf = value;
}
get
{
return data.mdf + OffsetMdf;
}
}
public int lv
{
protected set => data.lv = value;
get => data.lv;
}
public int Exp { set; get; }
public bool IsDeath { set; get; }
public People Target { get; set; }
public Animator Anim { get; set; }
protected int OffsetHp { set; get; }
protected int OffsetMp { set; get; }
protected int OffsetSpd { set; get; }
protected int OffsetAtt { set; get; }
protected int OffsetDef { set; get; }
protected int OffsetMdf { set; get; }
public Transform attPoint;
public delegate void Fun(People p);
protected event Fun Dead;
protected Dictionary<int, SkillBase> skills = new Dictionary<int, SkillBase>();
#region 初始化
protected virtual void InitValue()
{
Anim = GetComponent<Animator>();
data = GetComponent<DataObject>();
Dead = Death;
}
protected virtual void InitSkill()
{
}
#endregion
#region 事件
public void AddEventHandle(Fun funback)
{
Dead += funback;
}
public void RemoveEventHandle(Fun funback)
{
Dead -= funback;
}
protected virtual void Death(People p)
{
IsDeath = true;
Anim.SetTrigger("IsDeath");
p.Victory(this);
Invoke("Over", 5);
}
protected virtual void Victory(People p)
{
}
protected void Over()
{
print("over");
}
#endregion
#region 战斗伤害
protected float GetRandomRate()
{
return (Random.Range(-data.randomAtk, data.randomAtk + 1) + 100) * 0.01f;
}
public virtual void BePhysicsHit(int value, People p)
{
if (IsDeath)
{
return;
}
Hp -= value - Def;
UpdateUI();
if (Hp <= 0)
{
Dead(p);
}
}
public virtual void BeMagicHit(int value, People p)
{
if (IsDeath)
{
return;
}
Hp -= value - Mdf;
UpdateUI();
if (Hp <= 0)
{
Dead(p);
}
}
#endregion
#region Hp/Mp
public virtual void AddHp(int value)
{
Hp += value;
UpdateUI();
}
public virtual void AddMp(int value)
{
Mp += value;
UpdateUI();
}
public float GetHpRation()
{
return (float)Hp / HpMax;
}
#endregion
protected void Start()
{
InitSkill();
InitValue();
}
protected virtual void UpdateUI()
{
}
}
知识点:Image的冷却填充作用
创建两个Image父子物体:

将父物体放置一个图片,

对子物体添加一个半透明画面

调节子物体颜色及半透明度

类型选择为填充Fill

调节即可制作冷却

知识点结束,可以把Image删了

修改MyPlayer脚本代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyPlayer : People
{
[Header("==============子类变量==============")]
public Transform toolPanel;
new void Start() {
base.Start();
}
private void Update()
{
}
}
在Living脚本文件夹下新建脚本CameraCtrl


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraCtrl : MonoBehaviour
{
public float dis;
public float height;
public float speed;
Transform target;
Vector3 targetPos;
// Start is called before the first frame update
void Start()
{
target = MainGame.player.transform;
}
// Update is called once per frame
void Update()
{
transform.LookAt(target.position + Vector3.up * 1.5f);
targetPos = target.forward * (-dis) + target.up * height + target.position;
}
private void LateUpdate()
{
transform.position = Vector3.Lerp(transform.position, targetPos, speed);
}
}
更新MyPlayer代码:

再将CameraCtrl摄像机跟随代码挂载在Camera摄像机上

调节CameraCtrl数值后运行

如果不想运行时摄像机千里跟随,就可以将角色的位置复制给摄像机:


最后设置一下设摄像机的y轴调高一点
完成阶段代码