Unity 回合制战斗系统(高级篇)

项目文件找出来了,老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的。

需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成

项目包下载

————————————————————————

今天的这篇名字升级到“高级篇”了,因为战斗这块已经实现了原本的学习预期,接下来准备去搞搞角色创建、数据存储和主场景控制这些东西了。

这次高级篇的效果请看Gif:

新增内容如下:

1. 增加了远程兵种--弓箭手

2. 在单位等待行动阶段添加了特效(显示当前等待指令的是那个单位)

3. 最明显的就是场景加了些修饰

4. Gif因为没有音效不带感,实际是有场景和各种攻击音效的

特效资源也是从Assest Store找的免费的KTK Effect Sample Set.unitypackage,关于特效预制体的使用和参数修改看看教程就行,这里就不介绍啦。

本次涉及修改的内容如下:

UnitStats脚本,增加了一个用于区别单位攻击类型的变量。

    public int attackType = 0;          //单位攻击类型,0为近战,1远程

BattleTurnSystem脚本,

···在选中操作单位时根据单位当前position实例化特效预制体

···在得到攻击目标信息后(玩家的指令已经输入完毕)删除特效

下面先标出改动的几个函数,首先是ToBattle函数中获取当前行动对象时的修改

public void ToBattle()
    {
        remainingEnemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
        remainingPlayerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");

        //检查存活敌人单位
        if (remainingEnemyUnits.Length == 0)
        {
            Debug.Log("敌人全灭,战斗胜利");
            endImageText.text = "战斗胜利";
            endImageText.color = Color.green;
            endImage.SetActive(true);           //显示胜利界面
        }
        //检查存活玩家单位
        else if (remainingPlayerUnits.Length == 0)
        {
            Debug.Log("我方全灭,战斗失败");
            endImageText.text = "战斗失败";
            endImageText.color = Color.red;
            endImage.SetActive(true);           //显示失败界面
        }
        else
        {
            //取出参战列表第一单位,并从列表移除
            currentActUnit = battleUnits[0];
            battleUnits.Remove(currentActUnit);
            //重新将单位添加至参战列表末尾
            battleUnits.Add(currentActUnit);
            
            //Debug.Log("当前攻击者:" + currentActUnit.name);

            //获取该行动单位的属性组件
            UnitStats currentActUnitStats = currentActUnit.GetComponent<UnitStats>();

            //判断取出的战斗单位是否存活
            if (!currentActUnitStats.IsDead())
            {
                //在该单位脚底下显示特效
                thisPartical = Instantiate(partical_show, currentActUnit.transform.position, Quaternion.identity) as GameObject;
                //选取攻击目标
                FindTarget();
            }
            else
            {
                //Debug.Log("目标死亡,跳过回合");
                ToBattle();
            }
        }
    }

然后是获取到攻击目标后销毁特效,由于玩家和怪物的选取目标方式不一样,所以有2处要增加销毁命令

void FindTarget()
    {
        if (currentActUnit.tag == "EnemyUnit")
        {
            //如果行动单位是怪物则从存活玩家对象中随机一个目标
            int targetIndex = Random.Range(0, remainingPlayerUnits.Length);
            currentActUnitTarget = remainingPlayerUnits[targetIndex];

            Destroy(thisPartical);          //选择完目标后删除标识当前行动单位的特效

            attackTypeName = "无情撕咬";
            //如果是远程单位直接在这里LaunchAttack,就不需要RunToTarget
            if (currentActUnit.GetComponent<UnitStats>().attackType == 1)
            {
                LaunchAttack();
            }
            else
            {
                
                RunToTarget();
            }
        }
        else if (currentActUnit.tag == "PlayerUnit")
        {
            isWaitForPlayerToChooseSkill = true;
        }
    }

以及

