如何用U3D写一个SLG战斗场景

本文详细介绍了如何使用Unity3D构建一个SLG战斗场景,包括图形层和逻辑层的设计。图形层涉及地图层、地块层、角色层和UI层的实现,逻辑层涵盖回合制战斗和人物状态管理。提供了关键代码片段,并分享了一个完整的DEMO场景链接。作者同时表达了寻找成都游戏行业工作的意向。
摘要由CSDN通过智能技术生成

一般分为图形层和逻辑层

1.图形层:

架构如图:
架构如图
1.1 地图层:最底层为地图层,用于放置战斗地形图片,需要注意的是图形的大小和分辨率。分辨率代码如下,新建一个空物体然后挂上脚本,PS:我这里是固定分辨率,也可以进行动态调节。

public class ScreenMamager : MonoBehaviour {
   
    // Use this for initialization
    void Start () {
   
        if (Application.platform == RuntimePlatform.WindowsPlayer)
        {
   
            float height = Screen.height;
            Screen.SetResolution(1280, 768, true);
            Camera.main.orthographicSize = height / 200;
        }
        else if (Application.platform == RuntimePlatform.Android)
        {
   
            float height = Screen.height;
            Screen.SetResolution(1280, 768, true);
            Camera.main.orthographicSize = height / 200;
        }
    }

1.2 地块层:该层是由一个个战斗地块(四边形/六边形/菱形)拼凑组成,注意给每个地块添加一个布尔属性用于控制该地块是否可以通过(脚本代码如下)。

 public class IsCross : BattleManage {
   
    public bool isCross = false;
}

1.3 角色层 : 该层主要实现人物的模型显示,移动动画,技能等特效。
在这里插入图片描述
1.4 UI层:该层主要实现战斗界面,包括人物血条 蓝条,各种战斗文本信息显示,如上图。

2.逻辑层:

1.回合实现->2.人物状态定义以及实现

2.1回合实现

流程图如下:
在这里插入图片描述
代码如下:

public class Battle : MonoBehaviour {
   
    public static List<GameObject> fieldMesh;          //地块
    public static List<GameObject> charactor = new List<GameObject>();  //战斗角色
    public static readonly float Distence = 1.15f; //相邻地块的间距
    private int turn;    //turn状态
    private int currentCharactorNum;   //回合内当前角色在fieldMesh的下标
    private int roundNum;   //回合数
    enum turnState {
    begin = 0, inTurn = 1, turnOver = -1 };//定义三个状态:回合开始 回合中 回合结束
    public enum charactorState {
    idle = 0, walk = 1, skill = 2, die = 3 };

    // Use this for initialization
    void Start() {
   
        fieldMesh = new List<GameObject>(GameObject.FindGameObjectsWithTag("field"));
        //      CharactorPositon();
        InitMap();
        Touch();
        turn = (int)turnState.begin;
        currentCharactorNum = 0;
        roundNum = 1;
    }

    //初始化角色位置
    private void CharactorPositon()
    {
   
        int i = 0;
        int j = fieldMesh.Count - 1;
        foreach (GameObject obj in charactor)
        {
   
            if (i < j)
                if (obj.CompareTag("Player"))
                {
   
                    obj.transform.position = new Vector3(fieldMesh[i].transform.position.x, fieldMesh[i].transform.position.y, 0);
                    i++;
                }
                else if (obj.CompareTag("enemy"))
                {
   
                    obj.transform.position = new Vector3(fieldMesh[j].transform.position.x, fieldMesh[i].transform.position.y, 0);
                    j--;
                }
        }
    }

    //初始化地图
    public static void InitMap()
    {
   
        foreach (GameObject obj in fieldMesh)
        {
   
            obj.GetComponent<SpriteRenderer>().color = Color.white;
            obj.GetComponent<IsCross>().isCross = false;
        }
    }

    //给战场添加角色
    public static void AddCharactor(GameObject[] player, GameObject[] enemy)
    {
   
        charactor.Clear();
        charactor.AddRange(player);
        charactor.AddRange(enemy);
    }


    //回合
    private void Update()
    {
   
        switch (turn)
        {
   
            case (int)turnState.begin:
                TurnBegin();
                break;
            case (int)turnState.turnOver:
                TurnOut();
                break;
        }
        if (BattleEnd())
        {
   
            SceneManager.LoadScene(0);
        }
    }
    //回合开始
    private void TurnBegin()
    {
   
        turn = (int)turnState.inTurn;
        Debug.Log("这是第" + roundNum + "回合");
        this.BroadcastMessage("CharactorActive", charactor[currentCharactorNum].name);

    }

    //对象和地块碰撞
    public static void Touch()
    {
   
        foreach (GameObject charactor in Battle.charactor)
            foreach (GameObject obj in Battle.fieldMesh)
            {
   
                float dis = Vector2.Distance(charactor.transform.position, obj.transform.position);
                if (dis < 0.1)
                {
   
                    obj.GetComponent<SpriteRenderer>().color = Color.red;
                    obj.GetComponent<IsCross>().isCross = false;
                }
            }
    }
		
    //回合结束
    private void TurnOut()
    {
   
        currentCharactorNum = 0;
        roundNum++;
        Debug.Log("回合结束");
        turn = (int)turnState.begin;
    }

    //接收角色激活信息
    public void CharactorDeactive(string name)
    {
   
        GameObject obj = GameObject.Find(name);
        int index = charactor.IndexOf(obj);
        if (index==charactor.Count-1)
        {
   
            turn = (int)turnState.turnOver;
            return;
        }
        
        Debug.Log("下一个角色激活");
        this.BroadcastMessage("CharactorActive", charactor[index+1].name);
    }

    //角色移动范围与地块碰撞检测
    public static List<GameObject> OnTriggerField(float distence, GameObject playerOrEnemy)
    {
   
        Battle.InitMap();
        List<GameObject> field = new List<GameObject>();
        field.Clear();
        foreach (GameObject obj in Battle.fieldMesh)
        {
   
            float dis = Vector2.Distance(playerOrEnemy.transform.position, obj.transform.position);
            if (distence > dis)
            {
   
                obj.GetComponent<SpriteRenderer>().color = Color.red;
                obj.GetComponent<IsCross>().isCross = true;
                field.Add(obj);
            }
        }
        Battle.Touch();
        return field;
    }

    private bool BattleEnd()
    {
   
        List<GameObject> player = new List<GameObject>();
        List<GameObject> enemy = new List<GameObject>();
        foreach (GameObject obj in charactor)
        {
   
            if (obj.CompareTag("Player"))
            {
   
                player.Add(obj);
            }
            else if (obj.CompareTag("enemy"))
            {
   
                enemy.Add(obj);
            }
        }
        if (player.Count == 0 || enemy.Count == 0)
        {
   
            return true;
        }
        else return false;
    }
}
2.2人物的状态

2.2.1 玩家的状态以及实现,包括:手动移动 技能施放等,代码如下:

    public class Player : MonoBehaviour {
   
    private bool isActive;//当前角色是否激活
    private int state; //当前人物状态
    private float moveRange = Battle.Distence *
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值