void Update()
    {
        if (isWaitForPlayerToChooseTarget)
        {
            targetChooseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(targetChooseRay, out targetHit))
            {
                if (Input.GetMouseButtonDown(0) && targetHit.collider.gameObject.tag == "EnemyUnit")
                {
                    currentActUnitTarget = targetHit.collider.gameObject;
                    isWaitForPlayerToChooseTarget = false;

                    Destroy(thisPartical);          //选择完目标后删除标识当前行动单位的特效

                    //如果是远程单位直接在这里LaunchAttack,就不需要RunToTarget
                    if (currentActUnit.GetComponent<UnitStats>().attackType == 1)
                    {
                        LaunchAttack();
                    }
                    else
                    {
                        RunToTarget();
                    }
                }
            }
        }

        if (isUnitRunningToTarget)
        {
            currentActUnit.transform.LookAt(currentActUnitTargetPosition);           //单位移动的朝向
            distanceToTarget = Vector3.Distance(currentActUnitTargetPosition, currentActUnit.transform.position);           //到目标的距离,需要实时计算
            //避免靠近目标时抖动
            if (distanceToTarget > 1)
            {
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", true);
                currentActUnit.transform.Translate(Vector3.forward * unitMoveSpeed * Time.deltaTime, Space.Self);         //Time.deltaTime保证速度单位是每秒
            }
            else
            {
                //停止移动
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", false);
                //关闭移动状态
                isUnitRunningToTarget = false;
                //记录停下的位置
                currentactUnitStopPosition = currentActUnit.transform.position;
                //开始攻击
                LaunchAttack();
            }

        }

        if (isUnitRunningBack)
        {
            currentActUnit.transform.LookAt(currentActUnitInitialPosition);            //回来的朝向
            distanceToInitial=Vector3.Distance(currentActUnit.transform.position, currentActUnitInitialPosition);           //离初始位置的距离
            if (distanceToInitial > 1)
            {
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", true);
                currentActUnit.transform.Translate(Vector3.forward * unitMoveSpeed * Time.deltaTime, Space.Self);         //Time.deltaTime保证速度单位是每秒
            }
            else
            {
                //停止移动
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", false);
                //关闭移动状态
                isUnitRunningBack = false;
                //修正到初始位置和朝向
                currentActUnit.transform.position = currentActUnitInitialPosition;
                currentActUnit.transform.rotation = currentActUnitInitialRotation;

                //攻击单位回原位后行动结束,到下一个单位
                ToBattle();
            }
        }
    }


下面贴一下完整的BattleTurnSystem脚本,中间有些小的优化(像攻击动作之后,根据攻击动画时长动态延迟受击)记不太清楚了,就不一一列出来了

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class BattleTurnSystem : MonoBehaviour {

    private List<GameObject> battleUnits;           //所有参战对象的列表
    private GameObject[] playerUnits;           //所有参战玩家的列表
    private GameObject[] enemyUnits;            //所有参战敌人的列表
    private GameObject[] remainingEnemyUnits;           //剩余参战对敌人的列表
    private GameObject[] remainingPlayerUnits;           //剩余参战对玩家的列表

    private GameObject currentActUnit;          //当前行动的单位
    public GameObject currentActUnitTarget;            //当前行动的单位的目标

    public bool isWaitForPlayerToChooseSkill = false;            //玩家选择技能UI的开关
    public bool isWaitForPlayerToChooseTarget = false;            //是否等待玩家选择目标,控制射线的开关
    private Ray targetChooseRay;            //玩家选择攻击对象的射线
    private RaycastHit targetHit;           //射线目标

    private Vector3 currentActUnitInitialPosition;         //当前行动单位的初始位置
    private Quaternion currentActUnitInitialRotation;         //当前行动单位的初始朝向
    private Vector3 currentActUnitTargetPosition;           //当前行动单位目标的位置
    public bool isUnitRunningToTarget = false;            //玩家是否为移动至目标状态
    public bool isUnitRunningBack = false;          //玩家是否为移动回原点状态
    private float distanceToTarget;         //当前行动单位到攻击目标的距离
    private float distanceToInitial;         //当前行动单位到初始位置的距离
    public float unitMoveSpeed = 1f;         //单位战斗中的移动速度
    private Vector3 currentactUnitStopPosition;         //当前行动单位的移动后停下的位置

    public string attackTypeName;           //攻击技能名称
    public float attackDamageMultiplier;           //攻击伤害系数
    public float attackData;            //伤害值

    private GameObject endImage;            //游戏结束画面
    private Text endImageText;          //结束画面文本内容

    public GameObject bloodText;           //保存血条预制体

    public GameObject partical_show;            //展示当前行动单位的特效
    private GameObject thisPartical;            //存储生成的特效

    /// <summary>
    /// 创建初始参战列表,存储参战单位,并进行一次出手排序
    /// </summary>
    void Start ()
    {
        //获取结束菜单的引用,并禁用结束菜单
        endImage = GameObject.Find("ResultImage");
        endImageText = endImage.transform.Find("ResultText").GetComponent<Text>();
        endImage.SetActive(false);
        
        //创建参战列表
        battleUnits = new List<GameObject>();

        //添加玩家单位至参战列表
        playerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
        foreach (GameObject playerUnit in playerUnits)
        {
            battleUnits.Add(playerUnit);
        }

        //添加怪物单位至参战列表
        enemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
        foreach (GameObject enemyUnit in enemyUnits)
        {
            battleUnits.Add(enemyUnit);
        }

        //对参战单位列表进行排序
        listSort();

        //开始战斗
        ToBattle();
    }

    /// <summary>
    /// 判断战斗进行的条件是否满足,取出参战列表第一单位,并从列表移除该单位,单位行动
    /// 行动完后重新添加单位至队列,继续ToBattle()
    /// </summary>
    public void ToBattle()
    {
        remainingEnemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
        remainingPlayerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");

        //检查存活敌人单位
        if (remainingEnemyUnits.Length == 0)
        {
            Debug.Log("敌人全灭,战斗胜利");
            endImageText.text = "战斗胜利";
            endImageText.color = Color.green;
            endImage.SetActive(true);           //显示胜利界面
        }
        //检查存活玩家单位
        else if (remainingPlayerUnits.Length == 0)
        {
            Debug.Log("我方全灭,战斗失败");
            endImageText.text = "战斗失败";
            endImageText.color = Color.red;
            endImage.SetActive(true);           //显示失败界面
        }
        else
        {
            //取出参战列表第一单位,并从列表移除
            currentActUnit = battleUnits[0];
            battleUnits.Remove(currentActUnit);
            //重新将单位添加至参战列表末尾
            battleUnits.Add(currentActUnit);
            
            //Debug.Log("当前攻击者:" + currentActUnit.name);

            //获取该行动单位的属性组件
            UnitStats currentActUnitStats = currentActUnit.GetComponent<UnitStats>();

            //判断取出的战斗单位是否存活
            if (!currentActUnitStats.IsDead())
            {
                //在该单位脚底下显示特效
                thisPartical = Instantiate(partical_show, currentActUnit.transform.position, Quaternion.identity) as GameObject;
                //选取攻击目标
                FindTarget();
            }
            else
            {
                //Debug.Log("目标死亡,跳过回合");
                ToBattle();
            }
        }
    }

    /// <summary>
    /// 查找攻击目标,如果行动者是怪物则从剩余玩家中随机
    /// 如果行动者是玩家,则获取鼠标点击对象
    /// </summary>
    /// <returns></returns>
    void FindTarget()
    {
        if (currentActUnit.tag == "EnemyUnit")
        {
            //如果行动单位是怪物则从存活玩家对象中随机一个目标
            int targetIndex = Random.Range(0, remainingPlayerUnits.Length);
            currentActUnitTarget = remainingPlayerUnits[targetIndex];

            Destroy(thisPartical);          //选择完目标后删除标识当前行动单位的特效

            attackTypeName = "无情撕咬";
            //如果是远程单位直接在这里LaunchAttack,就不需要RunToTarget
            if (currentActUnit.GetComponent<UnitStats>().attackType == 1)
            {
                LaunchAttack();
            }
            else
            {
                
                RunToTarget();
            }
        }
        else if (currentActUnit.tag == "PlayerUnit")
        {
            isWaitForPlayerToChooseSkill = true;
        }
    }

    /// <summary>
    /// 攻击者移动到攻击目标前
    /// </summary>
    void RunToTarget()
    {
        currentActUnitInitialPosition = currentActUnit.transform.position;
        currentActUnitInitialRotation = currentActUnit.transform.rotation;         //保存移动前的位置和朝向,因为跑回来还要用
        currentActUnitTargetPosition = currentActUnitTarget.transform.position;         //目标的位置
        //开启移动状态
        isUnitRunningToTarget = true;
        //移动的控制放到Update里,因为要每一帧判断离目标的距离
    }

    /// <summary>
    /// 绘制玩家选择技能的窗口
    /// </summary>
    void OnGUI()
    {
        if (isWaitForPlayerToChooseSkill == true)
        {
            GUI.Window(1, new Rect(Screen.width / 2 + 300, Screen.height / 2+100, 100, 100), PlayerSkillChoose, "选择技能");
        }
    }

    /// <summary>
    /// 技能选择窗口的回调函数
    /// </summary>
    /// <param name="ID"></param>
    void PlayerSkillChoose(int ID)
    {
        if (GUI.Button(new Rect(10, 20, 80, 30), "普通攻击"))
        {
            isWaitForPlayerToChooseSkill = false;
            isWaitForPlayerToChooseTarget = true;
            attackTypeName = "普通攻击";
            attackDamageMultiplier = 1f;
            Debug.Log("请选择攻击目标......");
        }
        if (GUI.Button(new Rect(10, 60, 80, 30), "英勇打击"))
        {
            isWaitForPlayerToChooseSkill = false;
            isWaitForPlayerToChooseTarget = true;
            attackTypeName = "英勇打击";
            attackDamageMultiplier = 1.5f;
            Debug.Log("请选择攻击目标......");
        }
    }

    /// <summary>
    /// 用户控制玩家选择目标状态的开启
    /// </summary>
    void Update()
    {
        if (isWaitForPlayerToChooseTarget)
        {
            targetChooseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(targetChooseRay, out targetHit))
            {
                if (Input.GetMouseButtonDown(0) && targetHit.collider.gameObject.tag == "EnemyUnit")
                {
                    currentActUnitTarget = targetHit.collider.gameObject;
                    isWaitForPlayerToChooseTarget = false;

                    Destroy(thisPartical);          //选择完目标后删除标识当前行动单位的特效

                    //如果是远程单位直接在这里LaunchAttack,就不需要RunToTarget
                    if (currentActUnit.GetComponent<UnitStats>().attackType == 1)
                    {
                        LaunchAttack();
                    }
                    else
                    {
                        RunToTarget();
                    }
                }
            }
        }

        if (isUnitRunningToTarget)
        {
            currentActUnit.transform.LookAt(currentActUnitTargetPosition);           //单位移动的朝向
            distanceToTarget = Vector3.Distance(currentActUnitTargetPosition, currentActUnit.transform.position);           //到目标的距离,需要实时计算
            //避免靠近目标时抖动
            if (distanceToTarget > 1)
            {
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", true);
                currentActUnit.transform.Translate(Vector3.forward * unitMoveSpeed * Time.deltaTime, Space.Self);         //Time.deltaTime保证速度单位是每秒
            }
            else
            {
                //停止移动
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", false);
                //关闭移动状态
                isUnitRunningToTarget = false;
                //记录停下的位置
                currentactUnitStopPosition = currentActUnit.transform.position;
                //开始攻击
                LaunchAttack();
            }

        }

        if (isUnitRunningBack)
        {
            currentActUnit.transform.LookAt(currentActUnitInitialPosition);            //回来的朝向
            distanceToInitial=Vector3.Distance(currentActUnit.transform.position, currentActUnitInitialPosition);           //离初始位置的距离
            if (distanceToInitial > 1)
            {
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", true);
                currentActUnit.transform.Translate(Vector3.forward * unitMoveSpeed * Time.deltaTime, Space.Self);         //Time.deltaTime保证速度单位是每秒
            }
            else
            {
                //停止移动
                currentActUnit.GetComponent<Animator>().SetBool("Is_move", false);
                //关闭移动状态
                isUnitRunningBack = false;
                //修正到初始位置和朝向
                currentActUnit.transform.position = currentActUnitInitialPosition;
                currentActUnit.transform.rotation = currentActUnitInitialRotation;

                //攻击单位回原位后行动结束,到下一个单位
                ToBattle();
            }
        }
    }
    
    /// <summary>
    /// 当前行动单位执行攻击动作
    /// </summary>
    public void LaunchAttack()
    {
        //存储攻击者和攻击目标的属性脚本
        UnitStats attackOwner = currentActUnit.GetComponent<UnitStats>();
        UnitStats attackReceiver = currentActUnitTarget.GetComponent<UnitStats>();
        //根据攻防计算伤害
        attackData = (attackOwner.attack - attackReceiver.defense + Random.Range(-2, 2)) * attackDamageMultiplier;
        //播放攻击动画
        currentActUnit.GetComponent<Animator>().SetTrigger("Attack");
        currentActUnit.GetComponent<AudioSource>().Play();

        //获取攻击动画长度
        float attackAnimationTime=currentActUnit.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length;
        float damageAnimationTime = attackAnimationTime*0.4f;

        Debug.Log(currentActUnit.name + "使用技能(" + attackTypeName + ")对" + currentActUnitTarget.name+"造成了"+ attackData + "点伤害");
        
        //在对象承受伤害前添加延迟(伤害在动作砍下去就得出现)
        StartCoroutine(WaitForTakeDamage(damageAnimationTime));

        //下一个单位行动前延时
        StartCoroutine(WaitForRunBack(attackAnimationTime));
    }

    /// <summary>
    /// 对参战单位根据攻速计算值进行出手排序
    /// </summary>
    void listSort()
    {
        GameObject temp = battleUnits[0];
        for (int i = 0; i < battleUnits.Count - 1; i++)
        {
            float minVal = battleUnits[i].GetComponent<UnitStats>().attackTrun;       //假设i下标的是最小的值
            int minIndex = i;       //初始认为最小的数的下标

            for (int j = i + 1; j < battleUnits.Count; j++)
            {
                if (minVal > battleUnits[j].GetComponent<UnitStats>().attackTrun)
                {
                    minVal = battleUnits[j].GetComponent<UnitStats>().attackTrun;
                    minIndex = j;
                }
            }
            temp = battleUnits[i];       //把本次比较的第一个位置的值临时保存起来
            battleUnits[i] = battleUnits[minIndex];       //把最终我们找到的最小值赋给这一趟的比较的第一个位置
            battleUnits[minIndex] = temp;        //把本次比较的第一个位置的值放回这个数组的空地方,保证数组的完整性
        }

        for (int x = 0; x < battleUnits.Count; x++)
        {
            Debug.Log(battleUnits[x].name);
        }
    }

    /// <summary>
    /// 延时操作函数,避免在怪物回合操作过快
    /// </summary>
    /// <returns></returns>
    IEnumerator WaitForTakeDamage(float time)
    {
        yield return new WaitForSeconds(time);

        //被攻击者承受伤害
        currentActUnitTarget.GetComponent<UnitStats>().ReceiveDamage(attackData);

        //实例化伤害字体并设置到画布上(字体位置和内容的控制放在它自身的脚本中)
        GameObject thisText = Instantiate(bloodText) as GameObject;
        thisText.transform.SetParent(GameObject.Find("BloodTextGroup").transform, false);

        if (!currentActUnitTarget.GetComponent<UnitStats>().IsDead())
        {
            currentActUnitTarget.GetComponent<Animator>().SetTrigger("TakeDamage");
        }
        else
        {
            currentActUnitTarget.GetComponent<Animator>().SetTrigger("Dead");
        }

    }

    IEnumerator WaitForRunBack(float time)
    {
        yield return new WaitForSeconds(time);
        //远程单位不需要跑回来,延迟后直接下个单位行动
        if (currentActUnit.GetComponent<UnitStats>().attackType == 1)
        {
            ToBattle();
        }
        else
        {
            //此时开启跑回状态
            isUnitRunningBack = true;
        }
        
    }
}

至此战斗部分的学习和实现告一段落。

同样在学习Unity的同志们如果有疑问可以留言哈,共同学习进步


 

  • 24
    点赞
  • 139
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
回合制自己写的 战斗DEMO 加动画状态 Q键移动并攻击。 代码很简单。不要抱有太大希望 。作为新手学习使用。 public enum HeroStatus { idle = 0, //空闲 attack, //攻击 other, //其他 hit, //受击 die, //死亡 defense, //防御 cast, //施法 miss, //闪避 seriousInjury, //重伤 move, //移动 exit, //获取下一个状态 MAX, } public class hero : MonoBehaviour { public UISpriteAnimation m_spriteAnimation = null; public HeroStatus m_staus = HeroStatus.exit; //身体碰撞盒 public BoxCollider m_bodyBC = null; public string m_name = ""; public AttackCrash m_attackCrash = null; public byte m_posIndex = 0; void Awake() { m_spriteAnimation = transform.GetComponent(); m_bodyBC = transform.GetComponent(); } // Use this for initialization void Start () { m_spriteAnimation.AddFrameCallBack("attack", 1, AttackCallBack); m_spriteAnimation.AddFrameCallBack("attack", 4, AttackCallBack); m_spriteAnimation.AddFrameCallBack("attack", 7, AttackCallBack); } public float m_speed = 1f; public float m_offset = 0.5f; public Vector3 m_destination = Vector3.zero; public List m_actionList = new List(); // Update is called once per frame void Update () { switch (m_staus) { case HeroStatus.idle: //空闲状态 if (m_actionList.Count > 0) m_staus = HeroStatus.exit; break; case HeroStatus.attack: if (!m_spriteAnimation.isPlaying) { //攻击动画播放完毕 m_staus = HeroStatus.exit; } break; case HeroStatus.defense: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.hit: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.die: break; case HeroStatus.cast: break; case HeroStatus.miss: break; case HeroStatus.seriousInjury: break; case HeroStatus.move: transform.position = Vector3.MoveTowards(transform.position, m_destination, m_speed * Time.deltaTime); if (transform.position == m_destination) m_staus = HeroStatus.exit; break; case HeroStatus.exit: //获取下一个状态 if (m_actionList.Count > 0) { string str = "idle"; switch(m_actionList[0].status) { case HeroStatus.move: str = "idle"; break; default: str = Enum.GetName(typeof(HeroStatus), m_actionList[0].status); break; } m_spriteAnimation.namePrefix = str; m_spriteAnimation.loop = m_actionList[0].loop; m_destination = m_actionList[0].destinationMove; m_speed = m_actionList[0].speed; m_spriteAnimation.ResetToBeginning(); m_staus = m_actionList[0].status; m_actionList.RemoveAt(0); } else { m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); m_spriteAnimation.loop = true; m_spriteAnimation.ResetToBeginning(); m_staus = HeroStatus.idle; } break; // case HeroStatus.moveback: // //transform.position = Vector3.SmoothDamp(transform.position, destinationMove, ref cameraVelocity, smoothTime); // transform.position = Vector3.MoveTowards(transform.position, destinationMove, m_speed * Time.deltaTime); // if (transform.position == destinationMove) // m_staus = HeroStatus.idle; // break; } } public void SetPosition(byte pos, float x, float y) { m_posIndex = pos; transform.localPosition = new Vector3(x, y); } public void AttackCallBack() { //创建攻击特效 A攻击B B掉血222 B反击A闪避 UnityEngine.Object sourceObj = Resources.Load("AttackCrash"); GameObject go = UnityEngine.Object.Instantiate(sourceObj) as GameObject; go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localPosition = new Vector3(-70, 0, 0); } private void OnCollisionEnter(Collision co) { //进入碰撞 Debug.Log("进入碰撞!"); UnityEngine.Object sourceObj = Resources.Load("Effect"); GameObject go = UnityEngine.Object.Instantiate(sourceObj) as GameObject; go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localPosition = new Vector3(0, 0, 0); //Defense(); Hit(); } public void Attack(GameObject aims) { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.move; tmpAD.loop = true; UISprite tmpS = transform.GetComponent(); tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(aims.transform.localPosition.x + (tmpS.width/2), aims.transform.localPosition.y)); tmpAD.speed = Vector3.Distance(transform.position, tmpAD.destinationMove) * 4; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.attack; tmpAD1.loop = false; tmpAD1.destinationMove = Vector3.zero; tmpAD1.speed = 0; m_actionList.Add(tmpAD1); ActionData tmpAD2 = new ActionData(); tmpAD2.status = HeroStatus.move; tmpAD2.loop = true; tmpAD2.destinationMove = transform.position; tmpAD2.speed = Vector3.Distance(tmpAD.destinationMove, tmpAD2.destinationMove) * 4; //4/1秒到达目的地 m_actionList.Add(tmpAD2); } public void Defense() { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.defense; tmpAD.loop = false; tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(transform.localPosition.x - 25, transform.localPosition.y)); tmpAD.speed = 0.25f; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.move; tmpAD1.loop = false; tmpAD1.destinationMove = transform.position; tmpAD1.speed = 0.8f; //4/1秒到达目的地 m_actionList.Add(tmpAD1); } public void Hit() { ActionData tmpAD = new ActionData(); tmpAD.status = HeroStatus.hit; tmpAD.loop = false; tmpAD.destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(transform.localPosition.x - 25, transform.localPosition.y)); tmpAD.speed = 0.3f; //4/1秒到达目的地 m_actionList.Add(tmpAD); ActionData tmpAD1 = new ActionData(); tmpAD1.status = HeroStatus.move; tmpAD1.loop = false; tmpAD1.destinationMove = transform.position; tmpAD1.speed = 0.8f; //4/1秒到达目的地 m_actionList.Add(tmpAD1); } public void Idle() { m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); m_spriteAnimation.loop = true; m_spriteAnimation.ResetToBeginning(); m_staus = HeroStatus.idle; } public void Move() { // //transform.GetComponent().depth = 99; // GameObject go = GameObject.Find("enemy").gameObject; // destinationMove = GameObject.Find("UI Root/Camera").transform.TransformPoint(new Vector3(go.transform.localPosition.x + 98,go.transform.localPosition.y,go.transform.localPosition.z)); // m_speed = Vector3.Distance(transform.position, destinationMove) * 4; //4/1秒到达目的地 // m_staus = HeroStatus.moveto; // m_spriteAnimation.namePrefix = Enum.GetName(typeof(HeroStatus), HeroStatus.idle); // m_spriteAnimation.loop = true; // m_spriteAnimation.ResetToBeginning(); }
根据引用中提到的情景模式,"SCENE_MODE_NIGHT"是相机支持的夜景模式。根据引用中的描述,当相机设置为"USE_SCENE_MODE"时,必须使用"ANDROID_CONTROL_SCENE_MODE"来确定3A算法的行为。对于"SCENE_MODE_NIGHT",HAL可能会倾向于使用连续对焦(AF)模式,以便在夜间场景下获得更好的焦点。此外,在"SCENE_MODE_FACE_PRIORITY"下,AE/AWB/AF模式的工作方式与在"ANDROID_CONTROL_MODE_AUTO"模式下相同,但3A算法会倾向于进行测光,并对焦于已检测到的人脸。 因此,"SCENE_MODE_NIGHT"是相机的夜景模式,可以在夜间场景下获得更好的焦点。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span> #### 引用[.reference_title] - *1* *2* *3* [android中Camera获取系统支持的情景模式](https://blog.csdn.net/weixin_35899510/article/details/117764760)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *4* [Android Camera 3A 模式和状态转换](https://blog.csdn.net/haiping1224746757/article/details/106472497)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值